#include <stdio.h>
int main()
{
printf("%s","Hello world");
return 0;
}
$gcc -o hello hello.c
问题:
1 - 我相信printf函数的目标文件是静态链接的。这是对的吗?
2 - 如何配置/编写此代码以便库文件是动态链接的,或者我的意思是它在运行时使用共享库?
注意:我是这个概念的初学者,所以无论在哪里都没有意义,请随时纠正我
答案 0 :(得分:3)
链接器会获取它找到的任何内容。这通常是共享库。
在Linux系统上,您可以使用
file hello
找出它是静态链接还是动态链接。
E.g。
file /bin/bash
给出
/ bin / bash:ELF 64位LSB可执行文件,x86-64,版本1(SYSV),动态链接(使用共享库),用于GNU / Linux 2.6.24,BuildID [ sha1] = 0x6dafe33f9353cbb054b1b1f7b079545992575757,剥离
而
file /bin/busybox
给出
/ bin / busybox:ELF 64位LSB可执行文件,x86-64,版本1(SYSV),静态链接,适用于GNU / Linux 2.6.24,BuildID [sha1] = 0xac4943b7daf7c3c204a2866ea5398f2337ff93c9,剥离
您可以通过向gcc
添加-static
选项来强制使用静态链接
gcc -static -o hello hello.c
file hello
/ tmp / hello:ELF 64位LSB可执行文件,x86-64,版本1(GNU / Linux),静态链接,对于GNU / Linux 2.6.24,BuildID [sha1] = 0x790ec9b287fd2a276162560e5e6669ba6b73e68f,未剥离
更新
链接是将目标文件,动态和静态库以及一些样板对象放在一起的过程,以形成二进制可执行文件。
您可以在一个可执行文件中同时使用动态和静态库。将静态库所需的目标文件复制到可执行文件中。另一方面,动态库(实际上是动态对象)不会被复制,而是由生成的二进制文件引用。
更新
有两种库,静态库(ar archives,请参阅man ar
)
file /usr/lib/libnet.a
/usr/lib/libnet.a: current ar archive
和动态库(动态对象)
file /usr/lib/libnet.so.1.5.0
/usr/lib/libnet.so.1.5.0: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0x0c596357947e79001025b3c57be933690085dffb, stripped
您可以同时安装两种类型的库,例如
ls -l /usr/lib/libnet.*
-rw-r--r-- 1 root root 207780 Okt 28 2011 /usr/lib/libnet.a
-rw-r--r-- 1 root root 802 Okt 28 2011 /usr/lib/libnet.la
lrwxrwxrwx 1 root root 15 Okt 28 2011 /usr/lib/libnet.so -> libnet.so.1.5.0
lrwxrwxrwx 1 root root 15 Okt 28 2011 /usr/lib/libnet.so.1 -> libnet.so.1.5.0
-rw-r--r-- 1 root root 92712 Okt 28 2011 /usr/lib/libnet.so.1.5.0
ar
存档包含一个或多个目标文件,如果可执行文件需要,链接器会选择这些目标文件。共享对象是具有子例程的对象,允许在运行时由其他共享对象或可执行文件调用。
如果您对此主题感兴趣,还可以查看此Wikipedia - Library (computing)文章。