Un archivo .bbappend es el mecanismo de Yocto para personalizar recetas existentes sin modificar el archivo .bb original. Añade tus cambios a la receta en tiempo de parseo, manteniendo las actualizaciones upstream y tus personalizaciones completamente separadas.
Nunca edites un archivo .bb directamente — tus cambios se perderán la próxima vez que hagas pull de las actualizaciones upstream.
Esta guía cubre bbappend desde lo básico hasta 5 patrones prácticos, basándose en Yocto Scarthgap 5.0 LTS.
Qué es un archivo bbappend
Un archivo .bbappend añade variables y tareas a una receta .bb que reside en otra capa.
El mecanismo es simple. Cuando BitBake carga una receta, busca archivos .bbappend que coincidan y añade su contenido al final de la receta antes de procesarla. Esto significa que las configuraciones del .bbappend pueden sobrescribir la receta original.
meta-poky/recipes-example/someapp/someapp_1.0.bb ← receta original
meta-mylayer/recipes-example/someapp/someapp_%.bbappend ← tus adiciones
Esta separación importa por dos razones.
- Coexistencia con upstream: Ejecutar
git pullenmeta-pokyno tocará tus personalizaciones enmeta-mylayer - Visibilidad de cambios: Puedes ver qué capas modifican qué con
bitbake-layers show-appends
Para la creación de capas, consulta la guía de creación de capas.
Reglas de nomenclatura de archivos
El nombre del archivo bbappend debe coincidir con el nombre del archivo de la receta objetivo.
Coincidencia exacta de versión
someapp_1.0.bbappend → se aplica solo a someapp_1.0.bb
someapp_1.1.bbappend → se aplica solo a someapp_1.1.bb
Si la versión no coincide exactamente, el bbappend se ignora silenciosamente.
Uso del comodín % (Recomendado)
Actualizar el nombre del bbappend cada vez que cambia la versión de la receta es tedioso. El comodín % coincide con cualquier versión.
someapp_%.bbappend → se aplica a someapp_1.0.bb, someapp_2.3.bb, etc.
Verificar tu bbappend
Comprueba que tu bbappend sea reconocido con estos comandos.
# Listar todos los archivos bbappend y sus recetas objetivo
bitbake-layers show-appends
# Mostrar todas las versiones de una receta específica (útil para depurar discrepancias de versión)
bitbake-layers show-recipes someapp
Operaciones con variables
Las operaciones más comunes en archivos bbappend son añadir valores a variables y sobrescribirlas.
Añadir valores (:append)
:append agrega un valor al final de una variable. Debes incluir un espacio al inicio. A diferencia de +=, :append no inserta un espacio automáticamente.
# Correcto (espacio al inicio)
SRC_URI:append = " file://my-patch.patch"
# Incorrecto (sin espacio — se fusiona con el valor anterior y falla)
SRC_URI:append = "file://my-patch.patch"
También puedes usar +=, que auto-inserta un espacio, pero :append es preferido porque es más explícito.
# Esto también funciona (+= auto-inserta un espacio)
SRC_URI += "file://my-patch.patch"
Eliminar valores (:remove)
DISTRO_FEATURES:remove = "bluetooth wifi"
Sobrescribir valores
# Sobrescritura completa
SOME_VARIABLE = "new-value"
FILESEXTRAPATHS — Ruta de búsqueda para archivos adicionales
Cuando tu bbappend añade archivos (parches, archivos de configuración, etc.), necesitas indicar a BitBake dónde encontrarlos. La variable FILESEXTRAPATHS controla la ruta de búsqueda de archivos.
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
Esta sola línea tiene tres detalles críticos.
- Usa
:=(expansión inmediata):${THISDIR}se refiere al directorio que contiene el archivo actual. Con expansión diferida (=), se resolvería al directorio del archivo.bben su lugar - Los dos puntos finales
:son obligatorios: FILESEXTRAPATHS es una lista separada por dos puntos. Sin los dos puntos, las rutas se fusionan y fallan - Usa
:prepend: Asegura que tu ruta se busque antes que las rutas predeterminadas
Extender tareas
Puedes añadir procesamiento a las tareas de recetas (do_install, do_configure, etc.) con bbappend.
do_install:append() {
install -d ${D}${sysconfdir}
install -m 0644 ${WORKDIR}/myconfig.conf ${D}${sysconfdir}/
}
:append añade al final de la tarea. El procesamiento original de la tarea se conserva.
Usa :prepend para añadir procesamiento antes de la tarea original.
do_configure:prepend() {
# Se ejecuta antes del do_configure original
cp ${WORKDIR}/my-makefile ${S}/Makefile
}
5 patrones prácticos
Aquí tienes cinco casos de uso reales para archivos bbappend.
Patrón 1: Aplicar un parche
El caso de uso más básico. Aplica una corrección de error o parche de funcionalidad al código fuente upstream.
Estructura de directorios:
meta-mylayer/
recipes-example/
someapp/
someapp_%.bbappend
someapp/
0001-fix-memory-leak.patch
# someapp_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRC_URI:append = " file://0001-fix-memory-leak.patch"
${PN} se expande al nombre del paquete (someapp en este caso). ${THISDIR}/${PN} apunta al subdirectorio someapp/ junto al archivo bbappend.
Patrón 2: Añadir un archivo de configuración
Despliega un archivo de configuración personalizado en el dispositivo objetivo.
meta-mylayer/
recipes-core/
busybox/
busybox_%.bbappend
files/
custom-inittab
# busybox_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://custom-inittab"
do_install:append() {
install -m 0644 ${WORKDIR}/custom-inittab ${D}${sysconfdir}/inittab
}
Patrón 3: Añadir un servicio systemd
Añade un archivo de servicio systemd a una aplicación existente para inicio automático. Consulta la guía de inicio automático con systemd para el tutorial completo de la receta.
meta-mylayer/
recipes-example/
myapp/
myapp_%.bbappend
files/
myapp.service
# myapp_%.bbappend
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI:append = " file://myapp.service"
SYSTEMD_SERVICE:${PN} = "myapp.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"
FILES:${PN} += "${systemd_system_unitdir}/myapp.service"
do_install:append() {
install -d ${D}${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/myapp.service ${D}${systemd_system_unitdir}/
}
Nota: este patrón asume que la receta .bb original ya incluye inherit systemd. La directiva inherit solo es válida en archivos .bb y .bbclass — no está oficialmente soportada en archivos .bbappend. Si la receta original no hereda la clase systemd, necesitarás modificar la propia receta en lugar de usar un bbappend.
Patrón 4: Cambiar opciones de compilación
Usa PACKAGECONFIG para modificar las opciones de compilación de una receta.
# curl_%.bbappend
# Habilitar soporte OpenSSL
PACKAGECONFIG:append = " openssl"
# Deshabilitar soporte GnuTLS
PACKAGECONFIG:remove = "gnutls"
PACKAGECONFIG es un mecanismo de gestión de opciones soportado por muchas recetas. Las opciones disponibles se definen en el archivo .bb de la receta como entradas PACKAGECONFIG[xxx].
Para recetas basadas en autotools, también puedes añadir opciones de configuración directamente.
EXTRA_OECONF:append = " --enable-my-feature"
Patrón 5: Añadir dependencias
Añade dependencias en tiempo de compilación o ejecución.
# mypackage_%.bbappend
# Dependencia en tiempo de compilación
DEPENDS:append = " libssl"
# Dependencia en tiempo de ejecución (${PN} especifica qué paquete)
RDEPENDS:${PN}:append = " python3"
RDEPENDS requiere ${PN} porque es una variable por paquete. Sin ${PN}, BitBake no sabe a qué paquete pertenece la dependencia.
Solución de problemas comunes
bbappend no se está aplicando
# Verifica si el bbappend es reconocido
bitbake-layers show-appends | grep someapp
# Verifica si la capa está registrada en bblayers.conf
bitbake-layers show-layers
Las causas más comunes son la discrepancia de versión (no usar %) y que la capa no esté registrada.
Los valores de las variables se ven incorrectos
# Comando de depuración recomendado en Scarthgap
bitbake-getvar -r someapp SRC_URI
bitbake-getvar -r someapp FILESEXTRAPATHS
bitbake-getvar muestra el valor final de una variable y qué archivo lo estableció — tanto en forma expandida como sin expandir, con el archivo exacto y número de línea de cada operación.
Archivo no encontrado (error do_fetch)
Normalmente es un error de configuración de FILESEXTRAPATHS.
- ¿Usaste
:=en vez de=? - ¿Olvidaste los dos puntos finales
:? - ¿La ruta del directorio
files/coincide con lo que apunta FILESEXTRAPATHS?
Preguntas frecuentes
¿Puedo usar inherit en un archivo bbappend?
Oficialmente, inherit solo es válido en archivos .bb y .bbclass. El BitBake User Manual no lista .bbappend como ubicación válida para inherit. Aunque puede funcionar en la práctica en algunos casos, si la clase que necesitas no está heredada por la receta original, modifica el archivo .bb directamente o crea una nueva receta.
¿Cuál es la diferencia entre :append y +=?
Ambos añaden valores, pero :append es un operador de estilo override que se ejecuta después de todas las asignaciones +=. :append no inserta un espacio automáticamente — debes añadirlo tú. += inserta un espacio y se evalúa durante el parseo. En archivos bbappend, :append es preferido porque se ejecuta de forma confiable después de las asignaciones de la receta original.
¿Puedo tener múltiples archivos bbappend para la misma receta?
Sí. Si múltiples capas tienen un bbappend para la misma receta, BitBake los aplica en el orden en que las capas aparecen en bblayers.conf. El bbappend de la última capa gana en caso de asignaciones de variables en conflicto. Usa bitbake-layers show-appends para verificar el orden.
¿Cómo sobrescribo una variable establecida en la receta original?
Usa una asignación simple (=). Como el contenido del bbappend se añade después de la receta original, un = simple en el bbappend será el valor final. Para variables acumulativas (como SRC_URI), usa :append en su lugar para no perder los valores originales.
¿Importa la estructura de directorios dentro de mi capa?
Sí. El bbappend debe estar en la misma ruta relativa que la receta original. Si la receta está en meta-poky/recipes-core/busybox/busybox_1.36.1.bb, tu bbappend debería estar en meta-mylayer/recipes-core/busybox/busybox_%.bbappend. BitBake coincide por nombre de receta, no por directorio, pero seguir la misma estructura es una convención importante para la legibilidad.
¿Qué pasa si mi bbappend apunta a una receta que no existe?
Por defecto, BitBake ignora silenciosamente los archivos bbappend huérfanos. Para detectar esto, añade BB_DANGLINGAPPENDS_WARNLEVEL = "error" a tu local.conf. Esto hace que BitBake falle con un error cuando un bbappend no tiene receta correspondiente — muy útil para detectar archivos bbappend obsoletos después de eliminar o renombrar recetas.
¿Puedo eliminar un archivo que la receta original instala?
Sí. Usa do_install:append() con rm para eliminar archivos después de que el do_install original se ejecute.
do_install:append() {
rm -f ${D}${bindir}/unwanted-binary
}
Alternativamente, usa las variables PACKAGES y FILES para excluir archivos del paquete final sin eliminarlos del directorio de compilación.
Conclusión
bbappend es la forma correcta de personalizar recetas existentes en Yocto. Los elementos esenciales son pocos.
- Nombra los archivos
recipename_%.bbappend(usa el comodín%) - Para archivos adicionales, configura
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"(:=y los dos puntos finales son obligatorios) - Añade valores con
:append(no olvides el espacio al inicio) - Extiende tareas con
do_install:append() { ... } - Depura con
bitbake-layers show-appendsybitbake-getvar
Una vez que domines lo básico, considera también optimizar tu entorno de compilación.
Para profundizar en bbappend y la personalización de recetas, estos libros son excelentes referencias. Yocto Project Customization se enfoca específicamente en patrones de diseño de capas personalizadas.
Artículos relacionados: