Jak utworzyć dynamiczną bibliotekę (dylib) za pomocą Xcode?

Buduję kilka narzędzi wiersza poleceń w Xcode (zwykły C, bez Cocoa). Chcę, aby wszystkie używały mojej dostosowanej wersji libpng i chcę zaoszczędzić miejsce, dzieląc jedną kopię biblioteki pomiędzy wszystkie pliki wykonywalne(nie mam nic przeciwko ponownej dystrybucji .dylib z nimi).

Czy muszę zrobić jakąś magię, aby uzyskać symbole eksportu libpng?

Czy "Link binarny z bibliotekami" buduje łącze fazowe statycznie?

Dokumenty Apple wspominają o wczytywaniu bibliotek w czasie uruchamiania z dlopen, ale jak Mogę sprawić, że Xcode stworzy plik wykonywalny bez narzekania na brakujące symbole?


Chyba to rozgryzłem:

  • Libpng nie łączył się poprawnie, ponieważ zbudowałem 32/64-bitowe pliki wykonywalne i 32-bitową bibliotekę. Ustawienia kompilacji biblioteki i plików wykonywalnych muszą być zgodne.

  • Konfiguracja Libpng.h musi mieć mnóstwo definicji jak #define FEATURE_XXX_SUPPORTED

  • "Link Binary With Libraries" Faza budowania obsługuje biblioteki dynamiczne w porządku, a zmienna środowiskowa DYLD_FALLBACK_LIBRARY_PATH jest niezbędna do załadowania .dylib S z pakietu aplikacji.

Author: Kornel, 2008-10-11

4 answers

Prawdopodobnie musisz upewnić się, że dynamiczna biblioteka, którą budujesz, ma wyeksportowany plik symboli, który zawiera listę tego, co powinno zostać wyeksportowane z biblioteki. To tylko płaska lista symboli, po jednym na linię, do eksportu.

Również, gdy twoja dynamiczna biblioteka jest budowana, otrzymuje osadzoną w niej nazwę instalacji , która jest domyślnie ścieżką, na której jest budowana. Następnie wszystko, co się z nim łączy, będzie najpierw szukać go w podanej ścieżce, a dopiero później przeszukać (small) zestaw domyślnych ścieżek opisanych pod DYLD_FALLBACK_LIBRARY_PATH w dyld(1) strona man .

Jeśli chcesz umieścić tę bibliotekę obok plików wykonywalnych, powinieneś dostosować jej nazwę instalacji, aby się do niej odwoływać. Samo szukanie w Google "nazwa instalacji" powinno znaleźć mnóstwo informacji na ten temat.

 7
Author: Chris Hanson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-12 03:00:34

Dynamiczne łączenie na Mac OS X, mały przykład

Kroki:

  1. Utwórz bibliotekę libmylib.dylib zawierający mymod.o
  2. skompiluj i połącz "callmymod", który nazywa go
  3. wywołaj mymod z callmymod, używając DYLD_LIBRARY_PATH i DYLD_PRINT_LIBRARIES

Problem: "Po prostu" chcesz utworzyć bibliotekę dla innych modułów do użycia. Jest jednak zniechęcający stos programów-gcc , LD, MacOSX libtool, dyld -- z milionami opcji, niektóre dobrze zgniłe kompost i różnice między MacOSX i Linuksem. Jest mnóstwo stron podręcznika (liczę 7679 + 1358 + 228 + 226 linie w 10.4.11 ppc) ale nie za bardzo w sensie przykładów, czy programów z trybem "powiedz mi, co robisz".

(najważniejszą rzeczą w zrozumieniu jest uproszczenie Przegląd dla siebie: narysuj kilka zdjęć, Uruchom kilka małych przykładów, wyjaśnij to komuś innemu).

Background: Apple OverviewOfDynamicLibraries , Wikipedia Dynamic_library


Krok 1, Utwórz libmylib.dylib --

mymod.c:
    #include <stdio.h>
    void mymod( int x )
    {
        printf( "mymod: %d\n", x );
    }
gcc -c mymod.c  # -> mymod.o
gcc -dynamiclib -current_version 1.0  mymod.o  -o libmylib.dylib
    # calls libtool with many options -- see man libtool
    # -compatibility_version is used by dyld, see also cmpdylib

file libmylib.dylib  # Mach-O dynamically linked shared library ppc
otool -L libmylib.dylib  # versions, refs /usr/lib/libgcc_s.1.dylib

Krok 2, skompiluj i połącz callmymod --

callmymod.c:
    extern void mymod( int x );
    int main( int argc, char** argv )
    {
        mymod( 42 );
    }
gcc -c callmymod.c
gcc -v callmymod.o ./libmylib.dylib -o callmymod
    # == gcc callmymod.o -dynamic -L. -lmylib
otool -L callmymod  # refs libmylib.dylib
nm -gpv callmymod  # U undef _mymod: just a reference, not mymod itself

Krok 3, Uruchom callmymod łączący się z libmylib.dylib --

export DYLD_PRINT_LIBRARIES=1  # see what dyld does, for ALL programs
./callmymod
    dyld: loaded: libmylib.dylib ...
    mymod: 42

mv libmylib.dylib /tmp
export DYLD_LIBRARY_PATH=/tmp  # dir:dir:...
./callmymod
    dyld: loaded: /tmp/libmylib.dylib ...
    mymod: 42

unset DYLD_PRINT_LIBRARIES
unset DYLD_LIBRARY_PATH

To kończy jeden mały przykład; mam nadzieję, że pomoże zrozumieć kroki.
(Jeśli robisz to często, zobacz GNU Libtool czyli glibtool na Macach, i SCons .)
cheers
-- denis

 49
Author: denis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-07 12:37:00

Niestety, z mojego doświadczenia wynika, że dokumentacja Apple jest przestarzała, zbędna i brakuje wielu typowych informacji, których normalnie byś potrzebował.

Napisałem kilka rzeczy na ten temat na mojej stronie internetowej, gdzie musiałem uzyskać FMOD (Sound API) do pracy z moją grą międzyplatformową, którą opracowaliśmy w uni. Jego dziwny proces i jestem zaskoczony, że Apple nie dodaje więcej informacji na ich dokumentacji deweloperskiej.

Niestety, jako" zły " jak Microsoft, faktycznie robią znacznie lepszą robotę dbanie o ich deweloperów z dokumentacją(to pochodzi od Ewangelisty Apple ).

Myślę, że zasadniczo to, czego nie robisz, to po skompilowaniu swojego .pakiet aplikacji. Następnie należy uruchomić polecenie na pliku wykonywalnym binarnym / MyApp.app / contents / MacOS / MyApp w celu zmiany miejsca, w którym plik wykonywalny szuka swojego pliku bibliotecznego. Musisz utworzyć nową fazę budowania, która może uruchomić skrypt. Nie będę wyjaśniał tego procesu ponownie, zrobiłem to już dogłębnie tutaj:

Http://brockwoolf.com/blog/how-to-use-dynamic-libraries-in-xcode-31-using-fmod

Mam nadzieję, że to pomoże.

 6
Author: Brock Woolf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-06 17:04:47

Czy znasz stronę referencyjną Apple Dynamic Library Programming Topics? Powinno pokryć większość tego, czego potrzebujesz. Należy pamiętać, że istnieją biblioteki współdzielone, które są ładowane bezwarunkowo przy starcie programu i biblioteki dynamicznie ładowane (Pakiety, IIRC), które są ładowane na żądanie, a te dwa są nieco różne w systemie MacOS X od odpowiedników w Linuksie lub Solarisie.

 5
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-18 07:38:13