Optimize/optimize cfbox #34
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| # ── Native build + test ─────────────────────────────────────── | |
| native: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake g++-13 | |
| - name: Configure (Debug) | |
| run: cmake -B build -DCMAKE_CXX_COMPILER=g++-13 | |
| - name: Build | |
| run: cmake --build build -j $(nproc) | |
| - name: Unit tests | |
| run: ctest --test-dir build --output-on-failure --verbose -j $(nproc) | |
| - name: Integration tests | |
| run: bash tests/integration/run_all.sh | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: native-test-results | |
| path: build/Testing/ | |
| # ── Release build with size report ─────────────────────────── | |
| release-size: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake g++-13 | |
| - name: Configure (Release, -Os) | |
| run: > | |
| cmake -B build-release | |
| -DCMAKE_BUILD_TYPE=Release | |
| -DCMAKE_CXX_COMPILER=g++-13 | |
| -DCFBOX_OPTIMIZE_FOR_SIZE=ON | |
| - name: Build | |
| run: cmake --build build-release -j $(nproc) | |
| - name: Measure binary size | |
| run: | | |
| echo "=== -Os Release (dynamic) ===" | |
| size build-release/cfbox | |
| strip -o /tmp/cfbox-stripped build-release/cfbox | |
| echo "Stripped size: $(wc -c < /tmp/cfbox-stripped) bytes" | |
| - name: Upload release binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cfbox-x86_64-release | |
| path: /tmp/cfbox-stripped | |
| # ── Cross-compilation (aarch64 + armhf) ────────────────────── | |
| cross-compile: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - target: aarch64 | |
| toolchain: Toolchain-aarch64.cmake | |
| compiler_pkg: gcc-aarch64-linux-gnu g++-aarch64-linux-gnu | |
| strip: aarch64-linux-gnu-strip | |
| - target: armhf | |
| toolchain: Toolchain-armhf.cmake | |
| compiler_pkg: "" | |
| strip: arm-none-linux-gnueabihf-strip | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install cross-compiler (aarch64) | |
| if: matrix.target == 'aarch64' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y cmake ${{ matrix.compiler_pkg }} | |
| - name: Install cross-compiler (armhf) | |
| if: matrix.target == 'armhf' | |
| run: | | |
| curl -L -o /tmp/arm-toolchain.tar.xz \ | |
| https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz | |
| sudo tar -xJf /tmp/arm-toolchain.tar.xz -C /opt | |
| sudo ln -s /opt/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf /opt/arm-gnu-toolchain | |
| echo "/opt/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf/bin" >> "$GITHUB_PATH" | |
| - name: Cross-compile (dynamic, -Os) | |
| run: | | |
| cmake -B build-${{ matrix.target }} \ | |
| -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/${{ matrix.toolchain }} \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCFBOX_OPTIMIZE_FOR_SIZE=ON | |
| cmake --build build-${{ matrix.target }} -j $(nproc) | |
| - name: Verify target binary | |
| run: | | |
| file build-${{ matrix.target }}/cfbox | |
| size build-${{ matrix.target }}/cfbox | |
| ${{ matrix.strip }} -o /tmp/cfbox-${{ matrix.target }}-stripped build-${{ matrix.target }}/cfbox | |
| echo "Stripped size: $(wc -c < /tmp/cfbox-${{ matrix.target }}-stripped) bytes" | |
| - name: Cross-compile (static) | |
| run: | | |
| cmake -B build-${{ matrix.target }}-static \ | |
| -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain/${{ matrix.toolchain }} \ | |
| -DCMAKE_BUILD_TYPE=Release \ | |
| -DCFBOX_OPTIMIZE_FOR_SIZE=ON \ | |
| -DCFBOX_STATIC_LINK=ON | |
| cmake --build build-${{ matrix.target }}-static -j $(nproc) | |
| - name: Verify static binary | |
| run: | | |
| file build-${{ matrix.target }}-static/cfbox | |
| size build-${{ matrix.target }}-static/cfbox | |
| - name: Upload static binary | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cfbox-${{ matrix.target }}-static | |
| path: build-${{ matrix.target }}-static/cfbox | |
| # ── QEMU user-mode emulation tests ────────────────────────────── | |
| qemu-user-test: | |
| needs: cross-compile | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| target: [aarch64, armhf] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install QEMU user-mode | |
| run: sudo apt-get update && sudo apt-get install -y qemu-user-static | |
| - name: Download static binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cfbox-${{ matrix.target }}-static | |
| path: build-${{ matrix.target }}-static | |
| - name: Make binary executable | |
| run: chmod +x build-${{ matrix.target }}-static/cfbox | |
| - name: Smoke test | |
| run: | | |
| if [[ "${{ matrix.target }}" == "armhf" ]]; then | |
| QEMU_BIN=qemu-arm-static | |
| else | |
| QEMU_BIN=qemu-${{ matrix.target }}-static | |
| fi | |
| $QEMU_BIN build-${{ matrix.target }}-static/cfbox --list | |
| $QEMU_BIN build-${{ matrix.target }}-static/cfbox echo "Hello from ${{ matrix.target }}" | |
| - name: Integration tests under QEMU | |
| run: | | |
| if [[ "${{ matrix.target }}" == "armhf" ]]; then | |
| QEMU_BIN=qemu-arm-static | |
| else | |
| QEMU_BIN=qemu-${{ matrix.target }}-static | |
| fi | |
| # Create a wrapper script so test scripts work without modification | |
| wrapper="$(mktemp /tmp/cfbox-qemu-wrapper-XXXXXX.sh)" | |
| echo "#!/bin/sh" > "$wrapper" | |
| echo "exec $QEMU_BIN $(pwd)/build-${{ matrix.target }}-static/cfbox \"\$@\"" >> "$wrapper" | |
| chmod +x "$wrapper" | |
| CFBOX="$wrapper" bash tests/integration/run_all.sh | |
| # ── QEMU system-mode emulation tests ───── | |
| qemu-system-test: | |
| needs: cross-compile | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| target: [aarch64, armhf] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| submodules: true | |
| - name: Install dependencies | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y qemu-system-arm qemu-user-static cpio flex bison libelf-dev | |
| - name: Install aarch64 cross-compiler | |
| if: matrix.target == 'aarch64' | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-aarch64-linux-gnu | |
| - name: Install armhf cross-compiler | |
| if: matrix.target == 'armhf' | |
| run: | | |
| curl -L -o /tmp/arm-toolchain.tar.xz \ | |
| https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf.tar.xz | |
| sudo tar -xJf /tmp/arm-toolchain.tar.xz -C /opt | |
| sudo ln -s /opt/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf /opt/arm-gnu-toolchain | |
| echo "/opt/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-linux-gnueabihf/bin" >> "$GITHUB_PATH" | |
| - name: Download static binary | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cfbox-${{ matrix.target }}-static | |
| path: build-${{ matrix.target }}-static | |
| - name: Make binary executable | |
| run: chmod +x build-${{ matrix.target }}-static/cfbox | |
| - name: Determine kernel config | |
| id: kernel | |
| run: | | |
| if [[ "${{ matrix.target }}" == "aarch64" ]]; then | |
| echo "arch=arm64" >> "$GITHUB_OUTPUT" | |
| echo "image=arch/arm64/boot/Image" >> "$GITHUB_OUTPUT" | |
| echo "defconfig=allnoconfig" >> "$GITHUB_OUTPUT" | |
| echo "cross=aarch64-linux-gnu-" >> "$GITHUB_OUTPUT" | |
| echo "extra_config=configs/qemu-virt-aarch64.config" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "arch=arm" >> "$GITHUB_OUTPUT" | |
| echo "image=arch/arm/boot/zImage" >> "$GITHUB_OUTPUT" | |
| echo "defconfig=vexpress_defconfig" >> "$GITHUB_OUTPUT" | |
| echo "cross=arm-none-linux-gnueabihf-" >> "$GITHUB_OUTPUT" | |
| echo "extra_config=" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Restore Linux kernel cache | |
| id: cache-kernel | |
| uses: actions/cache/restore@v4 | |
| with: | |
| path: | | |
| third_party/linux/${{ steps.kernel.outputs.image }} | |
| third_party/linux/.config | |
| ${{ matrix.target == 'armhf' && 'third_party/linux/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb' || '' }} | |
| key: linux-kernel-${{ matrix.target }}-${{ hashFiles('third_party/linux/Makefile') }}-${{ steps.kernel.outputs.defconfig }} | |
| - name: Build Linux kernel | |
| if: steps.cache-kernel.outputs.cache-hit != 'true' | |
| run: | | |
| cd third_party/linux | |
| make ARCH=${{ steps.kernel.outputs.arch }} CROSS_COMPILE=${{ steps.kernel.outputs.cross }} ${{ steps.kernel.outputs.defconfig }} | |
| if [[ -n "${{ steps.kernel.outputs.extra_config }}" ]]; then | |
| while IFS='=' read -r key val; do | |
| [[ -z "$key" || "$key" =~ ^# ]] && continue | |
| ./scripts/config --enable "$key" | |
| done < "${{ github.workspace }}/${{ steps.kernel.outputs.extra_config }}" | |
| make ARCH=${{ steps.kernel.outputs.arch }} CROSS_COMPILE=${{ steps.kernel.outputs.cross }} olddefconfig | |
| fi | |
| make ARCH=${{ steps.kernel.outputs.arch }} CROSS_COMPILE=${{ steps.kernel.outputs.cross }} -j$(nproc) | |
| - name: Save Linux kernel cache | |
| if: steps.cache-kernel.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@v4 | |
| with: | |
| path: | | |
| third_party/linux/${{ steps.kernel.outputs.image }} | |
| third_party/linux/.config | |
| ${{ matrix.target == 'armhf' && 'third_party/linux/arch/arm/boot/dts/arm/vexpress-v2p-ca9.dtb' || '' }} | |
| key: linux-kernel-${{ matrix.target }}-${{ hashFiles('third_party/linux/Makefile') }}-${{ steps.kernel.outputs.defconfig }} | |
| - name: Build initramfs (CFBox only, no busybox) | |
| run: | | |
| bash scripts/build_initramfs.sh \ | |
| --arch ${{ matrix.target }} \ | |
| --cfbox build-${{ matrix.target }}-static/cfbox \ | |
| --output build/${{ matrix.target }}-initramfs.cpio | |
| - name: Run QEMU system-mode test | |
| run: | | |
| bash scripts/qemu_system_test.sh \ | |
| --arch ${{ matrix.target }} \ | |
| --kernel third_party/linux/${{ steps.kernel.outputs.image }} \ | |
| --initramfs build/${{ matrix.target }}-initramfs.cpio \ | |
| --timeout 120 |