Статическая ссылка функции общей библиотеки в gcc

138

Как я могу статически связать функцию общей библиотеки в gcc?

Суреш
источник
14
Что вы подразумеваете под статически связанными? Вы хотите, чтобы ваш исполняемый файл распространялся без использования .so?
Эмилиано

Ответы:

108

Ссылаться на:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

Вам нужна статическая версия библиотеки, чтобы связать ее.

Общая библиотека на самом деле является исполняемым файлом в специальном формате с указанными точками входа (включая некоторые проблемы с липкой адресацией). Он не имеет всей информации, необходимой для статической ссылки.

Вы не можете статически связать разделяемую библиотеку (или динамически связать статическую).

Флаг -staticзаставит компоновщик использовать статические библиотеки (.a) вместо общих (.so). Но статические библиотеки не всегда устанавливаются по умолчанию, поэтому вам может потребоваться установить статическую библиотеку самостоятельно.

Другой возможный подход заключается в использовании статификатора или горностая . Оба инструмента принимают в качестве входных данных динамически связанный исполняемый файл и в качестве выходных данных создают автономный исполняемый файл со всеми встроенными общими библиотеками.

Сэм Ляо
источник
11
Какую информацию имеет статическая библиотека, чтобы она могла быть статически связана, чего нет у динамической библиотеки?
Кболино
75

Если вы хотите связать, скажем, libapplejuice статически, но не, скажем, liborangejuice , вы можете связать это так:

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

Есть предостережение - если liborangejuiceиспользует libapplejuice, то libapplejuiceбудет также динамически связан.

Вы должны связать liborangejuiceстатически вместе с , libapplejuiceчтобы получить libapplejuiceстатический заряд.

И не забывайте, что -Wl,-Bdynamicиначе вы в конечном итоге будете связывать все статическое, в том числе libc(что не очень хорошая вещь).

Евгений Бужак
источник
2
Разве нет способа сказать gcc напрямую, что связывать статически, а не обойти его и поговорить с компоновщиком?
Элазар Лейбович
1
@ElazarLeibovich Вы не можете получить комбинацию статики и динамики таким образом.
Хаожунь
@EugeneBujak: предостережение не распространяется на мою систему. Пример: gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libB использует libA , она связана и lddне показывает ссылку на libA . Исполняемый файл работает отлично. Протестировано с g ++ 4.7.3.
radix
Непрямая (вложенная) статическая зависимость от прямой динамической зависимости сама по себе не становится динамически связанной.
Винни
Рассмотрим следующее: binA зависит от libB.so, который зависит от libC.a. Как уже говорили другие, .so сами являются исполняемыми файлами, поэтому, когда общий объект связан, любые статические библиотечные зависимости обрабатываются компоновщиком почти так же, как если бы исполняемый файл был связан: единственные символы, извлеченные из статической библиотеки .a, - это те, на которые ссылается (и не решает) .so. Это означает, что если binA ссылается на символ в libC.a, на который нет ссылок нигде в libB.so, то даже если binA ссылается на libB.so, этот символ будет неопределенным (кроме случаев, когда -Wl, - весь архив используется при компоновке libB.so).
Винни
18

Если у вас есть файл .a вашей общей библиотеки (.so), вы можете просто включить его в полный путь, как если бы это был объектный файл, например так:

Это генерирует main.o просто компилируя:

gcc -c main.c

Это связывает этот объектный файл с соответствующей статической библиотекой и создает исполняемый файл (с именем «main»):

gcc main.o mylibrary.a -o main

Или в одной команде:

gcc main.c mylibrary.a -o main

Это также может быть абсолютный или относительный путь:

gcc main.c /usr/local/mylibs/mylibrary.a -o main
NeoEGM
источник
12

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

Чтобы на самом деле продемонстрировать, что статическое связывание библиотеки разделяемых объектов невозможно с ld( gccкомпоновщиком) - в отличие от просто группы людей, которые настаивают на том, что это невозможно - используйте следующую gccкоманду:

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(Конечно , вы должны собрать objectname.oиз sourcename.c, и вы , вероятно , следует сделать свою собственную библиотеку разделяемой объекта , а также. Если вы это сделаете, использование -Wl,--library-path,.так что л.д. может найти свою библиотеку в локальном каталоге.)

Фактическая ошибка, которую вы получаете:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

Надеюсь, это поможет.

Ян Мут
источник
10

Немного поздно, но ... Я нашел ссылку, которую я сохранил пару лет назад, и подумал, что она может быть полезна вам, ребята:

CDE: автоматически создавать переносимые приложения Linux

http://www.pgbovine.net/cde.html

  • Просто скачайте программу
  • Выполните двоичный файл, передав в качестве аргумента имя двоичного файла, который вы хотите сделать переносимым, например: nmap

    ./cde_2011-08-15_64bit nmap

Программа прочитает все библиотеки, связанные с nmap и его зависимостями, и сохранит их в папке cde-package / (в том же каталоге, что и вы).

  • Наконец, вы можете сжать папку и развернуть переносимый двоичный файл в любой системе.

Помните, что для запуска переносимой программы вы должны выполнить исполняемый файл, расположенный в cde-package / nmap.cde

С уважением

Фрэнсис
источник
2
Хотя не совсем дать ответ на вопрос - это заметное решение проблемы.
Разонг
Ссылка сейчас кажется мертвой.
Синан
0

В gcc это не поддерживается. Фактически, это не поддерживается ни в одном существующем компиляторе / компоновщике, о котором я знаю.

nothrow
источник
4
Не могли бы вы объяснить, как статическая компоновка не поддерживается ни одним из существующих компиляторов?
jww
5
@noloader, статическое связывание динамической библиотеки?
nothrow