sjs*_*sam 10 c++ g++ unix-ar static-linking nm
我有两个文件37064544_p1.cpp,37064544_p2.cpp内容相同,如下所示:
int add(int x,int y)
{
return x+y;
}
Run Code Online (Sandbox Code Playgroud)
我用它们编译了它们
g++ -c 37064544_p2.cpp -o 37064544_p2.o
g++ -c 37064544_p2.cpp -o 37064544_p2.o
Run Code Online (Sandbox Code Playgroud)
并使用将它们添加到存档中
ar -rsc lib37064544pf.a 37064544_p1.o 37064544_p2.o
Run Code Online (Sandbox Code Playgroud)
和
$ nm -s lib37064544pf.a 
Run Code Online (Sandbox Code Playgroud)
给我 :
Archive index:
_Z3addii in 37064544_p1.o
_Z3addii in 37064544_p2.o
37064544_p1.o:
0000000000000000 T _Z3addii
37064544_p2.o:
0000000000000000 T _Z3addii
Run Code Online (Sandbox Code Playgroud)
和
$ ar -t lib37064544pf.a 
Run Code Online (Sandbox Code Playgroud)
给我
37064544_p1.o
37064544_p2.o
Run Code Online (Sandbox Code Playgroud)
我有一个驱动程序,它调用_Z3addii编译的函数
g++ -static 37064544driver.cpp -o 37064544driver.elf -L. -l37064544pf
Run Code Online (Sandbox Code Playgroud)
结果是
Sum : 11
Run Code Online (Sandbox Code Playgroud)
问题
符号是如何_Z3addii解决的?
ar?我该如何更改此订单?
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
Run Code Online (Sandbox Code Playgroud)
或者您可以进行部分链接而不是传统的存档,如果有任何重复项,则会出现错误
ld -r -o lib37064544pf.a 37064544_p1.o 37064544_p2.o
Run Code Online (Sandbox Code Playgroud)