Skip to content

Build & Release Cppcheck Binaries #25

Build & Release Cppcheck Binaries

Build & Release Cppcheck Binaries #25

# .github/workflows/build-cppcheck.yml
name: Build & Release Cppcheck Binaries
on:
workflow_dispatch:
permissions:
contents: write
jobs:
get-version:
name: Get Cppcheck Version
runs-on: ubuntu-latest
outputs:
version: ${{ steps.get_version.outputs.tag }}
env:
CPPCHECK_REPO: https://github.com/danmar/cppcheck.git
steps:
- name: Get latest Cppcheck tag
id: get_version
shell: bash
run: |
LATEST_TAG=$(git ls-remote --tags --sort="v:refname" ${{ env.CPPCHECK_REPO }} \
| awk -F/ '{print $NF}' \
| grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' \
| tail -n1)
echo "tag=${LATEST_TAG}" >> $GITHUB_OUTPUT
echo "Using Cppcheck version: ${LATEST_TAG}"
build:
name: Build Cppcheck (${{ matrix.artifact }})
needs: get-version
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
# ── Native GitHub-hosted runners ──────────────────────────────
- runner: ubuntu-latest
artifact: cppcheck-linux-x64
cross: false
- runner: ubuntu-24.04-arm
artifact: cppcheck-linux-arm64
cross: false
- runner: macos-15-intel
artifact: cppcheck-macos-x64
cross: false
- runner: macos-15
artifact: cppcheck-macos-arm64
cross: false
- runner: windows-latest
artifact: cppcheck-windows-x64
cross: false
# ── Cross-compiled on arm64 runner ─────────────────────────────
- runner: ubuntu-24.04-arm
artifact: cppcheck-linux-armv7
cross: true
cross_march: armv7-a -mfpu=vfpv3-d16
# ── QEMU-emulated (armv6 needs native sysroot) ─────────────────
- runner: ubuntu-latest
artifact: cppcheck-linux-armv6
qemu: true
qemu_arch: armv6
qemu_distro: bullseye
env:
CPPCHECK_REPO: https://github.com/danmar/cppcheck.git
CPPCHECK_VERSION: ${{ needs.get-version.outputs.version }}
steps:
- name: Checkout workflow repo
uses: actions/checkout@v4
# ── Dependencies: native Linux ──────────────────────────────────
- name: Install dependencies (Linux native)
if: runner.os == 'Linux' && matrix.cross == false && matrix.qemu != true
run: |
sudo apt-get update
sudo apt-get install -y git cmake g++ make libpcre3-dev
# ── Dependencies: cross-compile armhf on arm64 ─────────────────
- name: Install dependencies (Linux cross armhf)
if: matrix.cross == true
run: |
sudo dpkg --add-architecture armhf
sudo apt-get update
sudo apt-get install -y git cmake make crossbuild-essential-armhf libpcre3-dev:armhf
# ── Dependencies: macOS ─────────────────────────────────────────
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: |
brew update
brew install cmake pcre
# ── Dependencies + Build: Windows ───────────────────────────────
- name: Setup vcpkg (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
$vcpkgRoot = $env:VCPKG_INSTALLATION_ROOT
& "$vcpkgRoot\vcpkg.exe" install pcre:x64-windows-static --triplet x64-windows-static
echo "VCPKG_ROOT=$vcpkgRoot" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "VCPKG_TARGET_TRIPLET=x64-windows-static" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
# ── Clone ───────────────────────────────────────────────────────
- name: Clone Cppcheck at latest tag
if: matrix.qemu != true
run: |
git clone --depth 1 --branch "${{ env.CPPCHECK_VERSION }}" "${{ env.CPPCHECK_REPO }}" cppcheck-src
# ── Configure + Build: Unix native ──────────────────────────────
- name: Configure (Unix)
if: runner.os != 'Windows' && matrix.cross == false && matrix.qemu != true
working-directory: cppcheck-src
run: |
export CXXFLAGS="${CXXFLAGS} -O2"
export CPPFLAGS="${CPPFLAGS} -DNDEBUG"
export LDFLAGS="${LDFLAGS} -O2"
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_GUI=OFF \
-DHAVE_RULES=ON \
-DUSE_MATCHCOMPILER=yes \
-DFILESDIR=
- name: Configure (Windows)
if: runner.os == 'Windows'
working-directory: cppcheck-src
shell: pwsh
run: |
$env:CXXFLAGS = "$env:CXXFLAGS /O2"
$env:CPPFLAGS = "$env:CPPFLAGS /DNDEBUG"
$env:LDFLAGS = "$env:LDFLAGS /O2"
cmake -S . -B build `
-G "Visual Studio 17 2022" `
-A x64 `
-DCMAKE_BUILD_TYPE=Release `
-DCMAKE_TOOLCHAIN_FILE="${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET="${env:VCPKG_TARGET_TRIPLET}" `
-DBUILD_GUI=OFF `
-DHAVE_RULES=ON `
-DUSE_MATCHCOMPILER=yes `
-DFILESDIR=
- name: Build (Unix native)
if: runner.os != 'Windows' && matrix.cross == false && matrix.qemu != true
working-directory: cppcheck-src
run: cmake --build build --config Release --parallel
- name: Build (Windows)
if: runner.os == 'Windows'
working-directory: cppcheck-src
shell: pwsh
run: cmake --build build --config Release --parallel
# ── Collect binary: Unix native ──────────────────────────────────
- name: Collect binary (Unix native)
if: runner.os != 'Windows' && matrix.cross == false && matrix.qemu != true
working-directory: cppcheck-src
run: |
mkdir -p out
cp build/bin/cppcheck out/cppcheck
chmod +x out/cppcheck
cp -r cfg out/cfg
cp -r addons out/addons
cp -r platforms out/platforms
file out/cppcheck
- name: Verify binary architecture (Unix native)
if: runner.os != 'Windows' && matrix.cross == false && matrix.qemu != true
working-directory: cppcheck-src
run: |
INFO="$(file out/cppcheck)"
echo "$INFO"
case "${{ matrix.artifact }}" in
cppcheck-macos-x64) echo "$INFO" | grep -q 'x86_64' ;;
cppcheck-macos-arm64) echo "$INFO" | grep -q 'arm64' ;;
cppcheck-linux-x64) echo "$INFO" | grep -Eq 'x86-64|x86_64' ;;
cppcheck-linux-arm64) echo "$INFO" | grep -Eq 'aarch64|arm64' ;;
esac
- name: Collect binary (Windows)
if: runner.os == 'Windows'
working-directory: cppcheck-src
shell: pwsh
run: |
New-Item -ItemType Directory -Force -Path out
$binary = Get-ChildItem -Recurse -Filter "cppcheck.exe" build | Select-Object -First 1
if ($null -eq $binary) {
Write-Error "cppcheck.exe not found in build directory!"
exit 1
}
Write-Host "Found binary at: $($binary.FullName)"
Copy-Item $binary.FullName "out/cppcheck.exe"
Copy-Item -Recurse cfg out/cfg
Copy-Item -Recurse addons out/addons
Copy-Item -Recurse platforms out/platforms
# ── Cross-compile armhf (armv7) ─────────────────────────────────
- name: Configure (cross armhf)
if: matrix.cross == true
working-directory: cppcheck-src
run: |
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_SYSTEM_NAME=Linux \
-DCMAKE_SYSTEM_PROCESSOR=arm \
-DCMAKE_C_COMPILER=arm-linux-gnueabihf-gcc \
-DCMAKE_CXX_COMPILER=arm-linux-gnueabihf-g++ \
-DCMAKE_C_FLAGS="-march=${{ matrix.cross_march }} -O2 -DNDEBUG" \
-DCMAKE_CXX_FLAGS="-march=${{ matrix.cross_march }} -O2 -DNDEBUG" \
-DCMAKE_EXE_LINKER_FLAGS="-march=${{ matrix.cross_march }}" \
-DBUILD_GUI=OFF \
-DHAVE_RULES=ON \
-DUSE_MATCHCOMPILER=yes \
-DDISABLE_DMAKE=ON \
-DFILESDIR= \
$EXTRA_CMAKE_FLAGS
- name: Build (cross armhf)
if: matrix.cross == true
working-directory: cppcheck-src
run: cmake --build build --config Release --parallel
- name: Collect binary (cross armhf)
if: matrix.cross == true
working-directory: cppcheck-src
run: |
mkdir -p out
cp build/bin/cppcheck out/cppcheck
chmod +x out/cppcheck
cp -r cfg out/cfg
cp -r addons out/addons
cp -r platforms out/platforms
- name: Verify binary architecture (cross armhf)
if: matrix.cross == true
working-directory: cppcheck-src
run: |
file out/cppcheck
file out/cppcheck | grep -q 'ARM'
ARCH_TAG=$(arm-linux-gnueabihf-readelf -A out/cppcheck | grep 'Tag_CPU_arch:' | head -1 | awk '{print $2}')
echo "Tag_CPU_arch: ${ARCH_TAG}"
test "$ARCH_TAG" = "v7"
# ── QEMU build (armv6) ────────────────────────────────────────────
- name: Build in QEMU (armv6)
if: matrix.qemu == true
uses: uraimo/run-on-arch-action@v3
with:
arch: ${{ matrix.qemu_arch }}
distro: ${{ matrix.qemu_distro }}
githubToken: ${{ github.token }}
dockerRunArgs: --volume "${{ github.workspace }}:/workspace"
install: |
apt-get update -y
apt-get install -y git g++ make libpcre3-dev file python3 python3-pip
# Install newer CMake for armv6 (Bullseye has only 3.18.4, but we need 3.22+)
pip3 install cmake==3.22.6
run: |
cd /workspace
git clone --depth 1 --branch "${{ env.CPPCHECK_VERSION }}" "${{ env.CPPCHECK_REPO }}" cppcheck-src
cmake -S cppcheck-src -B cppcheck-src/build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_FLAGS="-O2 -DNDEBUG" \
-DCMAKE_CXX_FLAGS="-O2 -DNDEBUG" \
-DBUILD_GUI=OFF \
-DHAVE_RULES=ON \
-DUSE_MATCHCOMPILER=yes \
-DDISABLE_DMAKE=ON \
-DFILESDIR=
cmake --build cppcheck-src/build --config Release --parallel
mkdir -p cppcheck-src/out
cp cppcheck-src/build/bin/cppcheck cppcheck-src/out/cppcheck
chmod +x cppcheck-src/out/cppcheck
cp -r cppcheck-src/cfg cppcheck-src/out/cfg
cp -r cppcheck-src/addons cppcheck-src/out/addons
cp -r cppcheck-src/platforms cppcheck-src/out/platforms
file cppcheck-src/out/cppcheck
readelf -A cppcheck-src/out/cppcheck | grep 'Tag_CPU_arch:'
# ── Upload ────────────────────────────────────────────────────────
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: cppcheck-src/out/*
release:
name: Create Release
needs: [get-version, build]
runs-on: ubuntu-latest
steps:
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Package artifacts
run: |
for dir in cppcheck-linux-x64 cppcheck-linux-arm64 cppcheck-linux-armv7 cppcheck-linux-armv6 cppcheck-macos-x64 cppcheck-macos-arm64; do
chmod +x "artifacts/${dir}/cppcheck"
tar -czf "artifacts/${dir}.tar.gz" -C "artifacts/${dir}" .
done
cd artifacts/cppcheck-windows-x64 && zip -r ../cppcheck-windows-x64.zip . && cd ../..
- name: Create Release
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.get-version.outputs.version }}
name: Cppcheck ${{ needs.get-version.outputs.version }} Binaries
files: |
artifacts/cppcheck-linux-x64.tar.gz
artifacts/cppcheck-linux-arm64.tar.gz
artifacts/cppcheck-linux-armv7.tar.gz
artifacts/cppcheck-linux-armv6.tar.gz
artifacts/cppcheck-macos-x64.tar.gz
artifacts/cppcheck-macos-arm64.tar.gz
artifacts/cppcheck-windows-x64.zip
body: |
**Auto‑built Cppcheck ${{ needs.get-version.outputs.version }} portable binaries (with cfg & addons):**
| Archive | Arch | Method |
|---------|------|--------|
| `cppcheck-linux-x64.tar.gz` | Linux x86_64 | native |
| `cppcheck-linux-arm64.tar.gz` | Linux aarch64 | native (ubuntu-24.04-arm) |
| `cppcheck-linux-armv7.tar.gz` | Linux ARMv7 | cross-compile (arm64) |
| `cppcheck-linux-armv6.tar.gz` | Linux ARMv6 | QEMU |
| `cppcheck-macos-x64.tar.gz` | macOS x86_64 | native |
| `cppcheck-macos-arm64.tar.gz` | macOS Apple Silicon | native |
| `cppcheck-windows-x64.zip` | Windows x64 | native + PCRE |
Each archive contains `cppcheck`, `cfg/`, `addons/`, and `platforms/`.
Ready for pioarduino!
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}