Skip to content

Development Environment Setup

This guide covers setting up the development environment for building ToloMEO images inside a devcontainer.


Table of Contents


This project provides a Dev Container for a consistent development environment using Docker and Visual Studio Code. It ensures all dependencies and build tools are properly configured, making your setup reproducible and portable.

Prerequisites

Ensure you have the following installed:

  1. Docker (Get Docker)
  2. Running with sufficient resources (16GB RAM recommended)

  3. Visual Studio Code (Download)

  4. With Dev Containers extension installed

  5. Access Credentials (if applicable)

  6. GitLab/Bitbucket token for private registries

Setup Instructions

1. Open the Devcontainer

  1. Open the project in VS Code
  2. When prompted, click Reopen in Container (or use Command Palette → Dev Containers: Reopen in Container)
  3. Wait for the container to build and start (first time takes 5-10 minutes)

2. Verify the Setup

After the container is running, verify your environment:

# Inside the devcontainer
kas --version

# Verify SSTATE_MIRRORS are reachable
curl -I https://reed-cache01.tolomeo.io/sstate-cache/
# Expected: HTTP/1.1 200 OK (or 301/302 redirect)

If all commands succeed, the development container and Yocto environment are correctly configured.

Devcontainer Benefits

  • Consistent environment: All developers share identical tools and dependencies
  • Pre-configured tools: kas, bitbake, and Yocto dependencies ready to use
  • No host pollution: Build tools isolated in container
  • Remote sstate mirrors: Builds automatically pull cached artifacts from the project mirror and the Yocto public mirror

Sstate Cache Mirror

Yocto uses a shared state (sstate) cache to dramatically speed up incremental builds by reusing previously built components.

How It Works

By default, kas/common.yml configures two remote SSTATE_MIRRORS that BitBake queries before rebuilding any task:

SSTATE_MIRRORS ?= "file://.* https://reed-cache01.tolomeo.io/sstate-cache/PATH;downloads=PATH \
                   file://.* http://sstate.yoctoproject.org/all/PATH;downloadfilename=PATH \
                   "
  • reed-cache01.tolomeo.io — project-specific mirror with ToloMEO build artifacts
  • sstate.yoctoproject.org — public Yocto mirror as a fallback

No local setup is required. BitBake resolves cache hits automatically over HTTPS.

Mirror Configuration

The mirrors are defined in kas/common.yml under local_conf_header. To override them (e.g., to point to a different server), edit the SSTATE_MIRRORS value in that file.

Learn more: Yocto Shared State Cache Documentation


Using External Cache Directories (Optional)

If you have a shared DL_DIR or SSTATE_DIR available on paths outside the devcontainer (e.g., on a network share or a central build server mounted on your host), you can bind-mount those paths into the container and configure kas to use them directly instead of the remote HTTP mirrors.

When to Use This

  • You have a local or LAN-accessible sstate cache that is faster than the remote mirrors
  • You want downloads to persist across container rebuilds without relying on network fetches
  • You are running a dedicated build server with a pre-populated cache

Step 1: Add Bind Mounts to the Devcontainer

Edit .devcontainer/devcontainer.json and uncomment (or add) the two mount entries, replacing the source paths with the actual host-side paths to your cache directories:

"mounts": [
  // ... existing mounts (ssh, config) ...
  {
    "source": "/path/on/host/yocto-downloads",
    "target": "/workspaces/yocto/downloads",
    "type": "bind"
  },
  {
    "source": "/path/on/host/yocto-sstate-cache",
    "target": "/workspaces/yocto/sstate-cache",
    "type": "bind"
  }
]

Note: Replace /path/on/host/... with the absolute paths on your host machine. Rebuild the devcontainer after saving (Dev Containers: Rebuild Container).

Step 2: Enable DL_DIR and SSTATE_DIR in kas

Edit kas/common.yml and uncomment the DL_DIR and SSTATE_DIR lines, making sure the paths match the target values set in the devcontainer mounts:

# Central downloads directory (shared across builds)
DL_DIR ?= "/workspaces/yocto/downloads"

# Central sstate cache directory
SSTATE_DIR ?= "/workspaces/yocto/sstate-cache"

You may also comment out SSTATE_MIRRORS if you want BitBake to use only the local directory and skip the remote mirrors:

# SSTATE_MIRRORS ?= "..."

Important: DL_DIR and SSTATE_DIR take precedence over SSTATE_MIRRORS for artifacts that are already present locally. Leaving SSTATE_MIRRORS active as a fallback is safe and recommended if the local cache is only partially populated.

Local HTTP Sstate Server (Optional Add-on)

If you want to expose your locally mounted sstate directory as an HTTP mirror (for example, to share it with other containers or machines on the same network), the devcontainer includes a helper script:

# Start the local HTTP sstate server on port 8000
./scripts/start-sstate-server.sh

# Check server status
ps aux | grep "python3 -m http.server"

# View logs
tail -f /tmp/sstate-server.log

# Stop the server
kill $(cat /tmp/sstate-server.pid)

Then add the local mirror to SSTATE_MIRRORS in kas/common.yml:

SSTATE_MIRRORS ?= "file://.* http://localhost:8000/sstate-cache/PATH;downloadfilename=PATH"

Server quick reference:

Item Value
Port 8000
Log file /tmp/sstate-server.log
PID file /tmp/sstate-server.pid

Port conflicts

If port 8000 is already in use, change SERVER_PORT in .devcontainer/start-sstate-server.sh and update the URL in SSTATE_MIRRORS accordingly:

# Find and kill the process using port 8000
sudo lsof -ti:8000 | xargs kill -9

Performance Optimization

Tuning

You can add the following configuration to your kas target to optimize build performance in a portable and predictable way:

# In kas/<target>.yml
local_conf_header:
  build-tasks: |-
    BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
    BB_NUMBER_PARSE_THREADS ?= "${@max(1, oe.utils.cpu_count() // 2)}"
    PARALLEL_MAKE ?= "-j ${@int(oe.utils.cpu_count() * 1.25)}"
    PARALLEL_MAKEINST ?= "${PARALLEL_MAKE}"

These values work well across developer machines, CI systems, and dedicated build servers without requiring machine-specific tuning.


Tuning Guidelines

Adjust these variables based on your system capabilities:

  • BB_NUMBER_THREADS: Number of parallel BitBake tasks

  • Recommended: CPU cores

  • Example: 8-core system → BB_NUMBER_THREADS="8"

  • PARALLEL_MAKE: Compilation parallelism

  • -j N: CPU cores × 1.2–1.5

  • Example: 8-core system → PARALLEL_MAKE="-j 10"

Other build optimization tips:

  • SSD storage: Use SSD/NVMe for the build directory
  • Memory: 16 GB+ RAM recommended

Troubleshooting

Quick Troubleshooting Guide

Build is slow? → Check sstate mirror reachability Container won't start? → Check Docker resources Out of space?Clean old builds Network errors? → Check connectivity Errno 1 Operation not permitted on Ubuntu 24.04?Disable unprivileged user namespace restriction


Devcontainer Problems

Container won't start

Symptoms:

  • Container fails to build or crashes on startup
  • Docker errors in VS Code

Solutions:

  1. Ensure Docker is running and has sufficient resources
  2. Check available disk space (minimum 50GB required)
  3. Restart Docker service:
sudo systemctl restart docker

Slow builds

Symptoms:

  • Builds take much longer than expected
  • Tasks are being rebuilt unnecessarily

Solutions:

  1. Verify the remote sstate mirrors are reachable:
curl -I https://reed-cache01.tolomeo.io/sstate-cache/
curl -I http://sstate.yoctoproject.org/all/
  1. Check internet connectivity and firewall settings (outbound HTTPS must be allowed)

  2. If using external cache directories, verify the bind mounts are active inside the container:

ls /workspaces/yocto/downloads
ls /workspaces/yocto/sstate-cache

Build Issues

Out of disk space

Symptoms:

  • Build fails with "No space left on device"
  • Disk usage above 90%

Solutions:

# Check disk space
df -h

# Clean old builds
rm -rf tmp-*

# Clear downloads cache (only if necessary)
rm -rf yocto-downloads/*

# Clear sstate cache (last resort - will slow next build)
rm -rf yocto-sstate/*

Network issues

Symptoms:

  • Fetcher failures
  • Unable to download sources

Solutions:

  1. Check internet connectivity
  2. Verify firewall settings allow outbound connections
  3. Check proxy configuration if behind corporate firewall
  4. Verify access tokens for private repositories are valid

Cache corruption

Symptoms:

  • Inconsistent build results
  • Unexpected errors during builds
  • Tasks fail with checksum mismatches

Solutions:

# Clear sstate cache
rm -rf yocto-sstate/*

# Clear downloads (if checksums are wrong)
rm -rf yocto-downloads/*

BitBake fails with Errno 1 Operation not permitted (Ubuntu 24.04 host)

Symptoms:

  • BitBake fails with Errno 1 - Operation not permitted
  • Error originates from bitbake/lib/bb/utils.py disable_network attempting to write to /proc/self/uid_map
  • Only occurs on an Ubuntu 24.04 host machine running builds via the devcontainer

Cause:

Ubuntu 24.04 restricts unprivileged user namespaces by default as a security improvement — see the Ubuntu 24.04 Release Notes — Security Improvements. Because the devcontainer shares the host kernel, this restriction applies to BitBake running inside the container. This is a known issue in the Yocto community.

Solutions:

Both workarounds must be applied on the host machine, not inside the devcontainer. They require sudo and reduce the security isolation introduced in Ubuntu 24.04.

Temporary (lost on reboot):

echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns

Persistent (survives reboots):

Create /etc/sysctl.d/60-apparmor-namespace.conf with the following content, then reboot:

kernel.apparmor_restrict_unprivileged_userns=0

Performance Issues

Long build times

Causes:

  • Sstate mirrors unreachable or slow
  • Insufficient parallelization
  • Slow storage (HDD instead of SSD)

Solutions:

  1. Verify sstate mirrors are reachable (see above)
  2. Increase BB_NUMBER_THREADS and PARALLEL_MAKE:
export BB_NUMBER_THREADS="$(nproc)"
export PARALLEL_MAKE="-j $(($(nproc) * 2)) -l $(nproc)"
  1. Use faster storage (SSD recommended)
  2. Ensure Docker has sufficient memory (16GB recommended)

System becomes unresponsive

Symptoms:

  • System hangs during builds
  • High CPU/memory usage

Solutions:

  1. Reduce parallelization:
export BB_NUMBER_THREADS="2"
export PARALLEL_MAKE="-j 4 -l 4"
  1. Increase system memory or Docker memory limit
  2. Monitor system load:
watch -n 1 uptime
htop

Getting Help

If you encounter issues not covered here:

  1. Check kas documentation
  2. Review Yocto Project documentation
  3. Search existing issues in the project repository
  4. Create a new issue using the appropriate template:
  5. Bug reports: Use the bug issue template
  6. Feature requests: Use the feature issue template
  7. Documentation improvements: Use the documentation enhancement template

Include the following information: - Detailed error logs - System information (OS, memory, disk space) - Build target and machine configuration - Steps to reproduce the issue