Portál AbcLinuxu, 13. května 2025 20:59

Dotaz: linkování s knihovnami v nestandardním adresáři

10.6.2007 20:56 Espinosa | skóre: 24 | blog: Espblog | London
linkování s knihovnami v nestandardním adresáři
Přečteno: 500×
Odpovědět | Admin
Rád bych experimentálně zkompiloval ffmpeg, mlt a kdenlive, všechno verze ze SVN, nerad bych si tím zašpinil systém a zároveň měl jistotu, že kdenlive používá zamýšlenou ffmpeg verzi a ne tu systémovou. Udělal jsem si ho pod /home/espinosa/build, z něj to potom zamýšlím spouštět. Pomocí konfiguračních voleb --prefix --libdir by to mohlo vyjít.

Mám zhruba takovýto skript
DEST_DIR=~/build
cd ffmpeg ; \
./configure --prefix=${DEST_DIR} --libdir=${DEST_DIR} --enable-gpl \
--enable-shared --enable-libvorbis --enable-libogg --enable-pp --enable-swscaler
make
make install

cd ../mlt
./configure --prefix=${DEST_DIR} --libdir=${DEST_DIR} --enable-gpl \
--enable-motion-est --enable-mmx --avformat-swscale 
make
make install

cd ../mlt++
./configure --prefix=${DEST_DIR} --libdir=${DEST_DIR}
make install

cd ../kdenlive
sh bootstrap
./configure --prefix=${DEST_DIR} --libdir=${DEST_DIR}
make
make install
Bude to fungovat jak zamýšlím? Je nutné nastavovat libdir? Bude výsledná aplikace spustitelná i z jiného adresáře, pokud ji například zkopíruji (vč knihoven ffmpeg a mlt) do /opt/kdenlive? Nebo je navždy přikovaná k adresáři určenému v době kompilace (buildování)?

Musím se přiznat, že tyhle otázky mě už dlouho ležely v hlavě, ale dosud jsme je nepotřeboval řešit. /usr/local postačoval. Ne tak nyní.

O LD_LIBRARY_PATH vím, nicméně všude od toho zrazují, např http://xahlee.org/UnixResource_dir/_/ldpath.html - Why LD_LIBRARY_PATH is bad.

Jak přemluvit linuxový program, aby primárně použil knihovny z vlastního (pod)adresáře, místo systémových, a zároveň byl nezávislý na adresářovém umístění v souborovém systému?

Děkuji
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

10.6.2007 22:08 jiri.b | skóre: 30 | blog: jirib
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Odpovědět | | Sbalit | Link | Blokovat | Admin
slinkovani s knihovnou behem kompilace nema nic spolecneho se spousteni programu vyuzivajici sdilenou knihovnu.

vlastni spousteni, resp. naloadovani sdilene knihovny provadi specializovany program a hleda knihovnu v definovanych adresarich.

pri pouzivani uzivatelova adresare obsahujici vlastni knihovny muzes pouzit urcite promenne pro ten specializovany program - ld.so... pro vice man ld.so

snad jsem to moc nedomotal :)
10.6.2007 23:15 miso | skóre: 36 | blog: iSCSI_initiator_howto | Praha
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
mozes pouzit premennu LD_LIBRARY_PATH na nadefinovanie alternativnej cesty ku kniznici
Project Satan infects Calculon with Werecar virus
11.6.2007 00:03 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Všichni proti tomuto způsobu brojí. Viz můj dotaz, viz například http://xahlee.org/UnixResource_dir/_/ldpath.html

To je jedna věc. Druhá je, že potřebuji i KOMPILOVAT proti nové knihovně. Ta novější verze knihovny ze SVN může mít například novou funkci, jiné parametry etc.
11.6.2007 07:24 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
> Všichni proti tomuto způsobu brojí. ... viz například ...

Ten odkazovaný článok brojí proti globálnemu nastaveniu. Ale LD_LIBRARY_PATH môžeš nastaviť len pre ten program, ktorý ho potrebuje. Jednoducho miesto ./bar budeš spúšťať LD_LIBARY_PATH=/usr/local/foo/lib ./bar. Dá sa to tiež použiť v KDE menu/ikonkách takže to nejak nepohodlné nie je.

Používam Slackware a nerád používam binárne balíky, ktoré priamo v Slackware-i nie sú. A tak si kompilujem svoje veci. Vždy do /usr/local/meno-aplikacie. Samozrejme, že občas narazím na závislosti a tak kompilujem aj knižnice - rovnakým spôsobom: /usr/local/meno-knižnice. Občas je to trocha trápenie, ale človek sa sem tam aj niečo naučí. Týmto spôsobom mi funguje avidemux, mplayer, xdtv, tvtime, fontforge, scribus, audacity, inkscape, Battle For Wesnoth, lxdoom, ldescent, pingus, ... (Jedine čo so nedokázal rozbehať bola cinelerra - ale to je problém ich build-u.) A problém s tým nie je.
11.6.2007 20:12 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
/usr/local nejde použít v tomto případě. Oni by mi ji pak ten bleeding-edge ffmpeg ze svn a mlt začaly používat další aplikace a to NECHCI. Nerad bych aby mi kvůli pokusům přestal fungovat třeba mplayer, amarok či xine.

Aplikace a knihovny v /usr/local totiž obvykle mají přednost před těmi z /usr (specifické má přednost před obecným, lokální před systémovým distribučním).

Mě by se teď náramně hodilo chování aplikací ve Windows, které primárně hledají knihovnu v adresáři ze kterého jsou spuštěné a pak v systému. Sondoval jsme, jestli v Linuxu, resp. v utilitách automake a autoconfigu, není možnost nějak toto chování během kompilace vnutit aplikaci. Ale začínám mít dojem že není. Tedy alespoň bez zásahu do zdrojového kódu.
12.6.2007 08:04 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
> /usr/local nejde použít v tomto případě.

Nie /usr/local ale /usr/local/menokniznice

Oni by mi ji pak ten bleeding-edge ffmpeg ze svn a mlt začaly používat další aplikace a to NECHCI.

Nie sme na windowsoch. Samo od seba sa nič používať nezačne. Pokiaľ nainštaluješ knižnice do adresárov, ktoré nie sú v /etc/ld.so.conf a nemáš globálne nastavené LD_LIBRARY_PATH tak mplayer, amarok či xine nemajú odkiaľ vedieť, že na systéme pribudlo nejaké /usr/local/ffmpeg-pre-kdenlive/lib/libffmpeg-x.y.so. Problém býva len presvedčiť kompiláciu aplikácie o tom, kde hľadať tú knižnicu. Občas je na to switch pre configure. Občas treba pre shell, v ktorom kompiluješ, upraviť PKG_CONFIG_PATH, a občas treba hacknúť configure.
12.6.2007 12:28 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Jo tak, v /usr/local/ffmpeg-pre-kdenlive tam to asi opravdu linker hledat nebude. I když jeden nikdy neví ;-) V SUSE do /etc/ld.so.conf.d si vesele vpašoval svoji cestu mplayer plugin pro Mozillu.

Ještě by mě zajímalo jak to řešíte práva do /usr/local. Tam má standardně právo zápisu jen root, ne?

Problém býva len presvedčiť kompiláciu aplikácie o tom, kde hľadať tú knižnicu.

Co LD_LIBRARY_PATH, ta se při pekladu nebere v úvahu? No pak tu máme CFLAGS a LDFLAGS.
12.6.2007 12:52 rastos | skóre: 63 | blog: rastos
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
> Ještě by mě zajímalo jak to řešíte práva do /usr/local. Tam má standardně právo zápisu jen root, ne?

Práva do /usr/local ostali. Ako root vytvorím adresár pre aplikáciu resp. knižnicu a vlastníctvo toho adresára dám normálnemu užívateľovi. Užívateľ potom robí make install do odresára, ktorý vlastní. Výhodou je, že pokiaľ make install chce písať niekam inam, tak sa o tom dozviem.

> Co LD_LIBRARY_PATH, ta se při pekladu nebere v úvahu? No pak tu máme CFLAGS a LDFLAGS.

To je síce pravda, ale existujú napr. inštalačné skripty, ktoré tieto premenné predefinovávajú.
11.6.2007 00:48 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Dobře. zkusím to formulovat trochu jinak.

Řekněme, že chci poslat svůj binární výtvor kamarádovi. Chci, aby i u něj hlavní binárka načetla lokální verze knihoven a ne ty systémové. Nevím, do jakého adresáře si to zkopíruje. Nevím jaké má nastavení LD_LIBRARY_PATH, či linkeru obecně. Chci to udělat co nejuniverzálněji.

Lze to nějakými kompilačními parametry zabezpečit, aby hlavní binárka načetla lokální verze knihoven a ne ty systémové? Nebo chci něco nereálného?

Můžete navrhnout postavit RPM. To mám v plánu hned v další etapě, nicméně, budu tam muset řešit stejný problém. RPM tedy není řešení mého problému.

Mohu napsat jednoduchý sh wrapper skript okolo výsledné binárky, kde nastavím LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH nebo tak nějak, nicméně, to bych bral jako úplnou a poslední nouzovku. Jedna nemám tyhle obalující skriptíky rád, komplikuje to debuggovaní například, a od použití LD_LIBRARY_PATH se vesměs zrazuje.
11.6.2007 20:54 jiri.b | skóre: 30 | blog: jirib
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
anebo mit statickou binarku, sic nevim presne jak na to :)
10.6.2007 22:30 outsider
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Odpovědět | | Sbalit | Link | Blokovat | Admin
Linker ld má volbu -rpath, která určuje, kde se mají hledat knihovny při runtime linkování... Ale jak to přesně funguje, to si nejsem jistej...
10.6.2007 22:48 jiri.b | skóre: 30 | blog: jirib
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
no podle me ld se vola behem sestavovani, gcc hleda standardne v /usr/include a pripadne -I -L pro dalsi adresare.
12.6.2007 09:27 outsider
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
mate naprostou pravdu, ale to neznamena, ze ld behem sestavovani nemuze nastavit cestu ke knihovnam pro runtime linkovani :-)
11.6.2007 20:31 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Tohle vypadá nadějně! Díky
... A less common technique (and less documented it seems) is to use something called an RPATH. RPATH is like LD_LIBRARY_PATH in that it tells the runtime linker "look in this directory for shared libraries". The key difference between RPATH and LD_LIBRARY_PATH is that RPATH is written into the binary itself it's not an environment variable. ...
http://www.the-martins.org/index.php?name=Sections&req=viewarticle&artid=6&page=1 Soft intro to rpath
13.6.2007 11:29 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše rpath
Hmm, tak jsem skusil export CFLAGS="$CFLAGS -Wl,--rpath,../lib" Volba se zjevně propracovala až k gcc ale píše mi to tohle za každým příkazem gcc, viz příklad:
gcc -Wl,--rpath,../lib -fomit-frame-pointer -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization 
-Wpointer-arith -Wredundant-decls -Wno-pointer-sign -O3 -I"/home/espinosa/src/ffmpeg" -I"/home/espinosa/src/ffmpeg"
 -I"/home/espinosa/src/ffmpeg"/libavutil -I"/home/espinosa/src/ffmpeg"/libavcodec -I"/home/espinosa/src/ffmpeg"/libavformat
 -I"/home/espinosa/src/ffmpeg"/libswscale -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_ISOC9X_SOURCE -DHAVE_AV_CONFIG_H 
-I"/home/espinosa/src/ffmpeg"/libswscale -I"/home/espinosa/src/ffmpeg"/libavcodec  -DHAVE_AV_CONFIG_H 
-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_ISOC9X_SOURCE -I"/home/espinosa/src/ffmpeg" -I"/home/espinosa/src/ffmpeg"
 -I"/home/espinosa/src/ffmpeg"/libavutil 
-Wl,--rpath,../lib -fomit-frame-pointer -g -Wdeclaration-after-statement 
-Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -O3  
-c -o allcodecs.o allcodecs.c
In file included from allcodecs.c:27:
avcodec.h:2499: warning: ‘ImgReSampleContext’ is deprecated
avcodec.h:2505: warning: ‘ImgReSampleContext’ is deprecated
gcc: --rpath: linker input file unused because linking not done
gcc: ../lib: linker input file unused because linking not done
gcc: --rpath: linker input file unused because linking not done
gcc: ../lib: linker input file unused because linking not done
Není to chyba, jen varování. Mám se tím zabývat? Také je s podivem, že se to tam dostalo dvakrát! Nemám raději nastavit LDFLAGS?
11.6.2007 00:00 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Odpovědět | | Sbalit | Link | Blokovat | Admin
A další komplikace. Ono to snad bez toho roota ani nepůjde. Všechny ty make install totiž volají ldconfig a tam to na konci padá s chybou
espinosa@esplaptop:~/build/bin> /sbin/ldconfig
/sbin/ldconfig: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
16.6.2007 21:26 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Planý poplach, nic se neděje. ld cache není potřeba přegenerovat, protože žádné knihovny do standardní cesty systému nepřidáváme, takže to nemá cenu. Ta chyba je naštěstí toho rázu, že nepřeruší vykonávání dalších příkazů skriptu takže taky OK.
16.6.2007 21:24 Espinosa | skóre: 24 | blog: Espblog | London
Rozbalit Rozbalit vše Re: linkování s knihovnami v nestandardním adresáři
Odpovědět | | Sbalit | Link | Blokovat | Admin
OK vyřešeno, funguje :) Jen ta proměnná se jmenuje jinak - LD_RUN_PATH a ne RPATH. RPATH je buď starý název, nebo se používá v jiných systémech než linux (BSD? Solaris?).

Co je důležité, reaguje to na relativní cesty jak má. Díky tomu pak bude možné výsledný balík binárka a knihovny zkopírovat na libovolné místo (eh to jsem ještě nezkoušel..), třeba na /opt/kdenlive nebo /usr/local/kdenlive.

Výsledek je izolovaný od knihoven systému, můžete tak mít více verzí ffmpeg, mlt nebo kdenlive. Pokud se knihovna nenajde v přednastaveném adresáři (přednastaveném LD_RUN_PATH) hledá se dále již standardním způsobem podle cest co jsou v ld.so.conf resp. nastavení LD_LIBRARY_PATH. Tohle je důležité, aby se našli knihovny jako libc, libswscal, liblame, libmpeg2 které jsme nekompilovali ale chceme je vzít ze systému, distribuční verze.

Takhle pak může vypadat skript:
export DEST_DIR=~/build/kdenlive
export PATH=$DEST_DIR/bin:$PATH
export LD_RUN_PATH=../lib

cd ffmpeg &&
./configure --prefix=$DEST_DIR --enable-gpl --enable-shared --enable-libvorbis --enable-libogg --enable-pp &&
make &&
make install &&

cd ../mlt &&
./configure --prefix=$DEST_DIR  --enable-gpl --disable-mmx --avformat-swscale
make &&
make install &&


cd ../mlt++ &&
./configure --prefix=$DEST_DIR &&
make &&
make install &&


cd ../kdenlive &&
sh bootstrap &&
./configure --prefix=$DEST_DIR &&
make &&
make install
;;
Dobrá pomůcka pro zjištění, zda se LD_RUN_PATH prosadila do vašich knihoven a binárek je příkaz ldd:
espinosa@esplaptop:~/build/kdenlive/bin# ldd ../share/mlt/modules/libmltavformat.so
Pozor, pokud používáte relativní adresy, tak je důležité z jakého adresáře příkaz ldd voláte! A ještě podrobnější výpis jak se knihovny hledají:
espinosa@esplaptop:~/build/kdenlive/bin#LD_DEBUG=libs ./kdenlive

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.