4. Step 4 — Get built and tested on the target platforms#

What it unlocks

Target-platform builds & tests — Your module is actually compiled and tested by the pipelines — built for and deployed to every target platform (Linux x86_64, QNX, AutoSD, EBcLfSA aarch64), offered in the interactive CLI, and exercised by CI. This is the rung that turns a library into something that runs inside the integration images.

The integration provides build definitions for four target images, each built and tested by its own gating CI job — it does not distribute ready-to-flash images; you build them yourself from these definitions. The table lists the platforms, the image target, the runner used to execute it, and the per-platform CI check.

Table 4.1 Supported target platforms#

Platform

Arch

Image

Runner

Build & test workflow

Linux

x86_64

images/linux_x86_64

Docker (runners/docker_x86_64)

build_and_test_linux.yml

QNX 8

x86_64

images/qnx_x86_64

QEMU (runners/qemu_x86_64)

build_and_test_qnx.yml

Red Hat AutoSD

x86_64

images/autosd

Docker (runners/docker_x86_64)

build_and_test_autosd.yml

EB corbos Linux (Safety Apps)

aarch64

images/ebclfsa_aarch64

QEMU (runners/qemu_aarch64)

build_and_test_ebclfsa.yml

Note

The EB corbos Safety Applications image is special: it runs a high-integrity application demo under additional constraints. Read images/ebclfsa_aarch64/README.md before targeting it.

4.1. Run any image locally in QEMU#

Every image exposes a :run target that boots it in an emulator, so you can try your module on the real target without hardware:

bazel run //images/linux_x86_64:run
bazel run //images/qnx_x86_64:run
bazel run //images/autosd:run
bazel run //images/ebclfsa_aarch64:run

The QNX and aarch64 images boot under QEMU, which needs a one-time host setup (TUN device, bridge helper, libvirt network). Follow the QEMU runner how-to in runners/qemu_x86_64/README.md before the first run.

4.2. Two ways to get your module onto the images#

There are two ways to make your binary part of the images:

  • As a showcase (recommended). Bundle your binary once into the aggregate //showcases package; it is then deployed into every image automatically — one change covers all four platforms, and the binary is also offered in the interactive CLI. See Add a runtime showcase below.

  • Directly into each image. Wire the binary into each image’s build description by hand. This is per-image work that you repeat four times (once per image) and is only needed for components that are not run as a CLI showcase — typically a daemon. The datarouter is integrated this way; see how the QNX image does it in images/qnx_x86_64/build/BUILD (the datarouter source and the DATAROUTER_PATH mapping). See Add a binary directly to an image below. Prefer the showcase route unless you have a reason not to.

4.3. Add a runtime showcase#

A showcase is the vehicle that gets your module onto the platforms: you bundle a runnable binary, and the aggregate //showcases package is deployed into every image automatically. You do this once — there is no per-platform work.

There are two patterns under showcases/:

1. Define the bundle. Add a score_pkg_bundle target. To re-use a binary that lives in your module:

load("//bazel_common:bundlers.bzl", "score_pkg_bundle")

score_pkg_bundle(
    name = "my_module",
    bins = ["@score_my_module//examples:my_example"],
    config_data = ["//showcases/standalone:my_module.score.json"],
    package_dir = "standalone",
)

2. Add a CLI descriptor. Create a *.score.json next to the bundle. The CLI auto-discovers every *.score.json deployed under /showcases and offers it in the interactive menu, so no code change to the CLI is required:

{
    "name": "My Module Example",
    "description": "Demonstrates my_module at runtime",
    "apps": [
        {
            "path": "/showcases/bin/my_example",
            "args": [],
            "env": {},
            "dir": "/showcases/data/my_module"
        }
    ]
}

3. Register the bundle in the top-level showcase package. Add your bundle to the aggregate score_pkg_bundle in showcases/BUILD so it is packaged into the images:

score_pkg_bundle(
    name = "showcases",
    bins = ["//showcases/cli"],
    other_package_files = [
        "//showcases/standalone:comm_pkg_files",
        # ...
        "//showcases/standalone:my_module_pkg_files",
    ],
    package_dir = "showcases",
)

Once your bundle is part of //showcases, it is reachable from //images/<platform>:image and is therefore built by every platform CI job automatically.

4.4. Add a binary directly to an image#

If your component is not a CLI showcase — for example a background daemon that must always be present — you wire it straight into each image’s build description instead. Unlike the showcase route, this is per-image work: you repeat it for every image you target (Linux, QNX, AutoSD, EBcLfSA).

The reference example is the datarouter. In the QNX image it is added as a source of the image target and exposed to the image’s build description via a location mapping, then placed into the filesystem by system.build:

# images/qnx_x86_64/build/BUILD
qnx_ifs(
    name = "init",
    srcs = [
        # ...
        "//showcases",
        "@score_logging//score/datarouter",
        "//feature_integration_tests/configs/datarouter:etc_configs",
    ],
    ext_repo_maping = {
        "BUNDLE_PATH": "$(location //showcases:showcases)",
        "DATAROUTER_PATH": "$(location @score_logging//score/datarouter:datarouter)",
    },
)

See images/qnx_x86_64/build/BUILD and the matching deployment lines in images/qnx_x86_64/build/system.build for the full picture, and repeat the equivalent wiring in the other images you need (images/linux_x86_64, images/autosd, images/ebclfsa_aarch64).

If your module simply cannot run on a given platform, exclude its targets via metadata.exclude_test_targets / metadata.extra_test_config in known_good.json (Step 1) rather than editing the workflow.