Jump to content

How to Create Yocto Projects - Yocto Build Orchestration with kas

From RidgeRun Developer Wiki

Follow us on: YouTube Twitter LinkedIn Email Share this page

Share This Page


NVIDIA partner logo NXP partner logo





Purpose

kas is a setup tool designed for BitBake-based projects. It simplifies the process of defining, reproducing, and executing Yocto build environments by relying on declarative YAML configuration files. These configurations describe the required layers, repositories, and build settings in a structured and portable way.

By encapsulating the build environment in a single configuration, kas improves reproducibility, reduces manual setup, and helps ensure consistency across different development machines and teams. It also streamlines common workflows such as initializing build environments, checking out the required repositories, generating the necessary configuration, and invoking BitBake with the correct context.

This wiki provides both a technical and practical overview of kas. It is intended for engineers who want to use the tool effectively while gaining a deeper understanding of its internal behavior and design principles.

The content is organized sequentially, introducing concepts step by step. Each section builds on the previous one, allowing readers to progressively develop both conceptual knowledge and hands-on proficiency.

The Problem kas Solves

Yocto builds depend on:

  • Multiple Git repositories (layers)
  • Exact revisions of those repositories
  • Correct layer configuration
  • Proper configuration files (bblayers.conf, local.conf)

Yocto assumes these are already correctly prepared.

Consequences

  • Non-reproducible builds
  • Manual and undocumented setup steps
  • Differences between developer and CI environments

What kas introduces

kas provides a declarative configuration that describes:

  • Which repositories to use
  • Which revisions to check out
  • Which layers to enable
  • Which machine, distro, and target to build

This configuration can be executed to recreate the environment.

All of these aspects can also be achieved using tools such as repo or Git submodules. However, those approaches operate mainly at the source management level and do not cover the full build workflow.

kas adds value by integrating repository management, environment setup, and build execution into a single interface. For example:

  • A complete image build can be triggered with a single command
  • It lowers the entry barrier for users or customers with little or no Yocto experience
  • It makes deliverables easier to distribute and reproduce
  • Development environments can be isolated using containers (e.g., kas-container)
  • The same workflow can be reused across developers and CI systems

In practice, kas shifts the focus from manually preparing the environment to executing a well-defined configuration.

What kas Is (and Is Not)

kas is

  • A command-line interface (CLI) tool
  • A YAML-based configuration system for defining build environments
  • A setup and orchestration tool for BitBake-based workflows

kas is not

  • A build system (the actual build is performed by BitBake)
  • A replacement for BitBake
  • A dependency resolver (dependency resolution is handled by BitBake)
  • A tool that modifies or extends BitBake’s core behavior

Mental Model

kas prepares the environment → BitBake executes the build

kas is responsible for:

  • Fetching and checking out repositories at the specified revisions
  • Generating and injecting configuration (e.g., bblayers.conf, local.conf)
  • Setting up and orchestrating the build environment
  • Invoking BitBake with the correct context

BitBake is responsible for:

  • Parsing metadata (recipes, classes, and configuration)
  • Resolving dependencies between tasks and recipes
  • Executing tasks
  • Producing build artifacts

Quick Execution Overview

kas build kas.yml

This command executes a complete Yocto build workflow as defined in kas.yml. It is the primary entry point for users.

From the user perspective, this is a single-step operation: running the command is sufficient to set up the environment and start the build.

Internally, kas performs the following phases:

  1. Loading and resolving the configuration (including includes and overrides)
  2. Fetching and checking out repositories at the specified revisions
  3. Preparing the workspace and build directory
  4. Generating configuration files (bblayers.conf, local.conf)
  5. Invoking BitBake for the configured target

These steps are executed automatically by kas as part of the command. They are not manual steps and do not require user intervention.

In other words, kas build encapsulates the full process from environment setup to build execution.

Detailed Execution Model

kas commands can be understood as executing a sequence of logical phases. These phases are performed automatically and describe how a configuration file is transformed into a runnable BitBake build.

All kas commands start by resolving the configuration. From there, each command executes a different subset of the workflow.

Command Coverage

  • kas dump → performs Phase 1 only
  • kas checkout → performs Phases 1–5
  • kas shell → performs Phases 1–5, then opens an interactive environment
  • kas build → performs Phases 1–6 (full workflow)

This means that all commands share a common foundation, but stop at different points in the process.

Phase 1 — Configuration Resolution

Executed by: all commands

The process begins by loading the top-level YAML file passed on the command line.

At this stage, kas:

  • Parses the YAML structure
  • Loads included configuration files
  • Merges all configuration fragments into one effective configuration
  • Applies merge rules, where later definitions override earlier ones
  • Resolves final values for machine, distro, target, repositories, layers, and configuration fragments

This phase determines the complete project description that kas will execute.

kas dump kas.yml

The kas dump command executes only this phase and outputs the fully resolved configuration. It is useful for validating and debugging configuration composition.

Phase 2 — Repository Resolution and Materialization

Executed by: kas checkout, kas shell, kas build

After the configuration has been resolved, kas evaluates the repos: section.

At this stage, kas determines:

  • Which repositories are part of the project
  • Where each repository should be placed in the workspace
  • Which reference (branch, tag, or commit) should be used
  • Which repositories contribute layers to the build

kas then materializes the repository set by:

  • Cloning repositories that are not yet present locally
  • Reusing existing checkouts when possible
  • Fetching updates when required
  • Checking out the configured revision

This phase is critical for reproducibility. kas does not auto-discover missing repositories or layers. Only repositories explicitly declared in the configuration are processed.

Phase 3 — Layer Collection and Path Resolution

Executed by: kas checkout, kas shell, kas build

Once repositories are available locally, kas processes the relationship between repositories and layers.

At this stage, kas:

  • Reads the layer lists attached to the configured repositories
  • Resolves each layer path relative to the repository checkout
  • Builds the final ordered list of layers

Important distinctions:

  • A repository may provide one or more layers
  • Only explicitly selected layers are enabled
  • Repositories may be fetched without enabling all their layers

This phase produces the data that will populate bblayers.conf.

Phase 4 — Build Directory Initialization

Executed by: kas checkout, kas shell, kas build

kas prepares the build workspace:

  • Creates the build directory if it does not exist
  • Reuses it if it already exists
  • Sets up the directory structure expected by BitBake

At this point, the filesystem layout is equivalent to a manually initialized Yocto build environment.

Phase 5 — BitBake Configuration Generation

Executed by: kas checkout, kas shell, kas build

kas generates the configuration files required by BitBake:

  • conf/bblayers.conf
  • conf/local.conf

These files are derived from the resolved configuration:

  • Layers are written into bblayers.conf
  • Machine, distro, and other settings are written into local.conf
  • Optional configuration fragments are injected when defined

At the end of this phase, the build environment is fully prepared.

This is the point where kas checkout stops.

Phase 6 — Environment Setup and Build Invocation

Executed by: kas build

Once the repositories, layers, build directory, and configuration files are in place, kas invokes BitBake.

Conceptually, this corresponds to:

bitbake <target>

However, BitBake is executed within the prepared environment.

At this stage:

  • kas has completed environment preparation
  • BitBake parses metadata
  • BitBake resolves dependencies between recipes and tasks
  • BitBake executes tasks
  • BitBake produces build artifacts

kas does not participate in the build itself beyond invoking BitBake.

Interactive Environment (kas shell)

Executed by: kas shell

The kas shell command executes Phases 1–5 and then opens a shell inside the prepared build environment instead of running BitBake.

This allows:

  • Manual execution of BitBake
  • Inspection of environment variables and configuration
  • Debugging of build issues interactively

Summary

All kas commands share a common execution model based on the same sequence of phases.

The workflow can be understood as:

  1. Phase 1 → Configuration resolution (performed by all commands)
  2. Phase 2–5 → Environment preparation (completed by kas checkout)
  3. Phase 6 → Build execution (added by kas build)

Mapping to Yocto Concepts

kas Concept Yocto Equivalent Description
repos Git repositories Source repositories containing layers and metadata
layers bblayers.conf List of enabled layers used by BitBake
machine MACHINE Target hardware configuration
distro DISTRO Distribution configuration (policies, defaults, features)
target BitBake target Recipe or image passed to bitbake

Minimal Configuration (kas.yml)

header:
  version: 22

machine: qemux86-64
distro: poky

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    branch: kirkstone
    layers:
      meta:
      meta-poky:
      meta-yocto-bsp:

target: core-image-minimal

This configuration defines:

  • The target machine (MACHINE)
  • The distribution (DISTRO)
  • The repositories to fetch and their revisions
  • The layers to enable (used to generate bblayers.conf)
  • The BitBake target to build

Configuration Composition (Includes)

Includes are defined inside header:

header:
  version: 22
  includes:
    - base.yml
    - board.yml

The purpose of includes is to split a kas configuration into reusable fragments and then combine them into a single effective configuration.

This allows a project to separate concerns. For example:

  • A common base configuration
  • A board-specific configuration
  • A product-specific configuration
  • A developer or CI override layer

Instead of writing one large kas.yml file, the configuration can be composed from smaller files that are easier to maintain and reuse.

How includes are resolved

When kas loads a configuration file, it first reads the file itself and then resolves the entries listed in header.includes.

Included files can be specified in more than one way:

  • As a simple path string
  • As a dictionary that explicitly names the file and, if needed, the repository from which it should be loaded

In practice, this means an include may refer either to:

  • Another configuration file located in the same project tree
  • A configuration file stored in a different repository that is already part of the kas configuration

This makes includes suitable not only for in-tree composition, but also for sharing common configuration fragments across repositories.

Behavior

  • Files are processed as part of one configuration resolution step
  • Includes are expanded into a single effective configuration
  • Configuration data is merged, not textually inserted
  • The including file can override values coming from included files
  • When multiple files define the same key, the later effective definition wins, according to kas merge rules

This is why includes should be understood as a configuration composition mechanism, not as a source-code-style import mechanism. They do not simply paste file contents into place. Instead, kas interprets each file as configuration data and produces one resolved result.

Conceptual Example

Suppose the files are organized as follows:

# kas.yml
header:
  version: 22
  includes:
    - base.yml
    - board.yml
# base.yml
machine: qemux86-64
distro: poky
target: core-image-minimal
# board.yml
machine: beaglebone-yocto

The effective result is conceptually equivalent to:

machine: beaglebone-yocto
distro: poky
target: core-image-minimal

In this example:

  • base.yml provides common defaults
  • board.yml overrides the machine
  • The final configuration is the merged result of all files

This is the main practical value of includes: common configuration can be shared, while more specific files override only the parts they need to change.

Why this matters

Includes are one of the main reasons kas scales well for real projects.

Without includes, every build variant would require its own mostly duplicated configuration file. With includes, a project can define:

  • One shared base
  • Several board variants
  • Several product variants
  • Optional local or CI-specific overrides

This reduces duplication and makes configuration maintenance more predictable. It also makes the resulting configuration easier to reason about, because the final output can always be inspected with:

kas dump kas.yml

The dump command expands includes and prints the flattened configuration that kas will actually execute. This is the most direct way to verify that the merge behaved as expected.

Important clarification

Includes do not create multiple independent configurations. After resolution, kas works with one effective configuration.

That resolved configuration is then used for all later phases:

  • Repository materialization
  • Layer collection
  • Build directory preparation
  • Generation of bblayers.conf and local.conf
  • BitBake invocation

In other words, includes affect the configuration resolution phase, not the later build phases directly. Their role is to define the final input that those later phases consume.

Repository Revision Control

Repository revisions are defined inside repos:

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    branch: kirkstone
    commit: abcdef1234567890abcdef1234567890abcdef12

The purpose of revision control in kas is to define exactly which source state should be used for each repository in the build.

This is important because a Yocto build is not defined only by the set of repositories, but also by the exact revision of each one. Two builds that use the same repositories but different revisions may produce different results.

Supported revision selectors

kas supports several ways to identify the desired revision of a repository:

  • branch — a named development line, such as kirkstone
  • tag — a named fixed point in history
  • commit — an exact commit ID

According to the kas configuration reference, commit should be a full-length lowercase commit hash. If no commit, branch, or tag is specified, the revision obtained depends on the defaults of the underlying version control system.

Meaning of each selector

branch

A branch expresses a moving line of development.

Example:

branch: kirkstone

This is useful because it is readable and communicates intent clearly. A reader can immediately understand that the repository is expected to follow the kirkstone line.

However, a branch is a floating reference. Its tip may move over time as new commits are added upstream. That means that using only a branch does not guarantee that the same build performed later will use the same source revision.

tag

A tag identifies a named point in history.

Example:

tag: yocto-4.0.15

A tag is typically more stable than a branch because it usually refers to a fixed release point. However, from the perspective of strict reproducibility, the most explicit and unambiguous selector is still the exact commit ID.

commit

A commit identifies one exact repository state.

Example:

commit: abcdef1234567890abcdef1234567890abcdef12

This is the strongest option for reproducibility, because it pins the repository to one exact revision. If the same commit is checked out again, the repository content is expected to be identical. kas also uses exact commit IDs in lockfiles for precisely this reason.

Using branch and commit together

A common pattern is to specify both branch and commit:

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    branch: kirkstone
    commit: abcdef1234567890abcdef1234567890abcdef12

In this form:

  • branch documents the intended upstream line
  • commit pins the exact revision actually used

This gives a good balance between readability and reproducibility. The branch helps humans understand the expected maintenance line, while the commit ensures that the build is tied to a precise source state. The kas codebase also reflects this combined representation when both are present.

Why floating revisions are risky

A floating revision is any selector whose meaning may change over time, especially a branch and, in some workflows, a tag.

For example:

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    branch: kirkstone

This configuration is easy to read, but it does not fully pin the repository state. If the branch advances, a later checkout may produce a different source tree even though the kas file itself did not change.

This is one of the main reasons builds become hard to reproduce over time. kas explicitly provides lockfiles and ref resolution features to convert floating references into exact commit IDs.

Lockfiles and exact pinning

kas supports lockfiles to pin repositories to exact commits.

The documented behavior is:

  • A lockfile overrides repository commit values
  • It is used to turn floating branches or tags into exact SHAs
  • It is automatically applied when found next to the kas file
  • The lock plugin can generate or update it

This is the recommended mechanism when a project wants both:

  • Readable source configuration in the main kas file
  • Exact reproducibility in the executed build

In other words, a project may keep branch: kirkstone in the main file for readability, while the lockfile injects the exact commit used for the build.

Best practices

  • Use commit when reproducibility is critical
  • Use branch when you want readability and a clear indication of the intended upstream line
  • Use both branch and commit when you want readability together with exact pinning
  • Avoid floating revisions when long-term stability is required
  • Use lockfiles to convert floating references into exact commits without losing readability

Practical interpretation

From a workflow perspective, revision selectors affect Phase 2 of the execution model: repository materialization.

During that phase, kas:

  • Decides which repository to fetch
  • Determines which revision should be used
  • Checks out that repository at the configured state

This means revision control in kas is not a secondary detail. It is one of the core mechanisms by which kas makes builds repeatable and auditable.

bblayers Generation

Layers are defined under each repository:

repos:
  poky:
    url: https://git.yoctoproject.org/git/poky
    branch: kirkstone
    layers:
      meta:
      meta-poky:

The layers key specifies which layers from each repository are enabled in the build.

How kas uses this information

During the configuration phase, kas:

  • Collects all layers defined across repositories
  • Resolves each layer path relative to its repository checkout
  • Builds an ordered list of layer paths
  • Generates the conf/bblayers.conf file

The resulting bblayers.conf contains a BBLAYERS variable listing all enabled layers.

Conceptually, the generated file looks like:

BBLAYERS ?= " \
  /path/to/poky/meta \
  /path/to/poky/meta-poky \
"

This file is automatically created by kas and does not need to be edited manually.

Layer paths

Each layer entry in the kas configuration corresponds to a directory inside the repository.

For example:

layers:
  meta:
  meta-poky:

means:

  • meta<repo>/meta
  • meta-poky<repo>/meta-poky

kas resolves these into absolute paths when generating bblayers.conf.

Layer ordering

The order of layers in bblayers.conf is determined by:

  • The order of repositories in the configuration
  • The order of layers listed within each repository

BitBake reads layers in the order defined in BBLAYERS.

This order can influence:

  • Layer priority resolution
  • Which recipes or classes take precedence when multiple layers provide similar content

Therefore, layer ordering is part of the build configuration and should be considered carefully.

Important behavior

  • Only layers explicitly listed in the configuration are enabled
  • A repository may contain multiple layers, but only selected ones are included
  • kas does not automatically enable all layers in a repository
  • Missing required layers will result in BitBake errors during parsing

Customization

kas allows customization of bblayers.conf through configuration fragments, such as:

  • bblayers_conf_header
  • bblayers_conf_footer

These allow injecting additional content into the generated file without modifying it manually.

Why this matters

In a traditional Yocto workflow, bblayers.conf must be manually edited and maintained.

kas automates this process by:

  • Deriving the layer list from a declarative configuration
  • Ensuring consistency across environments
  • Eliminating manual errors in layer setup

This makes layer configuration reproducible and easier to maintain across developers and CI systems.

local conf Injection

local_conf_header:
  debug: |
    EXTRA_IMAGE_FEATURES += "debug-tweaks"

The local_conf_header key allows injecting configuration into the generated local.conf file.

The defined content is prepended to local.conf.

How it works

During the configuration generation phase, kas:

  • Generates conf/local.conf based on the resolved configuration
  • Inserts the content of local_conf_header at the beginning of the file

The injected content becomes part of the final BitBake configuration and is interpreted when BitBake parses local.conf.

Structure

The structure of local_conf_header is:

  • A dictionary of named fragments
  • Each key (e.g., debug) is only a label for organization
  • The value is a multi-line string containing BitBake configuration syntax

Example:

local_conf_header:
  debug: |
    EXTRA_IMAGE_FEATURES += "debug-tweaks"
  parallelism: |
    BB_NUMBER_THREADS = "8"
    PARALLEL_MAKE = "-j8"

All fragments are concatenated and written into local.conf.

Important behavior

  • The content is not interpreted by kas
  • It is passed verbatim to local.conf
  • Syntax must follow BitBake configuration rules
  • Errors in this section will result in BitBake parsing errors

Precedence and overrides

Since the content is prepended:

  • It appears before the default configuration generated by kas
  • Later definitions in local.conf may override earlier ones
  • BitBake ultimately determines the final value based on its variable assignment rules

For example:

  • = → overrides previous values
  • ?= → sets a default only if not already defined
  • += → appends to existing values

This means that the effect of injected configuration depends on both its position and the BitBake assignment operators used.

Related mechanisms

kas also provides:

  • local_conf_footer — content appended to the end of local.conf

This can be used when configuration must override all previous definitions.

Why this matters

In a traditional Yocto workflow, modifying local.conf requires manual editing.

kas enables:

  • Declarative configuration inside YAML
  • Reproducible and shareable build settings
  • Separation between generated files and user-defined configuration

This avoids modifying generated files directly and ensures that configuration changes are version-controlled.

Inspection Workflow

kas build kas.yml
kas shell kas.yml

The goal of inspection is to verify the effective configuration and the generated Yocto environment.

There are two main ways to inspect a kas-based build:

Using kas build

kas build kas.yml
  • Executes the full workflow (Phases 1–6)
  • Generates the build environment
  • Runs BitBake

After execution, the build directory is populated and can be inspected.

Using kas shell

kas shell kas.yml
  • Executes environment preparation (Phases 1–5)
  • Opens an interactive shell inside the configured build environment
  • Does not automatically run BitBake

This is the preferred method for inspection and debugging, since it allows manual interaction with the environment.

Inspecting generated configuration

Once the environment is prepared (via kas build or kas shell), the generated configuration files can be inspected:

cat conf/bblayers.conf
cat conf/local.conf

These files represent the final configuration that BitBake uses.

Example:

BBLAYERS ?= " \
  /path/to/poky/meta \
  /path/to/poky/meta-poky \
"

What to verify

When inspecting these files, check:

  • That all expected layers are present in BBLAYERS
  • That layer paths are correct and accessible
  • That local.conf contains the expected machine, distro, and custom settings
  • That injected configuration (e.g., local_conf_header) appears correctly

Additional inspection tools

kas also provides commands to inspect earlier stages of the workflow:

kas dump kas.yml
  • Shows the fully resolved configuration (Phase 1)
  • Useful to verify includes and overrides before environment setup

Why this matters

Inspection is essential for understanding how kas transforms a declarative configuration into a concrete Yocto build environment.

It allows:

  • Verifying that the configuration was resolved correctly
  • Debugging missing layers or incorrect settings
  • Ensuring reproducibility by checking the generated files

In practice, inspection bridges the gap between the kas configuration and the BitBake execution environment.

Debugging Strategy

Debugging a kas-based build involves verifying each phase of the execution model, from configuration resolution to BitBake execution.

Steps

  1. Inspect the generated configuration files
  2. Validate the kas YAML configuration
  3. Verify the resolved (merged) configuration using kas dump
  4. Inspect the build environment interactively if needed
  5. Analyze BitBake errors separately from kas issues

1. Inspect generated configuration

After running:

kas build kas.yml
# or
kas shell kas.yml

inspect:

cat conf/bblayers.conf
cat conf/local.conf

Verify:

  • All expected layers are present
  • Layer paths are correct
  • Machine and distro are correctly set
  • Injected configuration (e.g., local_conf_header) appears as expected

Most configuration-related issues can be identified at this stage.

2. Validate YAML configuration

Check for:

  • Syntax errors (invalid YAML structure)
  • Incorrect indentation
  • Wrong key names or misplaced fields
  • Missing required sections (e.g., repos, layers)

Note that kas does not silently fix YAML issues. Invalid configurations will result in errors during parsing.

3. Inspect merged configuration

kas dump kas.yml

This command shows the fully resolved configuration after includes and overrides.

Use it to verify:

  • That includes are resolved correctly
  • That overrides behave as expected
  • That the final values for machine, distro, repos, and layers are correct

This step corresponds to Phase 1 (Configuration Resolution).

4. Inspect the environment interactively

kas shell kas.yml

This allows:

  • Running BitBake manually
  • Inspecting environment variables
  • Testing changes without re-running the full build

Useful commands inside the shell:

bitbake -e | less

This shows the full BitBake environment and variable values.

5. Distinguish kas issues from BitBake issues

It is important to separate problems by layer:

  • kas issues:
 * Missing repositories
 * Incorrect layer paths
 * Configuration merge problems
  • BitBake issues:
 * Recipe errors
 * Dependency resolution failures
 * Task execution failures

kas prepares the environment; BitBake performs the build. Debugging should identify which stage is failing.

Common debugging patterns

  • Missing layer error → check bblayers.conf and repos
  • Unexpected configuration → check kas dump output
  • Variable not applied → check local.conf and assignment operators
  • Build failure → inspect BitBake logs (tmp/log/)

Summary

A reliable debugging workflow follows the execution model:

  1. Verify configuration (kas dump)
  2. Verify generated files (bblayers.conf, local.conf)
  3. Inspect environment (kas shell)
  4. Analyze BitBake execution

This structured approach allows isolating issues quickly and understanding where the failure occurs.

Reproducibility

Reproducibility in a kas-based workflow means that the same configuration produces the same build result when executed multiple times.

kas improves reproducibility by controlling the inputs to the build, but it does not guarantee full determinism on its own.

Controlled by kas

kas ensures reproducibility for the following aspects:

  • Repository revisions
    • Exact commits can be specified for each repository
    • Prevents changes caused by moving branches or tags
  • Layer configuration
    • The set of enabled layers is explicitly defined
    • Layer paths and ordering are reproducible
  • Build configuration
    • machine, distro, and other settings are defined declaratively
    • bblayers.conf and local.conf are generated consistently
    • Injected configuration (e.g., local_conf_header) is version-controlled

These elements define the build input space, which kas makes reproducible.

External factors

Some aspects of the build are outside of kas control:

  • Host system
    • OS version, installed tools, and environment differences
    • May affect build behavior or outputs
  • Network
    • Source downloads during the build (e.g., fetch tasks in BitBake)
    • Remote resources may change or become unavailable
  • Recipe behavior
    • Non-deterministic build steps inside recipes
    • Use of timestamps, random data, or external inputs
    • Differences in upstream sources or mirrors

These factors can introduce variability even when kas configuration is identical.

Practical considerations

To achieve higher reproducibility in practice:

  • Use exact commit revisions (or lockfiles) instead of floating branches
  • Use containerized environments to control the host system
  • Configure source mirrors and downloads to avoid network variability
  • Ensure recipes are deterministic and avoid time-dependent behavior

Summary

kas provides reproducibility at the configuration and environment level, but full build reproducibility depends on controlling external factors as well.

In other words:

  • kas defines what should be built
  • the environment and BitBake determine how it is built

Common Mistakes

The following are common pitfalls when working with kas-based workflows:

  • Using floating branches
    • Relying only on branch or tag without pinning a commit
    • Leads to non-reproducible builds as upstream changes over time
    • Use exact commits or lockfiles for stable builds
  • Editing generated files manually
    • Modifying conf/bblayers.conf or conf/local.conf directly
    • Changes are overwritten the next time kas runs
    • Instead, use kas configuration (repos, layers, local_conf_header, etc.)
  • Misunderstanding kas vs BitBake roles
    • Expecting kas to resolve dependencies or fix build errors
    • kas prepares the environment; BitBake performs the build
    • Debug accordingly: configuration issues vs recipe/build issues
  • Missing or incomplete layer definitions
    • Forgetting to include required layers in repos
    • kas does not auto-discover dependencies between layers
    • Results in BitBake parsing errors
  • Incorrect layer paths
    • Using wrong relative paths inside layers
    • Layers must match actual directories inside repositories
  • Misusing configuration injection
    • Incorrect syntax in local_conf_header
    • Assuming injected values always override defaults
    • BitBake variable operators (=, ?=, +=) determine final values
  • Not inspecting the effective configuration
    • Skipping kas dump
    • Leads to confusion when includes or overrides behave unexpectedly

Practical Tutorial

This section provides a practical workflow based on a preconfigured repository.

Instead of manually creating the project structure and configuration files, the repository is prepared in advance. This allows the focus to shift to how kas executes and manages the build process.

This reflects real-world workflows, where kas configurations are distributed as repositories and users interact with them through kas commands rather than manually constructing the setup.

Step 1 — Install kas

Install kas in the host environment:

pip3 install kas

Step 2 — Clone the repository

Clone the training repository:

git clone https://github.com/RidgeRun/kas-practical-tutorial.git
cd kas-practical-tutorial

The repository already contains the kas configuration files required for the exercise.

Step 3 — Inspect the configuration

List the available files:

ls kas/

Typical structure:

  • base.yml — common configuration
  • qemu.yml — machine-specific configuration

These files are composed using includes to form the final configuration.

Step 4 — Inspect the resolved configuration

Before building, inspect the effective configuration:

kas dump kas/qemu.yml

The dump command resolves the configuration and prints the flattened result. This is especially important when includes, overrides, or multiple configuration fragments are used. It is the most direct way to verify what kas is actually going to execute.

At this stage, no build is executed. The purpose is inspection.

Step 5 — Prepare the environment

Next, prepare the project workspace:

kas checkout kas/qemu.yml

The checkout command checks out all required repositories and sets up the build directory as specified in the configuration, but it does not start BitBake. This makes it useful when the environment should be prepared first for inspection or manual changes.

This step is useful because it separates:

  • Environment preparation
  • Build execution

That distinction is one of the key ideas behind kas workflows.

Step 6 — Inspect generated Yocto configuration

After kas checkout, inspect the generated files:

cat build/conf/bblayers.conf
cat build/conf/local.conf

At this point, you can verify that:

  • The correct layers were enabled
  • Layer paths were resolved correctly
  • The machine and distro were set as expected
  • Any injected configuration is present in local.conf

This is the point where the kas configuration becomes concrete Yocto configuration.

Step 7 — Open an interactive shell

To inspect the prepared environment or run commands manually, use:

kas shell kas/qemu.yml

The shell command checks out repositories, sets up the build environment, and then opens a shell inside that environment instead of immediately invoking BitBake. This is useful for running BitBake manually, inspecting variables, or debugging interactively.

Inside that shell, you may run for example:

bitbake-layers show-layers
bitbake -e | less

These commands allow you to:

  • Inspect which layers are enabled in the build
  • Examine the expanded BitBake environment
  • Verify how configuration variables are resolved

When finished, exit the shell:

exit

Step 8 — Build the target

Execute the full workflow:

kas build kas/qemu.yml

The build command performs the complete workflow: it checks out repositories, sets up the build environment, and invokes BitBake to build the configured target.

For a first build, this may take significant time because sources, toolchains, and build artifacts may need to be downloaded and generated.

Conceptually, this command executes:

  • Configuration resolution
  • Repository checkout
  • Layer setup
  • Build directory preparation
  • Configuration generation
  • BitBake execution

Step 9 — Make a small modification

Modify the configuration and observe the effect.

Example:

Change the machine in kas/qemu.yml or adjust a parameter in local_conf_header.

Then run:

kas dump kas/qemu.yml

Observe how the resolved configuration changes.

This step reinforces how kas interprets and applies configuration.

Step 10 — Understand the command roles

At this point, the practical meaning of the main kas commands is:

  • kas dump → inspect the resolved configuration
  • kas checkout → prepare repositories and build environment
  • kas build → prepare the environment and run the build
  • kas shell → prepare the environment and open an interactive shell

These commands are not unrelated tools. They represent different cut points in the same overall workflow.

Step 11 — Practical summary

A first kas workflow can therefore be summarized as:

  1. Clone the repository
  2. Inspect it with kas dump
  3. Prepare the environment with kas checkout
  4. Inspect generated configuration files
  5. Build with kas build
  6. Debug interactively with kas shell

This turns kas from a single command into an understandable workflow: resolve, prepare, inspect, build, and debug.

This reflects the intended use of kas: executing a defined configuration rather than manually preparing a build environment.

21. References



Cookies help us deliver our services. By using our services, you agree to our use of cookies.