2012-09-27 23 views
6

Estoy tratando de encontrar la mejor forma de empaquetar una biblioteca estática (llamémosla Lib1) que incluye una clase opcional (por ejemplo, ClassA)), que a su vez requiere una segunda biblioteca estática (Lib2). En otras palabras, Lib2 solo es necesario si se hace referencia a ClassA en el código del proyecto. Las cosas parecen funcionar bien, a menos que se use Lib1 en un proyecto que no usa ClassA (y por lo tanto no incluye Lib2), sino que requiere el indicador del enlazador -ObjC (debido a otras dependencias del proyecto, no a las mías).ObjC: Cómo compilar una biblioteca estática que incluye clases opcionales que dependen de una biblioteca de terceros

estoy tratando de llegar a un una solución fácil para los siguientes tres escenarios:
1) proyecto incluye mi lib estática, no utiliza la clase opcional, no especifica la bandera -ObjC
2) el proyecto incluye mi lib estática, NO usa la clase opcional, pero requiere -ObjC flag
3) el proyecto incluye mi biblioteca estática + segunda biblioteca estática, y SI usa la clase opcional (no nos importa la bandera -ObjC en este punto)

¿Hay una bandera del enlazador para quitar mi clase opcional de la aplicación de proyecto final para que no requiera la segunda libreta estática? Supongo que mis otras alternativas son lanzar varias versiones de mi lib estática, una que incluya la clase de opción (la opción estándar), otra que no (la alternativa, para proyectos con requisitos -ObjC), o tal vez proporcionar un archivo de resguardo, que proporciona implementaciones vacías de todas las clases necesarias de la segunda biblioteca estática? Parece que podría ser un problema común en el mundo de la biblioteca estática ... ¿existe una mejor práctica para este escenario?

Gracias!


Solución:

1) sugerir a mis usuarios que utilizan -ObjC -force_load lugar. (gracias Rob!)
2) Para los usuarios que no pueden hacer 1, voy a tener una compilación alternativa que no incluye ClassA

Respuesta

6

La mejor práctica es siempre tener el último enlace binario todas las libretas estáticas requeridas . Nunca debe agrupar una biblioteca estática en otra. No debe empaquetar una biblioteca estática bien conocida (es decir, de código abierto) en una biblioteca estática que envíe. Esto puede crear dolores de cabeza increíbles para el consumidor final porque pueden terminar con múltiples versiones del mismo código. Hacer un seguimiento de los errores que pueden venir de esto es terriblemente difícil. Si tienen suerte, obtendrán confusos errores de compilación. Si no tienen suerte, su código se comportará de forma impredecible y se bloqueará aleatoriamente.

Envíe todas las bibliotecas estáticas por separado. Dígale a sus clientes cuáles necesitan vincular para varias configuraciones. Tratar de evitar esto solo hace que sus vidas sean difíciles.

Algunas otras discusiones que pueden ser útiles:


El distintivo -ObjC debería evitar la extracción automática de ClassA en su totalidad, ya sea que se use o no (ver TN1490 para más detalles).

Si ClassA nunca se usa, excepto en ciertas circunstancias y desea ahorrar espacio, probablemente debería mover ClassA a su propia biblioteca estática. O use #ifdef para compilarlo condicionalmente.

Alternativamente, puede eliminar el indicador -ObjC y usar -force_load para cargar individualmente cualquier unidad de compilación de categoría solamente (que es el problema -ObjC se usa para direccionar).

+0

Gracias por los enlaces, me han ayudado a comprender mejor la composición de una lib estática. –

+0

No estoy realmente agrupando libs estáticas en mi lib estática. En mi lib estática (llámalo Lib1), tengo una clase (digamos Clase A) que depende de otra lib estática (Lib2) que está vinculada a la aplicación. ClassA nunca se usará sin la inclusión de Lib2. Parece que el compilador/enlazador es lo suficientemente inteligente como para despojar a ClassA de la aplicación final, si no se usó. Sin embargo, si se especifica el marcador del vinculador -ObjC, el compilador/vinculador intenta resolver las dependencias de Lib2 de ClassA, pero no puede ... independientemente de si alguna vez se hizo referencia a ClassA en la aplicación. Esperaba una bandera enlazadora mágica que tirara la clase A –

+1

actualizada con algunas reflexiones. No es fácil arreglar esto. ObjC es altamente dinámico, y es totalmente normal para las clases de referencia en el tiempo de ejecución de forma que el enlazador no puede ver en el tiempo del enlace (la carga de la punta se hace de esta manera). Es muy difícil para el enlazador hacer esto bien si coloca todo en el mismo archivo sin pasar los parámetros individuales -force_load en lugar del parámetro -ObjC grande. –

Cuestiones relacionadas