Test & CI
TEKNİK REHBER TEST & CI KAPSAMA 2026

Yocto Test Altyapısı —
oeqa & ptest.

bitbake testimage ile QEMU üzerinde otomatik runtime test, ptest çerçevesiyle paket bazlı doğrulama ve GitLab CI entegrasyonu.

00 Yocto test ekosistemi — genel bakış

OpenEmbedded/Yocto, birbirini tamamlayan birden fazla test mekanizması sunar. Doğru araç seçimi, ne test etmek istediğinize bağlıdır.

Test mekanizmaları karşılaştırması

MekanizmaNe test eder?Ne zaman kullanılır?
testimage (oeqa runtime)Çalışan image üzerinde sistem davranışıHer image build sonrası otomatik smoke test
ptestBireysel paket işlevselliğiUpstream test paketleri (busybox, openssl, Python)
SDK test (oeqa sdk)SDK toolchain ile derleme ve çalıştırmaSDK yayımı öncesi doğrulama
devtool testGeliştirici iş akışı testleriYeni recipe entegrasyonu

oeqa nedir?

oeqa (OpenEmbedded QA), OpenEmbedded'in test altyapısı paketidir. Python tabanlıdır ve üç ana test modülü içerir: oeqa.runtime (çalışan sistem testleri), oeqa.sdk (SDK testleri), oeqa.selftest (bitbake ve oeqa altyapısının kendi testi). Her modül, unittest tabanlı test case'ler içerir.

Akış diyagramı

  bitbake core-image-minimal

       │
       ▼
  Image derleme tamamlanır
  (.wic, .tar.bz2, kernel, dtb)
       │
       ▼
  bitbake -c testimage core-image-minimal
       │
       ▼
  oeqa test runner başlar
       │
  TEST_TARGET = qemu → QEMU başlatılır
  TEST_TARGET = ssh  → Gerçek donanıma SSH bağlantısı
       │
       ▼
  Test case'ler çalıştırılır
       │
       ▼
  Sonuçlar: tmp/log/oeqa/
    

01 testimage.bbclass — image testi

testimage.bbclass, bitbake üzerinden image test otomasyonu sağlar. Derleme sonrası otomatik test çalıştırmak için IMAGE_FEATURES üzerinden aktifleştirilir.

testimage'ı etkinleştirme

local.conf veya distro.conf — testimage ayarları
# testimage'ı etkinleştir
INHERIT += "testimage"

# Test hedefi: qemu (varsayılan) veya ssh
TEST_TARGET = "qemu"

# Çalıştırılacak test suite'leri
TEST_SUITES = "ping ssh df connman scp vnc date pam rpm ldd xorg syslog \
               buildcpio buildlgl buildgalculator"

# QEMU için ağ köprüsü (isteğe bağlı)
# TEST_TARGET_IP = "192.168.7.2"

# Test zaman aşımı (saniye)
TEST_QEMUBOOT_TIMEOUT = "300"

# Sadece belirli test case'ler
# TEST_SUITES = "ping ssh"

testimage'ı çalıştırma

bash — testimage komutları
# Image derle + testimage'ı çalıştır
bitbake core-image-minimal -c testimage

# Yalnızca testimage (image zaten derlenmiş)
bitbake core-image-minimal -c testimage

# Belirli test sınıfını çalıştır
TEST_SUITES="ping ssh" bitbake -c testimage core-image-minimal

# Test sonuçlarını gör
cat tmp/log/oeqa/$(ls -t tmp/log/oeqa/ | head -1)/testresults.json | python3 -m json.tool

IMAGE_FEATURES ile test desteği ekleme

local.conf — test için gerekli IMAGE_FEATURES
# ssh-server-openssh: SSH test için gerekli
IMAGE_FEATURES:append = " ssh-server-openssh"

# tools-debug: gdb, strace, ltrace testleri için
IMAGE_FEATURES:append = " tools-debug"

# ptest-pkgs: ptest paketleri dahil et
IMAGE_FEATURES:append = " ptest-pkgs"

# debug-tweaks: root şifresiz giriş (test ortamı için)
IMAGE_FEATURES:append = " debug-tweaks"

Test sonuçları konumu

tmp/log/oeqa/TIMESTAMP/
Her test çalıştırmasının log dizini. Zaman damgasıyla ayrılır.
testresults.json
Tüm test sonuçları JSON formatında. Test adı, durum (PASSED/FAILED/ERROR), log mesajları.
qemu-boot-log.txt
QEMU boot sürecinin tam log'u. Boot hatalarını tanılamak için.

02 QEMU üzerinde test çalıştırma

QEMU desteği Yocto'nun en güçlü özelliklerinden biridir. Gerçek donanım olmaksızın architecture-correct emülasyon ile kapsamlı sistem testleri yapılabilir.

runqemu ile manuel test

bash — runqemu kullanımı
# ARM64 image çalıştır
runqemu qemuarm64 core-image-minimal

# Network erişimiyle (host → QEMU SSH)
runqemu qemuarm64 core-image-minimal nographic \
  qemuparams="-m 512 -smp 2"

# Belirli kernel cmdline ekle
runqemu qemuarm64 core-image-minimal \
  bootparams="console=ttyAMA0 panic=5"

# Tap ağ arayüzü (kök yetki gerekir)
runqemu qemuarm64 core-image-minimal slirp

# SSH ile bağlan
ssh root@192.168.7.2  # qemuarm64 varsayılan IP

QEMU makine yapılandırması

conf/machine/qemuarm64.conf — örnek
require conf/machine/include/qemu.inc
require conf/machine/include/arm/arch-arm64.inc

DEFAULTTUNE = "cortexa57"

KERNEL_IMAGETYPE = "Image"
MACHINE_FEATURES = "usbhost alsa screen"

# QEMU parametreleri
QB_SYSTEM_NAME = "qemu-system-aarch64"
QB_MACHINE      = "-machine virt"
QB_CPU          = "-cpu cortex-a57"
QB_DEFAULT_FSTYPE = "ext4"
QB_MEM          = "-m 512"
QB_OPT_APPEND   = "-nographic -no-reboot"

# Ağ
QB_NETWORK_DEVICE = "-device virtio-net-device,netdev=net0,mac=@MAC@"
QB_TAP_OPT        = "-netdev tap,id=net0,ifname=@TAP@,script=no,downscript=no"
QB_SLIRP_OPT      = "-netdev user,id=net0"

QEMU testi hızlandırma

QEMU üzerinde testimage çalıştırmak uzun sürebilir. Birkaç optimizasyon tekniği: KVM (host x86 ise QEMU x86 görüntüsü ile 5-10x hızlanma), tmpfs üzerinde build (disk I/O azaltma), sstate cache kullanımı (yeniden derlemeyi önler), paralel test çalıştırma birden fazla QEMU instance'ı ile.

local.conf — QEMU performans optimizasyonu
# KVM hızlandırma (x86 host + x86 target için)
QB_OPT_APPEND:append:qemux86-64 = " -enable-kvm"

# Daha fazla bellek (testler için)
QB_MEM = "-m 1024"

# Çok çekirdek
QB_CPU_KVM = "-cpu host -smp 4"

# sstate cache (CI'da önemli)
SSTATE_DIR = "/shared/sstate-cache"
DL_DIR     = "/shared/downloads"

03 ptest çerçevesi — paket bazlı test

ptest (package test), bireysel paketlerin kendi test paketlerini hedef cihaz üzerinde çalıştırmasını sağlayan Yocto standardıdır. Upstream test paketleri (ör. busybox-ptest, openssl-ptest) bu mekanizma ile kullanılır.

ptest nasıl çalışır?

  Recipe: PACKAGES:append = " ${PN}-ptest"
       │
       ▼
  do_install_ptest_base() çalışır
  Test dosyaları: ${D}${PTEST_PATH}/
       │
       ▼
  Image içine dahil edilir
  /usr/lib/${PN}/ptest/ dizinine
       │
       ▼
  DUT üzerinde ptest-runner çalıştırılır
  ptest-runner -d /usr/lib/
       │
       ▼
  Sonuçlar stdout'a yazılır:
  PASS: test-name
  FAIL: test-name
    

ptest destekli recipe yazımı

recipes-example/mylib/mylib_1.0.bb
SUMMARY = "Örnek C kütüphanesi"
LICENSE = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=abc123"

SRC_URI = "git://github.com/example/mylib.git;protocol=https;branch=main"
SRCREV  = "abc123..."

S = "${WORKDIR}/git"

inherit cmake ptest

# ptest desteği için DEPENDS ekle
DEPENDS = "check"   # unit test framework

do_compile_ptest() {
    # Test binary'lerini derle
    oe_runmake -C ${B} tests
}

do_install_ptest() {
    # Test binary ve script'lerini ptest dizinine kopyala
    install -d ${D}${PTEST_PATH}
    install -m 0755 ${B}/tests/test_mylib ${D}${PTEST_PATH}/
    install -m 0755 ${S}/tests/run-ptest  ${D}${PTEST_PATH}/
}

# ptest runtime bağımlılıkları
RDEPENDS:${PN}-ptest += "bash ptest-runner"

run-ptest scripti

tests/run-ptest — ptest-runner uyumlu script
#!/bin/sh
# ptest-runner bu scripti çalıştırır
# Çıktı formatı: "PASS: test-adı" veya "FAIL: test-adı"

PTEST_DIR=$(dirname "$0")

run_test() {
    local name="$1"
    local cmd="$2"
    if $cmd > /dev/null 2>&1; then
        echo "PASS: $name"
    else
        echo "FAIL: $name"
    fi
}

run_test "basic-init"     "${PTEST_DIR}/test_mylib --test basic"
run_test "memory-alloc"   "${PTEST_DIR}/test_mylib --test memory"
run_test "thread-safety"  "${PTEST_DIR}/test_mylib --test threads"
run_test "edge-cases"     "${PTEST_DIR}/test_mylib --test edge"

ptest'i image'a dahil etme

local.conf — ptest paketleri
# ptest-pkgs feature tüm ptest paketlerini dahil eder
IMAGE_FEATURES:append = " ptest-pkgs"

# Veya belirli paketlerin ptest versiyonunu seç
IMAGE_INSTALL:append = " mylib-ptest busybox-ptest openssl-ptest python3-ptest"

# ptest-runner aracı (ptest çalıştırıcı)
IMAGE_INSTALL:append = " ptest-runner"

04 Runtime test yazma — OERuntimeTestCase

OERuntimeTestCase, oeqa runtime test case'lerini yazmak için temel sınıftır. SSH üzerinden DUT'a komut gönderir, çıktıyı alır ve assert ile doğrular.

Temel OERuntimeTestCase yapısı

meta-custom/lib/oeqa/runtime/cases/mytest.py
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.depends import OETestDepends
from oeqa.core.decorator.data import OETestDataDepends

class MyCustomTest(OERuntimeTestCase):
    """Özel runtime test case örneği."""

    @OETestDepends(['ssh.SSHTest.test_ssh'])
    def test_kernel_version(self):
        """Kernel sürümünün beklenen major version'a sahip olduğunu doğrula."""
        status, output = self.target.run("uname -r")
        self.assertEqual(status, 0, "uname komutu başarısız")
        major = int(output.split(".")[0])
        self.assertGreaterEqual(major, 6, f"Kernel 6.x beklendi, alınan: {output}")

    @OETestDepends(['ssh.SSHTest.test_ssh'])
    def test_ethernet_up(self):
        """Ethernet arayüzünün aktif olduğunu doğrula."""
        status, output = self.target.run("ip link show eth0")
        self.assertEqual(status, 0, "eth0 bulunamadı")
        self.assertIn("UP", output, f"eth0 aktif değil: {output}")

    def test_disk_space(self):
        """Root partition boş alan kontrolü."""
        status, output = self.target.run(
            "df / | tail -1 | awk '{print $5}' | tr -d '%'"
        )
        self.assertEqual(status, 0)
        usage = int(output.strip())
        self.assertLess(usage, 90, f"Root partition dolu: %{usage}")

    @OETestDepends(['ssh.SSHTest.test_ssh'])
    def test_file_copy(self):
        """SCP ile dosya kopyalama testi."""
        # Host'tan DUT'a dosya gönder
        self.target.copy_to("/tmp/test-file.txt", "/tmp/test-file.txt")
        status, output = self.target.run("cat /tmp/test-file.txt")
        self.assertEqual(status, 0)
        # Temizlik
        self.target.run("rm /tmp/test-file.txt")

Test suite kaydı

local.conf — özel test suite ekleme
# Özel test modülü yolunu ekle
TEST_SUITES_APPEND = "mytest"

# TEST_SUITES içinde kullanmak için tam modül yolu
TEST_SUITES = "ping ssh df mytest"

# Özel test dosyasının bulunduğu layer'ı ekle
BBPATH .= ":${LAYERDIR}"

# Test dosyaları araştırma yolu
OEQA_CUSTOM_TESTS_DIR = "${LAYERDIR}/lib/oeqa/runtime/cases"

SSH executor yapılandırması

local.conf — SSH hedef yapılandırması
# Gerçek donanıma SSH ile test
TEST_TARGET = "ssh"
TEST_TARGET_IP = "192.168.1.50"
TEST_SERVER_IP = "192.168.1.10"  # Host IP (dosya transferi için)

# SSH key (root şifresiz erişim)
TEST_TARGET_SSH_OPTIONS = "-o StrictHostKeyChecking=no \
  -o UserKnownHostsFile=/dev/null \
  -i /home/builder/.ssh/id_rsa_test"

05 SDK test — oeqa.sdk

oeqa.sdk, oluşturulan SDK'nın (Software Development Kit) düzgün çalışıp çalışmadığını doğrular. Özellikle SDK yayımı öncesinde kritik önem taşır.

SDK oluşturma

bash — SDK derleme
# Standart SDK
bitbake core-image-minimal -c populate_sdk

# eSDK (extensible SDK)
bitbake core-image-minimal -c populate_sdk_ext

# SDK çıktı konumu
ls tmp/deploy/sdk/
# poky-glibc-x86_64-core-image-minimal-cortexa57-toolchain-4.3.sh

SDK testini çalıştırma

bash — SDK test komutu
# SDK testini çalıştır
bitbake core-image-minimal -c testsdk

# local.conf içinde test suite ayarı
TOOLCHAIN_TEST_HOST         = "192.168.1.5"
TOOLCHAIN_TEST_HOST_USER    = "root"
TOOLCHAIN_TEST_HOST_PASSWORD = ""

# SDK test suite seçimi
SDK_TARGET_MANIFEST = ""

Özel SDK test case

meta-custom/lib/oeqa/sdk/cases/mysdktest.py
import os
import subprocess
from oeqa.sdk.case import OESDKTestCase

class MySDKBuildTest(OESDKTestCase):
    """SDK ile C programı derleme ve çalıştırma testi."""

    tc_is_sdk = True

    def test_c_compile(self):
        """Basit bir C programını SDK ile derle."""
        src = """
#include 
int main(void) {
    printf("SDK Build Test OK\\n");
    return 0;
}
"""
        src_path = os.path.join(self.tc.sdk_dir, "test_sdk.c")
        bin_path = os.path.join(self.tc.sdk_dir, "test_sdk")

        with open(src_path, "w") as f:
            f.write(src)

        # SDK environment'ı source edip derle
        result = self._run(
            f"${{CC}} {src_path} -o {bin_path} && echo COMPILE_OK"
        )
        self.assertIn("COMPILE_OK", result)

    def test_c_run(self):
        """Derlenen binary'yi çalıştır."""
        bin_path = os.path.join(self.tc.sdk_dir, "test_sdk")
        result = self._run(f"{bin_path}")
        self.assertIn("SDK Build Test OK", result)

    def test_pkg_config(self):
        """pkg-config ile kütüphane sorgulama."""
        result = self._run("pkg-config --libs openssl 2>&1 || echo MISSING")
        # openssl kütüphanesi SDK içinde mevcut olmalı
        self.assertNotIn("MISSING", result)

06 wic image + hardware test

wic ile oluşturulan SD kart imajları gerçek donanıma yazdırılarak test edilebilir. LAVA entegrasyonu veya script tabanlı flash + SSH test akışı bu senaryoyu otomatize eder.

wic image oluşturma

bash — wic image derleme
# wic image derle
bitbake core-image-minimal

# Çıktı
ls tmp/deploy/images/raspberrypi4-64/
# core-image-minimal-raspberrypi4-64.rootfs.wic.bz2

# Sıkıştırmayı aç
bunzip2 core-image-minimal-raspberrypi4-64.rootfs.wic.bz2

Otomatik SD kart flash scripti

bash — flash-and-test.sh
#!/bin/bash
# flash-and-test.sh — wic image yaz ve test çalıştır
set -e

IMAGE="$1"
SD_DEVICE="${2:-/dev/sdb}"
DUT_IP="${3:-192.168.1.50}"

echo "[1/4] SD kart yazılıyor: $SD_DEVICE"
dd if="$IMAGE" of="$SD_DEVICE" bs=4M conv=fsync status=progress
sync

echo "[2/4] DUT güç döngüsü..."
/usr/local/bin/pdu-ctrl.sh cycle dut-01

echo "[3/4] SSH erişimi bekleniyor..."
TIMEOUT=120
ELAPSED=0
until ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 \
    root@$DUT_IP "echo ALIVE" 2>/dev/null; do
  sleep 5
  ELAPSED=$((ELAPSED + 5))
  [ $ELAPSED -ge $TIMEOUT ] && { echo "SSH timeout!"; exit 1; }
done

echo "[4/4] Testler çalıştırılıyor..."
pytest tests/post-flash/ \
  --target-ip=$DUT_IP \
  --junit-xml=reports/flash-test.xml

echo "Flash ve test tamamlandı."

LAVA entegrasyonu ile wic flash

lava-wic-job.yaml — wic image LAVA job
job_name: yocto-wic-flash-test
device_type: rpi4b
priority: medium

actions:
  - deploy:
      to: usb
      image:
        url: http://artifact-server/core-image-minimal.wic.bz2
        compression: bz2
      os: oe

  - boot:
      method: u-boot
      commands: default
      auto_login:
        login_prompt: "login:"
        username: root
      prompts:
        - "root@raspberrypi4:~#"

  - test:
      definitions:
        - from: inline
          name: post-flash-smoke
          path: inline/smoke.yaml
          repository:
            metadata:
              format: Lava-Test Test Definition 1.0
              name: smoke
            run:
              steps:
                - lava-test-case "boot-ok" --result pass
                - lava-test-case "storage" --result pass \
                    --measurement "$(df / | tail -1 | awk '{print $4}')" --units KB

07 Pratik: Custom ptest recipe + GitLab CI pipeline

Sıfırdan bir ptest recipe oluşturma ve bunu GitLab CI içinde otomatik olarak derleme, test ve raporlama adımlarına entegre etme.

Örnek C kütüphanesi ve ptest recipe

meta-myproject/recipes-libs/libsensor/libsensor_1.0.bb
SUMMARY = "Sensor okuma kütüphanesi"
LICENSE  = "MIT"
LIC_FILES_CHKSUM = "file://LICENSE;md5=abc123"

SRC_URI = "git://gitlab.example.com/firmware/libsensor.git;protocol=https;branch=main"
SRCREV  = "${AUTOREV}"
PV      = "1.0+git${SRCPV}"

S = "${WORKDIR}/git"

inherit cmake ptest

DEPENDS = "libcheck"

# Normal derleme
do_configure:prepend() {
    cmake_do_configure
}

# ptest derleme
do_compile_ptest() {
    oe_runmake -C ${B} sensor_tests
}

# ptest kurulum
do_install_ptest() {
    install -d ${D}${PTEST_PATH}
    install -m 0755 ${B}/tests/sensor_tests ${D}${PTEST_PATH}/
    install -m 0755 ${S}/tests/run-ptest    ${D}${PTEST_PATH}/
    # Test fixtures (örnek veri dosyaları)
    install -d ${D}${PTEST_PATH}/fixtures
    cp -r ${S}/tests/fixtures/ ${D}${PTEST_PATH}/fixtures/
}

RDEPENDS:${PN}-ptest += "bash ptest-runner libcheck"
FILES:${PN}-ptest += "${PTEST_PATH}"

Tam GitLab CI pipeline

.gitlab-ci.yml — Yocto + ptest + testimage CI
stages:
  - build-image
  - test-qemu
  - test-hardware

variables:
  MACHINE:    "qemuarm64"
  DISTRO:     "poky"
  IMAGE:      "core-image-minimal"
  BUILD_DIR:  "${CI_PROJECT_DIR}/build"
  SSTATE_DIR: "/shared/yocto-sstate"
  DL_DIR:     "/shared/yocto-downloads"

# ── Image Derleme ───────────────────────────────────

build-yocto-image:
  stage: build-image
  tags: [yocto-builder]
  image: crops/poky:ubuntu-22.04
  script:
    - source poky/oe-init-build-env ${BUILD_DIR}
    - |
      cat >> conf/local.conf << 'EOF'
      MACHINE     = "${MACHINE}"
      DISTRO      = "${DISTRO}"
      SSTATE_DIR  = "${SSTATE_DIR}"
      DL_DIR      = "${DL_DIR}"
      INHERIT    += "testimage"
      IMAGE_FEATURES:append = " debug-tweaks ssh-server-openssh ptest-pkgs"
      IMAGE_INSTALL:append   = " libsensor-ptest"
      EOF
    - bitbake ${IMAGE}
  artifacts:
    paths:
      - build/tmp/deploy/images/${MACHINE}/
      - build/tmp/deploy/sdk/
    expire_in: 1 day

# ── QEMU Runtime Testleri ───────────────────────────

testimage-qemu:
  stage: test-qemu
  tags: [yocto-builder]
  needs: [build-yocto-image]
  image: crops/poky:ubuntu-22.04
  script:
    - source poky/oe-init-build-env ${BUILD_DIR}
    - |
      cat >> conf/local.conf << 'EOF'
      TEST_TARGET  = "qemu"
      TEST_SUITES  = "ping ssh df libsensor"
      QB_MEM       = "-m 512"
      EOF
    - bitbake ${IMAGE} -c testimage
    - |
      # Sonuçları JUnit'e dönüştür
      python3 scripts/oeqa-to-junit.py \
        build/tmp/log/oeqa/ \
        reports/qemu-junit.xml
  artifacts:
    reports:
      junit: reports/qemu-junit.xml
    paths:
      - build/tmp/log/oeqa/
    when: always

# ── Hardware Testleri (SSH hedef) ───────────────────

testimage-hardware:
  stage: test-hardware
  tags: [hil-yocto-board]
  needs: [build-yocto-image]
  resource_group: rpi4-board-01
  variables:
    DUT_IP: "192.168.1.50"
  script:
    - source poky/oe-init-build-env ${BUILD_DIR}
    - |
      cat >> conf/local.conf << 'EOF'
      TEST_TARGET    = "ssh"
      TEST_TARGET_IP = "${DUT_IP}"
      TEST_SUITES    = "ping ssh df libsensor ptest"
      EOF
    # wic image'ı flash et
    - ../scripts/flash-and-test.sh \
        build/tmp/deploy/images/raspberrypi4-64/core-image-minimal.wic.bz2 \
        /dev/sdb ${DUT_IP}
    - bitbake ${IMAGE} -c testimage
  artifacts:
    reports:
      junit: reports/hw-junit.xml
    when: always

Sonuç raporlama scripti

scripts/oeqa-to-junit.py
#!/usr/bin/env python3
"""oeqa testresults.json → JUnit XML dönüştürücü."""
import json
import sys
import xml.etree.ElementTree as ET
from pathlib import Path
from datetime import datetime

def convert(oeqa_dir: Path, output_file: Path):
    # En son test sonuç dizinini bul
    results_files = list(oeqa_dir.glob("*/testresults.json"))
    if not results_files:
        print("testresults.json bulunamadı")
        sys.exit(1)

    latest = max(results_files, key=lambda p: p.stat().st_mtime)
    data = json.loads(latest.read_text())

    suite = ET.Element("testsuite",
        name="oeqa",
        timestamp=datetime.now().isoformat()
    )

    for test_name, result in data.items():
        case = ET.SubElement(suite, "testcase", name=test_name)
        if result["status"] == "FAILED":
            failure = ET.SubElement(case, "failure", message=result.get("log", ""))
            failure.text = result.get("log", "")
        elif result["status"] == "ERROR":
            error = ET.SubElement(case, "error", message=result.get("log", ""))

    tree = ET.ElementTree(suite)
    output_file.parent.mkdir(parents=True, exist_ok=True)
    tree.write(output_file, encoding="utf-8", xml_declaration=True)
    print(f"JUnit rapor yazıldı: {output_file}")

if __name__ == "__main__":
    convert(Path(sys.argv[1]), Path(sys.argv[2]))
İpucu

Yocto derlemeleri uzun sürer. CI'da sstate cache paylaşımı çok önemlidir. SSTATE_DIR ve DL_DIR'i pipeline'lar arasında paylaşılan bir NFS/S3 dizinine yönlendirin. Bu ayar yeniden derleme süresini genellikle %80-90 oranında azaltır.