Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么ld需要我的可执行文件所依赖的库?_C++_Linux_G++_Ld - Fatal编程技术网

C++ 为什么ld需要我的可执行文件所依赖的库?

C++ 为什么ld需要我的可执行文件所依赖的库?,c++,linux,g++,ld,C++,Linux,G++,Ld,我正在尝试使用以下命令构建我的可执行文件(这取决于库utils.so g++ -L/path/to/libutils -lutils -I/path/to/utils_headers executable.cpp -o executable 实际上我没有utils.so-只有utils库的头文件 我得到了一个错误: ld: cannot find -lutils 链接器真的需要访问我的可执行文件所依赖的所有库才能构建我的可执行文件吗?如果有,我想知道为什么需要访问它们 我的可执行文件是一个共

我正在尝试使用以下命令构建我的可执行文件(这取决于库utils.so

g++ -L/path/to/libutils -lutils -I/path/to/utils_headers executable.cpp -o executable
实际上我没有utils.so-只有utils库的头文件

我得到了一个错误:

ld: cannot find -lutils
链接器真的需要访问我的可执行文件所依赖的所有库才能构建我的可执行文件吗?如果有,我想知道为什么需要访问它们


我的可执行文件是一个共享库。我确信utils库的头文件足以构建它(即没有utils.so)。

通常,ELF链接器需要链接到的共享对象的足够精确的表示形式。它不一定是一个实际工作的共享对象,而只是它的一个足够接近的表示。有几件事情需要对象本身不可用的数据:

  • 编译C程序时,对不完整类型的全局数据对象的引用不包含大小信息。链接器无法将对象放入数据段,除非它从某处获取大小信息。默认情况下(为可执行文件(包括饼图)编译时),由于编译器用于编译对全局数据对象的访问的重新定位,因此需要在多个目标上的数据段中分配对象
  • 类似地,如果链接编辑器没有足够的信息,它可能会错误地对齐全局数据对象
  • 许多库使用符号版本控制。符号版本信息仅在链接编辑器可以看到共享对象时可用。如果缺少该信息,链接编辑器将不会发出符号版本,这将指示动态链接器在运行时将符号绑定到基本版本,从而导致微妙的错误

但是,如果只使用C函数符号(不是数据符号,或者C++所需的符号种类),并且目标库不使用符号版本控制,则可以使用存根库进行链接。这是一个库,它定义了您需要的所有函数,并具有适当的soname,但这些函数只是虚拟函数,实际上不做任何事情。

默认情况下,链接选项
-lutils
指示链接器进行搜索, 首先在指定的库搜索目录(
-Ldir
)中,然后 在其默认搜索目录中,查找任何文件
libutils.so
( 共享库)或
libutils.a
(静态库),首选
libutils.so
如果在同一搜索目录中找到这两个

如果找到这样的文件,链接器将停止搜索并添加该文件 链接的输入文件,无论它是否解析中的任何引用 联系。链接器无法知道文件是否解析任何引用 如果没有输入文件

如果没有找到这样的文件,链接器会给出错误:
找不到-lutils
。因为 您告诉它查找
libutils.{so | a}
,但它找不到

你说:

我的可执行文件是一个共享库

但事实并非如此。编译和链接命令:

$ g++ -L/path/to/libutils -lutils -I/path/to/utils_headers executable.cpp -o executable
不是试图链接共享库。它试图链接一个程序。1

这将尝试链接共享库:

$ g++ -shared -I/path/to/utils_headers -o libexecutable.so executable.cpp -L/path/to/libutils -lutils
不能将程序链接到未解析的引用。但您可以链接共享库 有未解析的引用

所以,你可以链接一个
libexecutable.So
这样,或者你可以像这样链接它:

$ g++ -shared -I/path/to/utils_headers -o libexecutable.so executable.cpp
这是两种不同的链接:如果成功,它们将生成不同的输出文件

在第一个链接中,一些符号(假设)将解析为
libutils.so
libutils.a
(以找到的为准),这将通过以下方式反映:

  • libutils.so
    找到:
    libexecutable的
    .dynamic
    部分。so
    包含所需的
    dtu
    表示对
    libutils.so
    的运行时依赖关系的结构
    libutils.so
    将需要包含在包含
    libexecutable.so
    的任何链接中,但此类链接的输出文件本身将仅包含对
    libexecutable.so的运行时依赖项

  • libutils。找到一个
    libexecutable。因此
    本身包含所有符号的定义 它使用由
    libutils.a
    .2
    libexecutable.so中的对象文件定义的对象。因此
    可以包含在后续链接中,而不需要
    libutils.{so | a}

在第二个链接中,
libexecutable.so的
.dynamic
部分将不表示运行时 依赖于
libutils.so
文件也不会包含
libutils.{so | a}
提供的任何符号的定义
libutils.so
将(再次)需要包含在包含
libexecutable.so
的后续链接中,但此类链接的输出文件将获得对
libexecutable.so
libutils.so的独立运行时依赖关系

但是,如果在链接或任何链接中指定
-lutils
,并且链接器无法找到
libutils.{so | a}
在它的任何搜索目录中,您都会看到您观察到的错误,因为您告诉了链接器 输入一个文件,该文件对链接的影响只有在找到该文件时才能确定和实现,但无法找到该文件


[1] 可能失败的尝试,因为

[2] 看懂
为什么。

我不是在运行它,我只是在构建它。可能有未解决的符号,对吗?你所说的“拥有所有符号”是什么意思?我有所有的符号-它们在头文件中声明。这足以编译源文件并将目标文件放入可执行文件中。在这种情况下,为什么要添加
-lutils
?如果所有符号都在