diff --git a/.ci/cmake_ci_build.sh b/.ci/cmake_ci_build.sh new file mode 100755 index 000000000..d38eeb551 --- /dev/null +++ b/.ci/cmake_ci_build.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +set -euo pipefail + +if [ "$#" -lt 1 ]; then + echo "usage: $0 [--] [cmake configure args...]" >&2 + exit 2 +fi + +BUILD_DIR=$1 +shift + +if [ "${1:-}" = "--" ]; then + shift +fi + +USE_NINJA=${DTVM_CI_USE_NINJA:-0} +USE_SCCACHE=${DTVM_CI_USE_SCCACHE:-0} +DRY_RUN=${DTVM_CI_DRY_RUN:-0} +BUILD_JOBS=${DTVM_CI_BUILD_JOBS:-16} + +GENERATOR_ARGS=() +if [ "$USE_NINJA" = "1" ]; then + GENERATOR_ARGS=(-G Ninja) +fi + +LAUNCHER_ARGS=() +if [ "$USE_SCCACHE" = "1" ]; then + LAUNCHER_ARGS=( + -DCMAKE_C_COMPILER_LAUNCHER=sccache + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + ) +fi + +CONFIGURE_CMD=( + cmake + -S . + -B "$BUILD_DIR" + "${GENERATOR_ARGS[@]}" + "${LAUNCHER_ARGS[@]}" + "$@" +) +BUILD_CMD=(cmake --build "$BUILD_DIR" -j "$BUILD_JOBS") + +echo "DTVM CI CMake generator: ${USE_NINJA}" +echo "DTVM CI CMake sccache launcher: ${USE_SCCACHE}" + +printf '+' +printf ' %q' "${CONFIGURE_CMD[@]}" +printf '\n' + +if [ "$DRY_RUN" = "1" ]; then + printf '+' + printf ' %q' "${BUILD_CMD[@]}" + printf '\n' + exit 0 +fi + +if [ "$USE_SCCACHE" = "1" ] && ! command -v sccache >/dev/null 2>&1; then + echo "DTVM_CI_USE_SCCACHE=1 but sccache is not in PATH" >&2 + exit 1 +fi + +"${CONFIGURE_CMD[@]}" + +printf '+' +printf ' %q' "${BUILD_CMD[@]}" +printf '\n' +"${BUILD_CMD[@]}" diff --git a/.ci/run_test_suite.sh b/.ci/run_test_suite.sh index c0b45e430..617f4d423 100644 --- a/.ci/run_test_suite.sh +++ b/.ci/run_test_suite.sh @@ -114,14 +114,25 @@ export PATH=$PATH:$PWD/build CMAKE_OPTIONS_ORIGIN="$CMAKE_OPTIONS" if [[ ${INPUT_FORMAT} == "evm" ]]; then - ./tools/easm2bytecode.sh ./tests/evm_asm ./tests/evm_asm - ./tools/solc_batch_compile.sh + if [ "${DTVM_CI_DRY_RUN:-0}" = "1" ]; then + echo "+ ./tools/easm2bytecode.sh ./tests/evm_asm ./tests/evm_asm" + echo "+ ./tools/solc_batch_compile.sh" + else + ./tools/easm2bytecode.sh ./tests/evm_asm ./tests/evm_asm + ./tools/solc_batch_compile.sh + fi fi for STACK_TYPE in ${STACK_TYPES[@]}; do - rm -rf build - cmake -S . -B build $CMAKE_OPTIONS_ORIGIN $STACK_TYPE - cmake --build build -j 16 + if [ "${DTVM_CI_DRY_RUN:-0}" = "1" ]; then + echo "+ rm -rf build" + else + rm -rf build + fi + .ci/cmake_ci_build.sh build -- $CMAKE_OPTIONS_ORIGIN $STACK_TYPE + if [ "${DTVM_CI_DRY_RUN:-0}" = "1" ]; then + continue + fi case $TestSuite in "microsuite") diff --git a/.github/workflows/dtvm_evm_test_x86.yml b/.github/workflows/dtvm_evm_test_x86.yml index c5ddb7362..dec1f7fc4 100644 --- a/.github/workflows/dtvm_evm_test_x86.yml +++ b/.github/workflows/dtvm_evm_test_x86.yml @@ -56,6 +56,12 @@ jobs: runs-on: ubuntu-latest container: image: dtvmdev1/dtvm-dev-x64:main + env: + SCCACHE_GHA_ENABLED: "true" + SCCACHE_GHA_VERSION: dtvm-ci-sccache-v1 + SCCACHE_BASEDIRS: ${{ github.workspace }} + DTVM_CI_USE_NINJA: "1" + DTVM_CI_USE_SCCACHE: "1" steps: - name: Check out code uses: actions/checkout@v4 @@ -64,12 +70,24 @@ jobs: - name: Code Format Check run: | ./tools/format.sh check + - name: Setup sccache + uses: mozilla-actions/sccache-action@v0.0.10 - name: Build and Test run: | echo "current home is $HOME" export LLVM_SYS_150_PREFIX=/opt/llvm15 export LLVM_DIR=$LLVM_SYS_150_PREFIX/lib/cmake/llvm export PATH=$LLVM_SYS_150_PREFIX/bin:$PATH + echo "DTVM_CI_USE_NINJA=$DTVM_CI_USE_NINJA" + echo "DTVM_CI_USE_SCCACHE=$DTVM_CI_USE_SCCACHE" + echo "SCCACHE_GHA_VERSION=$SCCACHE_GHA_VERSION" + echo "SCCACHE_BASEDIRS=$SCCACHE_BASEDIRS" + which sccache + sccache --version + cmake --version + ninja --version + cc --version | head -n 1 + c++ --version | head -n 1 export CMAKE_BUILD_TARGET=Release export ENABLE_ASAN=true export RUN_MODE=multipass @@ -81,6 +99,45 @@ jobs: export ENABLE_GAS_METER=true bash .ci/run_test_suite.sh + - name: Print sccache stats + if: always() + run: | + if ! command -v sccache >/dev/null 2>&1; then + echo "sccache is not in PATH" + exit 1 + fi + sccache --show-stats + sccache --show-stats --stats-format=json > /tmp/sccache-stats.json + python3 - <<'PY' + import json + import numbers + import sys + + with open("/tmp/sccache-stats.json", encoding="utf-8") as f: + data = json.load(f) + + stats = data.get("stats", {}) + compile_requests = int(stats.get("compile_requests") or 0) + + def sum_numbers(value): + if isinstance(value, bool): + return 0 + if isinstance(value, numbers.Number): + return int(value) + if isinstance(value, dict): + return sum(sum_numbers(item) for item in value.values()) + if isinstance(value, list): + return sum(sum_numbers(item) for item in value) + return 0 + + cache_hits = sum_numbers(stats.get("cache_hits", {}).get("counts", {})) + print(f"sccache compile_requests={compile_requests}") + print(f"sccache aggregate_cache_hits={cache_hits}") + + if compile_requests <= 0: + print("sccache did not observe compiler requests", file=sys.stderr) + sys.exit(1) + PY build_test_evm_interpreter_x86_cli: name: Test DTVM-EVM interpreter with CLI on x86-64