2012-04-05 9 views
15

Si está intentando comprender la vinculación dinámica, es probable que this question sea de su interés.MacOS: cómo vincular una biblioteca dinámica con una ruta relativa mediante gcc/ld

Una de las respuestas a esa pregunta proporciona un maravilloso ejemplo de creación y uso de una biblioteca dinámica. Basado en ella, algunos archivos simples:

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 

Hasta ahora, todo funciona muy bien . Si hago y luego entrar en ./main en el símbolo del sistema, veo la salida esperada:

someFunction called with x=666 

Ahora, quiero mezclar las cosas un poco. Creé un directorio hidelib, que es un subdirectorio de mi directorio principal. Y yo estoy añadiendo una línea a mi 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/*.* 

Ahora, quiero añadir otra línea para el makefile por lo que se encuentra en el subdirectorio libmylibrary.dylib hidelib. Quiero poder ejecutar ./main de la misma manera. ¿Cómo puedo hacer eso?

EDIT: Gracias por la respuesta. Tener muchas opciones es maravilloso, pero un principiante solo quiere una opción concreta que funcione. Esto es lo que intento para la última línea, pero claramente no entiendo nada. El archivo MAKE se ejecuta sin errores, pero en el tiempo de ejecución dice "biblioteca no encontrada".

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

Respuesta

13

Una opción concreta que funciona sería establecer el indicador install_name al vincular el .dylib.

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

continuación, sólo puede vincular a la biblioteca normalmente:

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

es probable que tenga la bandera -L compilador/enlazador que se suma a la ruta de búsqueda de bibliotecas.

Están tratando de mover cosas después del enlace, necesitarán una variable de entorno dyld para buscar. man dyld y debería poder obtener más información sobre DYLD_LIBRARY_PATH y otras variables de entorno.

Por lo general, sin embargo, se establece el nombre de la instalación de la biblioteca antes de ligarse a algo con la bandera -install_name enlazador a algo así como @rpath/mylibrary.dylib como el valor, a continuación, establecer las rutas de búsqueda de ruta de carrera en el ejecutable principal al compilar con la bandera -rpath a @executable_path/hidelib.

Para más información ver install_name_tool y los -rpath & -install_name argumentos de ld.

Básicamente, hay muchas opciones para lo que estás tratando de hacer.

Cuestiones relacionadas