2010-09-12 13 views
18

Tengo un Makefile para Linux que transfiero a Darwin. El archivo MAKE toma un grupo de archivos .O y los vincula en un objeto compartido .so. De acuerdo, entonces pensé (¿me equivoco sobre esto?) Que el mejor análogo para esto en Darwin es el dylib. Así que cambié el indicador -shared por -dynamiclib.¿Cuál es el problema con los símbolos indefinidos en una biblioteca compartida o dylib?

Ahora el código que estoy uniendo en el dylib depende de muchas bibliotecas externas. Cuando intento construir el dylib, recibo errores que dicen que hay referencias indefinidas. Pero Linux Makefile no especifica ninguna de las opciones -lwhatever o -L/path/whatever en el paso de compilación que crea el archivo .so. ¿Hm? ¿Esto se debe a que al crear un archivo .so ELF, de forma predeterminada deja sin resolver las referencias externas y luego cuando se carga la biblioteca compartida, recursivamente carga las bibliotecas compartidas de las que depende la biblioteca compartida que está cargando? ¿No sería el caso que si la biblioteca compartida depende de un archivo .a o .o, TENDRÍA que vincular estáticamente a la biblioteca compartida, de lo contrario, no podría vincular en tiempo de ejecución? ¿Cómo puede salirse con la suya teniendo referencias no definidas en una biblioteca que se carga en tiempo de ejecución, a menos que las referencias también sean bibliotecas cargables dinámicamente?

De todos modos por lo que si puedo especificar

-undefined suppress -flat_namespace 

que no me exige añadir esas opciones -l y -L al crear la biblioteca compartida. Pero todavía no entiendo cómo esto puede funcionar en última instancia.

Respuesta

1

Use libtool.

libtool -dynamic -multiply_defined suppress -install_name `basename ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib` -o ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib ../../../../rlp/lib/universal-darwin9-gcc40/libbtd.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttrie.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtkey.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtunit.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtutilities.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtopts.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxcode.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtprops.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxml.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake3.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake5.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtac.a -lstdc++.6 -lgcc_s.10.4 ../../../../build_system/lib/universal-darwin9-gcc40/libgcc.a -lSystem -lSystemStubs` 
+1

Gracias, creo que funcionará, pero también estoy interesado en los antecedentes detrás de lo que está sucediendo. – eeeeaaii

+0

MacOS no es bastante Linux. Originalmente es NextOS, después de todo. El enlazador es un poco excéntrico. Agregue -v al libtool y le dirá lo que está haciendo. – bmargulies

13

This thread también trata este problema. Creo que el punto clave es que para obtener el comportamiento de enlace similar a Linux, debe especificar el indicador "-undefined dynamic_lookup". De forma predeterminada, el enlazador de Darwin arroja un error si hay referencias no definidas en una biblioteca dinámica. También puede usar -U para establecer este comportamiento en función de cada símbolo. Ver 'man ld' para referencia.

Cuestiones relacionadas