·8 min read

Yocto Layer Architecture: What Goes Where (And What to Delete)

YoctoEmbedded LinuxBSPBitBakeLayer Architecture

Ask a team to show you their Yocto layers and you'll learn more about their next two years than any roadmap document will tell you. Layers are how Yocto scales — and how it rots. When the structure is right, a Yocto upgrade is a week of work. When it's wrong, every change touches everything, and the upgrade becomes a rewrite nobody schedules.

This is the architecture we recommend to every team we work with: what belongs in each layer, what to keep out, and the anti-patterns that make platforms unmaintainable.

The three questions every layer should answer

A layer is a boundary of responsibility. Before adding anything, it should be able to answer: what does this layer own, what does it depend on, and which Yocto releases does it support (LAYERSERIES_COMPAT)? If a layer can't answer all three, it's not a layer — it's a junk drawer.

The structure that works

The BSP layer: hardware, nothing else

Your board support package layer owns the machine definitions (conf/machine/), the kernel and bootloader recipes, and the device trees. Nothing about your product's behavior lives here. The test: could you drop this layer onto a different product using the same board? If not, application logic has leaked into the hardware layer.

Vendor BSPs (the ones from your silicon supplier) are inputs, not foundations. Integrate them, pin them to a commit, and resist forking them. A forked vendor layer is a layer you now maintain forever, including every security patch.

The distro layer: policy, not packages

Your distro configuration (conf/distro/) is where product policy lives: DISTRO_FEATURES, the init system, package management choices, security flags. If a decision would change between two products on the same board, it belongs here, not in the BSP layer and not — this is the common one — in local.conf.

local.conf is a developer's scratch space. The moment a setting in local.conf is required to build the product, it has escaped version control. Product defaults belong in distro and machine configs; shared templates belong in TEMPLATECONF so every new build directory starts from the same checked-in baseline.

The application layer: your product

Your application recipes, your image recipes, and your product-specific configuration. Image recipes deserve emphasis: an image is a product definition, and it should be assembled from package groups you control — not by reaching into another layer's variables and hoping.

The bbappend discipline

.bbappend files are surgical instruments that teams use as duct tape. Rules that keep them healthy:

  • Append narrowly. A bbappend should do one thing: add a patch, adjust a configure option, extend FILESEXTRAPATHS. If your bbappend redefines large parts of the recipe, you don't have a configuration — you have a fork with extra steps.
  • Wildcards rot. Version-agnostic %.bbappend files apply silently to recipes they were never tested against. Version your appends, and let the build fail loudly when the upstream recipe moves.
  • Audit them. bitbake-layers show-appends lists every append in your build. If nobody can explain one, that's your cleanup backlog, in order.

Priority is not importance

The most misunderstood number in Yocto is layer priority. BBFILE_PRIORITY decides one thing: when two layers provide the same recipe at the same version, which one wins. It is not a ranking of trust or importance, and inflating a layer's priority to win an argument is how builds become dependent on accidents. When you need a specific version, say so explicitly with PREFERRED_VERSION or PREFERRED_PROVIDER — intent beats precedence.

Companion commands worth knowing: bitbake-layers show-layers (what's in the build and at what priority), bitbake-layers show-overlayed (where recipes shadow each other — a classic source of "my change did nothing"), and the yocto-check-layer script, which validates that your layer passes the Yocto Project's own compatibility checks.

Pinning: the architecture below the architecture

Layer structure stops mattering if the layers themselves float. Pin every layer to a commit — whether you manage that with kas, repo, git submodules, or a checked-in manifest. A build that can't name the exact commit of every input can't be reproduced, audited, or patched with confidence (we covered the reproducibility side in why your Yocto build isn't reproducible).

The cleanup backlog, in order

  1. List your layers and their declared dependencies. Delete the ones nobody can explain.
  2. Move product policy out of local.conf into distro/machine config under version control.
  3. Audit bbappends; version them; delete the ones fixing problems that no longer exist.
  4. Un-shadow overlayed recipes until each recipe has exactly one obvious home.
  5. Pin every layer to a commit and record it in the build.

None of this requires a rewrite. It requires an afternoon with bitbake-layers and the discipline to move one thing at a time. The payoff compounds: upgrades get smaller, new boards get cheaper to support, and the platform stops being a person and starts being a system.

Layer structure is the first thing we examine in a Yocto Build Health Check — along with reproducibility, image composition, and your update strategy. If your layers have become a junk drawer, book a free scoping call and we'll tell you honestly what it would take to clean them up.

Shipping an industrial Linux device?

We build the custom Yocto OS, AWS IoT onboarding, and update path beneath it — on your board or one we source. Start with a one-week audit and a fixed-price quote.