g не может связать библиотеку libatomic с агентом пользователя Microsoft

#azure-devops #linker #g #build-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(amp;a, amp;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 в списке отображается не 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 просто другой или я упускаю какой-либо очевидный вариант компоновщика?

Обновление Это фундаментальная концепция для порядка поиска символов компоновщика, которую я пропустил. Обычно компоновщик ищет символы слева направо, но для некоторых современных компоновщиков поиск выполняется во всех библиотеках независимо от порядка. Я протестировал это на одной из моих виртуальных машин ubuntu, и изменение порядка работает так, как ожидалось.

Обновится, как только я протестирую с помощью размещенного в Microsoft агента пользователя.

Обновление 2 Я могу подтвердить, что это разница между компоновщиком gcc в Ubuntu и Debian на моей локальной машине.

Ответ №1:

Чтобы ответить на мой собственный вопрос.

Разница, которую я обнаружил, заключается в том, что на компьютере Ubuntu компоновщик gcc выполняет поиск символов в порядке слева направо. Таким образом, размещение «- latomic » перед исходным файлом приведет к тому, что ссылка не будет найдена, а библиотека не будет связана.

На моей локальной машине Debian компоновщик выполняет поиск в обоих направлениях, поэтому библиотека связана независимо от расположения параметра «- l » в команде.