Xcode 11 está recompilando (¿casi?) Todo mi proyecto, incluso si solo cambio una variable privada local, o cambio el valor de una constante en el ámbito local, a veces incluso en el ámbito de la función privada local. En algún momento puedo obtener 2 o 3 cambios con compilaciones rápidas como se esperaba, pero muy pronto decide recompilar todo nuevamente (lo que lleva demasiado tiempo).
¿Alguna idea de lo que podría estar pasando? Si Xcode no puede determinar qué ha cambiado, ¿por qué recompila tantas otras cosas (incluso otros módulos)?
Cualquier consejo es muy apreciado, gracias!
Respuestas:
Tuvimos el mismo problema y lo solucionamos. Dos veces.
Construcción incremental (misma máquina de construcción):
antes: ~ 10m después: ~ 35s
¿CÓMO?
Comencemos con nuestra experiencia primero. Teníamos un proyecto masivo Swift / Obj-C y esa era la principal preocupación: los tiempos de construcción eran lentos y había que crear un nuevo proyecto para implementar una nueva característica (literalmente). Puntos de bonificación por resaltado de sintaxis que nunca funciona.
Teoría
Para solucionar esto realmente, debe comprender realmente cómo funciona el sistema de compilación. Por ejemplo, intentemos este fragmento de código:
e imagine que usa todas estas importaciones en su archivo. Y también este archivo depende de otro archivo, que depende de otras bibliotecas, que a su vez usa otras bibliotecas, etc.
Entonces, para compilar su archivo, Xcode tiene que compilar cada biblioteca que mencionó y cada archivo del que depende, por lo que si cambia uno de los archivos "centrales", Xcode tiene que reconstruir literalmente todo el proyecto.
La construcción de Xcode es multiproceso , pero consta de muchos árboles de subproceso único .
Entonces, en el primer paso de cada compilación incremental, Xcode decide qué archivos deben volver a compilarse y crea un árbol AST . Si cambia un archivo que actúa como " confiable " en otros archivos, entonces todos los demás archivos que actúan como " dependientes " tienen que volver a compilarse.
Entonces, el primer consejo es reducir el acoplamiento . Las partes de su proyecto deben ser independientes entre sí.
Obj-C / Puente Swift
Problema con esos árboles si está utilizando un puente Obj-C / Swift, Xcode tiene que pasar por más fases de lo habitual:
Mundo perfecto:
Obj-C / Puente Swift:
Entonces, si cambia algo del paso 1 o 2, básicamente está en problemas. La mejor solución es minimizar Obj-C / Swift Bridge (y eliminarlo de su proyecto).
Si no tiene un puente Obj-C / Swift, es increíble y puede continuar con el siguiente paso:
Swift Package Manager
Es hora de pasar a SwiftPM (o al menos configurar mejor sus Cocoapods).
La cuestión es que la mayoría de los marcos con configuración predeterminada de Cocoapods arrastran consigo muchas cosas que no necesita.
Para probar esto, cree un proyecto vacío con una sola dependencia como PinLayout, por ejemplo, e intente escribir este código con Cocoapods (configuración predeterminada) y SwiftPM.
Spoiler: Cocoapods compilará este código, porque Cocoapods importará CADA IMPORTACIÓN de PinLayout (incluido UIKit) y SwiftPM no porque SwiftPM importa marcos atómicamente.
Truco sucio
¿Recuerdas que la construcción de Xcode es multihilo?
Bueno, puede abusar de él si puede dividir su proyecto en muchas partes independientes e importarlas todas como marcos independientes para su proyecto. Reduce el acoplamiento y esa fue en realidad la primera solución que usamos, pero de hecho no fue muy efectiva, porque solo pudimos reducir el tiempo de construcción incremental a ~ 4-5m, lo cual no es NADA en comparación con el primer método.
fuente
No hay una bala de oro aquí, pero hay muchas cosas que verificar:
Asegúrese de estar utilizando la configuración de depuración en su esquema
Vea a continuación cómo asegurarse de que está utilizando compilaciones incrementales en comparación con el módulo completo según los consejos de Matt. También asegúrese de que su Nivel de optimización para las compilaciones de depuración no sea ninguno.
Si está utilizando marcos pesados de inferencia de tipos como RxSwift, agregar anotaciones de tipo explícitas puede acelerar los tiempos de construcción.
Si el proyecto es muy grande, podría considerar refactorizar grupos lógicos de archivos fuente en marcos, pero eso puede ser un cambio demasiado drástico de lo que preferiría
Podría ayudar si proporcionara más detalles sobre el proyecto: ¿está vinculando estáticamente alguna biblioteca? ¿Es un marco o objetivo de aplicación? ¿Qué tan grande y qué versión rápida estás usando? ¿Tiene alguna Fase de construcción personalizada como linters o generación de código que a veces se puede omitir?
fuente