ios - Vinculación débil de la biblioteca estática a través de-weak_library
objective-c xcode (0)
Pregunta:
¿Es posible vincular débilmente una biblioteca estática (Obj-C)?
Detalles cortos
Quiero que mi marco estático personalizado ( MyFramework.framework ) vincule débilmente mi otra biblioteca estática personalizada ( libMyLibrary.a ).
La funcionalidad detrás de libMyLibrary.a es opcional y se puede omitir si NO hay ninguna libMyLibrary.a vinculada por ninguna aplicación de terceros que utilice MyFramework.framework .
Estoy usando -weak_library
. Mi aplicación de prueba se queja de que el enlazador estático no puede encontrar el símbolo MyClass
MyLibrary dentro del símbolo ABCTracker.o de ABCTracker.o
:
Undefined symbols for architecture arm64:
"_OBJC_CLASS_$_MyClass", referenced from:
objc-class-ref in MyFramework(ABCTracker.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
¿Cómo configurar correctamente los enlaces débiles?
Todos los detalles
Preparar
- El proyecto Xcode construye un binario Mach-O estático y lo agrupa en un marco estático. El resultado es MyFramework.framework bundle.
- Otro proyecto crea un binario Mach-O estático y el resultado es un archivo de lib estático libMyLibrary.a con un encabezado MyLib.h
- libMyLibrary.a se elimina de MyFramework.framework target''s Build Fhases > Link Binary With Libraries ( como se sugiere aquí ). Solo MyLib.h está disponible para usar la API de la biblioteca de las clases de framework
- NO se utiliza ningún código de bits ni en el marco ni en la biblioteca
- MyFramework.framework , libMyLibrary.a y la aplicación personalizada están todos escritos en Objective-C
- MyLib.h define solo una clase Objective-C
MyClass
- MyFramework.framework utiliza
MyClass
de su propia claseABCTracker
verificando condicionalmente la disponibilidad de símbolos durante el tiempo de ejecución, por ejemplo,NSClassFromString(@"MyClass") == NULL
Desde la configuración de compilación del objetivo de MyFramework , he configurado
Other Librarian Flags
yOther Linker Flags
de-weak_library MyLibrary
con el mismo valor-weak_library MyLibrary
:OTHER_LDFLAGS = ( "-weak_library", MyLibrary, ); OTHER_LIBTOOLFLAGS = "-weak_library MyLibrary";
Resultado
- MyFramework.framework crea OK
Después de la compilación, he comprobado los símbolos en el binario resultante y el resultado fue emty (no se han incorporado símbolos de la biblioteca estática en el binario del marco estático):
$ otool -L MyFramework.framework/MyFramework | grep MyClass
A pesar de eso, mi aplicación de prueba que no está vinculada con MyLibrary en absoluto, crea con el error
ld
:Undefined symbols for architecture arm64: "_OBJC_CLASS_$_MyClass", referenced from: objc-class-ref in MyFramework(ABCTracker.o) ld: symbol(s) not found for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
¿Qué estoy haciendo mal aquí?
Otras observaciones
En el objetivo de MyFramework , establezco Other Librarian Flags
y Other Linker Flags
de enlace de igual valor:
-
-lMyLibrary
. Resultado:otool
muestra que los símbolos de la biblioteca están incorporados en el marco (esperado). -
-weak-lMyLibrary
. El resultado es el mismo que paralMyLibrary
(¿se espera?)
En mi destino de aplicación , configuré Other Linker Flags
de -force_load MyLibrary
para -force_load MyLibrary
. Resultado: el error del enlazador cambia ligeramente:
ld: file not found: MyClass
clang: error: linker command failed with exit code 1 (use -v to see invocation)