Habilitando la Compilación Incremental de Kotlin en Buck2 con la Build Tools API KEEP
Sources: https://engineering.fb.com/2025/08/26/open-source/enabling-kotlin-incremental-compilation-on-buck2, https://engineering.fb.com/2025/08/26/open-source/enabling-kotlin-incremental-compilation-on-buck2/, Meta
TL;DR
- La compilación incremental de Kotlin ya se integra en Buck2 para acelerar las compilaciones enfocándose solo en archivos modificados.
- El enfoque utiliza la Build Tools API KEEP como punto de integración oficial, abordando problemas de shading y conflictos de classpath.
- Las acciones incrementales de Buck2 permiten conservar salidas entre ejecuciones, usando hashes para detectar cambios y snapshots de classpath para considerar cambios en dependencias.
- Algunos módulos críticos pueden verse hasta 3x más rápidos, destacando ganancias de productividad a escala.
- Los plugins y el procesamiento de anotaciones (KSP2) se adaptaron para trabajar con rondas incrementales, asegurando resultados consistentes a través de múltiples pases. Fuente: blog de ingeniería de Meta sobre habilitar la compilación incremental de Kotlin en Buck2. Ver https://engineering.fb.com/2025/08/26/open-source/enabling-kotlin-incremental-compilation-on-buck2/ para el texto detallado.
Contexto y antecedentes
El compilador incremental de Kotlin ha sido una ventaja para desarrolladores que buscan retroalimentación rápida al volver a compilar solo las partes modificadas de un código. Buck2, el sistema de construcción de Meta, también promueve módulos pequeños para lograr compilaciones rápidas mediante paralelismo y ejecución incremental. A medida que el código crece y los equipos cambian, algunos módulos tienden a volverse más grandes, lo que puede afectar los tiempos de compilación. Para explorar si la compilación incremental podría generar beneficios en Buck2, Meta evaluó el compilador incremental de Kotlin dentro de la cadena de herramientas de Android. El beneficio central de la compilación incremental es sencillo: en lugar de reconstruir todo el módulo, el compilador se centra en los archivos modificados y en los que dependan de ellos. Meta observó que varios módulos críticos podrían beneficiarse significativamente, con compilaciones que se aceleran hasta tres veces. Este hallazgo motivó un esfuerzo de integración más profundo, equilibrando la estabilidad a largo plazo con la necesidad de velocidad. Desde el punto de vista de herramientas, se enfrentaron varios desafíos. En Kotlin 2.2.0, el único contrato público garantizado para el compilador es mediante la interfaz de línea de comandos (CLI). La CLI no admite compilación incremental, lo que empujó a Meta hacia puntos de integración alternativos. Las APIs internas del compilador no están destinadas al uso público y pueden ser inestables ante actualizaciones de Kotlin. La Build Tools API (KEEP), introducida con Kotlin 1.9.20, emergió como el punto de integración oficial más estable que incluye soporte para compilación incremental. La decisión fue adoptar KEEP, con la intención de influir en su dirección futura. Otro desafío práctico era el conflicto de classpath entre las jars del compilador Kotlin sombreado y el toolchain Android históricamente construido alrededor de un compilador no sombreado. Para resolver esto, Meta realizó inicialmente un desombrado temporal de la Build Tools API (con jarjar) para obtener un prototipo funcional, y luego migró completamente al compilador sombreado para garantizar la estabilidad a largo plazo. Para habilitar la compilación incremental, Buck2 debe tener acceso a las salidas de la construcción previa, ya que Buck2 elimina las salidas por defecto antes de reconstruir un módulo. El equipo introdujo un modo en las acciones incrementales de Buck2 que permite omitir la limpieza automática, permitiendo así reutilizar salidas anteriores. Esto implica que los desarrolladores deben limpiar manualmente lo que ya no es útil. Este cambio fue imprescindible para desbloquear la incrementabilidad mientras se mantiene la higiene del cache. Un objetivo más amplio era soportar builds distribuidos: Buck2 puede ejecutarse de forma remota y devolver los resultados. Un caché de compilación relocatable es crucial para evitar conflictos de ruta entre diferentes máquinas. Meta configuró explícitamente el directorio raíz del proyecto y el directorio de construcción dentro de las configuraciones de compilación incremental para mantener la estabilidad del caché, sin importar quién ejecute la compilación o dónde ocurra.
Qué hay de nuevo
- Adopción de la Build Tools API KEEP como punto de integración oficial para la compilación incremental de Kotlin en Buck2, brindando un camino más sostenible hacia el futuro.
- Una solución temporal durante la prototipación para desombrar la Build Tools API (con jarjar) antes de migrar al compilador sombreado completo, asegurando un prototipo funcional antes de la migración total.
- Buck2 incremental conserva salidas entre ejecuciones y genera digests de hash para cada entrada de acción, lo que permite detectar cambios con precisión y realizar una recompilación selectiva.
- La detección de cambios puede ser automática o manual. La detección automática depende de la versión de Kotlin; para versiones anteriores a 2.1.20, es necesario proporcionar una lista de archivos modificados. Incluso con detección automática, proporcionar la lista puede optimizar el proceso.
- Snapshots de classpath capturan el ABI de las bibliotecas. Al comparar snapshots actuales con los anteriores, el compilador puede determinar qué archivos del módulo se ven afectados por cambios en dependencias. Una acción dedicada genera estos snapshots y el artefacto resultante puede almacenarse en caché o ejecutarse de forma remota para evitar trabajo local pesado.
- Si el análisis de dependencias ya identifica los cambios relevantes, la comparación de snapshots puede omitirse para acelerar la construcción.
- Integrar la compilación incremental con plugins personalizados requirió ajustes: los plugins deben ser incrementales y capaces de manejar entradas parciales, ya que la compilación incremental puede operar con subconjuntos de archivos en rondas múltiples. El Kotlin Symbol Processing (KSP2) se utilizó para el procesamiento de anotaciones, funcionando como una herramienta independiente que utiliza la API de Análisis de Kotlin para analizar el código, lo que ayuda a mantener la compatibilidad con la incrementalidad.
Por qué importa (impacto para desarrolladores/empresas)
La integración ofrece mejoras de productividad al reducir el tiempo de reconstrucción de grandes bases de código Android. Al reutilizar salidas y enfocarse solo en archivos modificados, las builds terminan más rápido, lo que acorta los ciclos de retroalimentación y mejora la eficiencia de desarrollo. En entornos de builds distribuidos, un caché relocatable estable es crucial para evitar conflictos de ruta entre distintas máquinas. Este trabajo también ayuda a que los equipos escalen sus toolchains conforme crecen los módulos y se amplían los equipos, manteniendo la satisfacción de los desarrolladores y la eficiencia de las builds.
Detalles técnicos o Implementación
- El compilador Kotlin incremental requiere acceso a las salidas previas, que Buck2 borra por defecto. El equipo configuró las acciones incrementales para conservar estas salidas, con la advertencia de que los desarrolladores deben limpiar manualmente las salidas ya no útiles. Esto permite el estado previo para el proceso incremental.
- La detección de cambios puede ser automática o manual. La detección automática depende de la versión de Kotlin; para versiones anteriores a 2.1.20, es necesario proporcionar una lista de archivos modificados. Incluso con detección automática, proporcionar la lista puede mejorar el rendimiento.
- Buck2 captura digests de hash para cada entrada de acción para determinar qué cambió desde la construcción anterior. Esto facilita la identificación precisa de archivos afectados y minimiza el trabajo innecesario.
- Snapshots de classpath capturan el ABI de las bibliotecas. Al compararlos con snapshots previos, el compilador puede determinar qué archivos del módulo se ven afectados por cambios en dependencias. Una acción separada genera estos snapshots; el artefacto puede almacenarse en caché o ejecutarse de forma remota para evitar procesamiento local pesado.
- Si el análisis de dependencias ya identifica los cambios relevantes, la comparación de snapshots puede omitirse para acelerar la construcción.
- Integrar la compilación incremental con plugins personalizados requirió ajustes: los plugins deben ser incrementales y capaces de manejar entradas parciales, ya que la compilación incremental puede operar con subconjuntos de archivos en rondas. El Kotlin Symbol Processing (KSP2) se utiliza para el procesamiento de anotaciones como una herramienta independiente que usa la API de Análisis de Kotlin para analizar el código, ayudando a mantener la compatibilidad con la incrementalidad.
Resumen de cambios
| Opción de detección | Descripción |
| Cuando usar |
|---|
| --- |
| --- |
| Detección automática |
| Ideal con Kotlin 2.1.20+ |
| Lista manual |
| Necesario para Kotlin |
Referencias
More news
Un nuevo marco de clasificación consciente de la diversidad para mejorar la calidad de notificaciones en Instagram
Meta presenta un marco de clasificación de notificaciones consciente de la diversidad que agrega una capa de diversidad sobre los modelos de compromiso para reducir la repetición, ampliar la variedad de contenido y mejorar el CTR en las notificaciones de Instagram.
Soluciones de IA basadas en agentes para acceso y seguridad de datos en almacenes
Meta describe un enfoque basado en agentes para evolucionar su almacén de datos, habilitando un acceso a datos seguro y con contexto para usuarios humanos y agentes de IA. El artículo detalla agentes de usuario de datos y agentes de propietario de datos, sus subagentes, salvaguardas y un flujo de tr
Diff Risk Score: IA para desarrollo de software con gestión de riesgos en Meta
Diff Risk Score (DRS) usa un Llama ajustado para predecir incidentes en producción a partir de cambios de código y guiar el desarrollo consciente del riesgo a lo largo del ciclo de software.
Construir una interfaz humano‑máquina para todos: Meta explora entrada sEMG en la muñeca
Reality Labs de Meta avanza con dispositivos en la muñeca que usan sEMG para una interfaz humano‑máquina universal, ante el reto de generalización en HCI. Un episodio del Meta Tech Podcast analiza este enfoque.
Acelerando ML en el dispositivo en la familia de apps de Meta con ExecuTorch
ExecuTorch es el marco de inferencia en el dispositivo de Meta para dispositivos móviles y edge, basado en PyTorch 2.x. Mejora la latencia, la privacidad y el rendimiento en Instagram, WhatsApp, Messenger y Facebook.
Cómo Meta mantiene confiable su hardware de IA
La infraestructura de IA de Meta abarca centros de datos globales; el artículo describe detección y mitigación de fallas de hardware y corrupciones silenciosas de datos (SDC) para mantener la capacitación y la inferencia fiables a gran escala.