00 BitBake recipe anatomisi
BitBake recipe (.bb dosyası), bir yazılım bileşeninin nasıl indirileceğini, derleneceğini, kurulacağını ve paketleneceğini tanımlayan metadata dosyasıdır.
Minimal recipe örneği
SUMMARY = "Minimal C uygulaması örneği"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://COPYING;md5=0835ade698e0bcf8506ecda2f7b4f302"
SRC_URI = "git://github.com/example/helloworld.git;protocol=https;branch=main"
SRCREV = "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
S = "${WORKDIR}/git"
do_compile() {
oe_runmake
}
do_install() {
install -d ${D}${bindir}
install -m 0755 helloworld ${D}${bindir}/helloworld
}
Recipe task grafiği
do_fetch → Kaynak kodunu indir (DL_DIR'a)
do_unpack → WORKDIR'a aç
do_patch → Patch'leri uygula
do_configure → Build sistemini yapılandır (cmake, configure, ...)
do_compile → Derle (make, ninja, ...)
do_install → ${D} (destdir) içine kur
do_package → Dosyaları PACKAGES değişkenine göre böl
do_packagedata→ Paket metadata'yı kaydet
do_package_write_ipk/deb/rpm → Paket dosyasını yaz
Recipe adlandırma kuralı
| Dosya Adı | Anlamı |
|---|---|
myapp_1.0.0.bb | PV=1.0.0, PR=r0 (varsayılan) |
myapp_1.0.0-r1.bb | PV=1.0.0, PR=r1 — recipe değişikliği |
myapp_git.bb | Git sürümü — PV genellikle git${SRCPV} ile türetilir |
myapp_%.bbappend | Tüm sürümlere uygulanan bbappend |
Bu bölümde
- .bb dosyası: indir → aç → patch → yapılandır → derle → kur → paketle
- Her task sırayla çalışır; BitBake paralel task'ları otomatik planlar
- Dosya adı: PN_PV.bb biçimi (paket adı _ versiyon)
01 Temel recipe değişkenleri
Her recipe, BitBake'in kodu işlemesi için gereken temel meta-veriyi değişkenler aracılığıyla tanımlar.
| Değişken | Zorunlu | Açıklama | Örnek |
|---|---|---|---|
SUMMARY | Önerilir | Tek satır açıklama (72 karakter) | "HTTP sunucu kütüphanesi" |
DESCRIPTION | Hayır | Uzun açıklama (çok satır) | – |
HOMEPAGE | Hayır | Proje web sitesi | "https://libmicrohttpd.org" |
LICENSE | Evet | SPDX lisans tanımlayıcısı | "LGPL-2.1-or-later" |
LIC_FILES_CHKSUM | Evet | Lisans dosyasının MD5/SHA256 özeti | "file://COPYING;md5=..." |
SRC_URI | Evet | Kaynak konumu (git, https, file) | "git://github.com/..." |
S | Bağlam | Kaynak kodun açıldığı dizin | "${WORKDIR}/git" |
PV | Genelde dosya adından | Paket versiyonu | "1.0.0" |
PR | Hayır | Recipe revizyon numarası | "r0" |
DEPENDS | Gerekirse | Build-time bağımlılıklar | "openssl zlib" |
# Kaynak indirilip açıldıktan sonra COPYING dosyasının MD5'ini hesapla
md5sum COPYING
# 0835ade698e0bcf8506ecda2f7b4f302 COPYING
# Recipe'de kullanımı
LIC_FILES_CHKSUM = "file://COPYING;md5=0835ade698e0bcf8506ecda2f7b4f302"
# Birden fazla lisans dosyası
LIC_FILES_CHKSUM = "file://LICENSE.md5;md5=... \
file://src/foo/LICENSE;md5=..."
Upstream'in lisans dosyasını değiştirmesi durumunda LIC_FILES_CHKSUM doğrulaması başarısız olur ve build durur. Bu, kasıtsız lisans değişikliğine karşı koruma sağlar. Değişikliği kontrol edip checksum'ı güncellemeniz gerekir.
Bu bölümde
- LICENSE + LIC_FILES_CHKSUM zorunlu — lisans uyumu için kritik
- S = kaynak dizini; git clones için
${WORKDIR}/git - DEPENDS = build-time; RDEPENDS = runtime bağımlılıkları
02 SRC_URI seçenekleri
SRC_URI, kaynak kodun nereden ve nasıl indirileceğini tanımlar. Git, tarball, yerel dosya ve patch'ler desteklenir.
# HTTPS tarball — en yaygın kullanım
SRC_URI = "https://ftp.gnu.org/pub/gnu/wget/wget-${PV}.tar.gz"
SRC_URI[md5sum] = "abc123..."
SRC_URI[sha256sum] = "def456..."
# Git deposu
SRC_URI = "git://github.com/user/repo.git;protocol=https;branch=main"
SRCREV = "a1b2c3d4e5f6..." # tam commit SHA — güvenli
S = "${WORKDIR}/git"
# Git — tag ile
SRC_URI = "git://github.com/user/repo.git;protocol=https;tag=v${PV}"
# Yerel dosya (layer içindeki)
SRC_URI += "file://my-config.conf"
# Patch dosyası — do_patch aşamasında otomatik uygulanır
SRC_URI += "file://0001-fix-segfault.patch \
file://0002-add-feature.patch"
# Birden fazla kaynak
SRC_URI = "https://example.com/myapp-${PV}.tar.gz \
file://myapp.service \
file://0001-fix-crash.patch"
Git SRC_URI parametreleri
| Parametre | Açıklama | Örnek |
|---|---|---|
protocol | Transfer protokolü | https, ssh, git |
branch | Branch adı (SRCREV ile birlikte) | main, develop |
tag | Git tag'i (SRCREV yerine) | v1.0.0 |
nobranch | Branch kontrolünü devre dışı bırak | nobranch=1 |
submodules | Git submodule'leri indir | submodules=1 |
destsuffix | WORKDIR içindeki alt dizin adı | destsuffix=git |
name | SRC_URI checksum referans adı | name=tarball |
Patch oluşturma
# Kaynak dizine gir (BitBake workspace veya git clone)
cd /tmp/myapp-src
# Değişiklik yap
vim src/main.c
# git ile patch üret
git add -A
git commit -m "fix: NULL pointer dereference in init path"
git format-patch HEAD~1 -o /home/user/meta-myproduct/recipes-apps/myapp/myapp/
# Oluşur: 0001-fix-NULL-pointer-dereference-in-init-path.patch
Bu bölümde
- HTTPS tarball için SRC_URI[sha256sum] checksum şart
- Git için SRCREV tam SHA1 hash — AUTOREV üretimde kullanma
file://prefix ile yerel dosya ve patch'ler eklenir- Patch'ler do_patch aşamasında sıra numarasına göre uygulanır
03 do_compile ve do_install
do_compile kodu derler; do_install ise üretilen dosyaları ${D} (destination directory) dizinine kopyalar. Bu aşamalar recipe yazımının kalbidir.
do_compile
do_compile() {
# oe_runmake: cross-compile ortam değişkenleriyle make çalıştırır
# CC, LD, AR, STRIP, CFLAGS, LDFLAGS otomatik ayarlıdır
oe_runmake
# Belirli bir target
oe_runmake all
# Ek parametrelerle
oe_runmake "EXTRA_CFLAGS=-DDEBUG_BUILD"
}
do_install — yerleşim değişkenleri
| Değişken | Yol | Kullanım |
|---|---|---|
${D} | tmp/work/.../image/ | Tüm kurulum hedefinin kök dizini |
${bindir} | /usr/bin | Çalıştırılabilir dosyalar |
${sbindir} | /usr/sbin | Sistem yönetici araçları |
${libdir} | /usr/lib | Paylaşılan kütüphaneler |
${includedir} | /usr/include | Header dosyaları |
${sysconfdir} | /etc | Konfigürasyon dosyaları |
${systemd_system_unitdir} | /lib/systemd/system | systemd unit dosyaları |
${datadir} | /usr/share | Mimari bağımsız veri dosyaları |
${localstatedir} | /var | Çalışma zamanı değişken veriler |
do_install() {
# Önce hedef dizinleri oluştur
install -d ${D}${bindir}
install -d ${D}${sysconfdir}/myapp
install -d ${D}${localstatedir}/lib/myapp
# Binary kur — çalıştırılabilir (0755)
install -m 0755 ${B}/myapp ${D}${bindir}/myapp
# Config dosyası kur — sadece okuma (0644)
install -m 0644 ${WORKDIR}/myapp.conf ${D}${sysconfdir}/myapp/
# Kütüphane kur
install -d ${D}${libdir}
install -m 0755 ${B}/libmyapp.so.1.0 ${D}${libdir}/
ln -sf libmyapp.so.1.0 ${D}${libdir}/libmyapp.so.1
ln -sf libmyapp.so.1 ${D}${libdir}/libmyapp.so
# Header dosyaları kur
install -d ${D}${includedir}/myapp
install -m 0644 include/*.h ${D}${includedir}/myapp/
}
Bu bölümde
oe_runmakecross-compile ortam değişkenleriyle make çalıştırır${D}tüm kurulumun kök dizini — gerçek hedef sistemin köküdürinstall -ddizin,install -mdosya kopyalama- ${bindir}, ${libdir}, ${sysconfdir} gibi değişkenler yol taşınabilirliği sağlar
04 RDEPENDS ve RRECOMMENDS
Runtime bağımlılıkları, paketin hedef sistemde çalışabilmesi için gereken diğer paketleri tanımlar.
# RDEPENDS: Zorunlu runtime bağımlılıklar
# Paket kurulduğunda bu bağımlılıklar da kurulur
RDEPENDS:${PN} = "bash libssl3 libcurl4"
# RRECOMMENDS: Önerilen runtime bağımlılıklar
# Kurulmasa da paket çalışabilir, ama tavsiye edilir
RRECOMMENDS:${PN} = "ca-certificates"
# Sürüm kısıtlı bağımlılık
RDEPENDS:${PN} = "openssl (>= 3.0)"
# PROVIDES: Bu paketin sağladığı sanal paketler
PROVIDES += "virtual/webserver"
# RPROVIDES: Runtime'da sağlanan sanal paket adları
RPROVIDES:${PN} = "virtual/webserver"
# virtual/ ile sağlayıcı seçimi
PREFERRED_PROVIDER_virtual/webserver = "nginx"
PROVIDES ve virtual/ mekanizması
| Değişken | Aşama | Kullanım |
|---|---|---|
DEPENDS | Build-time | Derleme sırasında gereken kütüphane/araç |
RDEPENDS | Runtime | Hedef sistemde çalışmak için gereken paket |
PROVIDES | Build-time | Bu recipe'nin sağladığı sanal isimler |
RPROVIDES | Runtime | Bu paketin runtime'da sağladığı isimler |
RCONFLICTS | Runtime | Bu paketle birlikte kurulamayan paketler |
RREPLACES | Runtime | Bu paketin yerini aldığı paketler |
Bu bölümde
- RDEPENDS:${PN} — hedef sistemde zorunlu paketler
- RRECOMMENDS — kurulmasa da çalışır ama önerilir
- virtual/ mekanizması — soyut bağımlılık, PREFERRED_PROVIDER ile çözülür
05 Package splitting
Tek bir recipe birden fazla paket üretebilir — örneğin bir kütüphane için libfoo, libfoo-dev, libfoo-doc ve libfoo-staticdev paketleri ayrı üretilir.
# Üretilecek paket listesi
PACKAGES = "${PN}-staticdev ${PN}-dev ${PN}-doc ${PN}-dbg ${PN}"
# Her paketin dosya desenleri
FILES:${PN} = "${bindir}/* ${libdir}/libmyapp.so.*"
FILES:${PN}-dev = "${includedir}/* ${libdir}/libmyapp.so ${libdir}/pkgconfig/*"
FILES:${PN}-staticdev = "${libdir}/libmyapp.a"
FILES:${PN}-doc = "${docdir}/* ${mandir}/*"
# -dev paketi için runtime bağımlılık
RDEPENDS:${PN}-dev = "${PN}"
# Bazı paketleri IMAGE_INSTALL'dan çıkarmak için ALLOW_EMPTY
ALLOW_EMPTY:${PN}-doc = "1"
Varsayılan paket yapısı
| Paket | İçerik | Genelde IMAGE_INSTALL'a eklenir mi? |
|---|---|---|
${PN} | Runtime binary'ler, paylaşımlı kütüphaneler | Evet |
${PN}-dev | Header'lar, .so symlink'leri, .pc dosyaları | Hayır (SDK'da) |
${PN}-staticdev | .a statik kütüphaneler | Hayır |
${PN}-doc | Man page'leri, HTML dökümantasyon | Hayır |
${PN}-dbg | Debug sembolleri (.debug dizini) | Hayır (debug image'larda) |
${PN}-locale-* | Dil yerelleştirme dosyaları | Seçili lokaller |
Üretim image'larına yalnızca ${PN} ekleyin. -dev ve -staticdev paketleri SDK tarafında kullanılır. Bu ayrım image boyutunu önemli ölçüde küçültür.
Bu bölümde
- PACKAGES listesi üretilecek paket adlarını belirler
- FILES:${PN} her paketin hangi dosyaları içereceğini tanımlar
- -dev, -staticdev, -doc, -dbg paketleri geliştirme ortamı içindir
06 Classes inheritance
inherit komutuyla .bbclass dosyaları devralınır. Class'lar, ortak build sistemleri için hazır görev implementasyonları sağlar.
| Class | Kullanım amacı | Sağladığı görevler |
|---|---|---|
cmake | CMake projeleri | do_configure (cmake), do_compile (ninja/make) |
autotools | autoconf/automake projeleri | do_configure (./configure), do_compile (make) |
meson | Meson build sistemi | do_configure (meson), do_compile (ninja) |
python3-package | Python paketleri (setup.py/pyproject) | do_compile, do_install (pip) |
systemd | systemd servis entegrasyonu | do_install (unit dosyaları), postinst |
pkgconfig | .pc dosyası üretimi | FILES:${PN}-dev'e .pc ekler |
update-rc.d | SysVinit script yönetimi | postinst/postrm scriptleri |
useradd | Sistem kullanıcısı oluşturma | postinst kullanıcı ekleme |
inherit cmake systemd pkgconfig useradd
# CMake ek argümanları
EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release \
-DENABLE_TESTS=OFF \
-DINSTALL_SYSTEMD_UNIT=ON"
# systemd unit dosyaları
SYSTEMD_SERVICE:${PN} = "myapp.service myapp-watchdog.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"
# useradd: sistem kullanıcısı oluştur
USERADD_PACKAGES = "${PN}"
USERADD_PARAM:${PN} = "-r -s /sbin/nologin -d /var/lib/myapp myapp"
inherit autotools pkgconfig
# configure ek argümanları
EXTRA_OECONF = "--disable-static \
--enable-shared \
--with-openssl=${STAGING_DIR_TARGET}"
# autotools genellikle do_configure ve do_compile'ı otomatik halleder
# Sadece do_install'ı özelleştirmen gerekirse override edebilirsin
Bu bölümde
inherit cmake— CMake projesinin tüm build sürecini otomatikleştiririnherit autotools— autoconf/automake configure + make akışıinherit systemd— unit dosyalarını doğru yere kurar ve enable ederinherit useradd— postinst ile sistem kullanıcısı oluşturur
07 Native ve cross recipe
Bazı araçların hem hedef sistem (cross-compiled) için hem de build host üzerinde (native) çalışan versiyonları gerekir. BBCLASSEXTEND bu dönüşümü otomatik yapar.
BBCLASSEXTEND
# Aynı recipe'den üç varyant üret:
# myapp — hedef sistem için (cross-compiled)
# myapp-native — build host'ta çalışacak araç
# nativesdk-myapp — eSDK içinde host'ta çalışacak araç
BBCLASSEXTEND = "native nativesdk"
# Kullanım: başka recipe'de native aracı bağımlılık olarak belirt
DEPENDS += "myapp-native"
Native ile cross-compiled farkı
| Varyant | Nerede çalışır | Nasıl derlenir | Kullanım amacı |
|---|---|---|---|
myapp | Hedef ARM/RISC-V/... board | cross-gcc ile | Ürün image'ına girer |
myapp-native | Build host (x86-64 Linux) | host gcc ile | Build sırasında araç olarak kullanılır |
nativesdk-myapp | SDK'yı kullanan geliştirici host'u | SDK sysroot ile | populate_sdk_ext içinde geliştiriciye verilir |
# Sadece native build'de ekstra bağımlılık
DEPENDS:class-native = ""
# Native build için farklı EXTRA_OECMAKE
EXTRA_OECMAKE:class-native = "-DBUILD_TOOLS_ONLY=ON"
EXTRA_OECMAKE:class-nativesdk = "-DBUILD_TOOLS_ONLY=ON"
# Cross (hedef) build için tam özellik seti
EXTRA_OECMAKE = "-DCMAKE_BUILD_TYPE=Release"
Bu bölümde
- BBCLASSEXTEND = "native nativesdk" — tek recipe'den üç varyant
- -native: build host'ta çalışan araç (kod üreteci, protoc vb.)
- nativesdk-: SDK içinde geliştiricinin host makinesinde çalışır
:class-nativeoverride ile varyanta özgü ayar yapılır
08 Pratik: C daemon için tam recipe
CMake ile derlenip systemd tarafından yönetilen, konfigürasyon dosyası ve -dev paketi içeren eksiksiz bir C daemon recipe'si.
Proje yapısı
mydaemon/
├── CMakeLists.txt
├── COPYING ← MIT lisansı
├── include/
│ └── mydaemon.h
├── src/
│ └── main.c
└── dist/
└── mydaemon.service.in ← systemd template
Tam recipe — mydaemon_1.2.0.bb
SUMMARY = "MyProduct arka plan daemon'ı"
DESCRIPTION = "Sensör verisi toplayan ve MQTT'ye aktaran C daemon"
HOMEPAGE = "https://git.mycompany.com/mydaemon"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://COPYING;md5=5d9e6b2c1f7a3b8d4e0c2f9a1b3c7e5d"
SRC_URI = "git://git.mycompany.com/mydaemon.git;protocol=https;branch=main \
file://mydaemon.conf \
file://0001-fix-signal-handler.patch"
SRCREV = "d3a1f2c4b5e6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
PV = "1.2.0+git${SRCPV}"
S = "${WORKDIR}/git"
# Build-time bağımlılıklar
DEPENDS = "openssl mosquitto libgpiod"
# Runtime bağımlılıklar
RDEPENDS:${PN} = "libssl3 libmosquitto1 libgpiod2 bash"
# Class inheritance
inherit cmake systemd pkgconfig useradd
# CMake argümanları
EXTRA_OECMAKE = "\
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_MQTT=ON \
-DENABLE_GPIO=ON \
-DINSTALL_SYSTEMD=ON \
-DDAEMON_USER=mydaemon \
"
# systemd entegrasyonu
SYSTEMD_SERVICE:${PN} = "mydaemon.service"
SYSTEMD_AUTO_ENABLE:${PN} = "enable"
# Sistem kullanıcısı: /var/lib/mydaemon home dizini, login shell yok
USERADD_PACKAGES = "${PN}"
USERADD_PARAM:${PN} = "-r -s /sbin/nologin -d /var/lib/mydaemon -m mydaemon"
# Paket bölme
PACKAGES =+ "${PN}-dev"
FILES:${PN} = "${bindir}/mydaemon \
${sysconfdir}/mydaemon \
${systemd_system_unitdir}/mydaemon.service \
${localstatedir}/lib/mydaemon"
FILES:${PN}-dev = "${includedir}/mydaemon.h \
${libdir}/pkgconfig/mydaemon.pc"
do_install:append() {
# Konfigürasyon dizini ve dosyası
install -d ${D}${sysconfdir}/mydaemon
install -m 0640 ${WORKDIR}/mydaemon.conf \
${D}${sysconfdir}/mydaemon/mydaemon.conf
# Çalışma zamanı veri dizini
install -d ${D}${localstatedir}/lib/mydaemon
chown -R mydaemon:mydaemon ${D}${localstatedir}/lib/mydaemon || true
}
Dosya yapısı ve build
meta-myproduct/recipes-apps/mydaemon/
├── mydaemon_1.2.0.bb
└── mydaemon/
├── mydaemon.conf ← SRC_URI file://
└── 0001-fix-signal-handler.patch ← SRC_URI file://
# Recipe'yi derle
bitbake mydaemon
# Üretilen paket dosyalarını listele
find tmp/deploy/ipk -name "mydaemon*.ipk"
# tmp/deploy/ipk/cortexa53/mydaemon_1.2.0+git..._cortexa53.ipk
# tmp/deploy/ipk/cortexa53/mydaemon-dev_1.2.0+git..._cortexa53.ipk
# Paketin içeriğini görüntüle
bitbake -e mydaemon | grep '^FILES'
# do_install çıktısını kontrol et
find tmp/work/cortexa53-poky-linux/mydaemon/image/ -type f
Bu bölümde
- CMake + systemd + useradd class'ları birlikte kullanıldı
- USERADD_PARAM ile güvenli sistem kullanıcısı oluşturuldu
- ${PN} ve ${PN}-dev paketleri ayrı dosya setleriyle tanımlandı
- do_install:append ile konfigürasyon ve veri dizinleri kuruldu