Связывание частично статическое и частично динамическое в GCC
Я пытаюсь скомпилировать очень простую (простую, как hello world) программу на C, используя как динамическое, так и статическое соединение с GCC. Я хочу знать, как это сделать в целом, поэтому мой минимальный тестовый пример просто пытается связать libc как статический и libm динамически.
Я столкнулся, по крайней мере, со следующими другими вопросами по той же теме:
GCC: статическое связывание только некоторых библиотек
Статическая ссылка функции разделяемой библиотеки в gcc
В некоторых ответах на это предлагаются такие вещи, как использование -Wl,-Bstatic и -Wl,-Bdynamic для указания, какие библиотеки являются соответственно статическими и динамическими. Также предлагается, среди прочего, просто указать полный путь статической библиотеки для ссылки.
Я попробовал несколько из этих предложений, и их варианты. Я не понимаю сообщение об ошибке, которое оно мне дает. Я знаю, что такое пирог, но не понимаю, как это связано с тем, что я пытаюсь сделать.
Вот несколько неудачных попыток:
$ 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
Компиляция просто без аргументов и с -static работают нормально, но мне нужна частичная статическая компиляция:
$ gcc test.c -lm
$ gcc -static test.c -lm
Однако следующее тоже не работает:
$ gcc test.c /usr/lib64/libc.a /usr/lib64/libm.a
Я сталкивался с подобной ошибкой в этом посте:
C++ Статически связанная разделяемая библиотека
Однако ответы, похоже, не относятся к моей проблеме.
Программа, которую я пытаюсь скомпилировать, просто (как test.c):
#include <stdio.h>
#include <math.h>
int main(int argc, char **argv)
{
int i = 0;
for(i = 0; i < 65535; i++) {
printf("%f\n", sinf(i));
printf("%f\n", cosf(i));
printf("%f\n", tanf(i));
printf("%f\n", sqrtf(i));
}
return 0;
}
РЕДАКТИРОВАТЬ: Обратите внимание, что программа должна быть достаточно сложной, чтобы фактически потребовать libm, в противном случае попытки связывания могут дать ложные срабатывания, если libm действительно не требуется. В моем исходном примере test.c я использовал только sinf() для постоянного значения, что заставило компилятор полностью оптимизировать вызов sinf().
Я использую:
$ gcc --version
gcc (Gentoo 4.7.3-r1 p1.4, pie-0.5.5) 4.7.3
1 ответ
Следующее сработало для меня
ln -s `gcc -print-file-name=libc.a`
gcc -static-libgcc -L. -lc test.c
затем ldd a.out
дает:
not a dynamic executable
Редактировать:
ОП хочет связать одну библиотеку динамически, а другую статически. У него есть пример ссылки libc
статически и libm
динамически. Именно этого конкретного случая мне не удалось достичь. Однако возможно и обратное, т.е. libc
динамически и libm
статически.
ln -s `gcc -print-file-name=libm.a`
gcc test.c -L. -lm
затем ldd a.out
дает
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0x41960000)
/lib/ld-linux.so.2 (0x4193d000)
Обратите внимание, что порядок ссылок имеет значение.eg gcc -L. -lm test.c
не работает.
Это работает и с другими библиотеками. Например gomp
gcc -fopenmp test.c
лдд шоу libgomp.so.1
, Мы можем связать это статически, как это
ln -s `gcc -print-file-name=libgomp.a`
gcc -L. -fopenmp test.c
Сейчас ldd a.out
не показывает libgomp.so.1
, Но в этом случае pthreads
все еще динамически связан. Для статического связывания pthreads требуется, чтобы libc
быть связаны статически, а также.