为什么在可执行文件的编译期间我们需要共享库的存在?我的理由是,由于共享库未包含在我的可执行文件中并在运行时加载,因此在编译期间不应该需要它。或者我错过了什么?
#include<stdio.h>
int addNumbers(int, int); //prototype should be enough, no?
int main(int argc, char* argv[]){
int sum = addNumbers(1,2);
printf("sum is %d\n", sum);
return 0;
}
我当前目录中有libfoo.so
,但我将其名称更改为libfar.so
,以发现编译时需要共享库,或者它不能编译。
gcc -o main main.c -L. -lfoo
提供main.c:(.text+0x28): undefiend reference to 'addNumber'
我认为仅拥有共享库的名称就足够了。不需要共享库本身,因为它在LD_LIBRARY_PATH中找到并在运行时动态加载。除了共享库的名称之外是否还需要其他东西?
答案 0 :(得分:5)
编译时无需任何操作,因为C有单独编译翻译单元的概念。但是,一旦编译完所有不同的来源,就可以将所有内容链接在一起了。共享库的概念在标准中不存在,但它现在是常见的,所以这里是通用链接器如何进行:
这会生成可执行文件。然后在加载时,动态加载程序知道所需的所有动态模块,并将它们与实际可执行文件一起加载到内存中(如果它们尚未存在)并构建(虚拟)内存映射
答案 1 :(得分:0)
gcc -o main main.c -L. -lfoo
此命令执行(至少)两个步骤:将main.c
编译为目标文件,并将所有资源链接到可执行文件main
。您看到的错误来自最后一步,即链接器。
链接器负责生成最终的可执行机器代码。它需要共享对象库,因为它需要生成加载它的机器代码并执行其中使用的任何函数。