Следующие вопросы актуальны, но не отвечают на мой вопрос:
Связывание частично статичного и частично динамического в GCC
GCC: статическая привязка только к некоторым библиотекам
Статическая ссылка функции общей библиотеки в gcc
Я задал очень похожий вопрос раньше, но так как предыдущий вопрос, начатый мной, несколько захламлен в разделе комментариев и не полностью ответил (но я отметил его как ответ, так как он был хорошим усилием и хотя бы частично ответил на него ) Я задам новый вопрос. Вопрос в том, как связать libc как статический, а динамически связывать некоторую другую библиотеку (например, libm). Было высказано предположение, что это невозможно сделать в первом вопросе, верно ли это? Если так, было бы очень интересно знать, почему бы и нет.
Возможно ли это сделать? Кто-то сделал комментарий (который по какой-то причине был удален, может быть, он был неправильным?), Но это возможно, но там также должна существовать динамически связанная версия libc, так как она потребуется динамической библиотеке (например, динамическая libm будет требуют динамического libc (?)).
Это хорошо для меня, но для меня не очевидно, как сказать GCC, чтобы сделать это, т.е. ссылку в libc как статическую, так и динамическую. Как это сделать (я сделал пару попыток, некоторые из них показаны позже в вопросе)? Или есть какой-то другой способ сделать то, что я хочу?
Сначала мы видим, что простым запуском gcc test.c -lm все связано динамически следующим образом:
$ gcc test.c -lm
$ ldd a.out
linux-vdso.so.1 (0x00007fffb37d1000)
libm.so.6 => /lib64/libm.so.6 (0x00007f3b0eeb6000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3b0eb10000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3b0f1b0000)
Чтобы связать только libm как статический, позволяя libc оставаться динамическим, мы можем сделать (как указал Z бозон в одном из вышеупомянутых вопросов):
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libm.a
$ ldd a.out
linux-vdso.so.1 (0x00007fff747ff000)
libc.so.6 => /lib64/libc.so.6 (0x00007f09aaa0c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f09aadb2000)
Однако попытка выполнить ту же самую процедуру для ссылки на libc static и libm dynamic не работает:
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
Что означает это сообщение об ошибке?
Некоторые другие попытки (большинство из них также были включены в мой первый вопрос):
$ gcc test.c /usr/lib64/libc.a
linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
urned 1 exit status
$ gcc test.c -Wl,-Bdynamic -lm -Wl,-Bstatic -lc
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bdynamic -lm -Wl,-Bstatic -lc test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
$ gcc -Wl,-Bstatic -lc -Wl,-Bdynamic -lm test.c
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so -lm
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../x86_64-pc-linux-gnu/bin/ld: dynamic STT_GNU_IFUNC symbol `strcmp' with pointer equality in `/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a(strcmp.o)' can not be used when making an executable; recompile with -fPIE and relink with -pie
collect2: error: ld returned 1 exit status
$ gcc test.c /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.so /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/../../../../lib64/libc.a -lm
Обратите внимание, что последний успешно скомпилирован/связан. Однако libc не был связан статически, только динамически, поэтому это еще одна неудачная попытка.
Программа тестирования проста:
$ cat test.c
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i;
int result;
for(i = 0; i < 65535; i++) {
result = sin(i);
}
return 0;
}
Edit:
Я также попробовал статику и горностай, как это было предложено в этом вопросе:
Статическая ссылка функции общей библиотеки в gcc
Ничего не работает.