g++ 不能 link Microsoft 用户代理上的 libatomic 库
g++ cannot link libatomic library on Microsoft user-agent
我有一个非常简单的虚拟程序调用 main.c,如下所示:
#include <stdlib.h>
#include <stdio.h>
#define TEST __atomic_compare_exchange
void test() {
__int128 unsigned a = 1, b = 2, c = 3;
__atomic_compare_exchange_16(&a, &b, c, 1, 1, 1);
printf("hello");
}
当使用以下命令编译时,它在我的本地 Linux 机器(Debian gcc 版本 6)上工作正常:
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
然而,当使用 Microsoft 托管代理 ubuntu-18.04 时,无论我尝试什么命令,它都会失败。以下是我尝试过的命令列表:
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
g++ --shared -o libmain.so /usr/lib/x86_64-linux-gnu/libatomic.so.1 main.c -Wl,--no-as-needed
g++ --shared -o libmain.so -L/usr/lib/x86_64-linux-gnu/ -l:libatomic.so.1 main.c -Wl,--no-as-needed
当运行 ldd libmain.so
not libatomic 显示在列表中时:
linux-vdso.so.1 (0x00007ffc3c5b6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f889324e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8892eb0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8892c98000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88928a7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f889385d000)
当 运行 readelf -W -s libatomic.so
时,__atomic_compare_exchange_16 显示为未定义,没有任何后缀 @...
指示要查找的 libatomic 库。
Symbol table '.dynsym' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __atomic_compare_exchange_16
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (3)
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 22 _edata
9: 0000000000201040 0 NOTYPE GLOBAL DEFAULT 23 _end
10: 000000000000070a 150 FUNC GLOBAL DEFAULT 12 _Z4testv
11: 00000000000005c0 0 FUNC GLOBAL DEFAULT 9 _init
12: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 23 __bss_start
13: 00000000000007a0 0 FUNC GLOBAL DEFAULT 13 _fini
我也检查了 g++ --print-search-dirs
,库搜索目录对我来说看起来都是正确的。
Microsoft Hosted Agent 环境只是不同还是我缺少任何明显的链接器选项?
更新
这是我错过的链接器符号搜索顺序的基本概念。通常,链接器从左到右搜索符号,但对于一些现代链接器,搜索所有库而不考虑顺序。我已经在我的另一个 ubuntu VM 上测试过这个并且改变顺序确实按预期工作。
将在我使用 Microsoft 托管的用户代理进行测试后进行更新。
更新 2
我可以确认这是 Ubuntu 和我本地机器 Debian 中的 gcc 链接器之间的区别。
回答我自己的问题。
我发现的不同之处在于,在 Ubuntu 机器上,gcc 链接器似乎以从左到右的顺序搜索符号。因此,在源文件之前放置“-latomic”会导致找不到引用并且不会链接库。
在我的本地 Debian 机器上,链接器会双向搜索,因此无论命令中“-l”选项的位置如何,库都会被链接。
我有一个非常简单的虚拟程序调用 main.c,如下所示:
#include <stdlib.h>
#include <stdio.h>
#define TEST __atomic_compare_exchange
void test() {
__int128 unsigned a = 1, b = 2, c = 3;
__atomic_compare_exchange_16(&a, &b, c, 1, 1, 1);
printf("hello");
}
当使用以下命令编译时,它在我的本地 Linux 机器(Debian gcc 版本 6)上工作正常:
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
然而,当使用 Microsoft 托管代理 ubuntu-18.04 时,无论我尝试什么命令,它都会失败。以下是我尝试过的命令列表:
g++ --shared -o libmain.so -latomic main.c -Wl,--no-as-needed
g++ --shared -o libmain.so /usr/lib/x86_64-linux-gnu/libatomic.so.1 main.c -Wl,--no-as-needed
g++ --shared -o libmain.so -L/usr/lib/x86_64-linux-gnu/ -l:libatomic.so.1 main.c -Wl,--no-as-needed
当运行 ldd libmain.so
not libatomic 显示在列表中时:
linux-vdso.so.1 (0x00007ffc3c5b6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f889324e000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8892eb0000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8892c98000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88928a7000)
/lib64/ld-linux-x86-64.so.2 (0x00007f889385d000)
当 运行 readelf -W -s libatomic.so
时,__atomic_compare_exchange_16 显示为未定义,没有任何后缀 @...
指示要查找的 libatomic 库。
Symbol table '.dynsym' contains 14 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND __atomic_compare_exchange_16
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __stack_chk_fail@GLIBC_2.4 (3)
5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTable
6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
8: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 22 _edata
9: 0000000000201040 0 NOTYPE GLOBAL DEFAULT 23 _end
10: 000000000000070a 150 FUNC GLOBAL DEFAULT 12 _Z4testv
11: 00000000000005c0 0 FUNC GLOBAL DEFAULT 9 _init
12: 0000000000201038 0 NOTYPE GLOBAL DEFAULT 23 __bss_start
13: 00000000000007a0 0 FUNC GLOBAL DEFAULT 13 _fini
我也检查了 g++ --print-search-dirs
,库搜索目录对我来说看起来都是正确的。
Microsoft Hosted Agent 环境只是不同还是我缺少任何明显的链接器选项?
更新 这是我错过的链接器符号搜索顺序的基本概念。通常,链接器从左到右搜索符号,但对于一些现代链接器,搜索所有库而不考虑顺序。我已经在我的另一个 ubuntu VM 上测试过这个并且改变顺序确实按预期工作。
将在我使用 Microsoft 托管的用户代理进行测试后进行更新。
更新 2 我可以确认这是 Ubuntu 和我本地机器 Debian 中的 gcc 链接器之间的区别。
回答我自己的问题。
我发现的不同之处在于,在 Ubuntu 机器上,gcc 链接器似乎以从左到右的顺序搜索符号。因此,在源文件之前放置“-latomic”会导致找不到引用并且不会链接库。
在我的本地 Debian 机器上,链接器会双向搜索,因此无论命令中“-l”选项的位置如何,库都会被链接。