LINUX.ORG.RU

[C] Использование динамической библиотеки

 


0

0

Есть библиотека, которая собирается в моей рабочей дире так:

gcc -c -fPIC -Wall -o libmylib.o libmylib.c gcc -o libmylib.so libmylib.o -Wl,-soname,libmylib.so -lc -ldl -shared

Понятно, получается файл libmylib.so

Потом я пытаюсь прилинковать эту библиотку к проге как это описано в разных руководствах - передавая gcc параметры -L. -lmylib, но получаю ошибку: /usr/bin/ld: cannot find -lmylib

Наверное ld ищет libmylib.a, но мне-то нужно прилинковаться к динамической библиотеке. В общем, не знаю что делать.

В доках пишут что динамическую библиотеку _инсталлируют_ (т.е. типа копируют в /usr/lib) и запускают ldconfig. Но у меня другая ситуация - моя mylib.so должна лежать в дире с самой прогой, которая использует mylib.so, а сама прога может у юзеров быть где угодно.

Что делать? ©

Предлагаю динамически подгружать твою либу через dlopen().

cvv ★★★★★
()

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

может так поможет?

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

Может хватить и одного libtool

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

А у меня всё работает.

touch e.c

gcc -fPIC -c e.c -o e.o

gcc -shared -Wl,-soname,libe.so e.o -o libe.so -lc -ldl

echo 'main;' > c.c

gcc c.c -L. -le

anonymous
()

> Потом я пытаюсь прилинковать эту библиотку к проге как это описано в разных руководствах - передавая gcc параметры -L. -lmylib, но получаю ошибку: /usr/bin/ld: cannot find -lmylib

Оно у тебя падает на линковке приложения? Или падает при запуске?

Если при запуске, то обнови переменную LD_LIBRARY_PATH и добавь туда путь к своей либе.

anonymous
()

>> Потом я пытаюсь прилинковать эту библиотку к проге как это описано в разных руководствах - передавая gcc параметры -L. -lmylib, но получаю ошибку: /usr/bin/ld: cannot find -lmylib

Покажи точно какие команды даёшь.

>> В доках пишут что динамическую библиотеку _инсталлируют_ (т.е. типа копируют в /usr/lib) и запускают ldconfig.

Это не обязательно, всё должно работать и так.

>> Но у меня другая ситуация - моя mylib.so должна лежать в дире с самой прогой, которая использует mylib.so, а сама прога может у юзеров быть где угодно.

Можно прогу собирать с опцией -rpath (google it) на конкретный путь (поидее можно передать ".") или запускать программу небольшим скриптиком, который делает export LD_LIBRARY_PATH=".:${LD_LIBRARY_PATH}" и затем запускает программу.

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

Заморачиваться с autotools радить только этой библиотеки не хочу.

LD_LIBRARY_PATH мне при сборке не помогает; поможет, если буду подгружать ее сам с dlopen. Может так и сделаю.

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

>> LD_LIBRARY_PATH мне при сборке не помогает;

Команды сборки в студию. ВСЕ.

>> поможет, если буду подгружать ее сам с dlopen. Может так и сделаю.

В dlopen можно полные или относительные пути передавать, так что нужды в LD_LIBRARY_PATH нету.

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

Попробовал с -rpath вот так: gcc -o libmylib.so libmylib.o -Wl,-rpath,. -lc -ldl -shared Собирается нормально.

Линковка программы выглядит так: gcc -o [мои *.о файлы] -L. -lm -ldl -lmylib -lpthread -static

Все та же ошибка: не могу найти -lmylib

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

Понял, у меня из-за -static оно не собиралось. Тогда такой вопрос, как мне влинковать в свой исполняемый файл все-все-все кроме mylib?

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

вместо ключей -L && -l указать полный путь к файлу шареной либы например. некоторые линкеры понимают чередование -static with -dynamic

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

Полные пути не помогают. Параметра -dynamic нету, попытался использовать -shared, но если есть оба ключа (-static и -shared), то происходит Segmentation fault при старте.

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

>Полные пути не помогают. Параметра -dynamic нету,

небольшая опечатка. Поиск как всегда рулит:

-Bdynamic
-dy
-call_shared
Link against dynamic libraries. This is only meaningful on platforms for which shared libraries are
supported. This option is normally the default on such platforms. The different variants of this
option are for compatibility with various systems. You may use this option multiple times on the com-
mand line: it affects library searching for -l options which follow it.


>попытался использовать -shared, но если есть оба ключа (-static и -shared), то происходит Segmentation fault при старте.


а ты не пытался читать описание ключа -shared? странно что оно вообще стартует. какая у тебя система?

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

Нашел ключик -static-libgcc, но он не работает.

Rarruga
() автор топика
Ответ на: комментарий от cvv

> а ты не пытался читать описание ключа -shared? странно что оно вообще стартует. какая у тебя система?

Ну собственно оно и не стартует. до main точно не доходит.

Спасибо за инфо, сейчас попробую.

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

А в какой доке написано про -Bdynamic, -dy, -call-shared?

Я смотрю в манах для GCC 4.3 - ничего такого нет. Точнее, есть -Bdynamic, но только для Darvin.

У меня Debian Lenny, gcc 4.3.1

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

еслиб не стартовало то б нечему было в сегфолт валится.

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

молодец. Ключи линковки надо искать в описании линкера. если лень дергать линкер напрямую можеш передавать ему ключи через gсс.

у меня под рукой нету твоего компилера но там должен быть аналог -Bdynamic

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

Ну собрал я все. Правла оно ругалось на multiple definitions вот так:

/usr/lib/gcc/i486-linux-gnu/4.3.1/../../../../lib/libpthread.a(lowlevellock.o): In function `__lll_lock_wait_private':
(.text+0x0): multiple definition of `__lll_lock_wait_private'
/usr/lib/gcc/i486-linux-gnu/4.3.1/../../../../lib/libc.a(libc-lowlevellock.o):( .text+0x0): first defined here
/usr/lib/gcc/i486-linux-gnu/4.3.1/../../../../lib/libpthread.a(lowlevellock.o): In function `__lll_unlock_wake_private':
(.text+0x110): multiple definition of `__lll_unlock_wake_private'
/usr/lib/gcc/i486-linux-gnu/4.3.1/../../../../lib/libc.a(libc-lowlevellock.o):( .text+0x30): first defined here
collect2: ld returned 1 exit status

Это дело я полечил ключиком -zmuldefs

Собралось. Бинарник увеличился в размере как полагается. Но при старте опять сегфолтится.

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

КОМАНДНАЯ СТРОКА ГДЕ???

ато сильно смахивает что сверх всего у тебя с системой нелады.

на тему сегфолта существует gdb && valgrind. Посмотри на трассу - мож че увидиш.

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

Может я опоздал, но слово скажу. Для динамической линковки автоматически (т.е. без использвания в коде dlopen итд) линкеру нужен файл "libmylib.a". Его создаешь с помощью утилиты ar: ar rcs libmylib.a myobj1.o myobj2.o По-идее всё должно работать. Еще примечание: прога не будет по-умолчанию грузить so-файлы из просто из своего каталога, где она лежит. (Читай man ld.so). Если так очень надо - то добавить путь в LD_LIBRARY_PATH (точка для текущего каталога не подойдет, нужен конкретный путь), либо прописать путь в /etc/ld.so.conf. Вроде все.

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

>> Для динамической линковки автоматически (т.е. без использвания в коде dlopen итд) линкеру нужен файл "libmylib.a".

Не обязательно.

>> Его создаешь с помощью утилиты ar: ar rcs libmylib.a myobj1.o myobj2.o

ИМХО при этом получится статическая библиотека.

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

>Для динамической линковки автоматически (т.е. без использвания в коде dlopen итд) линкеру нужен файл "libmylib.a". Его создаешь с помощью утилиты ar: ar rcs libmylib.a myobj1.o myobj2.o По-идее всё должно работать.

ты в чемто принципиально ошибаешся

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

>ты в чемто принципиально ошибаешся

ошибаюсь, а в чём непонятно? Кстати аналогично в Виндах делается: если хочешь чтобы прога автоматически подгружала DLL-ку, то надо при линковке указать LIB-файл. В Линухе LIB нету, зато есть A.

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

Для линковки динамической либы lib.so никогда не было необходимости в наличии статической lib.a Многие либы .so в системе не имеют пары .a Некоторые либы вообще проблематично сделать статическими - попробуй сделать статическую либу glibc ! Проблемма с линковкой so-lib стандартным линковщиком ld только одна - они должны лежать в строго определенных местах (указанных в конфиге ld) и должны быть проиндексированы - иначе ld их не найдет!

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

Ну пока мой маздайный опыт говорит мне что в винде (и, кстати, не только в ней) это сделано грамотнее. При сборке динамической либы генерится *.lib с символами, которую "прилинковывают" к нужной проге. И потом не возникает проблем, когда нужно прилинковать одновременно и статические и динамические либы.

Я не говорю что аналогичные механизмы в Linux не работают, нет. Но то как оно организовано... в общем не видно пока преймуществ. Надеюсь они есть.

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

> попробуй сделать статическую либу glibc !

А в чем проблема? Я не делал статическую glibc, но сборка любой проги на С со стандартным набором функций и ключем -static все пихает в бинарник. Это легко проверить с помощью ldd. Стало быть, статическая glibc есть?

> Проблемма с линковкой so-lib стандартным линковщиком ld только одна - они должны лежать в строго определенных местах (указанных в конфиге ld) и должны быть проиндексированы - иначе ld их не найдет!

Вот это вообще жесть. Мой мозг отказывается понять необходимость такого подхода.

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

>> Проблемма с линковкой so-lib стандартным линковщиком ld только одна - они должны лежать в строго определенных местах (указанных в конфиге ld) и должны быть проиндексированы - иначе ld их не найдет!

Кто вам такое сказал? У меня прекрасно всё компонуется независимо от места расположения *.so'шок.

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

>Для линковки динамической либы lib.so никогда не было необходимости в наличии статической lib.a

Неужели? А кто тогда сидит в /usr/lib под названием libc.a? Если её нету в /lib, то не значит что её нету нигде.

>Некоторые либы вообще проблематично сделать статическими - попробуй сделать статическую либу glibc

Оооочень проблематично. Ты хоть раз собирал glibc из исходников? Видать нет.

garikello
()
Ответ на: комментарий от Rarruga

>> Проблемма с линковкой so-lib стандартным линковщиком ld только одна - они должны лежать в строго определенных местах (указанных в конфиге ld) и должны быть проиндексированы - иначе ld их не найдет!

>Вот это вообще жесть. Мой мозг отказывается понять необходимость такого подхода.

так проще обеспечить безопасность и предсказуемость поведения.

>> попробуй сделать статическую либу glibc !

>А в чем проблема? Я не делал статическую glibc, но сборка любой проги на С со стандартным набором функций и ключем -static все пихает в бинарник. Это легко проверить с помощью ldd. Стало быть, статическая glibc есть?

Да она есть. Но если её удалить с системы то часть приложений перестанет запускатся. Это к тому что не все можно прилинковать статически. Почему - я не вникал.

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