如何解析外部符号

How are external symbols resolved?

本文关键字:符号 外部 何解析      更新时间:2023-10-16

我有两个文件37064544_p1.cpp&37064544_p2.cpp,内容如下:

int add(int x,int y)
{
return x+y;
}

我用编译了它们

g++ -c 37064544_p2.cpp -o 37064544_p2.o
g++ -c 37064544_p2.cpp -o 37064544_p2.o

并使用将它们添加到档案中

ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o

$ nm -s lib37064544pf.a 

给我:

Archive index:
_Z3addii in 37064544_p1.o
_Z3addii in 37064544_p2.o
37064544_p1.o:
0000000000000000 T _Z3addii
37064544_p2.o:
0000000000000000 T _Z3addii

$ ar -t lib37064544pf.a 

给我

37064544_p1.o
37064544_p2.o

我有一个驱动程序,它调用用编译的_Z3addii函数

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf

结果是

Sum : 11

问题

  1. 符号_Z3addii是如何解析的?

    • 是否根据档案索引
    • 它是否根据我们使用ar填充归档的顺序
  2. 如何更改此订单?

  3. 如何防止ar具有重复符号

编译器:g++4.6.3

符号_Z3addii是如何解析的?

实现可以自由地做它喜欢做的任何事情,这违反了一个定义规则。

实际上,在第一次匹配后,它将停止寻找任何给定的符号,这可能遵循文件插入存档的顺序。

如何更改此订单?

使用ar,在插入对象文件时,可以使用a(after)和b(before)修饰符在归档中定位对象文件,但这仍然违反了ODR。

如何防止ar有重复的符号?

据我所知,ar相对来说是愚蠢的,这是有充分理由的,因为有些语言确实允许相同的符号,这就是为什么在链接到存档时不会出现任何错误(ODR违规不需要诊断)。

您可以强制ld读取整个档案

g++ -static 37064544driver.cpp -o 37064544driver.elf -L. 
-Wl,--whole-archive -l37064544pf -Wl,--no-whole-archive

或者你可以做一个部分链接,而不是传统的存档,如果有任何重复的,这会给你一个错误

ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o
相关文章: