LINUX.ORG.RU

Можно ли статически прилинковать динамическую библиотеку?

 ,


1

3

Делаю

gcc -I/usr/local/mysql/include -L/usr/local/mysql/lib -lmysqlclient mysql.c -o mysql
все компиляется, линкуется нормально. Стоит сделать так
gcc -I/usr/local/mysql/include -L/usr/local/mysql/lib -static -lmysqlclient mysql.c  -o mysql
/tmp/ccFATyET.o: In function `main':
mysql.c:(.text+0x10): undefined reference to `mysql_get_client_info'
collect2: ошибка: выполнение ld завершилось с кодом возврата 1
В чем дело? Так вообще законно делать?

★★★

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

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Разве что в одну директорию, как вантузятники, напихать все нужные библиотеки и запускать с нужным LD_PRELOAD_PATH.

man rpath, неуч.

anonymous ()

Есть тулзы которые могут паковать все нужные .so в один бинарник, физически это не тоже самое что статическая линкова. Но при желании можно заморочиться с полной перепаковкой.

mashina ★★★★★ ()

пересобери mysql с --enable-static, но зачем тебе это нужно?

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

ld option -rpath:

-rpath=dir

Add a directory to the runtime library search path. This is used when linking an ELF executable with shared objects. All ‘-rpath’ arguments are concatenated and passed to the runtime linker, which uses them to locate shared objects at runtime. The ‘-rpath’ option is also used when locating shared objects which are needed by shared objects explicitly included in the link; see the description of the ‘-rpath-link’ option. If ‘-rpath’ is not used when linking an ELF executable, the contents of the environment variable LD_RUN_PATH will be used if it is defined.

The ‘-rpath’ option may also be used on SunOS. By default, on SunOS, the linker will form a runtime search patch out of all the ‘-L’ options it is given. If a ‘-rpath’ option is used, the runtime search path will be formed exclusively using the ‘-rpath’ options, ignoring the ‘-L’ options. This can be useful when using gcc, which adds many ‘-L’ options which may be on NFS mounted file systems.

For compatibility with other ELF linkers, if the ‘-R’ option is followed by a directory name, rather than a file name, it is treated as the ‘-rpath’ option.

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

почему статические и динамические библиотеки так называются?

Потому, что статические библиотеки можно линковать только статически, а динамические — как статически, так и динамически.

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

А для чего тогда нужны статические библиотеки, если динамические справляются с обеими задачами? И как же мне слинковать динамическую либу статически?

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

Статическая библиотека гарантированно присутствует, т.к. вкорячена линкером в результирующий бинарник. Разделяемая — может и протеряться армейским способом, либо её может перекрыть более другая, сломав поведение.

Кстати, а ты уверен, что mysqlclient — разделяемая библиотека?

one_more_hokum ★★★ ()

Можно же. Линкуешь динамически и создаешь бинарник в котором как ресурсы лежат твоя прога и либа. При запуске этого бинарника он сначала их распаковывает, а затем передает управление проге.

Но это плохо, так никто не делает. Создай пакет и пропиши в зависимостях.

Deleted ()
Ответ на: комментарий от one_more_hokum

Статическая библиотека гарантированно присутствует, т.к. вкорячена линкером в результирующий бинарник. Разделяемая — может и протеряться армейским способом, либо её может перекрыть более другая, сломав поведение.

В чем отличие между статическим линкованием динамической либы и динамическим линкованием динамической либы?

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

Статическое линкование дин. библиотеки подразумевает проверку статическим линкером (ld) всех зависимостей символов ещё на этапе сборки. Если что-то из зависимостей не будет найдено — линкер ругается.

Динамическая линовка дин. библиотеки перекладывает проверку зависимостей на runtime. Т.е. скомпилится нормально, но если при запуске не обнаружит требуемой дин. библиотеки — то динамический линкер (ld.so) скажет об этом. Но это — если указана явная динамическая линковка. В случае неявной, если не было обращений к функциям отсутствующей дин. библиотеки — программа будет работать.

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

Ясно, спасибо за разъяснение. А то мне всегда казалось, что статическое линкование - это именно вкорячивание библиотеки внутрь бинарника, чтобы он не лез за библиотекой наружу.

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

подразумевает проверку статическим линкером

А можно ссылочку где используется такое определение.

anonymous ()
Ответ на: комментарий от one_more_hokum

А как ld вкорячит .so-шку в бинарь, если нет .o-объектных файлов/архива со статичной либой .a? Можешь привести пример?

В любом случае вывод file my_prog будет выводить, что прога динамически слинкована. Это для всех видов описанных тобой линковок с динамической либой.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от slyjoeh

А для чего тогда нужны статические библиотеки, если динамические справляются с обеими задачами?.

Он ерунду несёт. У статических и динамических библиотек основная разница в типе генерируемого кода. У динамических библиотек он PIC, у статических обычно нет. PIC код медленнее из-за чего оба варианта библиотек не эквивалентны с эксплутационной точки зрения. Технически можно слинковать .so по типу статичекской библиотеки, но так не делают и ld этого тоже делать не умеет.

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

где используется такое определение

Я счас перевожу документацию на гнутый линкер, и из оттуда (плюс чтение прочих доков) следует такое поведение. Там нет такого, чтоб на одном месте было указано вот это поведение, но общая картина складывается именно такая.

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

как ld вкорячит .so-шку в бинарь

Зачем вкорячивать дин. либу в бинарник? ld свяжет егойную таблицу импорта с указанной .so-либой, и пропишет некоторые флаги, на основании которых динамический линкер будет искать её либо сразу при запуске исполняемого файла (явная динамическая линковка), либо при попытке уже запущенного бинарника обратиться к символам этой либы (неявная динамическая линковка).

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

У динамических библиотек он PIC, у статических обычно нет

man ld -pie:

Create a position independent executable. This is currently only supported on ELF platforms

Ты бы, барин, дальше первого абзаца педивикию почитал, чтоб PIC-code с relocatable не путать.

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

Зачем вкорячивать дин. либу в бинарник?

Либо ты путаешь терминологию, либо я что-то не понял :)

Бинарник со статически слинкованной библиотекой несет в себе все функции этой библиотеки, чтобы не обращаться к динамическому загрузчику. Т.о. бинарник можно запустить даже на системе где нет никаких библиотек, которые нужны бинарю в случае динамической линковки. В примере ТС это libmysql.so. Статическая линковка программы должна запихнуть в бинарь libmysqlclient.a и все другие *.a, которые нужны libmysqlclient.a для нормального функционирования (либо все *.o, смысл мало меняется).

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

Вот тут все ясно описано: http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

Где ты вычитал «статическое линкование дин. библиотеки» я не знаю.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от gh0stwizard

Не открывается этот ваш youlinux.com.

Где ты вычитал «статическое линкование дин. библиотеки» я не знаю

Например, здесь. Суть в том, кто будет проверять таблицу импорта, и её зависимости: ld при линковке исполняемого файла, или ld.so при запуске полученного файла на исполнение.

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

Например, здесь.
Написал DLL на Delphi и хочу статически подключить ее к программе на Visual C 6.0.

Не, я даже не стану читать. Вобщем, с дин. библиотеками можно работать через dlopen(), либо просто через ld.so.

Суть в том, кто будет проверять таблицу импорта, и её зависимости: ld при линковке исполняемого файла, или ld.so при запуске полученного файла на исполнение.

С моей ссылки выше:

Example makefile statement: g++ -rdynamic -o appexe $(OBJ) $(LINKFLAGS) -Wl,--whole-archive -L{AA_libs} -laa -Wl,--no-whole-archive $(LIBS)

  • --whole-archive: This linker directive specifies that the libraries listed following this directive (in this case AA_libs) shall be included in the resulting output even though there may not be any calls requiring its presence. This option is used to specify libraries which the loadable libraries will require at run time.
  • -no-whole-archive: This needs to be specified whether you list additional object files or not. The gcc/g++ compiler will add its own list of archive libraries and you would not want all the object code in the archive library linked in if not needed. It toggles the behavior back to normal for the rest of the archive libraries.

Ты про это говоришь? Еще раз, с примерами было бы понятней, что ты имеешь в виду.

Другое нормальное объяснение: http://www.ibm.com/developerworks/library/l-dynamic-libraries/

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

Не, я даже не стану читать

Религиозные фанатики такие фанатики.

с дин. библиотеками можно работать через dlopen(), либо просто через ld.so

Угу, неявная, и явная динамические линковки динамических же библиотек.

С моей ссылки выше

Каким боком --[no-]whole-archive относится к обсуждаемому вопросу? Эта опция говорит линкеру (который ld), пихать ли в результирующий бинарник содержимое заданного архива целиком, либо только требуемые в этой линковке объекты.

Другое нормальное объяснение

И сразу же: ld-linux.so is itself an ELF shared library, but it is statically compiled. Удивительно, да? Библиотека shared, но скомпилирована statically. Вот за это я и говорил, что внешние зависимости проверяет ld, на этапе компиляции. В том случае бинарник скомпилирован без внешних зависимостей, но можно и с ними. Разумеется, они будут захардкожены унутре результирующего файла, что не есть хорошо в общем случае, но иногда может и пригодиться.

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

Религиозные фанатики такие фанатики.

Нет, не фанатик, я просто испугался что как обычно тред на 150 страниц. Вобщем, нашел.

Ага. По английски implicit/explicit, а по русски динамическая/статическая.

Качество перевода зашкаливает. Неявное/явное в дословном переводе. Епрст, исходя из примеров там как раз случай про dlopen() аналог виндовой LoadLibrary()/explicit/«статическая линковка».

И разблокируй yolinux.com, отличный ресурс, там по ссылке как раз описаны моменты linux vs windows.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от one_more_hokum

Библиотека shared, но скомпилирована statically. Вот за это я и говорил, что внешние зависимости проверяет ld, на этапе компиляции.

Качество статей на ibm devworks обычно ниже среднего. Читать следует по диагонали, т.к. главное в этой статье это картинки :) Если я напишу либу на asm'е, слинкую ее динамически, она также не будет иметь внешних зависимостей. Ты тоже скажешь, что я слинковал ее статически-динамически, мм? :)

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

Ты тоже скажешь, что я слинковал ее статически-динамически
В том случае бинарник скомпилирован без внешних зависимостей, но можно и с ними

Полностью пост не читай, сарказмом всех удивляй.

one_more_hokum ★★★ ()

распространяй рядом с бинарником, не слушай этих фанатиков юникс-вея.

crowbar ()
Ответ на: комментарий от one_more_hokum

Полностью пост не читай, сарказмом всех удивляй.

Все, я все понял, что ты имеешь в виду. Допустим, надо выпустить либу без внешних зависимостей. Т.о. надо запихнуть в .so все объектные файлы, которые идут как зависимости. Чтобы это сделать насколько я знаю нужны либо *.a, либо *.o файлы, чтобы ld смог их скомпоновать в один наш файл .so. Да, тогда можно назвать этот процесс со «статической компиляцией».

Но это не относится к делу, т.к. это детали того как собрана библиотека, а не обсуждаемый вопрос линкование программы с библиотекой. Программу также можно собрать полностью со статической линковкой (через *.a файлы) и тогда для ее запуска не нужно ничего по сути, либо динамически через dlopen (plugin-architecture, ручная загрузка) или через ld.so (автоматическая загрузка).

В любом случае, при сборки программы или библиотеки т.о., чтобы не было никаких зависимостей при загрузке требуются *.o, либо *.a файлы. В противном случае, получим динамическую загрузку, что выражается другими словами в необходимости возить вместе с программой/библиотекой файлы-зависимости. В случае статической линковки, конечный файл не требует никаких доп. файлов, т.к. внутри содержится все необходимое.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)
Ответ на: комментарий от one_more_hokum

Я РосКомНадзор, шоле, его разблокировать?

Пруф (скриншот), что роскомнадзор заблокировал. Будет новостью дня.

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

я все понял, что ты имеешь в виду...

Не, не так. Внешние зависимости могут быть, вопрос в том, кто их будет проверять: ld при линковке после компиляции, либо ld.so при загрузке исполняемого бинарника, либо при попытках выполнить функции из него, указывающие наружу.

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

Страницы-заглушки нет, но при хождении туда через Google-translator сайт кажет. А так — web-страница недоступна, и всё...

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

статическим линкером (ld)
динамический линкер (ld.so)
более корректным будет их обзывать compile-time-линкер, и runtime-линкер
Я счас перевожу документацию на гнутый линкер, ...

Не надо!

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

можешь дать пример команды, которая позволит «статически» прилинковать динамическую либу? Что конкретно нужно написать в командной строке? Очень интересно стало, хочу так же.

stevejobs ★★★★☆ ()
Ответ на: комментарий от one_more_hokum

Это сработает только когда есть версии *.a для указанных библиотек: -lpq -lssl -lcrypt -lcrypto -lz. Ну и автор сам поясняет всю «ипичность» ситуации:

libpq also depends on krb5, but there's no static version of it in my distribution, so I'll link it to final binary.

Таким образом, может возникнуть ситуация, когда libkrb откажется работать с libpq (или наоборот).

Плюс, для критичных либ, таких как libssl, статическая линковка крайне не рекомендуется. Ибо, если мейнтейнер пропустит момент обновиться у себя, то у заказчика окажется дырявая версия, которую поимеют во все места злые дяди. IMHO, bad practice.

gh0stwizard ★★★★★ ()
Последнее исправление: gh0stwizard (всего исправлений: 1)

С технической точки зрения здесь уже обсудили, но с логической почему же нельзя «абсорбировать» разделяемый объект в бинарник вместе с тем объединив зависимости бинарника и «абсорбированного» объекта. По этому я считаю, что решение такой задачи не противоречит здравой логике, другое дело насколько это технически сложно.

Кстати, может настало время написать тулзу для этого? :)

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

Ну и автор сам поясняет всю «ипичность» ситуации

Таки да, но вопрос был за принципиальную осуществимость сего деяния, а не за последующие проблемы.

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

Да все нормально. Я и некоторые пацаны подумали, что можно статично линковать *.so-шки, когда нет ни *.o, *.a файлов. И поэтому было интересно услышать как это осуществить :)

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

Да все нормально. Я и некоторые пацаны подумали, что можно статично линковать *.so-шки, когда нет ни *.o, *.a файлов. И поэтому было интересно услышать как это осуществить :)

Он везде путает между собой «прилинковать статичкски либу» и «сделать статичкски слинкованную либу». И не только это.

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