Как я могу статически связать только некоторые определенные библиотеки с моим двоичным файлом при связывании с GCC?
gcc ... -static ...
пытается статически связать все связанные библиотеки, но у меня нет статической версии некоторых из них (например: libX11).
gcc
linker
static-libraries
Пеоро
источник
источник
Ответы:
gcc -lsome_dynamic_lib code.c some_static_lib.a
источник
code.c
файлом гарантирует, что символы в ней будут проигнорированы, если только не произойдетmain()
функции в одном из библиотеки объектных файлов.Вы также можете использовать
ld
опцию-Bdynamic
Все библиотеки после него (включая системные библиотеки, автоматически подключаемые gcc) будут связаны динамически.
источник
вы также можете использовать:
-static-libgcc -static-libstdc++
flags для библиотек gccимейте в виду, что если
libs1.so
иlibs1.a
оба существуют, компоновщик выберетlibs1.so
, до-Wl,-Bstatic
или после-Wl,-Bdynamic
. Не забудьте пройти-L/libs1-library-location/
перед звонком-ls1
.источник
-static
где-то в команде не работает (я предполагаю, что он пытается статически связать больше вещей, чем только библиотеки, которые мне нужны).-Wl,-Bstatic
и-Wl,-Bdynamic
важен.На странице руководства
ld
(это не работает с gcc), ссылаясь на--static
параметр:Одно из решений - поставить динамические зависимости перед
--static
параметром в командной строке.Другая возможность - не использовать
--static
, а вместо этого предоставить полное имя файла / путь к статическому объектному файлу (то есть без использования опции -l) для статической компоновки конкретной библиотеки. Пример:Как видно из примера,
libX11
его нет в списке динамически подключаемых библиотек, поскольку он был связан статически.Осторожно:
.so
файл всегда связан динамически, даже если он указан с полным именем файла / путем.источник
ldd a.out
?ldd
выводит необходимые разделяемые библиотеки, а libX11 не появляется в этом списке.Проблема, как я понимаю, в следующем. У вас есть несколько библиотек, некоторые статические, некоторые динамические, а некоторые статические и динамические. По умолчанию gcc связывает "в основном динамические". То есть, когда это возможно , gcc ссылается на динамические библиотеки, но в остальном возвращается к статическим библиотекам. Когда вы используете параметр -static для gcc, поведение заключается в том, чтобы связывать только статические библиотеки и выходить с ошибкой, если статическая библиотека не может быть найдена, даже если есть соответствующая динамическая библиотека.
Другой вариант, о котором я несколько раз мечтал иметь gcc , - это то, что я называю -mostly-static и по сути является противоположностью -dynamic (по умолчанию). -mostly-static , если бы он существовал, предпочел бы связываться со статическими библиотеками, но вернулся бы к динамическим библиотекам.
Этого варианта не существует, но его можно эмулировать с помощью следующего алгоритма:
Создание командной строки ссылки без включения -static .
Перебирайте параметры динамической ссылки.
Накапливать пути к библиотекам, т.е. те параметры формы -L <lib_dir> в переменной <lib_path>
Для каждой опции динамической ссылки, то есть тех, которые имеют форму -l <lib_name> , запустите команду gcc <lib_path> -print-file-name = lib <lib_name> .a и запишите вывод.
Если команда выводит что-то иное, чем то, что вы передали, это будет полный путь к статической библиотеке. Замените параметр динамической библиотеки полным путем к статической библиотеке.
Промойте и повторяйте, пока не обработаете всю командную строку ссылки. При желании сценарий также может принимать список имен библиотек для исключения из статической компоновки.
Следующий сценарий bash, кажется, помогает:
Например:
в моей системе возвращается:
или с исключением:
Тогда я получаю:
источник
Существует также
-l:libstatic1.a
(без двоеточия) вариант параметра -l в gcc, который можно использовать для связывания статической библиотеки (благодаря https://stackoverflow.com/a/20728782 ). Это задокументировано? Нет в официальной документации gcc (что не совсем верно для общих библиотек): https://gcc.gnu.org/onlinedocs/gcc/Link-Options.htmlДокумент binutils ld описывает это. Эта
-lname
опция будет искатьlibname.so
затем дляlibname.a
добавления префикса lib и.so
(если он включен в данный момент) или.a
суффикса. Но-l:name
опция будет искать только точно по указанному имени: https://sourceware.org/binutils/docs/ld/Options.htmlЭтот вариант
-l:namespec
задокументирован, начиная с версии binutils 2.18 (2007 г.): https://sourceware.org/binutils/docs-2.18/ld/Options.htmlисточник
Некоторые загрузчики (компоновщики) предоставляют переключатели для включения и выключения динамической загрузки. Если GCC работает в такой системе (Solaris - и, возможно, в других), вы можете использовать соответствующую опцию.
Если вы знаете, какие библиотеки вы хотите связать статически, вы можете просто указать файл статической библиотеки в строке ссылки - по полному пути.
источник
чтобы связать динамическую и статическую библиотеки в одной строке, вы должны поместить статические библиотеки после динамических библиотек и объектных файлов, например:
gcc -lssl main.o -lFooLib -o main
в противном случае это не сработает. мне действительно нужно время, чтобы понять это.
источник