我正在尝试使用以下命令构建可执行文件(取决于库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 lib的头文件足以构建它(即没有utils.so)。
答案 0 :(得分:3)
默认情况下,链接选项-lutils
指导链接器进行搜索,
首先在指定的库搜索目录(-Ldir
)中,然后
在其默认搜索目录中,对于文件libutils.so
(
共享库)或libutils.a
(静态库),最好使用libutils.so
如果两者都在同一搜索目录中。
如果找到了这样的文件,则链接器将停止搜索并添加该文件 链接的输入文件,是否解析其中的任何引用 链接。链接器无法知道文件是否解析任何引用 如果没有输入文件。
如果未找到此类文件,则链接器将给出错误:cannot find -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
: .dynamic
的{{1}}部分包含libexecutable.so
表示对DT_NEEDED
的运行时依赖性的结构。 libutils.so
将需要包含在任何包含libutils.so
的链接中,但是这种链接的输出文件本身将仅包含对libexecutable.so
的运行时依赖性。
libexecutable.so
: libutils.a
本身包含所有符号的定义
它使用libexecutable.so
中的目标文件定义的。 2 libutils.a
可以包含在后续链接中,而无需libexecutable.so
。
在第二个链接中,libutils.{so|a}
的{{1}}部分将不表示运行时
对.dynamic
nor 的依赖将使文件包含libexecutable.so
提供的任何符号的定义。 (再次)需要将libutils.so
包括在包含libutils.{so|a}
的后续链接中,但是这种链接的输出文件将获得对libutils.so
和{{1}的独立运行时依赖关系}。
但是,如果您在链接(或任何链接)中指定libexecutable.so
,则链接程序将找不到libexecutable.so
在其任何搜索目录中,然后您都会看到所观察到的错误,因为您告诉链接器
输入一个文件,只有在找到该文件的情况下,才能确定该文件对链接的影响,并且无法找到该文件。
[1]由于it consumes libraries before the object files that refer to them
而可能失败的尝试[2]请参见static-libraries以了解 为什么。
答案 1 :(得分:2)
通常,ELF链接器需要足够准确地表示链接到的共享库。它不一定是实际工作的共享库,而只是一个足够接近的表述。 绝对需要一些在对象本身中不可用的数据:
但是,如果仅使用C函数符号(而不是数据符号或C ++所需的各种符号),并且目标库不使用符号版本控制,则可以将存根库用于链接。这是一个库,它定义了您需要的所有功能,并具有适当的名称,但是这些功能只是虚拟实体,实际上不执行任何操作。