diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 858b2d7e..7a525dff 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -20,7 +20,7 @@ jobs: .github/scripts/install_deps.sh ubuntu-latest lcov - name: Generate coverage report run: | - contrib/coverage.bash ubuntu-ci + contrib/coverage.bash --os ubuntu-latest --jobs "$(getconf _NPROCESSORS_ONLN)" - name: Upload coverage report uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/create-release-artifacts.yml b/.github/workflows/create-release-artifacts.yml index dd9a1861..d24027f0 100644 --- a/.github/workflows/create-release-artifacts.yml +++ b/.github/workflows/create-release-artifacts.yml @@ -11,9 +11,6 @@ env: CLICOLOR_FORCE: 1 CMAKE_COLOR_DIAGNOSTICS: ON # Tells CMake-generated build systems to have colored output. - # Approximate number of CPU cores in GitHub's runners as of 2026-03-18: - # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories - CMAKE_BUILD_PARALLEL_LEVEL: 4 # `cmake --build` now implies `--parallel 4`. CMAKE_BUILD_TYPE: Release # `cmake -S` now implies `-DCMAKE_BUILD_TYPE=Release`. CMAKE_CONFIG_TYPE: Release # `cmake --build` now implies `--config Release`. @@ -92,7 +89,7 @@ jobs: ./.github/scripts/install_deps.sh ubuntu-22.04 - name: Build binaries run: | - make -kj WARNFLAGS="-Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q= + make -k -j "$(getconf _NPROCESSORS_ONLN)" WARNFLAGS="-Wall -Wextra -pedantic -static" PKG_CONFIG="pkg-config --static" Q= strip rgb{asm,link,fix,gfx} - name: Create install script run: | diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 4665a900..a59c5cae 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -11,9 +11,8 @@ env: CMAKE_COLOR_DIAGNOSTICS: ON # Tells CMake-generated build systems to have colored output. CMAKE_CONFIG_TYPE: Debug # `cmake --build` now implies `--config Debug`. - # Approximate number of CPU cores in GitHub's runners as of 2026-03-18: - # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories - CTEST_PARALLEL_LEVEL: 0 # `ctest` now implies `--parallel 0` (number of logical CPUs). + + CTEST_PARALLEL_LEVEL: "" # `ctest` now implies `--parallel` (default number of logical CPUs). CTEST_NO_TESTS_ACTION: error # Make CTest fail if it cannot find any tests. (That should never happen.) CTEST_OUTPUT_ON_FAILURE: ON # CTest reports test program output on failure. @@ -57,11 +56,11 @@ jobs: - name: Build using Make if: matrix.buildsys == 'make' run: | - make develop -kj Q= CXX=${{ matrix.cxx }} + make develop -k -j "$(getconf _NPROCESSORS_ONLN)" Q= CXX=${{ matrix.cxx }} - name: Install using Make if: matrix.buildsys == 'make' run: | - sudo make install -j Q= + sudo make install Q= type rgbasm rgblink rgbfix rgbgfx man -w 1 rgbasm rgblink rgbfix rgbgfx - name: Build using CMake @@ -111,7 +110,7 @@ jobs: - name: Run tests using our script if: matrix.buildsys == 'make' run: | - CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} + CXX=${{ matrix.cxx }} test/run-tests.sh --os ${{ matrix.os }} --jobs "$(getconf _NPROCESSORS_ONLN)" - name: Run tests using CTest if: matrix.buildsys == 'cmake' run: | @@ -328,7 +327,7 @@ jobs: test/external/fetch-repos.sh - name: Run tests run: | - test/run-tests.sh --os ${{ matrix.os }} + test/run-tests.sh --os ${{ matrix.os }} --jobs "$(getconf _NPROCESSORS_ONLN)" cygwin: strategy: @@ -365,15 +364,15 @@ jobs: pkg-config - name: Build run: | # Cygwin does not support `make develop` sanitizers ASan or UBSan - make -kj Q= + make -k -j "$(getconf _NPROCESSORS_ONLN)" Q= - name: Install run: | - make install -j Q= + make install Q= type rgbasm rgblink rgbfix rgbgfx man -w 1 rgbasm rgblink rgbfix rgbgfx - name: Run tests run: | - test/run-tests.sh --only-internal + test/run-tests.sh --only-internal --jobs "$(getconf _NPROCESSORS_ONLN)" - name: Use Windows git location in the PATH shell: pwsh run: | # Prevents the `actions/checkout` post-job cleanup from using Cygwin's git binary @@ -400,7 +399,7 @@ jobs: .github/scripts/install_deps.sh freebsd run: | # Leak detection is not supported on FreeBSD, so disable it. cmake -B build --preset develop - cmake --build build --verbose -- -k -j 4 + cmake --build build --verbose -- -k -j "$(getconf _NPROCESSORS_ONLN)" ASAN_OPTIONS=detect_leaks=0 ctest --test-dir build --schedule-random --label-exclude external cmake --install build --verbose type rgbasm rgblink rgbfix rgbgfx diff --git a/Dockerfile b/Dockerfile index ca8d2080..bf070f58 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,7 +10,7 @@ RUN apt-get update && \ # Install dependencies and compile RGBDS RUN ./.github/scripts/install_deps.sh debian -RUN make -j CXXFLAGS="-O3 -flto -DNDEBUG -static" PKG_CONFIG="pkg-config --static" Q= +RUN make -j "$(getconf _NPROCESSORS_ONLN)" CXXFLAGS="-O3 -flto -DNDEBUG -static" PKG_CONFIG="pkg-config --static" Q= # Create the install script RUN make install.sh Q= diff --git a/contrib/coverage.bash b/contrib/coverage.bash index 6b0f7777..6217d310 100755 --- a/contrib/coverage.bash +++ b/contrib/coverage.bash @@ -1,17 +1,55 @@ #!/usr/bin/env bash set -e +usage() { + cat <<"EOF" +Generates LCOV code coverage report for RGBDS. +Options: + -h, --help show this help message + -o, --open open the HTML report in the preferred application + --jobs build RGBDS and external codebases with `make -j` + --os skip tests known to fail on (e.g. `macos-14`) +EOF +} + +# Parse options in pure Bash because macOS `getopt` is stuck +# in what util-linux `getopt` calls `GETOPT_COMPATIBLE` mode +make_args=() +runtests_args=() +open_report=false +while [[ $# -gt 0 ]]; do + case "$1" in + -h|--help) + usage + exit 0 + ;; + -o|--open) + open_report=true + ;; + --jobs) + shift + make_args+=("-j" "$1") + runtests_args+=("--jobs" "$1") + ;; + --os) + shift + runtests_args+=("--os" "$1") + ;; + *) + echo "$(basename "$0"): unknown option '$1'" + exit 1 + ;; + esac + shift +done + # Build RGBDS with gcov support -make coverage -j +make coverage "${make_args[@]}" # Run the tests pushd test external/fetch-repos.sh -if [[ $# -eq 0 ]]; then - ./run-tests.sh -else - ./run-tests.sh --os "$1" -fi +./run-tests.sh "${runtests_args[@]}" popd # Generate coverage logs @@ -24,12 +62,14 @@ lcov -c --no-external -d . -o "$COVERAGE_INFO" lcov -r "$COVERAGE_INFO" src/asm/parser.{hpp,cpp} src/link/script.{hpp,cpp} -o "$COVERAGE_INFO" genhtml --dark-mode --num-spaces 4 -f -s -o coverage/ "$COVERAGE_INFO" -# Check whether running from coverage.yml workflow -if [ "$1" != "ubuntu-ci" ]; then - # Open report in web browser - if [ "$(uname)" == "Darwin" ]; then - open coverage/index.html - else - xdg-open coverage/index.html - fi +if "$open_report"; then + # Open the report in the preferred web browser + if [ "$(uname)" == "Darwin" ]; then + open coverage/index.html + else + xdg-open coverage/index.html + fi +else + # Output the path to the report + echo "Generated LCOV report at $PWD/coverage/index.html" fi diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e78fb93..f9a587d8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -9,6 +9,15 @@ else() endif() set(TESTS_OS_NAME "${TESTS_OS_NAME}" CACHE STRING "Skip running tests known to fail on this OS.") +include(ProcessorCount) +ProcessorCount(PROCESSOR_COUNT) +if(PROCESSOR_COUNT EQUAL 0) + set(PROCESSOR_COUNT 4) + message(STATUS "Could not determine CPU count; defaulting to ${PROCESSOR_COUNT}.") +else() + message(STATUS "Counted ${PROCESSOR_COUNT} logical CPU cores.") +endif() + add_executable(randtilegen gfx/randtilegen.cpp) add_executable(rgbgfx_test gfx/rgbgfx_test.cpp) set_target_properties(randtilegen rgbgfx_test PROPERTIES @@ -29,7 +38,7 @@ foreach(component "asm" "link" "fix" "gfx") COMMAND bash -- test.sh WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${component}") set_tests_properties("rgb${component}" PROPERTIES REQUIRED_FILES "$" - PROCESSORS 1 + PROCESSORS 1 # These cannot be parallelized. LABELS "internal;free") endforeach() set_tests_properties(rgbgfx PROPERTIES REQUIRED_FILES "$;$;$") @@ -69,10 +78,10 @@ foreach(cfg_file IN LISTS ext_projects) endif() add_test(NAME "${project}" - COMMAND bash -- external/test.sh ${project} + COMMAND bash -- external/test.sh ${project} -j "${PROCESSOR_COUNT}" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") set_tests_properties(${project} PROPERTIES DEPENDS "rgbasm;rgblink;rgbfix;rgbgfx" # Only attempt external tests after all individual tool tests. - PROCESSORS 4 + PROCESSORS "${PROCESSOR_COUNT}" LABELS "external;${freedom}" FIXTURES_REQUIRED "${freedom}-repos") endforeach() diff --git a/test/external/fetch-repos.sh b/test/external/fetch-repos.sh index 4a8e7682..be0c7796 100755 --- a/test/external/fetch-repos.sh +++ b/test/external/fetch-repos.sh @@ -7,10 +7,11 @@ usage() { cat <<"EOF" Downloads source code of Game Boy project repos used as RGBDS test cases. Options: - -h, --help show this help message - --only-free download only freely licensed codebases - --get-hash print repos' commit hashes instead of downloading them - --get-paths print repos' clone paths instead of downloading them + -h, --help show this help message + --only-free download only freely licensed codebases + --only-nonfree download only non-freely licensed codebases + --get-hash print repos' commit hashes instead of downloading them + --get-paths print repos' clone paths instead of downloading them EOF } diff --git a/test/external/test.sh b/test/external/test.sh index a5345ae6..f9c98989 100755 --- a/test/external/test.sh +++ b/test/external/test.sh @@ -8,13 +8,16 @@ export SOURCE_DATE_EPOCH=609165296 cd "$(dirname "$0")" -if [ ! -f "$1.cfg" ]; then - echo >&2 'External test file '"$1"'.cfg does not exist' +NAME="$1" +shift # Any remaining arguments get forwarded to `make`. + +if [ ! -f "$NAME.cfg" ]; then + echo >&2 'External test file '"$NAME"'.cfg does not exist' exit 1 fi -# Sourcing "$1.cfg" defines `EXT_TEST_*` variables used below. -. "$1.cfg" +# Sourcing "$NAME.cfg" defines `EXT_TEST_*` variables used below. +. "$NAME.cfg" if ! cd "$EXT_TEST_REPO"; then echo >&2 'Please fetch test deps before running any external test' @@ -23,7 +26,7 @@ fi RGBDS_PATH="RGBDS=../../../" git clean -fdx # Clean any previous build products so `make` rebuilds everything from scratch. -make -j4 "$EXT_TEST_TARGET" $RGBDS_PATH +make "$@" "$EXT_TEST_TARGET" $RGBDS_PATH hash="$(sha1sum -b "$EXT_TEST_FILE" | head -c 40)" if [ "$hash" != "$EXT_TEST_HASH" ]; then diff --git a/test/run-tests.sh b/test/run-tests.sh index b9325929..1d209f7c 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -16,6 +16,7 @@ Options: --only-internal only run tests that build local examples --only-external only run tests that build external codebases --only-free skip tests that build nonfree codebases + --jobs build external codebases with `make -j` --os skip tests known to fail on (e.g. `macos-14`) --installed-rgbds use the system installed RGBDS (only compatible with external codebases) @@ -28,6 +29,7 @@ nonfree=true internal=true external=true installedrgbds=false +make_jobs= osname= while [[ $# -gt 0 ]]; do case "$1" in @@ -47,6 +49,10 @@ while [[ $# -gt 0 ]]; do --installed-rgbds) installedrgbds=true ;; + --jobs) + shift + make_jobs="-j$1" + ;; --os) shift osname="$1" @@ -122,6 +128,6 @@ for cfg in *.cfg; do ( # Run nonfree tests only if they are opted into. if ! "$EXT_TEST_IS_NONFREE" || "$nonfree"; then - ./test.sh "$test_name" + ./test.sh "$test_name" "$make_jobs" fi ); done