diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index e6737f17e..e618873cd 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -29,127 +29,79 @@ concurrency: jobs: build-2604-gcc: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + name: Build | ubuntu-26.04 | gcc uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: linux - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: ubuntu-26.04 + cc: gcc + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: ubuntu-26.04, cc: gcc, asan: 0} build-2604-clang: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + name: Build | ubuntu-26.04 | clang uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: linux - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: ubuntu-26.04 + cc: clang + dev-asan: 1 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: ubuntu-26.04, cc: clang, asan: 1} build-2404-gcc: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + name: Build | ubuntu-24.04 | gcc uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: linux - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: ubuntu-24.04 + cc: gcc + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: ubuntu-24.04, cc: gcc, asan: 0} build-2404-clang: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + name: Build | ubuntu-24.04 | clang uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: linux - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: ubuntu-24.04 + cc: clang + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: ubuntu-24.04, cc: clang, asan: 0} build-2204-gcc: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + name: Build | ubuntu-22.04 | gcc uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: linux - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: ubuntu-22.04 + cc: gcc + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: ubuntu-22.04, cc: gcc, asan: 0} - build-osx-gcc: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + build-macos-15-gcc: + name: Build | macos-15 | gcc uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: osx - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: macos-15 + cc: gcc + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: macos-15, cc: gcc, asan: 0} - build-osx-clang: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }} + build-macos-15-clang: + name: Build | macos-15 | clang uses: ./.github/workflows/reusable-build.yml with: sha: ${{ github.sha }} - os: ${{ matrix.os }} - os-name: osx - cc: ${{ matrix.cc }} - dev-asan: ${{ matrix.asan }} + os: macos-15 + cc: clang + dev-asan: 0 dev-gcov: 0 - strategy: - fail-fast: false - matrix: - include: - - {os: macos-15, cc: clang, asan: 0} build-windows: - name: Build | ${{ matrix.os }} | ${{ matrix.cc }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - {os: windows-2025-vs2026, cc: msvc} + name: Build | windows-2025-vs2026 | msvc + runs-on: windows-2025-vs2026 env: - CI_OS_NAME: win CCACHE_COMPRESS: 1 CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_LIMIT_MULTIPLE: 0.95 @@ -177,7 +129,7 @@ jobs: name: verilator-win.zip test-2604-gcc: - name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }} + name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.suite }} needs: build-2604-gcc uses: ./.github/workflows/reusable-test.yml with: @@ -201,7 +153,7 @@ jobs: - {os: ubuntu-26.04, cc: gcc, reloc: 0, suite: vltmt-2} test-2604-clang: - name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }} + name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.suite }} needs: build-2604-clang uses: ./.github/workflows/reusable-test.yml with: @@ -225,7 +177,7 @@ jobs: - {os: ubuntu-26.04, cc: clang, reloc: 0, suite: vltmt-2} test-2404-gcc: - name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }} + name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.suite }} needs: build-2404-gcc uses: ./.github/workflows/reusable-test.yml with: @@ -249,7 +201,7 @@ jobs: - {os: ubuntu-24.04, cc: gcc, reloc: 0, suite: vltmt-2} test-2404-clang: - name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }} + name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.suite }} needs: build-2404-clang uses: ./.github/workflows/reusable-test.yml with: @@ -273,7 +225,7 @@ jobs: - {os: ubuntu-24.04, cc: clang, reloc: 1, suite: vltmt-2} test-2204-gcc: - name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }} + name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.suite }} needs: build-2204-gcc uses: ./.github/workflows/reusable-test.yml with: diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 38d4c9a50..3b21b8f48 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -43,7 +43,6 @@ jobs: # between the root of the pull request and the target branch sha: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }} os: ubuntu-24.04 - os-name: linux cc: gcc dev-asan: 0 dev-gcov: 1 diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index 5a604fa73..693190453 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -15,18 +15,12 @@ jobs: format: runs-on: ubuntu-24.04 name: Ubuntu 24.04 | format - env: - CI_OS_NAME: linux - CI_RUNS_ON: ubuntu-24.04 - CI_COMMIT: ${{ github.sha }} steps: - name: Checkout uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Install packages for build - env: - CI_BUILD_STAGE_NAME: build run: | sudo apt install clang-format-18 || \ sudo apt install clang-format-18 diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml index f19fa4ad1..a956d927e 100644 --- a/.github/workflows/reusable-build.yml +++ b/.github/workflows/reusable-build.yml @@ -17,9 +17,6 @@ on: cc: # 'clang' or 'gcc' required: true type: string - os-name: # 'linux' or 'osx' - required: true - type: string dev-asan: required: true type: number @@ -32,12 +29,9 @@ on: value: ${{ jobs.build.outputs.archive }} env: - CI_OS_NAME: ${{ inputs.os-name }} CCACHE_COMPRESS: 1 CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_LIMIT_MULTIPLE: 0.95 - INSTALL_DIR: ${{ github.workspace }}/install - RELOC_DIR: ${{ github.workspace }}/relloc defaults: run: @@ -52,11 +46,6 @@ jobs: outputs: archive: ${{ steps.create-archive.outputs.archive }} env: - CI_BUILD_STAGE_NAME: build - CI_DEV_ASAN: ${{ inputs.dev-asan }} - CI_DEV_GCOV: ${{ inputs.dev-gcov }} - CI_RUNS_ON: ${{ inputs.os }} - CXX: ${{ inputs.cc == 'clang' && 'clang++' || 'g++' }} CACHE_BASE_KEY: build-${{ inputs.os }}-${{ inputs.cc }} CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total) steps: @@ -78,10 +67,16 @@ jobs: ${{ env.CACHE_KEY }}- - name: Install packages for build - run: ./ci/ci-install.bash + run: ./ci/ci-install.bash build - name: Build - run: ./ci/ci-script.bash + run: | + ./ci/ci-build.bash \ + --prefix ${{ github.workspace }}/install \ + --compiler ${{ inputs.cc }} \ + --ccwarn \ + ${{ inputs.dev-asan && '--asan' || '' }} \ + ${{ inputs.dev-gcov && '--gcov' || '' }} - name: Create repository archive id: create-archive diff --git a/.github/workflows/reusable-lint-py.yml b/.github/workflows/reusable-lint-py.yml index f37027aa7..ae7ff30b6 100644 --- a/.github/workflows/reusable-lint-py.yml +++ b/.github/workflows/reusable-lint-py.yml @@ -8,9 +8,6 @@ on: workflow_call: env: - CI_OS_NAME: linux - CI_BUILD_STAGE_NAME: build - CI_RUNS_ON: ubuntu-22.04 CCACHE_COMPRESS: 1 CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_LIMIT_MULTIPLE: 0.95 @@ -32,7 +29,7 @@ jobs: path: repo - name: Install packages for build - run: ./ci/ci-install.bash + run: ./ci/ci-install.bash build - name: Configure run: | diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml index b36134108..1c393c4f0 100644 --- a/.github/workflows/reusable-test.yml +++ b/.github/workflows/reusable-test.yml @@ -28,12 +28,9 @@ on: type: number env: - CI_OS_NAME: linux CCACHE_COMPRESS: 1 CCACHE_DIR: ${{ github.workspace }}/.ccache CCACHE_LIMIT_MULTIPLE: 0.95 - INSTALL_DIR: ${{ github.workspace }}/install - RELOC_DIR: ${{ github.workspace }}/relloc defaults: run: @@ -46,9 +43,6 @@ jobs: runs-on: ${{ inputs.os }} name: Test env: - CI_BUILD_STAGE_NAME: test - CI_RUNS_ON: ${{ inputs.os }} - CI_RELOC: ${{inputs.reloc }} CXX: ${{ inputs.cc == 'clang' && 'clang++' || 'g++' }} CACHE_BASE_KEY: test-${{ inputs.os }}-${{ inputs.cc }}-${{inputs.reloc }}-${{ inputs.suite }} CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M in total) @@ -78,17 +72,17 @@ jobs: - name: Install test dependencies run: | - ./ci/ci-install.bash + ./ci/ci-install.bash test make venv - name: Test id: run-test continue-on-error: true - env: - TESTS: ${{ inputs.suite }} run: | source .venv/bin/activate - ./ci/ci-script.bash + ./ci/ci-test.bash \ + --suite ${{ inputs.suite }} \ + ${{ inputs.reloc && format('--reloc {0}/reloc', github.workspace) || '' }} - name: Combine code coverage data if: ${{ inputs.dev-gcov }} diff --git a/ci/ci-build.bash b/ci/ci-build.bash new file mode 100755 index 000000000..722ed6563 --- /dev/null +++ b/ci/ci-build.bash @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: CI build job script +# +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +################################################################################ +# Executed in the 'build' stage. +################################################################################ + +# Destructive to the checkout (reconfigures and rebuilds); never run locally +if [ "$GITHUB_ACTIONS" != "true" ]; then + echo "ERROR: $(basename "$0") must only be run in GitHub Actions CI" >&2 + exit 1 +fi + +set -e +set -x + +source "$(dirname "$0")/ci-common.bash" + +################################################################################ +# Parse arguments + +OPT_ASAN=0 +OPT_CCWARN=0 +OPT_GCOV=0 +OPT_COMPILER= +OPT_PREFIX= +while [ $# -gt 0 ]; do + case "$1" in + --asan) OPT_ASAN=1 ;; + --ccwarn) OPT_CCWARN=1 ;; + --compiler) + [ $# -ge 2 ] || fatal "--compiler requires an argument" + OPT_COMPILER="$2" + shift + ;; + --gcov) OPT_GCOV=1 ;; + --prefix) + [ $# -ge 2 ] || fatal "--prefix requires an argument" + OPT_PREFIX="$2" + shift + ;; + *) fatal "Unknown option: '$1'" ;; + esac + shift +done + +[ -n "$OPT_COMPILER" ] || fatal "--compiler is required" +[ -n "$OPT_PREFIX" ] || fatal "--prefix is required" + +# Map the compiler name to the executable name configure CXX expects +case "$OPT_COMPILER" in + clang) CXX=clang++ ;; + gcc) CXX=g++ ;; + *) fatal "Unknown compiler: '$OPT_COMPILER'" ;; +esac + +################################################################################ +# Configure + +CONFIGURE_ARGS="--prefix=$OPT_PREFIX --enable-longtests" +if [ "$OPT_CCWARN" = 1 ]; then + CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-ccwarn" +fi +if [ "$OPT_ASAN" = 1 ]; then + CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-asan" + CXX="$CXX -DVL_LEAK_CHECKS" +fi +if [ "$OPT_GCOV" = 1 ]; then + CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-gcov" +fi +autoconf +./configure $CONFIGURE_ARGS CXX="$CXX" + +################################################################################ +# Build + +ccache -z +"$MAKE" -j "$NPROC" -k +ccache -svv diff --git a/ci/ci-common.bash b/ci/ci-common.bash new file mode 100644 index 000000000..ef2fe23c8 --- /dev/null +++ b/ci/ci-common.bash @@ -0,0 +1,37 @@ +# DESCRIPTION: Verilator: CI common definitions, sourced by the stage scripts +# +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +################################################################################ +# Common definitions sourced by the CI stage scripts; not executed directly. +################################################################################ + +fatal() { + echo "ERROR: $(basename "$0"): $1" >&2; exit 1; +} + +case "$(uname -s)" in + Linux) + HOST_OS=linux + MAKE=make + NPROC=$(nproc) + # Distro id/version; subshell keeps os-release out of our namespace + if [ -r /etc/os-release ]; then + DISTRO_ID=$(. /etc/os-release; echo "$ID") + DISTRO_VERSION=$(. /etc/os-release; echo "$VERSION_ID") + fi + ;; + Darwin) + HOST_OS=macOS + MAKE=make + NPROC=$(sysctl -n hw.logicalcpu) + # Disable ccache, doesn't always work in GitHub Actions + export OBJCACHE= + ;; + *) + fatal "Unknown host OS: '$(uname -s)'" + ;; +esac + +export MAKE diff --git a/ci/ci-install.bash b/ci/ci-install.bash index b3ae2e06d..db71c8159 100755 --- a/ci/ci-install.bash +++ b/ci/ci-install.bash @@ -1,7 +1,7 @@ #!/usr/bin/env bash # DESCRIPTION: Verilator: CI dependency install script # -# SPDX-FileCopyrightText: 2020 Geza Lore +# SPDX-FileCopyrightText: 2026 Wilson Snyder # SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 ################################################################################ @@ -10,30 +10,33 @@ # required by the particular build stage. ################################################################################ +# Installs system packages with sudo; never run locally +if [ "$GITHUB_ACTIONS" != "true" ]; then + echo "ERROR: $(basename "$0") must only be run in GitHub Actions CI" >&2 + exit 1 +fi + set -e set -x cd $(dirname "$0")/.. +source "$(dirname "$0")/ci-common.bash" + +################################################################################ +# Parse arguments + +# Which stage to install dependencies for: 'build' or 'test' +STAGE="$1" + +################################################################################ +# Install dependencies + # Avoid occasional cpan failures "Issued certificate has expired." export PERL_LWP_SSL_VERIFY_HOSTNAME=0 echo "check_certificate = off" >> ~/.wgetrc -fatal() { - echo "ERROR: $(basename "$0"): $1" >&2; exit 1; -} - -if [ "$CI_OS_NAME" = "linux" ]; then - MAKE=make -elif [ "$CI_OS_NAME" = "osx" ]; then - MAKE=make -elif [ "$CI_OS_NAME" = "freebsd" ]; then - MAKE=gmake -else - fatal "Unknown CI_OS_NAME: '$CI_OS_NAME'" -fi - -if [ "$CI_OS_NAME" = "linux" ]; then +if [ "$HOST_OS" = "linux" ]; then # Avoid slow "processing triggers for man db" echo "path-exclude /usr/share/doc/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc echo "path-exclude /usr/share/man/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc @@ -44,100 +47,100 @@ install-wavediff() { source ci/docker/buildenv/wavetools.conf local _base_url="https://github.com/hudson-trading/wavetools/releases/download/${WAVETOOLS_VERSION}" local _platform - if [ "$CI_OS_NAME" = "linux" ]; then + if [ "$HOST_OS" = "linux" ]; then _platform="linux-x86_64" - elif [ "$CI_OS_NAME" = "osx" ]; then + elif [ "$HOST_OS" = "macOS" ]; then _platform="macos-arm64" - elif [ "$CI_OS_NAME" = "windows" ]; then - _platform="windows-x86_64" else - echo "WARNING: No wavetools binary available for CI_OS_NAME=$CI_OS_NAME, skipping" + echo "WARNING: No wavetools binary available for HOST_OS=$HOST_OS, skipping" return 0 fi local _tmpdir _tmpdir=$(mktemp -d) local _archive="wavetools-${WAVETOOLS_VERSION}-${_platform}" - if [ "$CI_OS_NAME" = "windows" ]; then - wget -q -O "${_tmpdir}/${_archive}.zip" "${_base_url}/${_archive}.zip" - unzip -o "${_tmpdir}/${_archive}.zip" -d "${_tmpdir}" - else - wget -q -O "${_tmpdir}/${_archive}.tar.gz" "${_base_url}/${_archive}.tar.gz" - tar -xzf "${_tmpdir}/${_archive}.tar.gz" -C "${_tmpdir}" - fi + wget -q -O "${_tmpdir}/${_archive}.tar.gz" "${_base_url}/${_archive}.tar.gz" + tar -xzf "${_tmpdir}/${_archive}.tar.gz" -C "${_tmpdir}" sudo cp "${_tmpdir}/${_archive}/wavediff" /usr/local/bin/wavediff rm -rf "${_tmpdir}" } -if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then +if [ "$STAGE" = "build" ]; then ############################################################################## # Dependencies of jobs in the 'build' stage, i.e.: packages required to # build Verilator - if [ "$CI_OS_NAME" = "linux" ]; then - sudo apt-get update || - sudo apt-get update - sudo apt-get install --yes ccache help2man libfl-dev || - sudo apt-get install --yes ccache help2man libfl-dev - if [[ ! "$CI_RUNS_ON" =~ "ubuntu-22.04" ]]; then - # Some conflict of libunwind verison on 22.04, can live without it for now - sudo apt-get install --yes libjemalloc-dev || - sudo apt-get install --yes libjemalloc-dev - fi - if [[ "$CI_RUNS_ON" =~ "ubuntu-22.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-24.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-26.04" ]]; then - if [[ ! "$CI_RUNS_ON" =~ "-riscv" ]]; then - sudo apt-get install --yes libsystemc libsystemc-dev || - sudo apt-get install --yes libsystemc libsystemc-dev + if [ "$HOST_OS" = "linux" ]; then + if [ "$DISTRO_ID" = "ubuntu" ]; then + PACKAGES=( + bear + ccache + help2man + libfl-dev + libsystemc-dev + mold + ) + # libunwind conflict on 22.04, can live without libjemalloc there + if [ "$DISTRO_VERSION" != "22.04" ]; then + PACKAGES+=(libjemalloc-dev) fi + sudo apt-get update || + sudo apt-get update + sudo apt-get install --yes "${PACKAGES[@]}" || + sudo apt-get install --yes "${PACKAGES[@]}" fi - if [[ "$CI_RUNS_ON" =~ "ubuntu-22.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-24.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-26.04" ]]; then - sudo apt-get install --yes bear mold || - sudo apt-get install --yes bear mold - fi - elif [ "$CI_OS_NAME" = "osx" ]; then + elif [ "$HOST_OS" = "macOS" ]; then + PACKAGES=( + autoconf + bison + ccache + flex + gperftools + help2man + perl + ) brew update || brew update - brew install ccache perl gperftools autoconf bison flex help2man || - brew install ccache perl gperftools autoconf bison flex help2man - elif [ "$CI_OS_NAME" = "freebsd" ]; then - sudo pkg install -y autoconf bison ccache gmake perl5 + brew install "${PACKAGES[@]}" || + brew install "${PACKAGES[@]}" else - fatal "Unknown CI_OS_NAME: '$CI_OS_NAME'" + fatal "Unknown HOST_OS: '$HOST_OS'" fi - - if [ -n "$CCACHE_DIR" ]; then - mkdir -p "$CCACHE_DIR" - fi -elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then +elif [ "$STAGE" = "test" ]; then ############################################################################## # Dependencies of jobs in the 'test' stage, i.e.: packages required to # run the tests - if [ "$CI_OS_NAME" = "linux" ]; then - sudo apt-get update || - sudo apt-get update - # libfl-dev needed for internal coverage's test runs - sudo apt-get install --yes gdb gtkwave lcov libfl-dev ccache jq z3 || - sudo apt-get install --yes gdb gtkwave lcov libfl-dev ccache jq z3 - # Required for test_regress/t/t_dist_attributes.py - if [[ "$CI_RUNS_ON" =~ "ubuntu-22.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-24.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-26.04" ]]; then - sudo apt-get install --yes python3-clang mold || - sudo apt-get install --yes python3-clang mold + if [ "$HOST_OS" = "linux" ]; then + if [ "$DISTRO_ID" = "ubuntu" ]; then + PACKAGES=( + ccache + gdb + jq + lcov + libfl-dev + libsystemc-dev + mold + python3-clang + z3 + ) + sudo apt-get update || + sudo apt-get update + sudo apt-get install --yes "${PACKAGES[@]}" || + sudo apt-get install --yes "${PACKAGES[@]}" fi - if [[ "$CI_RUNS_ON" =~ "ubuntu-22.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-24.04" ]] || [[ "$CI_RUNS_ON" =~ "ubuntu-26.04" ]]; then - if [[ ! "$CI_RUNS_ON" =~ "-riscv" ]]; then - sudo apt-get install --yes libsystemc libsystemc-dev || - sudo apt-get install --yes libsystemc libsystemc-dev - fi - fi - elif [ "$CI_OS_NAME" = "osx" ]; then + elif [ "$HOST_OS" = "macOS" ]; then + PACKAGES=( + ccache + jq + perl + z3 + ) + brew update || brew update - # brew cask install gtkwave # fst2vcd hangs at launch, so don't bother - brew install ccache perl jq z3 - elif [ "$CI_OS_NAME" = "freebsd" ]; then - # fst2vcd fails with "Could not open '', exiting." - sudo pkg install -y ccache gmake perl5 python3 jq z3 + brew install "${PACKAGES[@]}" || + brew install "${PACKAGES[@]}" else - fatal "Unknown CI_OS_NAME: '$CI_OS_NAME'" + fatal "Unknown HOST_OS: '$HOST_OS'" fi # Common installs install-wavediff @@ -146,5 +149,11 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then else ############################################################################## # Unknown build stage - fatal "Unknown CI_BUILD_STAGE_NAME: '$CI_BUILD_STAGE_NAME'" + fatal "Unknown stage '$STAGE' (expected 'build' or 'test')" fi + +# Report where the tools we may have installed live (ok if some are missing) +for bin in autoconf bear bison ccache flex gdb help2man jq lcov mold perl wavediff z3; do + echo -n "$bin " + which "$bin" || true +done diff --git a/ci/ci-script.bash b/ci/ci-script.bash deleted file mode 100755 index aa7a5987a..000000000 --- a/ci/ci-script.bash +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env bash -# DESCRIPTION: Verilator: CI main job script -# -# SPDX-FileCopyrightText: 2020 Geza Lore -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -################################################################################ -# This is the main script executed in the 'script' phase by all jobs. We use a -# single script to keep the CI setting simple. We pass job parameters via -# environment variables using 'env' keys. -################################################################################ - -set -e -set -x - -fatal() { - echo "ERROR: $(basename "$0"): $1" >&2; exit 1; -} - -if [ "$CI_OS_NAME" = "linux" ]; then - export MAKE=make - NPROC=$(nproc) -elif [ "$CI_OS_NAME" = "osx" ]; then - export MAKE=make - NPROC=$(sysctl -n hw.logicalcpu) - # Disable ccache, doesn't always work in GitHub Actions - export OBJCACHE= -elif [ "$CI_OS_NAME" = "freebsd" ]; then - export MAKE=gmake - NPROC=$(sysctl -n hw.ncpu) -else - fatal "Unknown CI_OS_NAME: '$CI_OS_NAME'" -fi -NPROC=$(expr $NPROC '+' 1) - -if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then - ############################################################################## - # Build verilator - - autoconf - CONFIGURE_ARGS="--enable-longtests --enable-ccwarn" - if [ "$CI_DEV_ASAN" = 1 ]; then - CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-asan" - CXX="$CXX -DVL_LEAK_CHECKS" - fi - if [ "$CI_DEV_GCOV" = 1 ]; then - CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-gcov" - fi - ./configure $CONFIGURE_ARGS --prefix="$INSTALL_DIR" - ccache -z - "$MAKE" -j "$NPROC" -k - # 22.04: ccache -s -v - ccache -s - if [ "$CI_OS_NAME" = "osx" ]; then - file bin/verilator_bin - file bin/verilator_bin_dbg - md5 bin/verilator_bin - md5 bin/verilator_bin_dbg - stat bin/verilator_bin - stat bin/verilator_bin_dbg - fi -elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then - ############################################################################## - # Run tests - - export VERILATOR_TEST_NO_CONTRIBUTORS=1 # Separate workflow check - export VERILATOR_TEST_NO_LINT_PY=1 # Separate workflow check - - if [ "$CI_OS_NAME" = "osx" ]; then - export VERILATOR_TEST_NO_GDB=1 # Pain to get GDB to work on OS X - # TODO below may no longer be required as configure checks for -pg - export VERILATOR_TEST_NO_GPROF=1 # Apple Clang has no -pg - # export PATH="/Applications/gtkwave.app/Contents/Resources/bin:$PATH" # fst2vcd - file bin/verilator_bin - file bin/verilator_bin_dbg - md5 bin/verilator_bin - md5 bin/verilator_bin_dbg - stat bin/verilator_bin - stat bin/verilator_bin_dbg - # For some reason, the dbg exe is corrupted by this point ('file' reports - # it as data rather than a Mach-O). Unclear if this is an OS X issue or - # CI's. Remove the file and re-link... - rm bin/verilator_bin_dbg - "$MAKE" -j "$NPROC" -k - elif [ "$CI_OS_NAME" = "freebsd" ]; then - export VERILATOR_TEST_NO_GDB=1 # Disable for now, ideally should run - # TODO below may no longer be required as configure checks for -pg - export VERILATOR_TEST_NO_GPROF=1 # gprof is a bit different on FreeBSD, disable - fi - - TEST_REGRESS=test_regress - if [ "$CI_RELOC" == 1 ]; then - # Testing that the installation is relocatable. - "$MAKE" install - mkdir -p "$RELOC_DIR" - mv "$INSTALL_DIR" "$RELOC_DIR/relocated-install" - export VERILATOR_ROOT="$RELOC_DIR/relocated-install/share/verilator" - TEST_REGRESS="$RELOC_DIR/test_regress" - mv test_regress "$TEST_REGRESS" - NODIST="$RELOC_DIR/nodist" - mv nodist "$NODIST" - # Feeling brave? - find . -delete - ls -la . - fi - - # Run the specified test - ccache -z - case $TESTS in - dist-vlt-0) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=0/4 - ;; - dist-vlt-1) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=1/4 - ;; - dist-vlt-2) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=2/4 - ;; - dist-vlt-3) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=3/4 - ;; - vltmt-0) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=0/3 - ;; - vltmt-1) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=1/3 - ;; - vltmt-2) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=2/3 - ;; - coverage-dist) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist" - ;; - coverage-vlt-0) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=0/10 - ;; - coverage-vlt-1) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=1/10 - ;; - coverage-vlt-2) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=2/10 - ;; - coverage-vlt-3) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=3/10 - ;; - coverage-vlt-4) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=4/10 - ;; - coverage-vlt-5) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=5/10 - ;; - coverage-vlt-6) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=6/10 - ;; - coverage-vlt-7) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=7/10 - ;; - coverage-vlt-8) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=8/10 - ;; - coverage-vlt-9) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=9/10 - ;; - coverage-vltmt-0) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=0/10 - ;; - coverage-vltmt-1) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=1/10 - ;; - coverage-vltmt-2) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=2/10 - ;; - coverage-vltmt-3) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=3/10 - ;; - coverage-vltmt-4) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=4/10 - ;; - coverage-vltmt-5) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=5/10 - ;; - coverage-vltmt-6) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=6/10 - ;; - coverage-vltmt-7) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=7/10 - ;; - coverage-vltmt-8) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=8/10 - ;; - coverage-vltmt-9) - "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=9/10 - ;; - *) - fatal "Unknown TESTS: $TESTS" - ;; - esac - - # To see load average (1 minute, 5 minute, 15 minute) - uptime - # 22.04: ccache -s -v - ccache -s - -else - ############################################################################## - # Unknown build stage - fatal "Unknown CI_BUILD_STAGE_NAME: '$CI_BUILD_STAGE_NAME'" -fi diff --git a/ci/ci-test.bash b/ci/ci-test.bash new file mode 100755 index 000000000..f35257b94 --- /dev/null +++ b/ci/ci-test.bash @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +# DESCRIPTION: Verilator: CI test job script +# +# SPDX-FileCopyrightText: 2026 Wilson Snyder +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +################################################################################ +# Executed in the 'test' stage. +################################################################################ + +# Destructive to the checkout (runs 'find . -delete'); never run locally +if [ "$GITHUB_ACTIONS" != "true" ]; then + echo "ERROR: $(basename "$0") must only be run in GitHub Actions CI" >&2 + exit 1 +fi + +set -e +set -x + +source "$(dirname "$0")/ci-common.bash" + +################################################################################ +# Parse arguments + +OPT_RELOC= +OPT_SUITE= +while [ $# -gt 0 ]; do + case "$1" in + --reloc) + [ $# -ge 2 ] || fatal "--reloc requires an argument" + OPT_RELOC="$2" + shift + ;; + --suite) + [ $# -ge 2 ] || fatal "--suite requires an argument" + OPT_SUITE="$2" + shift + ;; + *) fatal "Unknown option: '$1'" ;; + esac + shift +done + +[ -n "$OPT_SUITE" ] || fatal "--suite is required" + +################################################################################ +# Run tests + +export VERILATOR_TEST_NO_CONTRIBUTORS=1 # Separate workflow check +export VERILATOR_TEST_NO_LINT_PY=1 # Separate workflow check + +if [ "$HOST_OS" = "macOS" ]; then + export VERILATOR_TEST_NO_GDB=1 # No working GDB on macOS +fi + +TEST_REGRESS=test_regress +if [ -n "$OPT_RELOC" ]; then + # Testing that the installation is relocatable. + "$MAKE" install + # Install prefix, as configured into the Makefile at build time + INSTALL_DIR=$(sed -n 's/^prefix = //p' Makefile) + mkdir -p "$OPT_RELOC" + mv "$INSTALL_DIR" "$OPT_RELOC/relocated-install" + export VERILATOR_ROOT="$OPT_RELOC/relocated-install/share/verilator" + TEST_REGRESS="$OPT_RELOC/test_regress" + mv test_regress "$TEST_REGRESS" + NODIST="$OPT_RELOC/nodist" + mv nodist "$NODIST" + # Delete everything else + find . -delete + ls -la . +fi + +# Run the specified suite +ccache -z +case $OPT_SUITE in + dist-vlt-0) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=0/4 + ;; + dist-vlt-1) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=1/4 + ;; + dist-vlt-2) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=2/4 + ;; + dist-vlt-3) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=3/4 + ;; + vltmt-0) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=0/3 + ;; + vltmt-1) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=1/3 + ;; + vltmt-2) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=2/3 + ;; + coverage-dist) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist" + ;; + coverage-vlt-0) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=0/10 + ;; + coverage-vlt-1) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=1/10 + ;; + coverage-vlt-2) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=2/10 + ;; + coverage-vlt-3) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=3/10 + ;; + coverage-vlt-4) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=4/10 + ;; + coverage-vlt-5) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=5/10 + ;; + coverage-vlt-6) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=6/10 + ;; + coverage-vlt-7) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=7/10 + ;; + coverage-vlt-8) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=8/10 + ;; + coverage-vlt-9) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=9/10 + ;; + coverage-vltmt-0) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=0/10 + ;; + coverage-vltmt-1) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=1/10 + ;; + coverage-vltmt-2) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=2/10 + ;; + coverage-vltmt-3) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=3/10 + ;; + coverage-vltmt-4) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=4/10 + ;; + coverage-vltmt-5) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=5/10 + ;; + coverage-vltmt-6) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=6/10 + ;; + coverage-vltmt-7) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=7/10 + ;; + coverage-vltmt-8) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=8/10 + ;; + coverage-vltmt-9) + "$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=9/10 + ;; + *) + fatal "Unknown suite: $OPT_SUITE" + ;; +esac +ccache -svv +uptime # To see load average