我正在一个非常大的c++项目中工作,以创建一个大的共享对象,我们正在使用一个外部SDK,其中有几个头文件和几个属于彼此的共享库。这意味着SDK类的声明在头文件中,但它们的定义在共享对象中。
我明白,由于头文件中的声明,我可以编译这段代码。
但是我不明白的是什么时候我必须明确地为链接器指定使用的共享对象?
也就是说,如果我指定它(例如在cmake中使用target_link_libraries命令),那么链接器可以检查符号是否在共享库中。但是,如果我不指定它会发生什么(即没有任何-l[shared_object_name]标志在联动)?我的经验是(这让我感到惊讶),它工作正常(即整个建筑过程完成)。这怎么可能?
在POSIX共享库中,您可以在共享库中使用未定义的符号,并且所有符号都可以正常链接。只要可执行文件被完全链接,就不会有链接错误。
这样做是因为动态库模仿静态库的行为,并且静态库可以有未定义的符号(静态库一开始就没有链接)。
如果你使用的是Windows操作系统,那么你会很惊讶,因为Windows dll中不能有未定义的符号。
如果您担心这一点,您可以检查链接器选项--no-undefined
和--no-allow-shlib-undefined
我的经验是(这让我很惊讶)工作正常(即整个建筑过程完成)。
这似乎不太可能。
fact…
这怎么可能?
。
唯一的解释是没有使用那些库文件中定义的符号。它们要么在第三方代码的标题部分,要么根本不是第三方代码的一部分。或者您正在构建自己的共享库。但是,最终的可执行文件仍然需要链接到第三方库。