kompilacja bez shared libraries
kompilacja bez shared libraries
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).
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.
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.
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
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
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
Istnieje jeszcze taki plik konfiguracyjny gdzie podajesz sciezki do bibliotek /etc/ld.so.conf.
Wiecej tutaj: http://www.yolinux.com/TUTORIALS/Librar ... namic.html
Kod: Zaznacz cały
export LD_LIBRARY_PATH=/home/jakis/katalog/:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
Wiecej tutaj: http://www.yolinux.com/TUTORIALS/Librar ... namic.html
@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)
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)
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?
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?
Mozesz ;-)Nie mozesz w kodzie napisac: "wez ta biblioteke z tego katalogu i jej użyj"
Kod: Zaznacz cały
dlopen("/opt/lib/libctest.so", RTLD_LAZY);
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?
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?
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:
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
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
Kolejnosc, najpierw zmienne globalne, pozniej pliki konfiguracyjne. Czyli najpierw laduje ze zmienej LD_LIBRARY_PATH