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
Author: Community, 2012-04-05

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
 14
Author: leedm777,
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ć.

 7
Author: wbyoung,
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