Как статически связать все библиотеки, кроме нескольких, используя g ++? - PullRequest
7 голосов
/ 28 мая 2011

У меня есть требование, чтобы я связывал все мои библиотеки статически, включая libstdc ++, libc, pthread и т. Д. Есть одна библиотека omniorb, которую я хочу связать динамически.

В настоящее время я динамически связал все библиотеки.ldd показывает следующее

linux-vdso.so.1 =>  (0x00007fff251ff000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f291cc47000)
libomniDynamic4.so.1 (0x00007f291c842000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f291c536000)
libm.so.6 => /lib64/libm.so.6 (0x00007f291c2e0000)
libgomp.so.1 => /usr/lib64/libgomp.so.1 (0x00007f291c0d7000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f291bebf000)
libc.so.6 => /lib64/libc.so.6 (0x00007f291bb66000)
/lib64/ld-linux-x86-64.so.2 (0x00007f291ce63000)
librt.so.1 => /lib64/librt.so.1 (0x00007f291b95d000)
libomniORB4.so.1 (0x00007f291b6aa000)
libomnithread.so.3 (0x00007f291cf35000

Мне нужен ldd, чтобы показать libomniDynamic4.so.1 в качестве единственной динамически связанной библиотеки.

Как мне этого добиться?

Ответы [ 4 ]

10 голосов
/ 28 мая 2011

Пытаетесь сделать исполняемый файл linux, который работает на всех дистрибутивах, а? Удачи ... Но я отвлекся ...

Вы хотите посмотреть на вывод флага -v для g ++. Он показывает команды внутренней ссылки, выполняемые g ++ / ld. В частности, вы захотите проверить последнюю команду ссылки collect2 и все ее аргументы. Затем вы можете указать точные пути к библиотекам .a, с которыми вы хотите ссылаться. Вам также придется отслеживать статичные библиотеки всего. Мой libstdc ++. A находится в /usr/lib/gcc/x86_64-linux-gnu/4.4/libstdc++.a

разглагольствовать: моя самая большая жалоба на Linux - это испорченное состояние исполняемых файлов. Почему я не могу скомпилировать двоичный файл на одном компьютере, скопировать его на другой и запустить !? Даже дистрибутивы Ubuntu одного выпуска будут создавать двоичные файлы, которые не могут быть запущены в другом из-за несовместимости libc / libstdc ++ ABI

edit # 1 Я просто хотел добавить, что Скрипт на этой странице создает .png зависимостей исполняемых файлов .so. Это очень полезно при попытке сделать то, что вы описываете.

Имейте в виду, ldd <exename> перечислит все зависимости в цепочке, а не только непосредственные зависимости исполняемого файла. Таким образом, даже если ваш исполняемый файл зависит только от omniorb.so, а omniorb.so зависит от libphread.so, в выводе ldd это будет указано. Просмотрите справочную страницу readelf, чтобы найти только непосредственные зависимости двоичного файла.

Еще один предмет, о котором следует знать. если omniorb.so зависит от libstdc ++., поэтому у вас не будет другого выбора, кроме как зависеть от той же самой библиотеки. В противном случае несовместимость ABI нарушит RTTI между вашим кодом и кодом omniorb.

6 голосов
/ 31 мая 2011

Мне нужен ldd, чтобы показать libomniDynamic4.so.1 в качестве единственной динамически связанной библиотеки.

То есть невозможно .

Во-первых,ldd будет всегда показывать ld-linux-x86-64.so.2 для любого (x86_64) двоичного файла, который требует динамического связывания.Если вы используете динамическое связывание (которое вы использовали бы с libomniDynamic4.so.1), то вы получите get ld-linux-x86-64.so.2.

Во-вторых, linux-vdso.so.1 будет "введено" в ваш процесс ядром,Вы также не можете избавиться от этого.

Далее, вопрос , почему вы хотите минимизировать использование динамических библиотек.Наиболее распространенной причиной обычно является ошибочное мнение, что «в основном статические» двоичные файлы более переносимы и будут работать на большем количестве систем.В Linux это противоположно истине.

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

0 голосов
/ 22 ноября 2018

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

Обратите внимание, что двоичный файл собран с более старой версией glibc - т.е.старый дистрибутив Linux - может работать и на новых дистрибутивах Linux.Это работает, потому что glibc обратно совместим.

Возможный способ получить желаемый результат:

  • скомпилировать двоичный файл на старой ОС Linux

  • найдите все необходимые библиотеки для вашего скомпилированного двоичного файла, используя команду ldd или lsof (при запуске) для двоичного файла, подробности здесь

  • скопируйте необходимые библиотеки старой ОС Linux в папку custom-lib *

  • всегда связывайте / выпускайте эту custom-lib папку с вашим двоичным файлом

  • создайте сценарий bash, который помещает папку custom-lib поверх списка папок в переменной окружения LD_LIBRARY_PATH, а затем вызывает вашуДвоичный файл.

Таким образом, выполняя двоичный файл с помощью сценария bash, я смог выполнить двоичные файлы на множестве встроенных устройств с очень разными версиями Linux.Но всегда есть проблемные случаи, когда это не удается.

Обратите внимание, я всегда проверял это с помощью приложений / двоичных файлов cli.

Другие возможные способы ..

Также существуют элегантные способы компиляции двоичных файлов, совместимых с glibc, например, это , который, кажется, компилирует двоичные файлы, совместимые с более старыми ABI.Но я не проверил этот маршрут.

0 голосов
/ 28 мая 2011

при связывании, используйте -static перед указанием библиотек, с которыми вы хотите статически связываться, и используйте -dynamic перед библиотеками, с которыми вы хотите связать динамически.В итоге вы должны получить командную строку, которая выглядит следующим образом:

g++ <other options here> -dynamic -lomniDynamic4 -static -lpthread -lm -lgomp <etc>

Конечно, вам понадобятся .a версии библиотек, которые вы хотите статически связать (duh).

...