#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 » в команде.