ci/cxx: Add out-of-tree build CI test.

Introduce a new CI test to validate out-of-tree builds
and prevent regressions in the `make export` workflow.
Specifically, this change adds `test-oot-build.sh` that:
* Builds NuttX using a selected configuration.
* Runs `make export` to generate the export package.
* Copies the `nuttx-export` to the OOT build project.
* Verifies that compilation and linking succeed.

Signed-off-by: trns1997 <trns1997@gmail.com>
This commit is contained in:
trns1997 2025-09-14 15:41:01 +02:00 committed by Xiang Xiao
parent a3e63c44dd
commit d7b2df6d85
4 changed files with 244 additions and 0 deletions

View file

@ -201,6 +201,51 @@ jobs:
path: buildartifacts/
continue-on-error: true
# Test the out-of-tree build
OOT-Build:
needs: Linux
runs-on: ubuntu-latest
env:
DOCKER_BUILDKIT: 1
steps:
- name: Download Source Artifact
uses: actions/download-artifact@v5
with:
name: source-bundle
path: .
- name: Extract sources
run: tar zxf sources.tar.gz
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Export NuttX Repo SHA
run: echo "nuttx_sha=`git -C sources/nuttx rev-parse HEAD`" >> $GITHUB_ENV
- name: Run Out-of-Tree Build Test
uses: ./sources/nuttx/.github/actions/ci-container
env:
BLOBDIR: /tools/blobs
with:
run: |
echo "::add-matcher::sources/nuttx/.github/gcc.json"
git config --global --add safe.directory /github/workspace/sources/nuttx
git config --global --add safe.directory /github/workspace/sources/apps
cd sources/nuttx
./tools/ci/cibuild-oot.sh
- uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: oot-build-artifacts
path: sources/apps/testing/cxx-oot-build
continue-on-error: true
# Select the macOS Builds based on PR Arch Label
macOS-Arch:
uses: apache/nuttx/.github/workflows/arch.yml@master

View file

@ -0,0 +1,75 @@
========================================
``cxx-oot-build`` Out-of-Tree Build Test
========================================
The ``cxx-oot-build`` test automates building an **Out-of-Tree (OOT)** NuttX
project using a NuttX export tarball. Its primary purpose is to validate that
NuttX can be built outside of the main source tree and to prevent regressions
in the build process for C++ projects.
**Important:** This test uses a specialized defconfig that is **not functional**
for running actual applications. It is intended purely for CI/build
verification. Functional OOT projects should be configured according to
the instructions in :ref:`cpp_cmake`.
The test script is located at:
- ``tools/ci/cibuild-oot.sh``
### Out-of-Tree App Content
The source content for this OOT test can be found in:
- ``apps/testing/cxx-oot-build``
Its structure provides a basic skeleton for building a C++ NuttX application:
.. code-block:: text
testing/cxx-oot-build
├── CMakeLists.txt
├── include
│ └── HelloWorld.hpp
└── src
├── HelloWorld.cpp
└── main.cpp
This minimal structure includes:
- `CMakeLists.txt` - Build instructions for the OOT C++ project
- `include/HelloWorld.hpp` - Example header file
- `src/HelloWorld.cpp` - Example class implementation
- `src/main.cpp` - Entry point for the test application
### How to Run the Test
Execute the test script from the NuttX CI tools directory:
cd ${NUTTX_PATH}/tools/ci
./cibuild-oot.sh
The script performs the following steps:
1. Configures NuttX for the ``cxx-oot-build`` board profile
2. Builds an export tarball of NuttX
3. Prepares the Out-of-Tree project by extracting the tarball
4. Builds the OOT project using CMake
5. Verifies that the output binaries ``oot`` and ``oot.bin`` exist
### Expected Output
On success, you should see:
✅ SUCCESS: OOT build completed. Output:
-rwxrwxr-x 1 <user> <group> 94K <date> /path/to/oot
-rwxrwxr-x 1 <user> <group> 46K <date> /path/to/oot.bin
If any step fails, the script will exit immediately with an error message.
### Notes
- No additional configuration options are required for this test. The
``cxx-oot-build`` defconfig is preconfigured to build correctly but is
**not suitable for running applications**.
- For functional OOT builds, please follow the procedure documented in
:doc:`here </guides/cpp_cmake>`.

View file

@ -0,0 +1,48 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_FPU is not set
# CONFIG_ARCH_LEDS is not set
# CONFIG_DISABLE_OS_API is not set
# CONFIG_SYSTEM_DD is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="stm32f4discovery"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y
CONFIG_ARCH_CHIP="stm32"
CONFIG_ARCH_CHIP_STM32=y
CONFIG_ARCH_CHIP_STM32F407VG=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LATE_INITIALIZE=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_CXX_EXCEPTION=y
CONFIG_CXX_STANDARD="c++17"
CONFIG_DRVR_MKRD=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_INIT_NONE=y
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBCXXTOOLCHAIN=y
CONFIG_LINE_MAX=64
CONFIG_MM_REGIONS=2
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_STM32_JTAG_SW_ENABLE=y
CONFIG_STM32_PWR=y
CONFIG_STM32_SPI1=y
CONFIG_STM32_USART2=y
CONFIG_USART2_RXBUFSIZE=128
CONFIG_USART2_SERIAL_CONSOLE=y
CONFIG_USART2_TXBUFSIZE=128

76
tools/ci/cibuild-oot.sh Executable file
View file

@ -0,0 +1,76 @@
#!/usr/bin/env bash
############################################################################
# tools/ci/cibuild-oot.sh
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
set -euo pipefail
CID=$(cd "$(dirname "$0")" && pwd)
CIWORKSPACE=$(cd "${CID}"/../../../ && pwd -P)
NUTTX_PATH=${CIWORKSPACE}/nuttx
APP_PATH=${CIWORKSPACE}/apps
# === CONFIGURATION ===
# Allow overriding from environment for CI
EXPORT_CONFIG=${EXPORT_CONFIG:-"stm32f4discovery:cxx-oot-build"}
OOT_SRC=${OOT_SRC:-"$APP_PATH/testing/cxx-oot-build"}
BUILD_DIR=${BUILD_DIR:-"$OOT_SRC/build"}
# Place ourselves in the nuttx dir
cd $NUTTX_PATH
echo "=== [1/5] Configuring NuttX Export ($EXPORT_CONFIG) ==="
./tools/configure.sh -E -l "$EXPORT_CONFIG"
echo "=== [2/5] Building Export Tarball ==="
make -j"$(nproc)" export
EXPORT_TARBALL=$(find . -maxdepth 1 -type f -name "nuttx-export-*.tar.gz" | sort | tail -n 1)
if [[ -z "$EXPORT_TARBALL" ]]; then
echo "❌ ERROR: No export tarball found"
exit 1
fi
echo "=== [3/5] Preparing Out of Tree (OOT) Project ==="
rm -rf "$OOT_SRC"/nuttx-export-*
tar -xzf "$EXPORT_TARBALL" -C "$OOT_SRC"
TOOLCHAIN_FILE=$(find "$OOT_SRC" -type f -path "*/scripts/toolchain.cmake" | head -n 1)
if [[ ! -f "$TOOLCHAIN_FILE" ]]; then
echo "❌ ERROR: toolchain.cmake not found after export"
exit 1
fi
echo "=== [4/5] Building OOT ==="
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
cmake .. -DCMAKE_TOOLCHAIN_FILE="$TOOLCHAIN_FILE" -DBUILD_OOTCPP=ON
make -j"$(nproc)"
echo "=== [5/5] Verifying Output ==="
if [[ ! -f "$BUILD_DIR/oot" || ! -f "$BUILD_DIR/oot.bin" ]]; then
echo "❌ ERROR: oot or oot.bin not found in $BUILD_DIR"
exit 1
fi
echo "✅ SUCCESS: OOT build completed. Output:"
ls -lh "$BUILD_DIR"/oot*