在今天之前,我始终认为在链接阶段将对象和库传递给g ++的顺序并不重要.然后,今天,我尝试从c ++代码链接到c代码.我将所有C头文件包装在一个extern"C"块中,但链接器仍然很难找到我知道在C对象归档中的符号.
困惑,我创建了一个相对简单的例子来隔离链接错误,但令我惊讶的是,更简单的示例链接没有任何问题.
经过一些试验和错误后,我发现通过模拟简单示例中使用的链接模式,我可以得到主要代码链接OK.模式首先是对象代码,对象归档第二,例如:
g++ -o serverCpp serverCpp.o algoC.o libcrypto.a
任何人都可以解释为什么会这样吗?我在链接普通的c ++代码时从未见过这个问题.
小智 43
您指定目标文件和库的顺序在GCC中非常重要 - 如果您在领导一个充满魅力的生活之前没有被这种情况所困扰.链接器按照它们出现的顺序搜索符号,因此如果您有一个包含对库函数调用的源文件,则需要将其放在库之前,否则链接器将不知道它必须解析它.复杂的库使用意味着你必须不止一次地指定库,这是一个正确的痛苦.
Mar*_*k B 20
传递给gcc/g ++的库顺序确实很重要.如果A
依赖于B
,则必须首先列出A. 原因是它优化了未引用的符号,因此如果它B
首先看到库,并且没有人在那时引用它,那么它根本不会链接任何东西.
静态库是分组到存档中的目标文件的集合.链接时,链接器只选择解析当前未定义符号所需的对象.由于对象是按命令行给定的顺序链接的,因此只有当库位于依赖于它的所有对象之后,才会包含库中的对象.
所以链接顺序非常重要; 如果您要使用静态库,那么您需要小心跟踪依赖关系,并且不要在库之间引入循环依赖关系.
小智 3
您可以使用--start-group archives --end-group
和编写 2 个依赖库而不是存档:
gcc main.o -L. -Wl,--start-group -lobj_A -lobj_b -Wl,--end-group
Run Code Online (Sandbox Code Playgroud)