kompilacja bez shared libraries

Tematy związane z oprogramowaniem, instalacją, konfiguracją
kaszub
Posty: 10
Rejestracja: 07 kwietnia 2007, 02:41

kompilacja bez shared libraries

Post autor: kaszub »

Cze, chce sobie skompilowac openftpd zeby dzialal na kazdym linuksie, a nie tylko na tym na ktorym go kompiluje, i tu pojawia sie problem. Domyslnie mi kompiluje z uzyciem bibliotek wspoldzielonych, jak zrobic zeby skompilowal mi program tak zeby nie wymagal zewnetrznych bibliotek, (wkompilowanie w binarke, ewentualnie trzymanie tych bibliotek w katalogu z binarka).
giaur
Member
Posty: 1915
Rejestracja: 25 maja 2007, 22:16

Post autor: giaur »

Hm, jak sie uprzesz to prawdopodobnie mozesz to zrobic.

Przede wszystkim musisz utworzyc swoj wlasny makefile.

Jezeli chcesz "wbudowac" biblioteki w program:
Do zrodel dodajesz zrodla wszystkich bibliotek, includy zamieniasz na lokalne - po skompilowaniu tego masz "wszystko razem", czyli biblioteki wbudowane w program.
Drugie wyjscie to skompilowac biblitoeki statycznie i potem dodac do projektu (wyjdzie na to samo).

A jezeli chcesz miec biblioteki ładowane dynamicznie w katalogu programu, to moge sie mylic - ale raczej nie da sie tak zrobic (to niestety nie Windows). Poza tym w tym wypadku i tak to by raczej nie dzialalo na innych distrach linuksa, bo biblioteki dynamiczne moga korzystac z jeszcze innych biblitoek dynamicznych, ktore musza byc zawarte np. w odpowiednich katalogach, zaleznych od dystrybucji - i tu kółko sie zamyka...

Ogolnie sprawa nie jest prosta, a po tych zabiegach i tak nie bedzie pewnosci ze program na pewno sie odpali w kazdym distro. Nie bez powodu w Linuksie programy sa rozpowszechniane w postaci zrodel do samodzielnego skompilowania.

Oczywiscie mozna zrobic, ze program bedzie sie odpalac w kazdym distro (jak Firefox), ale do tego napisano wlasny framework i to jest juz zupelnie inna bajka.
AdeBe
Junior Member
Posty: 825
Rejestracja: 01 grudnia 2007, 14:41

Post autor: AdeBe »

Generalnie podpowiem tylko, że jeśli chcesz kompilować statycznie, to od tego jest przełącznik -static w gcc.
giaur
Member
Posty: 1915
Rejestracja: 25 maja 2007, 22:16

Post autor: giaur »

W tym miejscu (od siebie) moge dodac, ze chyba jednak windowsowe dll-ki sa lepsze od linuksowych bibliotek dynamicznych - chodzi mi ogolnie o mechanizm dzialania.

Pod Windows wystarczy, jezeli biblioteka dynamiczna bedzie w katalogu programu lub sciezce wyszukiwania (przy ladowaniu statycznym) lub w jakimkolwiek katalogu (i stamtad ladujemy ja dynamicznie, podajac na sztywno w programie sciezke dostepu - wzgledna lub bezwzgledna).
Malo tego - majac 2 wersje tej samej biblioteki (np. nowsza wersja w katalogu z programem, starsza widoczna system wide - np. katalog Windows), mozna wskazac, ktora wersje system ma automatycznie ładować (i to bez rekompilacji programu).

Pod linuksem, jak sie zdaje - takie kombinacje nie sa mozliwe, a w szczegolnosci nie mozna chyba zrobic sobie tak, ze majac skompilowany program "przeniesiemy" biblioteke dynamiczna do katalogu roboczego i to wystarczy zeby zostala uzyta... jest jedynie ładowanie bibliotek z katalogow systemowych - to duzy minus
LiTE
Beginner
Posty: 208
Rejestracja: 25 marca 2008, 13:22
Lokalizacja: Nowa Ruda

Post autor: LiTE »

giaur niestety sie mylisz i to grubo ;-) Jest taka zmienna globalna $LD_LIBRARY_PATH. Zawartosc jej mozna odczytac wpisujac echo LD_LIBRARY_PATH, a zmienic wartosc

Kod: Zaznacz cały

export LD_LIBRARY_PATH=/home/jakis/katalog/:$LD_LIBRARY_PATH 
export LD_LIBRARY_PATH
Istnieje jeszcze taki plik konfiguracyjny gdzie podajesz sciezki do bibliotek /etc/ld.so.conf.

Wiecej tutaj: http://www.yolinux.com/TUTORIALS/Librar ... namic.html
giaur
Member
Posty: 1915
Rejestracja: 25 maja 2007, 22:16

Post autor: giaur »

@LiTE

Wiem o tym. Ale zauwaz, ze owszem - mozesz sterowac, gdzie programy maja szukac bibliotek dynamicznych.

Tylko ze aplikacja nie moze sama "zlokalizowac" biblioteki. Nie mozesz w kodzie napisac: "wez ta biblioteke z tego katalogu i jej użyj". Możesz owszem konfigurowac sobie sciezki do bibliotek, ale jezeli biblioteki nie ma w tej ścieżce, a jest nawet w katalogu roboczym programu, albo w tym samym katalogu co program to i tak nie zostanie znaleziona. Czyli de facto - biblioteka jest "obok", a program jej nie zobaczy... bo szuka tylko w katalogach zdefiniowanych w globalnych ustawieniach systemu, a "okok siebie" juz nie szuka (chyba ze o czyms nie wiem, w kazdym razie nie slyszalem o takiej mozliwosci)
LiTE
Beginner
Posty: 208
Rejestracja: 25 marca 2008, 13:22
Lokalizacja: Nowa Ruda

Post autor: LiTE »

Co rozumiesz przez szukanie obok siebie? Nie wydaje mi sie, aby Windows szukal jakos rekurencyjnie bibliotek, jedynie ograniczy sie do glownego katalogu i moze jakiegos katalogu /dll/.
Bo biblioteki sa w katalogu bibliotek, a programy w katalogu programow, pliki konfiguracyjne w katalogu plikow konfiguracyjnych

Odpowiednio
/usr/bin
/usr/lib
/home/.[Co.Programista.Sobie.Wymysli]

Jezeli chcesz, aby program 'szukal' bibliotek 'obok' siebie wystarczy do LD_LIBRARY_PATH dodac './' wtedy to jest katalog macierzysty z ktorego odpalany jest program. Ewentualnie mozna dodac mu './lib'. Jedna z mozliwosci jest jeszcze cofanie sie w katalogach '../' lub '../../'. O to Ci chodzilo?
Nie mozesz w kodzie napisac: "wez ta biblioteke z tego katalogu i jej użyj"
Mozesz ;-)

Kod: Zaznacz cały

dlopen("/opt/lib/libctest.so", RTLD_LAZY);
giaur
Member
Posty: 1915
Rejestracja: 25 maja 2007, 22:16

Post autor: giaur »

Ok, o tym nie wiedzialem - ten temat w Linuksie jest mi nieco mniej znany niz w Windows.

Tyle, ze z tego co napisales - aby programy widzialy biblioteki dynamiczne obecne w ich katalogach, nalezy zmienic konfiguracje systemu - bo domyslnie tak nie jest. Mowie tu o juz skompilowanych programach.

Co do tego, jak Windows szuka bibliotek dll - tu sprawa jest jasna. Przede wszystkim mamy 2 sposoby na skorzytanie z biblioteki dll:

- ładowanie statyczne. Biblioteka jest na stałe "związana" z programem i automatycznie ładowana przy jego starcie - nie mamy na to żadnego wpływu w kodzie źródłowym programu. Nie znaleziono biblioteki - program sie nie odpali - koniec kropka. Gdzie system szuka biblioteki - najpierw w katalou Windows i System32, jak nie ma - w katalogu programu (mozna wymusic ladowanie biblioteki najpierw z katalogu programu poprzez utworzenie pliku .local - nie wymaga to rekompilacji programu - w tym przypadku biblioteka obecna w katalogu Windows bedzie zignorowana). Jak ustawia sie kolejnosc poszukiwania bibliotek dynamicznych w Linuksie?

- ładowanie dynamiczne - na przykłąd LoadLibrary(ścieżka) - jak mniemam odpowiednik dlopen. Jest to łądowanie "na żądanie" i o tym ze wybranej biblioteki nie ma dowiadujemy sie dopiero podczas wykonania funkcji LoadLibrary - błąd powinnismy obsluzyc sami i generalnie nie przerywa on dzialania programu.

Czy w Linuksie istnieje analogiczne rozgraniczenie - 2 sposoby ładowania bibliotek dynamicznych?
LiTE
Beginner
Posty: 208
Rejestracja: 25 marca 2008, 13:22
Lokalizacja: Nowa Ruda

Post autor: LiTE »

Mowiac Linuks nie szuka bibliotek dynamicznych z macierzystym katalogu to za duze slowo. Kazdy moze sobie stworzyc distro, ktore bedzie mialo to defaultowo ustawione. W przypadku debiana i pewnie innych znanych dystrybucji system szuka bibliotek w /usr/lib i pochodnych.
Ale czy zmiana konfiguracji systemu to taki bol?;-)

Co do ladowania bibliotek to oczywiscie dziala to na podobnej zasadzie. Biblioteka ladowana dynamicznie, przyklad kompilacji:

Kod: Zaznacz cały

gcc  -o ./obj/dmatrix.o -fPIC  c -Wall -O3 -I./include src/matrix.c
gcc -shared -Wl,-soname,libmatrix.so -o ./lib/libmatrix.so ./obj/dmatrix.o
gcc -o ./bin/program-dynamic ./obj/main.o -L./lib/ -lmatrix
Jezeli w kodzie uzywamy dlopen() to normalnie kompilujemy, on sobie pobierze biblioteki ze sciezek podanych z kodzie.

Kolejnosc, najpierw zmienne globalne, pozniej pliki konfiguracyjne. Czyli najpierw laduje ze zmienej LD_LIBRARY_PATH
ODPOWIEDZ