Связывание частично статическое и частично динамическое в 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 быть связаны статически, а также.

Другие вопросы по тегам