LINUX.ORG.RU

смешанная динамическая и статическая линковка в одной команде gcc


0

2

Собираю ffmpeg, мне нужно, чтобы библиотеки кодеков в него вкомпилировались статически. Для некоторых кодеков у меня доступны только .a-библиотеки, для некоторых и .so и .a - насколько я понял, при обычном вызове gcc в первом случае он подхватит статическую .a-библиотеку, при наличии выбора - из .so и .a он выберет .so.

Нашел опцию -static - вроде оно и судя по логам configure, он пытается подхватить статические библиотеки вместо динамических, но вылезла другая проблема - gcc совсем отказался от динамической линковки. Это вылелось в то, что некоторые статические библиотеки не подлючаются с ошибкой «undefined reference to `acosf'», хотя -lm в командной строке указана - просто в системе нет статической версии libm.a, а есть только динамическая libm.so.

На тестовом файле:

> gcc -lm test.cc

все ок

> gcc -static -lm test.cc
/tmp/cchTDfOq.o: In function `main':
test.cc:(.text+0xd): undefined reference to `acosf'
collect2: ld returned 1 exit status
-lm test.cc
/tmp/cchTDfOq.o: In function `main':
test.cc:(.text+0xd): undefined reference to `acosf'
collect2: ld returned 1 exit status

Можно как-нибудь сделать, чтобы при опции -static персонально -lm линковать динамически, или указать более мягкую преференцию - если доступна статическая библиотека - использовать ее, если только динамическая - использовать динамическую?

★★★★★

Как видно из мануала, они взаимоисключаемые.
cmake в этом случае разруливает двумя разными каталогами сборки и соответствующими параметрами (shared/static).

UVV ★★★★★
()
Ответ на: комментарий от crutch

спасибо, скомпилял:

gcc -static -Wl,-Bdynamic -lm test.cc


без ошибок, но при запуске a.out:
bash: ./a.out: No such file or directory

мда, в общем, походу проще или откопать где-нибудь libm.a, или переименовать все .so'шки на время компиляции, чтобы не мешали подцеплять .a.

bender ★★★★★
() автор топика

В общем, статическая libm.a оказывается была в системе, но gcc ее в упор не хотел видеть даже с -static, судя по беглому просмотру топиков в инете стало ясно, что прилинковать статически стандартные либы тоже та еще задача, да и изначально у меня цели такой не стояло. В конечном итоге переименовал все шаредные либы ".so" так, чтобы линкер их не находил и видел только их статические варианты ".a" и скомпилял без флага -static. Жесть конечно.

bender ★★★★★
() автор топика
Ответ на: комментарий от Shtucer

>Винду не пробовал переустановить?
пока нет, но с таким набором доступных опций этот способ решения проблем перестает казаться таким смешным, как раньше.

LIBPATH не спасет?


От переменной окружения LIBRARY_PATH толку мало, т.к. *.so и *.a файлы лежат в одном каталоге. Есть вариант скопировать все *.a файлы в одно место (что уже является кривостью) и задать LIBRARY_PATH туда, но у меня все эти либы установлены в /usr/lib (это кодеки из репозитория vlc) - там эти so-шки gcc все равно находит полюбому в первую очередь вне зависимости от того, задана LIBRARY_PATH или пустая. В голову приходит только удаление vlc со всеми либами на время компиляции, что равносильно переименованию. Есть способ исключить весь /usr/lib из списка поиска либ для конкретной команды gcc? - такой костыль по крайней мере помог бы обойтись без переименования.

bender ★★★★★
() автор топика

можно указывать библиотеки не только в -l параметре ,
но и именем файла напрямую, с динамическими библиотеками этого хотя лучше не делать, а вот статику вполне можно задавать

$gcc test.c /usr/lib/libm.a -o test

gcc -static -lm test.cc

кстати .cc расширения для .c (gcc) лучше не использовать, это для C++ (g++)

Sylvia ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.