2015-09-30 223 views
0

我正在一个非常大的C++项目中创建一个大的共享对象,我们在这里使用一个外部SDK,其中有几个头文件和几个共享库,它们都属于对方。这意味着SDK类的声明在头文件中,但它们的定义在共享对象中。将共享对象链接到其他共享对象C++项目

据我所知,由于头文件中的声明我可以编译这段代码。

但我不明白的是什么时候我必须明确指定链接器使用的共享对象?

即如果我指定它(例如,在与target_link_libraries命令cmake的),则链接器可以检查一个符号将在共享库或没有。但是如果我没有指定它会发生什么(即链接中没有任何-l [shared_object_name]标志)?我的经验是(令我感到惊讶的)是正常工作(即整个建筑过程已完成)。它怎么可能?

+0

一些编译器,如Microsoft-VC有一个'#pragma',它允许你在源代码中指定编译器和链接器选项。 Boost使用它根据编译器宏自动选择正确的共享库。 – rodrigo

+0

我们在linux下使用GCC,不使用#pragma :( –

回答

3

在POSIX共享库中,您可以在共享库中有未定义的符号,并且所有链接都可以很好地链接。只要可执行文件完全链接,就不会有链接程序错误。

这样做是因为动态库模仿静态库的行为,而静态库可能有未定义的符号(静态库没有链接,开始)。

如果你来自Windows的背景,那么它会让你感到意外,因为Windows DLL不能有未定义的符号。

如果您担心这一点,您可以检查链接选项--no-undefined--no-allow-shlib-undefined

+0

这意味着在可执行文件中它必须链接我的共享对象和共享对象中使用的共享对象?相反,我的共享对象无法找到使用的符号的主体。 –

+0

@TiborTakács:是的。您的共享对象不是_trying_来查找其他共享对象中的符号。这一切都得到解决时,你建立一个实际的可执行文件 –

+0

@TiborTakács:如果第二个SO中的第一个SO链接,它会在第一个SO头中添加一个“NEEDED”条目,这样当该exe链接到第一个SO时,第二个SO将自动链接。但是如果你连接第一个SO而没有第二个SO,那么EXE将需要链接到两者,否则它将失败。 – rodrigo

2

我的经验是(令我感到惊讶的)工作正常(即整个建筑过程完成)。

这似乎不太可能。

实际上...... hellip;

这怎么可能?

不是。

唯一的解释是你使用的符号在不是这些库文件中定义的符号。它们或者只在第三方代码的标头部分,或者根本不属于第三方代码。

或者您正在构建您自己的共享库。不过,最终的可执行文件仍然需要链接第三方库。

+1

我也在创建一个共享库,这是一个原因吗? –

+0

@TiborTakács:是的,这是一个至关重要的细节,应该从一开始就在问题中现在,我的答案的原始最后一段是你要找的。 –