2012-04-05 10 views
15

Se si sta tentando di comprendere il collegamento dinamico, è probabile che sia interessante il numero this question.MacOS - come collegare una libreria dinamica con un percorso relativo utilizzando gcc/ld

Una delle risposte a questa domanda fornisce un meraviglioso esempio di creazione e utilizzo di una libreria dinamica. Basati su di esso, I alcuni file semplice:

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 

Finora, tutto funziona alla grande . Se faccio e quindi immettere ./main al prompt dei comandi, vedo l'uscita prevista:

someFunction called with x=666 

Ora, voglio mescolare le cose un po '. Ho creato una directory hidelib, che è una sottodirectory della mia directory principale. E sto aggiungendo una riga al mio 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/*.* 

Ora, voglio aggiungere un'altra linea per il makefile in modo da trovare libmylibrary.dylib nella sottodirectory hidelib. Voglio essere in grado di eseguire ./main allo stesso modo. Come lo posso fare?

EDIT: Grazie per la risposta. Avere molte opzioni è meraviglioso, ma un principiante vuole solo un'opzione concreta che funzioni. Ecco cosa sto cercando per l'ultima riga, ma chiaramente non capisco qualcosa. Il makefile viene eseguito senza errori, ma in fase di esecuzione dice "libreria non trovata".

gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main 

risposta

13

Un'opzione concreta che funziona sarebbe quella di impostare il flag install_name quando si collega .dylib.

gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib 

Poi si può solo link alla libreria normalmente:

gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main 
7

probabilmente è necessario il flag -L compilatore/linker che aggiunge al percorso di ricerca per le librerie.

Sta cercando di spostare le cose dopo il collegamento, avrete bisogno di una variabile di ambiente dyld per dove cercare. man dyld e dovresti essere in grado di ottenere maggiori informazioni su DYLD_LIBRARY_PATH e altre variabili di ambiente.

In genere, però, si imposta il nome di installazione della libreria prima di collegarlo a qualcosa con la bandiera -install_name linker a qualcosa come @rpath/mylibrary.dylib come valore, quindi impostare i percorsi di ricerca percorso corsa sulla eseguibile principale durante la compilazione con il flag -rpath a @executable_path/hidelib.

Per ulteriori informazioni consultare install_name_tool ei -rpath & -install_name argomenti di ld.

Fondamentalmente, ci sono molte opzioni per quello che stai cercando di fare.

Problemi correlati