Компиляция с -static-libgcc -static-libstdС++ по-прежнему приводит к динамической зависимости от libc.so
Я пытаюсь сделать исполняемый файл максимально переносимым. После удаления нескольких зависимостей я столкнулся с следующим при запуске двоичного файла в другой системе:
/lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.15' not found (required by foob)
/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by foob)
Я бы предпочел, чтобы мой двоичный файл не требовал от пользователя обновления своей версии libc, поэтому я также хотел бы удалить эту зависимость.
Флаги компоновщика, которые произвели вышеупомянутый бинарный файл, уже включили -static-libgcc -static-libstdc++
. Как получилось, что двоичный файл все еще требуется для общего libc.so.6?
Я также попытался добавить флаг -static
, однако, когда я пытаюсь запустить этот двоичный файл, результат очень странный:
$ ls -l foob
-rwxr-xr-x 1 claudiu claudiu 13278191 Oct 10 13:03 foob
$ ./foob
bash: ./foob: No such file or directory
Что делать?
EDIT:
$ file foob
foob: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=5adee9a598b9261a29f1c7b0ffdadcfc72197cd7, not stripped
$ strace -f ./foob
execve("./foob", ["./foob"], [/* 64 vars */]) = -1 ENOENT (No such file or directory)
write(2, "strace: exec: No such file or di"..., 40strace: exec: No such file or directory
) = 40
exit_group(1) = ?
+++ exited with 1 +++
Интересно, что если я ldd
версия без -static
, у нее есть две меньше записей, чем версия с -static
, а именно:
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f4f420c1000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f4f41636000)
Ответы
Ответ 1
GNU libc не предназначен для статической привязки. Важные функции, например. gethostbyname
и iconv
, будут неисправны или вообще не работают в статическом двоичном формате. Вероятно, еще хуже, при некоторых условиях статический двоичный файл будет пытаться динамически открывать и использовать libc.so.6
, хотя вся точка статической связи должна избегать таких зависимостей.
Вы должны скомпилировать свою программу против uClibc или musl libc.
(Это верно в течение как минимум 15 лет.)
Ответ 2
Прежде всего помните, что статическая привязка libc может не улучшить переносимость вашей программы, так как libc может зависеть от других частей вашей системы, например. версии ядра.
Если вы хотите попробовать статическое связывание, просто используя -static, следует трюк. При условии наличия статических версий всех используемых библиотек.
Вы можете проверить, связана ли ваша программа только с статическими библиотеками, используя:
ldd binary_name
EDIT:
Другим способом, который предоставляет полезную информацию для отладки этой проблемы, было бы добавить --verbose к вашим флагам компоновщика.