BookinglyTech News
Software

Sincronizar el backend GCC de Rust: dos meses y varios bloqueos en cadena

El backend GCC de rustc tardó casi dos meses en sincronizarse con el repositorio principal del compilador por culpa de licencias, caché de CI y versiones de binutils.

2 min de lecturaLobsters0 vistas

Sincronizar el backend GCC de Rust con el repositorio principal del compilador ha costado casi dos meses. El proceso se fue encadenando con problemas de licencia, caché de CI, binutils y un revert de GitHub que falló, hasta que el último bloqueo conocido cayó el 17 de agosto. Quien lo cuenta lo presenta como un caso práctico de la ley de Murphy.

Qué es el backend GCC y por qué hay que sincronizarlo

Conviene no confundirlo con gccrs, que es un front-end de Rust para GCC. rustc_codegen_gcc es un generador de código: permite que rustc emita a través de libgccjit en lugar de LLVM. Vive en su propio repositorio para poder experimentar sin romper la CI del compilador, pero su código está copiado además dentro de rustc, en compiler/rustc_codegen_gcc. Cuando el compilador añade una funcionalidad, los tres backends —LLVM, Cranelift y GCC— tienen que reflejarla, así que los dos repositorios acumulan cambios propios y hay que fusionarlos cada cierto tiempo.

Para eso usan git subtree, una función que el autor describe como incompleta y problemática con repositorios grandes. Requiere compilar a mano una versión parcheada de git. El procedimiento son varios push y pull entre ambos lados, más la actualización del submódulo src/gcc a la versión concreta de GCC que espera el backend. Las instrucciones están en la documentación del proyecto.

Cómo se torció

El PR #159844 se abrió el 24 de julio. Primer obstáculo: un archivo copiado para detectar funcionalidades de CPU tenía problemas de licencia, resueltos el 31 de julio. En paralelo, la nueva versión de GCC necesitaba un make más reciente que el de la imagen docker, así que metieron el código fuente de make en el espejo interno de la CI y reconstruyeron la imagen. El PR se fusionó el 3 de agosto.

Apenas se fusionó, el equipo de infraestructura avisó por Zulip: la CI estaba rota. Revertir desde la interfaz de GitHub no funcionó por restricciones del repositorio, así que lo hicieron a mano y todo volvió a la normalidad. Quedaba la duda de por qué el PR original había pasado la CI.

La investigación encontró dos cosas: el GCC compilado no tenía ciertas funcionalidades habilitadas y había un bug en la caché. Al construirse, GCC se configura según las herramientas del sistema: si el linker no soporta retain, esa funcionalidad se desactiva. El backend acababa de añadir "externally implementable items", que depende de retain, y sus tests se habían desmarcado como ignorados. El arreglo pasó por instalar binutils más nuevo, en el PR #161006, y se fusionó el 17 de agosto.

El relato es útil para cualquiera que mantenga CI con artefactos precompilados. Una caché puede esconder durante semanas un fallo de configuración, y un binario construido en un entorno con menos herramientas que el de destino se comporta distinto sin avisar. La sincronización, por ahora, seguía pendiente de un último escollo que el texto original no llega a detallar.