MacOS - jak połączyć dynamiczną bibliotekę ze ścieżką względną za pomocą gcc/ld
Jeśli próbujesz zrozumieć dynamiczne łączenie, to pytanie może być interesujące.
Jedna z odpowiedzi na to pytanie stanowi wspaniały przykład tworzenia i używania dynamicznej biblioteki. Na jego podstawie mam kilka prostych plików:
Main.c:
extern void someFunction (int x);
int main (int argc, char** argv ) {
someFunction(666);
}
Mylibrary.c:
#include <stdio.h>
void someFunction (int x) {
printf ("\nsomeFunction called with x=%d\n", x);
}
Makefile:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
gcc -v main.o ./libmylibrary.dylib -o main
clean:
rm *.o
rm main
rm *.dylib
Jak na razie wszystko działa świetnie. Jeśli zrobię, a potem wejdę ./main w wierszu polecenia widzę oczekiwane wyjście:
someFunction called with x=666
Teraz, Ja chcę coś pomieszać. Stworzyłem katalog hidelib, który jest podkatalogiem mojego katalogu głównego. A ja dodaję jedną linijkę do mojego makefile:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
mv libmylibrary.dylib hidelib # this is the new line
clean:
rm *.o
rm main
rm hidelib/*.*
Teraz chcę dodać kolejną linijkę do pliku makefile, aby znalazł libmylibrary.dylib w podkatalogu hidelib. Chcę móc uciekać ./ main w ten sam sposób. Jak mogę to zrobić?
EDIT: dzięki za odpowiedź. Posiadanie wielu opcji jest wspaniałe, ale początkujący chce tylko jednej konkretnej opcji, która działa. Proszę. to jest to, co staram się na ostatnią linijkę, ale najwyraźniej czegoś nie rozumiem. Plik makefile jest wykonywany bez błędów, ale w czasie wykonywania mówi " library not found."
gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main
2 answers
Jedna konkretna opcja, która działa, to ustawienie znacznika install_name
Podczas łączenia .dylib
.
gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib
Wtedy możesz po prostu link do biblioteki normalnie:
gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main
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
2012-04-13 14:42:56
Prawdopodobnie potrzebujesz znacznika -L
kompilatora/linkera, który dodaje do ścieżki wyszukiwania bibliotek.
Próbujesz przenieść rzeczy po połączeniu, będziesz potrzebował zmiennej środowiskowej dyld
, Gdzie szukać. {[2] } i powinieneś być w stanie uzyskać więcej informacji na temat DYLD_LIBRARY_PATH
i innych zmiennych środowiskowych.
Zazwyczaj ustawia się nazwę instalacji biblioteki, zanim połączy się z czymś z flagą linkera -install_name
na coś takiego jak @rpath/mylibrary.dylib
jako wartość, a następnie ustawia run szukanie ścieżek ścieżki w głównym pliku wykonywalnym podczas kompilacji z flagą -rpath
do @executable_path/hidelib
.
Po Więcej informacji patrz install_name_tool
i -rpath
& -install_name
argumenty ld
.
Zasadniczo, istnieje wiele opcji tego, co próbujesz zrobić.
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
2012-04-05 02:09:53