¿Cómo Xcode encuentra dependencies de destino implícitas?

Xcode encuentra dependencies automáticamente a veces. Creo que está bien cuando soy el que está definiendo las relaciones y cuando me siento perezoso …

Pero más que a menudo me encuentro enfrentando un proyecto existente (de tamaño mediano a grande) con varios objectives. Como el proyecto ha sido realizado por otra persona, me resulta muy difícil comprender qué objectives dependen de lo que, dado que no todas las relaciones son explícitas .

¿Cuáles son las reglas que usa Xcode para encontrar esas relaciones? (Espero poder comprender la lógica, de modo que la ejecute en mi mente y tal vez me ahorre algo de time en el futuro). O ¿Qué hace que un objective sea dependiente implícitamente de otro?

Un objective y el producto que crea se pueden relacionar con otro objective. Si un objective requiere la salida de otro objective para build, se dice que el primer objective depende del segundo. Si ambos objectives están en el mismo espacio de trabajo, Xcode puede descubrir la dependencia, en cuyo caso construye los productos en el order requerido. Tal relación se conoce como una dependencia implícita.

Fuente: Biblioteca de desarrolladores de iOS → Xcode Concepts → Xcode Target

Esta respuesta se aplica a Xcode 8.x, y creo que para Xcode 9.0.

En primer lugar, debe asegurarse de que "Buscar dependencies implícitas" esté habilitado en el panel de compilation del esquema que está intentando crear.

Un objective "A" se puede hacer "implícitamente" dependiendo del objective "B" de dos maneras:

  1. El objective A tiene una fase de compilation "Enlace binary con bibliotecas" que tiene una biblioteca en su list que tiene el mismo nombre que un producto de B. Este producto puede estar en el mismo proyecto u otro proyecto en el área de trabajo. Tenga en count que dije "el mismo nombre". El hecho de que eliges libA.a del objective A no significa que las dependencies implícitas lo generarán si tienes otro producto libA.a en un objective diferente. Vea a continuación para más detalles.
  2. El objective A tiene una "Fase de files de copy" que copy un file con un nombre base que coincide con un producto de B. Normalmente, una fase de compilation de "Copiar files" no puede referirse a un file que no está en el mismo proyecto que su objective, pero puede configurar una dependencia entre proyectos si crea un file ficticio para la fase de copyr el file para copyr que tenga el mismo nombre que un producto de B. Por ejemplo, si tiene un espacio de trabajo que contiene dos proyectos ProjectA y ProjectB. ProjectA tiene TargetA que crea libA.a, y ProjectB tiene TargetB que crea libB.a. TargetA podría hacer que TargetB construya libB.a al tener un file de byte cero "falso" como parte de TargetA que pasó a llamarse libB.a, y esto sería suficiente para get libB.a, aunque el libB.a se refirió a en la fase "Copiar files" es un file totalmente diferente a la salida del producto de la compilation TargetB. Si marca la casilla "Copiar solo al instalar", Xcode no realizará la copy, pero aún así resolverá la dependencia. De hecho, puede eliminar el file falso de su disco que creó únicamente para tener algo que poner en la fase "Copiar files" (pero debe dejarlo en su proyecto).

Entonces, ¿por qué alguien querría hacer el horror que es "2"? Puedo encontrar un par de razones.

  1. TargetA necesita algunos files copydos / generados por TargetB, pero TargetB no genera una biblioteca para vincular. Probablemente podrías evitar esto haciendo que TargetB genere una pequeña biblioteca ficticia, pero eso puede ser doloroso por otros motivos.
  2. Digamos que tenía projectA, targetA y libA.a (y equivalentes para el proyecto B, C y D), y libA.a dependía de libB.a y libC.a, que tanto necesitaban libD.a para build primero (posiblemente algunos encabezados y / o fonts generadas). Podría hacerlo todo utilizando la fase "Enlace con bibliotecas" (también conocida como solución # 1), pero en ese caso terminaría con dos copys de los files .o en libD en la versión final vinculada de libA. Si haces esto lo suficientemente profundo (por ejemplo, un espacio de trabajo que tiene 40 proyectos que tienen diferentes niveles de dependencia entre ellos) rápidamente terminarás con enormes files de biblioteca con varios files .o idénticos en ellos, y tus times de enlace se volverán horribles.

Si crees que son situaciones artificiales, actualmente estoy presionando a ambos a mover un código henetworkingado de una serie de dependencies explícitas a dependencies implícitas. ¿Por qué me estoy mudando a dependencies implícitas? Debido a que las dependencies explícitas en Xcode requieren el anidamiento de proyectos, y una vez que obtiene suficientes dependencies explícitas, el browser de proyectos se vuelve extremadamente lento, y verá muchas bolas de playa dentro de Xcode para cosas aleatorias.

¿Qué sucede si tiene dos objectives dentro del mismo espacio de trabajo que generan productos con el mismo nombre y dependen de ellos desde un tercer objective? Las dependencies implícitas elegirán uno. Parece que hace una coincidencia basada en el nombre base del producto (por lo que foo / bar.a y baz / bar.a son los mismos), y seleccionará el primero que encuentre.