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”选项的位置如何,库都会被链接。