ios objective-c xcode linker static-libraries

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 clase ABCTracker 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 y Other 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 para lMyLibrary (¿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)