32blogby StudioMitsu

Cómo escribir recetas Yocto: Guía de archivos .bb

Escribe recetas Yocto desde cero. Cubre Hello World, obtención de fuentes desde GitHub, CMake y Autotools con clases inherit.

7 min read

This article contains affiliate links.

Contenido

Quieres incluir tu propia aplicación en una imagen Linux de Yocto. Necesitas compilar un proyecto de GitHub con Yocto. Pero, ¿cómo se escribe un archivo .bb?

Esta guía te lleva paso a paso por la creación de recetas Yocto desde cero, con ejemplos de código funcional en cada paso. Una vez que entiendas cómo funcionan las recetas, puedes empaquetar prácticamente cualquier software en una imagen Yocto.

¿Qué es una receta Yocto?

Una receta es un archivo .bb que describe cómo compilar e instalar una pieza específica de software. Piensa en ella como un script de compilación autónomo que responde cuatro preguntas:

  • Dónde obtener el código fuente (SRC_URI)
  • Cómo compilarlo (do_compile)
  • Dónde instalarlo (do_install)
  • Qué licencia usa (LICENSE)

Nomenclatura de archivos de recetas

Los nombres de archivo de recetas siguen el patrón nombrePaquete_versión.bb:

text
hello-world_1.0.bb      # hello-world versión 1.0
myapp_2.3.1.bb          # myapp versión 2.3.1
busybox_1.36.1.bb       # busybox versión 1.36.1

BitBake extrae automáticamente el nombre del paquete (PN) y la versión (PV) del nombre de archivo.

Estructura básica de una receta

text
# hello-world_1.0.bb

# ===== Metadatos =====
SUMMARY = "Hello World sample"
DESCRIPTION = "A minimal example recipe for learning Yocto"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

# ===== Adquisición de fuentes =====
SRC_URI = "file://hello.c"

# ===== Directorio de fuentes =====
S = "${WORKDIR}"

# ===== Compilación =====
do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} -o hello hello.c
}

# ===== Instalación =====
do_install() {
    install -d ${D}${bindir}
    install -m 0755 hello ${D}${bindir}
}

Variables clave

Metadatos del paquete

VariableDescripciónEjemplo
SUMMARYDescripción corta de una línea"Hello World sample"
DESCRIPTIONDescripción detallada"A minimal learning example..."
LICENSEIdentificador de licencia (SPDX)"MIT", "GPL-2.0-only", "Apache-2.0"
LIC_FILES_CHKSUMChecksum del archivo de licenciafile://LICENSE;md5=xxx
SRC_URIDónde obtener las fuentes"file://", "git://", "https://"
SDónde se desempaquetan las fuentes$/git

Variables de compilación e instalación

VariableDescripciónSe expande a
${WORKDIR}Directorio de trabajo para esta compilación/tmp/work/.../hello-world/1.0-r0/
${D}Raíz de staging para instalación.../image/
${bindir}Ruta /usr/bin/usr/bin
${libdir}Ruta /usr/lib/usr/lib
${sysconfdir}Ruta /etc/etc
${CC}Compilador cruzadoarm-poky-linux-gnueabi-gcc

Compilación de una receta Hello World

Compilemos la receta más simple posible y confirmemos que funciona de extremo a extremo.

Crear una capa personalizada

Siempre pon tus recetas en tu propia capa — nunca directamente en las capas de Poky.

bash
cd ~/yocto/poky
source oe-init-build-env build

# Crear una nueva capa
cd ..
bitbake-layers create-layer meta-mylayer

# Añadirla a la compilación
cd build
bitbake-layers add-layer ../meta-mylayer

Consulta la guía de creación de capas para detalles sobre la gestión de capas.

Crear la estructura de directorios y el código fuente

bash
mkdir -p ../meta-mylayer/recipes-example/hello-world/files

Escribe files/hello.c:

c
// files/hello.c
#include <stdio.h>

int main(void) {
    printf("Hello from Yocto!\n");
    printf("This app was built with a custom recipe.\n");
    return 0;
}

Escribir la receta

Crea hello-world_1.0.bb:

text
# hello-world_1.0.bb
SUMMARY = "Hello World - Yocto recipe learning example"
DESCRIPTION = "A minimal application demonstrating how to write a custom Yocto recipe"

LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "file://hello.c"

S = "${WORKDIR}"

do_compile() {
    ${CC} ${CFLAGS} ${LDFLAGS} -o hello hello.c
}

do_install() {
    install -d ${D}${bindir}
    install -m 0755 hello ${D}${bindir}
}

Compilar e incluir en tu imagen

bash
# Compilar la receta individualmente
bitbake hello-world

# El éxito se ve así:
NOTE: Tasks Summary: Attempted 123 tasks of which 120 didn't need to be rerun

Añade a conf/local.conf para incluirlo en la imagen:

text
IMAGE_INSTALL:append = " hello-world"

Recompila y prueba en QEMU:

bash
bitbake core-image-minimal
runqemu qemux86-64 nographic

# Después del arranque:
root@qemux86-64:~# hello
Hello from Yocto!
This app was built with a custom recipe.

Obtener fuentes desde GitHub

En proyectos reales, normalmente obtendrás las fuentes de un repositorio externo en lugar de incluirlas localmente.

Ejemplo: Añadir nlohmann/json

text
# nlohmann-json_3.11.3.bb
SUMMARY = "JSON for Modern C++"
DESCRIPTION = "A header-only JSON library for C++"
HOMEPAGE = "https://github.com/nlohmann/json"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE.MIT;md5=f5f7c71504da070bcf4f090205ce1080"

# Obtener de GitHub usando HTTPS
SRC_URI = "git://github.com/nlohmann/json.git;protocol=https;branch=master"

# Fijar a un commit específico — siempre haz esto para reproducibilidad
SRCREV = "9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03"

S = "${WORKDIR}/git"

inherit cmake

EXTRA_OECMAKE = "-DJSON_BuildTests=OFF"

Patrones de SRC_URI

Tipo de fuenteFormato de SRC_URI
Archivo localfile://hello.c
Git (HTTPS)git://github.com/user/repo.git;protocol=https;branch=main
Git (SSH)git://git@github.com/user/repo.git;protocol=ssh;branch=main
Tarball HTTP/HTTPShttps://example.com/file.tar.gz
Archivo de parchefile://fix-build.patch

Uso de clases Inherit

Yocto incluye clases que encapsulan patrones de compilación comunes. Usar inherit te ahorra escribir tareas repetitivas de do_compile y do_install.

ClaseCaso de usoQué automatiza
cmakeProyectos CMakecmake → make → make install
autotoolsProyectos Autoconfconfigure → make → make install
mesonProyectos Mesonmeson → ninja → install
setuptools3Paquetes Pythoninstalación de setuptools / wheel
systemdServicios systemdHabilitación de servicios

Ejemplo de proyecto CMake

text
# myapp-cmake_1.0.bb
SUMMARY = "My CMake App"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"

SRC_URI = "git://github.com/user/myapp.git;protocol=https;branch=main"
SRCREV = "abc123def456..."
S = "${WORKDIR}/git"

inherit cmake

EXTRA_OECMAKE = "-DBUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release"

Ejemplo de proyecto Autotools

text
# myapp-autotools_1.0.bb
SUMMARY = "My Autotools App"
LICENSE = "GPL-2.0-only"
LIC_FILES_CHKSUM = "file://COPYING;md5=..."

SRC_URI = "https://example.com/myapp-1.0.tar.gz"
SRC_URI[sha256sum] = "def456..."

inherit autotools

EXTRA_OECONF = "--disable-docs"

Servicios systemd

Para iniciar automáticamente tu aplicación en el arranque, usa inherit systemd. Para configuración detallada, consulta la guía de servicios systemd.

Errores comunes y soluciones

Discrepancia de LIC_FILES_CHKSUM

text
ERROR: License checksum mismatch...

Causa: El hash MD5 en tu receta no coincide con el archivo de licencia real.

Solución: Recalcula el hash correcto:

bash
md5sum LICENSE

do_fetch falló

text
ERROR: Fetcher failure: Unable to find file...

Causa: Ruta incorrecta en SRC_URI, o problema de red al obtener de Git.

Solución: Verifica tu SRC_URI y SRCREV. Asegúrate de que el hash de commit existe en el repositorio.

Nothing PROVIDES 'hello-world'

text
ERROR: Nothing PROVIDES 'hello-world'

Causa: La capa que contiene tu receta no está en bblayers.conf.

Solución: Añade la capa:

bash
bitbake-layers add-layer ../meta-mylayer

Discrepancia de checksum de SRC_URI

text
ERROR: SRC_URI checksum mismatch...

Causa: El checksum de una descarga HTTP/HTTPS no está configurado o no coincide.

Solución: Calcula el checksum correcto:

bash
sha256sum downloaded-file.tar.gz

Conclusión

Esto es lo que hay que recordar sobre escribir recetas Yocto:

  • Las recetas son archivos .bb que describen un proceso de compilación completo
  • Variables fundamentales: SRC_URI, do_compile, do_install
  • Siempre pon tus recetas en una capa personalizada, no en Poky
  • Usa inherit para manejar automáticamente proyectos CMake/Autotools/Meson
  • Añade paquetes a una imagen con IMAGE_INSTALL:append
  • Siempre fija SRCREV a un hash de commit específico para reproducibilidad

Una vez que te sientas cómodo escribiendo recetas, puedes empaquetar cualquier cosa en una imagen Yocto. Estos son los siguientes pasos:

Para profundizar en Linux embebido, estos libros son excelentes referencias.