diff --git a/.github/actions/install-sis-deps/action.yml b/.github/actions/install-sis-deps/action.yml new file mode 100644 index 00000000..73209b73 --- /dev/null +++ b/.github/actions/install-sis-deps/action.yml @@ -0,0 +1,109 @@ +name: Install Synesis dependencies +description: >- + Clones, builds, and installs the named Synesis Information Systems + dependencies into a single CMake prefix, and exports that prefix both as + the SIS_DEPS environment variable and as the `prefix` output. + +inputs: + build-type: + description: CMake build type, for single-configuration generators + required: false + default: Release + c-compiler: + description: C compiler name, or the selector `cl` + required: true + cpp-compiler: + description: C++ compiler name; unused for the `cl` selector + required: true + dependencies: + description: >- + Whitespace-separated synesissoftware repository names, in dependency + order. Each is configured against those already installed, so this + list is deliberately NOT in lexicographic order. + required: true + install-prefix: + description: Directory into which every dependency is installed + required: false + default: '' + toolchain: + description: >- + Toolchain selector, for a toolchain that is not implied by the compiler + names and needs its own generator; presently only `mingw`. Empty + otherwise, in which case the compiler names alone select the toolchain. + required: false + default: '' + +outputs: + prefix: + description: Directory into which every dependency was installed + value: ${{ steps.install.outputs.prefix }} + +runs: + using: composite + + steps: + - id: install + shell: bash + run: | + set -euo pipefail + + PREFIX="${{ inputs.install-prefix }}" + [ -n "$PREFIX" ] || PREFIX="${RUNNER_TEMP}/sis-deps" + + mkdir -p "$PREFIX" + + if [ "${{ inputs.toolchain }}" = "mingw" ]; then + export PATH="/mingw64/bin:$PATH" + fi + + for dep in ${{ inputs.dependencies }}; do + + echo "::group::Installing $dep" + + SRC="${RUNNER_TEMP}/${dep}-src" + BUILD="${RUNNER_TEMP}/${dep}-build" + + git clone --depth 1 "https://github.com/synesissoftware/${dep}" "$SRC" + + # NOTE: the generator and the build-type/compiler options are the + # *only* things that may differ between these paths; every other + # -D option is passed in all cases, so that no branch can silently + # ignore one. + if [ "${{ inputs.c-compiler }}" = "cl" ]; then + cmake -S "$SRC" -B "$BUILD" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --config "${{ inputs.build-type }}" --parallel + cmake --install "$BUILD" --config "${{ inputs.build-type }}" + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then + cmake -S "$SRC" -B "$BUILD" -G "MinGW Makefiles" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --parallel 2 + cmake --install "$BUILD" + else + cmake -S "$SRC" -B "$BUILD" \ + -DBUILD_EXAMPLES=OFF \ + -DBUILD_TESTING=OFF \ + -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_INSTALL_PREFIX="$PREFIX" \ + -DCMAKE_PREFIX_PATH="$PREFIX" + cmake --build "$BUILD" --parallel + cmake --install "$BUILD" + fi + + echo "::endgroup::" + done + + echo "prefix=$PREFIX" >> "$GITHUB_OUTPUT" + echo "SIS_DEPS=$PREFIX" >> "$GITHUB_ENV" diff --git a/.github/workflows/ci-cell.yml b/.github/workflows/ci-cell.yml index 1c29fed5..230a5f26 100644 --- a/.github/workflows/ci-cell.yml +++ b/.github/workflows/ci-cell.yml @@ -3,26 +3,38 @@ name: CI cell on: workflow_call: inputs: - cell-id: - required: true + build-type: + required: false type: string - os: + default: Release + c-compiler: required: true type: string - c-compiler: + cell-id: required: true type: string cpp-compiler: required: true type: string - build-type: + no-b64: + required: false + type: boolean + default: false + no-shwild: + required: false + type: boolean + default: false + os: + required: true + type: string + toolchain: required: false type: string - default: Release + default: '' jobs: - build: - name: Build (${{ inputs.cell-id }}) + build-and-test: + name: Build and test (${{ inputs.cell-id }}) runs-on: ${{ inputs.os }} steps: @@ -33,7 +45,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y clang - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' + if: runner.os == 'Windows' && inputs.toolchain == 'mingw' uses: msys2/setup-msys2@v2 with: msystem: MINGW64 @@ -43,183 +55,60 @@ jobs: mingw-w64-x86_64-cmake mingw-w64-x86_64-make - - name: Install test dependencies (STLSoft + shwild + xTests + b64) - shell: bash - run: | - set -euxo pipefail - - DEPS="${RUNNER_TEMP}/sis-deps" - STLSRC="${RUNNER_TEMP}/stlsoft-src" - STLBUILD="${RUNNER_TEMP}/stlsoft-build" - SHWSRC="${RUNNER_TEMP}/shwild-src" - SHWBUILD="${RUNNER_TEMP}/shwild-build" - XTSRC="${RUNNER_TEMP}/xtests-src" - XTBUILD="${RUNNER_TEMP}/xtests-build" - B64SRC="${RUNNER_TEMP}/b64-src" - B64BUILD="${RUNNER_TEMP}/b64-build" - - mkdir -p "$DEPS" - - # 1. STLSoft - git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$STLBUILD" --config "${{ inputs.build-type }}" - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$STLSRC" -B "$STLBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel 2 - cmake --install "$STLBUILD" - else - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel - cmake --install "$STLBUILD" - fi - - # 2. shwild - git clone --depth 1 https://github.com/synesissoftware/shwild "$SHWSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$SHWSRC" -B "$SHWBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$SHWBUILD" --config "${{ inputs.build-type }}" - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$SHWSRC" -B "$SHWBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --parallel 2 - cmake --install "$SHWBUILD" - else - cmake -S "$SHWSRC" -B "$SHWBUILD" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$SHWBUILD" --parallel - cmake --install "$SHWBUILD" - fi - - # 3. xTests - git clone --depth 1 https://github.com/synesissoftware/xTests "$XTSRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$XTSRC" -B "$XTBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$XTBUILD" --config "${{ inputs.build-type }}" - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$XTSRC" -B "$XTBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --parallel 2 - cmake --install "$XTBUILD" - else - cmake -S "$XTSRC" -B "$XTBUILD" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$XTBUILD" --parallel - cmake --install "$XTBUILD" - fi - - # 4. b64 - git clone --depth 1 https://github.com/synesissoftware/b64 "$B64SRC" - if [ "${{ inputs.c-compiler }}" = "cl" ]; then - cmake -S "$B64SRC" -B "$B64BUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --config "${{ inputs.build-type }}" --parallel - cmake --install "$B64BUILD" --config "${{ inputs.build-type }}" - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$B64SRC" -B "$B64BUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --parallel 2 - cmake --install "$B64BUILD" - else - cmake -S "$B64SRC" -B "$B64BUILD" \ - -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --parallel - cmake --install "$B64BUILD" - fi + - name: Install test dependencies (STLSoft${{ !inputs.no-shwild && ' + shwild' || '' }} + xTests${{ !inputs.no-b64 && ' + b64' || '' }}) + uses: ./.github/actions/install-sis-deps + with: + build-type: ${{ inputs.build-type }} + c-compiler: ${{ inputs.c-compiler }} + cpp-compiler: ${{ inputs.cpp-compiler }} + dependencies: >- + STLSoft + ${{ !inputs.no-shwild && 'shwild' || '' }} + xTests + ${{ !inputs.no-b64 && 'b64' || '' }} + toolchain: ${{ inputs.toolchain }} - name: Configure shell: bash run: | set -euo pipefail + NO_B64_OPT="" + if [ "${{ inputs.no-b64 }}" = "true" ]; then + NO_B64_OPT="-DNO_B64=ON" + fi + NO_SHWILD_OPT="" + if [ "${{ inputs.no-shwild }}" = "true" ]; then + NO_SHWILD_OPT="-DNO_SHWILD=ON -DCMAKE_DISABLE_FIND_PACKAGE_shwild=TRUE" + fi if [ "${{ inputs.c-compiler }}" = "cl" ]; then cmake -B build -S . \ -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=ON \ - -DBUILD_TESTING=ON - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + -DBUILD_TESTING=ON \ + $NO_B64_OPT \ + $NO_SHWILD_OPT + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" - cmake -B build -G "MinGW Makefiles" \ + cmake -B build -S . -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ - -DCMAKE_C_COMPILER=gcc \ - -DCMAKE_CXX_COMPILER=g++ \ - -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=ON \ - -DBUILD_TESTING=ON + -DBUILD_TESTING=ON \ + $NO_B64_OPT \ + $NO_SHWILD_OPT else cmake -B build -S . \ -DCMAKE_BUILD_TYPE="${{ inputs.build-type }}" \ -DCMAKE_C_COMPILER="${{ inputs.c-compiler }}" \ -DCMAKE_CXX_COMPILER="${{ inputs.cpp-compiler }}" \ - -DCMAKE_PREFIX_PATH="${RUNNER_TEMP}/sis-deps" \ + -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=ON \ - -DBUILD_TESTING=ON + -DBUILD_TESTING=ON \ + $NO_B64_OPT \ + $NO_SHWILD_OPT fi - name: Build @@ -228,141 +117,46 @@ jobs: set -euo pipefail if [ "${{ inputs.c-compiler }}" = "cl" ]; then cmake --build build --config "${{ inputs.build-type }}" --parallel - elif [ "${{ inputs.c-compiler }}" = "mingw" ]; then + elif [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake --build build --parallel 2 else cmake --build build --parallel fi - - name: Upload build tree - uses: actions/upload-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build - retention-days: 1 - - run-examples: - name: Examples (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build - - - name: Run examples + - name: Run unit tests shell: bash run: | set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + if [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" fi - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_examples.sh -M - - test-unit: - name: Unit tests (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --unit-only - - name: Run unit tests + - name: Run component tests shell: bash run: | set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + if [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" fi - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --unit-only - - test-component: - name: Component tests (${{ inputs.cell-id }}) - needs: build - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --component-only - - name: Run component tests + - name: Run examples shell: bash run: | set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + if [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" fi - SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_unit_tests.sh -M --component-only - - test-scratch: - name: Scratch tests (${{ inputs.cell-id }}) - needs: build - continue-on-error: true - runs-on: ${{ inputs.os }} - - steps: - - uses: actions/checkout@v4 - - - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && inputs.c-compiler == 'mingw' - uses: msys2/setup-msys2@v2 - with: - msystem: MINGW64 - update: true - install: mingw-w64-x86_64-toolchain - - - name: Download build tree - uses: actions/download-artifact@v4 - with: - name: sis-build-${{ inputs.cell-id }} - path: build + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_examples.sh -M - name: Run scratch tests + continue-on-error: true shell: bash run: | set -euo pipefail - if [ "${{ inputs.c-compiler }}" = "mingw" ]; then + if [ "${{ inputs.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" fi SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_scratch_tests.sh -M diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a3fd669d..31f7c4b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,6 +38,22 @@ jobs: os: ubuntu-latest c_compiler: gcc cpp_compiler: g++ + - id: linux-gcc-no-b64 + os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + no_b64: true + - id: linux-gcc-no-b64-no-shwild + os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + no_b64: true + no_shwild: true + - id: linux-gcc-no-shwild + os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + no_shwild: true - id: macos-clang os: macos-latest c_compiler: clang @@ -50,21 +66,27 @@ jobs: os: windows-latest c_compiler: cl cpp_compiler: cl + # `toolchain` carries what is not a compiler: MinGW needs its own + # generator and PATH, but the compilers it drives are gcc and g++ - id: windows-mingw os: windows-latest - c_compiler: mingw + c_compiler: gcc cpp_compiler: g++ + toolchain: mingw uses: ./.github/workflows/ci-cell.yml with: - cell-id: ${{ matrix.id }} - os: ${{ matrix.os }} + build-type: Release c-compiler: ${{ matrix.c_compiler }} + cell-id: ${{ matrix.id }} cpp-compiler: ${{ matrix.cpp_compiler }} - build-type: Release + no-b64: ${{ matrix.no_b64 == true }} + no-shwild: ${{ matrix.no_shwild == true }} + os: ${{ matrix.os }} + toolchain: ${{ matrix.toolchain }} secrets: inherit install-smoke: - name: Install smoke (${{ matrix.os }}, ${{ matrix.c_compiler }}) + name: Install smoke (${{ matrix.os }}, ${{ matrix.toolchain || matrix.c_compiler }}${{ matrix.no_b64 && ', no-b64' || '' }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -73,6 +95,10 @@ jobs: - os: ubuntu-latest c_compiler: gcc cpp_compiler: g++ + - os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + no_b64: true - os: ubuntu-latest c_compiler: clang cpp_compiler: clang++ @@ -83,8 +109,9 @@ jobs: c_compiler: cl cpp_compiler: cl - os: windows-latest - c_compiler: mingw + c_compiler: gcc cpp_compiler: g++ + toolchain: mingw steps: - uses: actions/checkout@v4 @@ -94,7 +121,7 @@ jobs: run: sudo apt-get update && sudo apt-get install -y clang - name: Setup MSYS2 MinGW - if: runner.os == 'Windows' && matrix.c_compiler == 'mingw' + if: runner.os == 'Windows' && matrix.toolchain == 'mingw' uses: msys2/setup-msys2@v2 with: msystem: MINGW64 @@ -104,98 +131,40 @@ jobs: mingw-w64-x86_64-cmake mingw-w64-x86_64-make - - name: Install STLSoft and b64 dependencies - shell: bash - run: | - set -euo pipefail - DEPS="${RUNNER_TEMP}/sis-deps" - STLSRC="${RUNNER_TEMP}/stlsoft-src" - STLBUILD="${RUNNER_TEMP}/stlsoft-build" - B64SRC="${RUNNER_TEMP}/b64-src" - B64BUILD="${RUNNER_TEMP}/b64-build" - mkdir -p "$DEPS" - git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSRC" - if [ "${{ matrix.c_compiler }}" = "cl" ]; then - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --config "${{ env.BUILD_TYPE }}" --parallel - cmake --install "$STLBUILD" --config "${{ env.BUILD_TYPE }}" - elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$STLSRC" -B "$STLBUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel 2 - cmake --install "$STLBUILD" - else - cmake -S "$STLSRC" -B "$STLBUILD" \ - -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$STLBUILD" --parallel - cmake --install "$STLBUILD" - fi - git clone --depth 1 https://github.com/synesissoftware/b64 "$B64SRC" - if [ "${{ matrix.c_compiler }}" = "cl" ]; then - cmake -S "$B64SRC" -B "$B64BUILD" \ - -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --config "${{ env.BUILD_TYPE }}" --parallel - cmake --install "$B64BUILD" --config "${{ env.BUILD_TYPE }}" - elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then - export PATH="/mingw64/bin:$PATH" - cmake -S "$B64SRC" -B "$B64BUILD" -G "MinGW Makefiles" \ - -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --parallel 2 - cmake --install "$B64BUILD" - else - cmake -S "$B64SRC" -B "$B64BUILD" \ - -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ - -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ - -DCMAKE_PREFIX_PATH="$DEPS" \ - -DCMAKE_INSTALL_PREFIX="$DEPS" \ - -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - cmake --build "$B64BUILD" --parallel - cmake --install "$B64BUILD" - fi - echo "SIS_DEPS=$DEPS" >> "$GITHUB_ENV" + - name: Install dependencies (STLSoft${{ !matrix.no_b64 && ' + b64' || '' }}) + uses: ./.github/actions/install-sis-deps + with: + build-type: ${{ env.BUILD_TYPE }} + c-compiler: ${{ matrix.c_compiler }} + cpp-compiler: ${{ matrix.cpp_compiler }} + dependencies: ${{ matrix.no_b64 && 'STLSoft' || 'STLSoft b64' }} + toolchain: ${{ matrix.toolchain }} - name: Configure shell: bash run: | set -euo pipefail + NO_B64_OPT="" + if [ "${{ matrix.no_b64 }}" = "true" ]; then + NO_B64_OPT="-DNO_B64=ON" + fi if [ "${{ matrix.c_compiler }}" = "cl" ]; then cmake -B build -S . \ -DCMAKE_DISABLE_FIND_PACKAGE_MFC=TRUE \ -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF - elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + -DBUILD_TESTING=OFF \ + $NO_B64_OPT + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" - cmake -B build -G "MinGW Makefiles" \ + cmake -B build -S . -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ - -DCMAKE_C_COMPILER=gcc \ - -DCMAKE_CXX_COMPILER=g++ \ + -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + $NO_B64_OPT else cmake -B build -S . \ -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ @@ -203,7 +172,8 @@ jobs: -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ -DCMAKE_PREFIX_PATH="${{ env.SIS_DEPS }}" \ -DBUILD_EXAMPLES=OFF \ - -DBUILD_TESTING=OFF + -DBUILD_TESTING=OFF \ + $NO_B64_OPT fi - name: Build @@ -212,7 +182,7 @@ jobs: set -euo pipefail if [ "${{ matrix.c_compiler }}" = "cl" ]; then cmake --build build --config "${{ env.BUILD_TYPE }}" --parallel - elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake --build build --parallel 2 else @@ -270,10 +240,12 @@ jobs: -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX};${{ env.SIS_DEPS }}" cmake --build consumer-build --config "${{ env.BUILD_TYPE }}" --parallel consumer-build/${{ env.BUILD_TYPE }}/consumer.exe - elif [ "${{ matrix.c_compiler }}" = "mingw" ]; then + elif [ "${{ matrix.toolchain }}" = "mingw" ]; then export PATH="/mingw64/bin:$PATH" cmake -S "$CONSUMER" -B consumer-build -G "MinGW Makefiles" \ -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_C_COMPILER="${{ matrix.c_compiler }}" \ + -DCMAKE_CXX_COMPILER="${{ matrix.cpp_compiler }}" \ -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX};${{ env.SIS_DEPS }}" cmake --build consumer-build --parallel 2 consumer-build/consumer.exe @@ -286,3 +258,143 @@ jobs: cmake --build consumer-build --parallel consumer-build/consumer fi + + # CMakeLists.txt offers three ways to locate STLSoft, of which the jobs + # above exercise only find_package(). These cells cover the other two, + # which short-circuit find_package() entirely and so are not merely a + # different spelling of the same code path. + stlsoft-routes: + name: STLSoft route (${{ matrix.route }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + route: + - environment + - variable + + steps: + - uses: actions/checkout@v4 + + # These routes consume STLSoft as a source tree, so it is cloned + # rather than built and installed. + - name: Clone STLSoft + shell: bash + run: | + set -euo pipefail + STLSOFT_SRC="${RUNNER_TEMP}/stlsoft-src" + git clone --depth 1 https://github.com/synesissoftware/STLSoft "$STLSOFT_SRC" + echo "STLSOFT_SRC=$STLSOFT_SRC" >> "$GITHUB_ENV" + + - name: Configure + shell: bash + run: | + set -euo pipefail + # Deliberately no CMAKE_PREFIX_PATH: nothing here may fall back to + # the STLSoft package. + if [ "${{ matrix.route }}" = "variable" ]; then + cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DSTLSOFT="${STLSOFT_SRC}" \ + -DNO_B64=ON \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=OFF \ + 2>&1 | tee configure.log + else + STLSOFT="${STLSOFT_SRC}" cmake -B build -S . \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DNO_B64=ON \ + -DBUILD_EXAMPLES=ON \ + -DBUILD_TESTING=OFF \ + 2>&1 | tee configure.log + fi + + # Without this, a regression that silently routed the build through + # find_package() would leave the cell green while testing nothing new. + - name: Assert the intended route was taken + shell: bash + run: | + set -euo pipefail + if [ "${{ matrix.route }}" = "variable" ]; then + expected="STLSOFT provided as CMake variable" + else + expected="STLSOFT provided as environment variable" + fi + if ! grep -q "$expected" configure.log; then + echo "configure did not report '${expected}'" >&2 + exit 1 + fi + + - name: Build + shell: bash + run: | + set -euo pipefail + cmake --build build --parallel + + - name: Run examples + shell: bash + run: | + set -euo pipefail + SIS_CMAKE_BUILD_DIR="${{ github.workspace }}/build" ./run_all_examples.sh -M + + - name: Install + shell: bash + run: | + set -euo pipefail + PREFIX="${RUNNER_TEMP}/install-prefix" + echo "INSTALL_PREFIX=$PREFIX" >> "$GITHUB_ENV" + cmake --install build --prefix "$PREFIX" + + - name: Verify install tree + shell: bash + run: | + set -euo pipefail + test -f "${INSTALL_PREFIX}/include/pantheios/pantheios.h" + test -f "${INSTALL_PREFIX}/lib/cmake/pantheios/pantheios-config.cmake" + + # On these routes the export does not reference STLSoft::STLSoft, so + # the package configuration must not require the package either. + - name: Assert package config does not require STLSoft + shell: bash + run: | + set -euo pipefail + config="${INSTALL_PREFIX}/lib/cmake/pantheios/pantheios-config.cmake" + test -f "$config" + if ! grep -B 2 'find_dependency(STLSoft)' "$config" | grep -q '^if()'; then + echo "expected the find_dependency(STLSoft) guard to be empty/false" >&2 + cat "$config" >&2 + exit 1 + fi + + # Deliberately omit SIS_DEPS from CMAKE_PREFIX_PATH: the consumer must + # resolve cleanly using only the installed Pantheios prefix. + - name: Configure and run install smoke consumer + shell: bash + run: | + set -euo pipefail + CONSUMER="${RUNNER_TEMP}/consumer" + mkdir -p "$CONSUMER" + cat > "$CONSUMER/CMakeLists.txt" <<'EOF' + cmake_minimum_required(VERSION 3.13) + project(pantheios_install_smoke CXX) + find_package(Pantheios REQUIRED) + add_executable(consumer consumer.cpp) + target_link_libraries(consumer PRIVATE + Pantheios::Pantheios.core + Pantheios::Pantheios.be.fprintf + Pantheios::Pantheios.bec.fprintf + Pantheios::Pantheios.fe.simple + Pantheios::Pantheios.util + ) + EOF + cat > "$CONSUMER/consumer.cpp" <<'EOF' + #include + PANTHEIOS_EXTERN const char PANTHEIOS_FE_PROCESS_IDENTITY[] = "install_smoke_consumer"; + int main() { return 0; } + EOF + cmake -S "$CONSUMER" -B consumer-build \ + -DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}" \ + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" + cmake --build consumer-build --parallel + consumer-build/consumer + diff --git a/CMakeLists.txt b/CMakeLists.txt index ca04b11f..8e41fea1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -226,25 +226,31 @@ endif() # ############################ # shwild -if(BUILD_TESTING) +if(NOT NO_SHWILD) + + if(BUILD_TESTING) - find_package(shwild QUIET) + find_package(shwild QUIET) - if(shwild_FOUND) + if(shwild_FOUND) - message("-- CMake package shwild found (version ${shwild_VERSION})") + message("-- CMake package shwild found (version ${shwild_VERSION})") - add_compile_definitions(HAS_shwild) - add_compile_definitions(PANTHEIOS_HAS_SHWILD) - add_compile_definitions(XTESTS_HAS_SHWILD) - else(shwild_FOUND) + add_compile_definitions(HAS_shwild) + add_compile_definitions(PANTHEIOS_HAS_SHWILD) + add_compile_definitions(XTESTS_HAS_SHWILD) + else(shwild_FOUND) + + add_compile_definitions(PANTHEIOS_NO_SHWILD) + endif(shwild_FOUND) + else(BUILD_TESTING) add_compile_definitions(PANTHEIOS_NO_SHWILD) - endif(shwild_FOUND) -else(BUILD_TESTING) + endif(BUILD_TESTING) +else() add_compile_definitions(PANTHEIOS_NO_SHWILD) -endif(BUILD_TESTING) +endif() # ############################ diff --git a/TODO.md b/TODO.md index 2998a755..38a8947d 100644 --- a/TODO.md +++ b/TODO.md @@ -6,9 +6,10 @@ ### 1.0.1-rc3 (10th September 2026) -* [ ] CI refactoring; +* [x] ~~~CI refactoring~~~ - ✅; * [ ] **README.md** (and other project markdown) significant enhancement (in a similar vein as has been done for **xqsr3** (Ruby)); * [ ] Integration of **woad**; +* [ ] Refactor CMake test targets / options so that only unit-test executables are built when only executing unit tests (and similarly for component, scratch, and performance tests); * [ ] Using **AnsiConsole**; * [ ] Using **ACE**; diff --git a/prepare_cmake.sh b/prepare_cmake.sh index abbae162..cfa4d10e 100755 --- a/prepare_cmake.sh +++ b/prepare_cmake.sh @@ -14,6 +14,7 @@ ExamplesDisabled=0 MSVC_MT=0 MinGW=0 NO_b64=0 +NO_shwild=0 RunMake=0 STLSoftDirGiven= TestingDisabled=0 @@ -55,6 +56,10 @@ while [[ $# -gt 0 ]]; do NO_b64=1 ;; + --no-shwild) + + NO_shwild=1 + ;; -m|--run-make) RunMake=1 @@ -110,6 +115,9 @@ Flags/options: --no-b64 suppresses discovery of b64 package + --no-shwild + suppresses discovery of shwild package + -m --run-make executes make after a successful running of CMake @@ -158,6 +166,7 @@ echo "Executing CMake for ${ProjectName} (in ${CMakeDir})" if [ $ExamplesDisabled -eq 0 ]; then CMakeBuildExamplesFlag="ON" ; else CMakeBuildExamplesFlag="OFF" ; fi if [ $MSVC_MT -eq 0 ]; then CMakeMsvcMtFlag="OFF" ; else CMakeMsvcMtFlag="ON" ; fi if [ $NO_b64 -eq 0 ]; then CMakeNoB64="OFF" ; else CMakeNoB64="ON" ; fi +if [ $NO_shwild -eq 0 ]; then CMakeNoShwild="OFF" ; else CMakeNoShwild="ON" ; fi if [ -z $STLSoftDirGiven ]; then CMakeSTLSoftVariable="" ; else CMakeSTLSoftVariable="-DSTLSOFT=$STLSoftDirGiven/" ; fi if [ $TestingDisabled -eq 0 ]; then CMakeBuildTestingFlag="ON" ; else CMakeBuildTestingFlag="OFF" ; fi if [ $VerboseMakefile -eq 0 ]; then CMakeVerboseMakefileFlag="OFF" ; else CMakeVerboseMakefileFlag="ON" ; fi @@ -172,6 +181,7 @@ if [ $MinGW -ne 0 ]; then -DBUILD_TESTING:BOOL=$CMakeBuildTestingFlag \ -DCMAKE_BUILD_TYPE=$Configuration \ -DNO_B64=$CMakeNoB64 \ + -DNO_SHWILD=$CMakeNoShwild \ -G "MinGW Makefiles" \ -S $Dir \ -B $CMakeDir \ @@ -187,6 +197,7 @@ else -DCMAKE_VERBOSE_MAKEFILE:BOOL=$CMakeVerboseMakefileFlag \ -DMSVC_USE_MT:BOOL=$CMakeMsvcMtFlag \ -DNO_B64=$CMakeNoB64 \ + -DNO_SHWILD=$CMakeNoShwild \ -S $Dir \ -B $CMakeDir \ || (cd ->/dev/null ; exit 1) diff --git a/test/unit/test.unit.getversion/test.unit.getversion.c b/test/unit/test.unit.getversion/test.unit.getversion.c index f888a7b3..140a4449 100644 --- a/test/unit/test.unit.getversion/test.unit.getversion.c +++ b/test/unit/test.unit.getversion/test.unit.getversion.c @@ -4,7 +4,7 @@ * Purpose: Implementation file for the test.unit.getversion project. * * Created: 28th August 2008 - * Updated: 6th September 2026 + * Updated: 10th September 2026 * * ////////////////////////////////////////////////////////////////////// */ @@ -151,7 +151,7 @@ static void test_composite(void) TEST_INT_EQ(expected, PANTHEIOS_VER); TEST_INT_EQ(expected, pantheios_getVersion()); - TEST_INT_EQ(PANTHEIOS_VER_1_0_1_RC2, PANTHEIOS_VER); + TEST_INT_EQ(PANTHEIOS_VER_1_0_1_RC3, PANTHEIOS_VER); }