From b34f0be98849d07be62c1345ce743a52cdb15920 Mon Sep 17 00:00:00 2001 From: Trent Houliston Date: Sun, 24 Sep 2023 16:06:24 +1000 Subject: [PATCH] Add ccache to speed up builds (#90) --- .github/workflows/gcc.yaml | 101 ++++++++++++++++++ .github/workflows/linting.yaml | 69 ++++++++++++ .github/workflows/macos.yaml | 63 +++++++++++ .github/workflows/main.yaml | 170 ------------------------------ .github/workflows/sonarcloud.yaml | 29 ++++- .github/workflows/windows.yaml | 85 +++++++++++++++ src/util/demangle.cpp | 6 +- tests/util/demangle.cpp | 2 +- 8 files changed, 348 insertions(+), 177 deletions(-) create mode 100644 .github/workflows/gcc.yaml create mode 100644 .github/workflows/linting.yaml create mode 100644 .github/workflows/macos.yaml delete mode 100644 .github/workflows/main.yaml create mode 100644 .github/workflows/windows.yaml diff --git a/.github/workflows/gcc.yaml b/.github/workflows/gcc.yaml new file mode 100644 index 000000000..4bec64c00 --- /dev/null +++ b/.github/workflows/gcc.yaml @@ -0,0 +1,101 @@ +# Continuous Integration tests +name: GCC + +on: + push: + branches: [main] + pull_request: + branches: [main] + +# Ensure that only one instance of the workflow is run at a time for each branch/tag. +# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. +# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. +concurrency: + # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier + group: ${{ format('{0}:{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + linux-gcc: + strategy: + matrix: + toolchain: + - container: ubuntu:22.04 + version: "13" + - container: ubuntu:22.04 + version: "12" + - container: ubuntu:22.04 + version: "11" + - container: ubuntu:22.04 + version: "10" + - container: ubuntu:22.04 + version: "9" + - container: ubuntu:20.04 + version: "8" + - container: ubuntu:20.04 + version: "7" + - container: ubuntu:18.04 + version: "6" + - container: ubuntu:18.04 + version: "5" + + name: Linux GCC-${{ matrix.toolchain.version }} + runs-on: ubuntu-latest + continue-on-error: true + + # Use the container for this specific version of gcc + container: ${{ matrix.toolchain.container }} + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + # Update for all the actions that need to install stuff + - run: | + apt-get update + apt-get install -y software-properties-common + + - name: Install GCC + run: | + add-apt-repository ppa:ubuntu-toolchain-r/test + apt-get update + apt-get install -y gcc-${{ matrix.toolchain.version }} g++-${{ matrix.toolchain.version }} + + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }}-gcc-${{ matrix.toolchain.version }} + max-size: 100M + + - name: Configure CMake + run: | + cmake -E make_directory build + cmake -S . -B build \ + -GNinja \ + -DCMAKE_C_COMPILER=/usr/bin/gcc-${{ matrix.toolchain.version }} \ + -DCMAKE_CXX_COMPILER=/usr/bin/g++-${{ matrix.toolchain.version }} \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCI_BUILD=ON \ + -DENABLE_CLANG_TIDY=OFF + + - name: Build + timeout-minutes: 30 + run: cmake --build build --config Release + + - name: CCache Stats + run: ccache --show-stats + + - name: Test + timeout-minutes: 10 + run: | + build/tests/test_nuclear + for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done diff --git a/.github/workflows/linting.yaml b/.github/workflows/linting.yaml new file mode 100644 index 000000000..b7f933710 --- /dev/null +++ b/.github/workflows/linting.yaml @@ -0,0 +1,69 @@ +name: Linting + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [main] + pull_request: + branches: [main] + +# Ensure that only one instance of the workflow is run at a time for each branch/tag. +# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. +# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. +concurrency: + # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier + group: ${{ format('{0}:{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + linux-clang-tidy: + name: Linux Clang-Tidy + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Install clang-tidy-15 + run: | + wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - + echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee /etc/apt/sources.list.d/llvm-15 + echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee -a /etc/apt/sources.list.d/llvm-15 + sudo apt-get update + sudo apt-get install -y clang-tidy-15 + + # Download and install cmake + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + # Download and setup ccache + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }} + max-size: 100M + + - name: Configure CMake + run: | + cmake -E make_directory build + cmake -S . -B build \ + -GNinja \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCI_BUILD=ON \ + -DENABLE_CLANG_TIDY=ON + + - name: Build + timeout-minutes: 30 + # Execute the build. You can specify a specific target with "--target " + run: cmake --build build --config Release --parallel 2 + + - name: CCache Stats + run: ccache --show-stats diff --git a/.github/workflows/macos.yaml b/.github/workflows/macos.yaml new file mode 100644 index 000000000..c90283799 --- /dev/null +++ b/.github/workflows/macos.yaml @@ -0,0 +1,63 @@ +# Continuous Integration tests +name: MacOS + +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [main] + pull_request: + branches: [main] + +# Ensure that only one instance of the workflow is run at a time for each branch/tag. +# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. +# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. +concurrency: + # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier + group: ${{ format('{0}:{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + macos-latest: + name: MacOS Latest + runs-on: macos-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }} + max-size: 100M + + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + - name: Configure CMake + run: | + cmake -E make_directory build + cmake -S . -B build \ + -GNinja \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Release \ + -DCI_BUILD=ON \ + -DENABLE_CLANG_TIDY=OFF + + - name: Build + timeout-minutes: 30 + run: cmake --build build --config Release + + - name: CCache Stats + run: ccache --show-stats + + - name: Test + timeout-minutes: 10 + run: | + build/tests/test_nuclear + for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml deleted file mode 100644 index af028dc64..000000000 --- a/.github/workflows/main.yaml +++ /dev/null @@ -1,170 +0,0 @@ -# Continuous Integration tests -name: CI - -# Controls when the action will run. -on: - # Triggers the workflow on push or pull request events but only for the main branch - push: - branches: [main] - pull_request: - branches: [main] - -# Ensure that only one instance of the workflow is run at a time for each branch/tag. -# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. -# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. -concurrency: - # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier - group: ${{ format('{0}:{1}', github.workflow, github.ref) }} - cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - build-linux: - name: Linux GCC - - strategy: - matrix: - container: - ["gcc:5", "gcc:7", "gcc:9", "gcc:10", "gcc:11", "gcc:12", "gcc:13"] - - # The type of runner that the job will run on - runs-on: ubuntu-latest - continue-on-error: true - - # Use the container for this specific version of gcc - container: ${{ matrix.container }} - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - # Download and install cmake - - name: Install CMake - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.27.1 - ninjaVersion: 1.11.1 - - - name: Configure CMake - run: | - cmake -E make_directory build - cmake -S . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCI_BUILD=ON - - - name: Build - timeout-minutes: 30 - # Execute the build. You can specify a specific target with "--target " - run: cmake --build build --config Release --parallel 2 - - - name: Test - timeout-minutes: 10 - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: | - build/tests/test_nuclear - for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done - - build-osx: - name: MacOS Clang - runs-on: macos-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Configure CMake - run: | - cmake -E make_directory build - cmake -S . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release - - - name: Build - timeout-minutes: 30 - # Execute the build. You can specify a specific target with "--target " - run: cmake --build build --config Release --parallel 2 - - - name: Test - timeout-minutes: 10 - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: | - build/tests/test_nuclear - for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done - - build-windows: - name: Windows MSVC - - # The type of runner that the job will run on - runs-on: windows-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Configure CMake - run: | - cmake -E make_directory build - cmake -S . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release - - - name: Build - timeout-minutes: 30 - # Execute the build. You can specify a specific target with "--target " - run: cmake --build build --config Release --parallel 2 - - - name: Test - timeout-minutes: 10 - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: | - build/tests/Release/test_nuclear.exe - for f in build/tests/individual/Release/*; do echo "Testing $f"; ./$f; done - shell: bash - - check-clang-tidy-linux: - name: Clang-Tidy Linux - runs-on: ubuntu-latest - - steps: - - name: Install clang-tidy-15 - run: | - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee /etc/apt/sources.list.d/llvm-15 - echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main" | sudo tee -a /etc/apt/sources.list.d/llvm-15 - sudo apt-get update - sudo apt-get install -y clang-tidy-15 - - - name: Checkout Code - uses: actions/checkout@v3 - - # Download and install cmake - - name: Install CMake - uses: lukka/get-cmake@latest - with: - cmakeVersion: 3.27.1 - ninjaVersion: 1.11.1 - - - name: Configure CMake - run: | - cmake -E make_directory build - cmake -S . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCI_BUILD=ON -DENABLE_CLANG_TIDY=ON - - - name: Build - timeout-minutes: 30 - # Execute the build. You can specify a specific target with "--target " - run: cmake --build build --config Release --parallel 2 - - check-clang-tidy-msvc: - name: Clang-Tidy MSVC - runs-on: windows-latest - - steps: - - name: Checkout Code - uses: actions/checkout@v3 - - - name: Configure CMake - run: | - cmake -E make_directory build - cmake -S . -B build -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release -DCI_BUILD=ON -DENABLE_CLANG_TIDY=ON - - - name: Build - timeout-minutes: 30 - # Execute the build. You can specify a specific target with "--target " - run: cmake --build build --config Release --parallel 2 diff --git a/.github/workflows/sonarcloud.yaml b/.github/workflows/sonarcloud.yaml index c81078dd7..10f1f3c51 100644 --- a/.github/workflows/sonarcloud.yaml +++ b/.github/workflows/sonarcloud.yaml @@ -31,11 +31,34 @@ jobs: - name: Install sonar-scanner and build-wrapper uses: SonarSource/sonarcloud-github-c-cpp@v2 - - name: Run build-wrapper + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }} + max-size: 100M + + - name: Configure CMake run: | cmake -E make_directory build - cmake -S . -B build -DCMAKE_CXX_FLAGS="--coverage" -DBUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCI_BUILD=ON - build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Debug + cmake -S . -B build \ + -GNinja \ + -DCMAKE_CXX_FLAGS="--coverage" \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DBUILD_TESTS=ON \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCI_BUILD=ON \ + -DENABLE_CLANG_TIDY=OFF + + - name: Build with Sonar Wrapper + timeout-minutes: 30 + run: build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Debug - name: Run tests to generate coverage statistics timeout-minutes: 10 diff --git a/.github/workflows/windows.yaml b/.github/workflows/windows.yaml new file mode 100644 index 000000000..500b9ea75 --- /dev/null +++ b/.github/workflows/windows.yaml @@ -0,0 +1,85 @@ +# Continuous Integration tests +name: Windows + +on: + push: + branches: [main] + pull_request: + branches: [main] + +# Ensure that only one instance of the workflow is run at a time for each branch/tag. +# Jobs currently running on the branch/tag will be cancelled when new commits are pushed. +# See https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#concurrency. +concurrency: + # `github.workflow` is the workflow name, `github.ref` is the current branch/tag identifier + group: ${{ format('{0}:{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + windows-latest: + name: Windows Latest ${{ matrix.toolchain.name }} + + strategy: + matrix: + toolchain: + - name: MSVC + c: cl + cxx: cl + # Code does not compile on GCC on windows + # - name: GCC + # c: gcc + # cxx: g++ + + runs-on: windows-latest + continue-on-error: true + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Setup CCache + uses: hendrikmuhs/ccache-action@v1.2 + with: + key: ${{ github.job }}-${{ matrix.toolchain.name }} + max-size: 100M + variant: sccache + + - name: Install CMake + uses: lukka/get-cmake@latest + with: + cmakeVersion: 3.27.1 + ninjaVersion: 1.11.1 + + # This lets ninja find MSVC + - name: Add MSVC to path + uses: ilammy/msvc-dev-cmd@v1 + + - name: Configure CMake + shell: cmd + run: | + cmake -E make_directory build + cmake -S . -B build ^ + -GNinja ^ + -DCMAKE_C_COMPILER=${{ matrix.toolchain.c }} ^ + -DCMAKE_CXX_COMPILER=${{ matrix.toolchain.cxx }} ^ + -DCMAKE_C_COMPILER_LAUNCHER=sccache ^ + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache ^ + -DBUILD_TESTS=ON ^ + -DCMAKE_BUILD_TYPE=Release ^ + -DCI_BUILD=ON ^ + -DENABLE_CLANG_TIDY=OFF + + - name: Build + timeout-minutes: 30 + run: cmake --build build --config Release + + - name: SCCache Stats + run: sccache --show-stats + + - name: Test + timeout-minutes: 10 + shell: bash + run: | + build/tests/test_nuclear.exe + for f in build/tests/individual/*; do echo "Testing $f"; ./$f; done diff --git a/src/util/demangle.cpp b/src/util/demangle.cpp index fd6ed6480..1e9dbd235 100644 --- a/src/util/demangle.cpp +++ b/src/util/demangle.cpp @@ -62,9 +62,9 @@ namespace util { } std::string demangle(const char* symbol) { - // If the symbol is the empty string then just return it - if (symbol != nullptr && symbol[0] == '\0') { - return symbol; + // If the symbol is null or the empty string then just return it + if (symbol == nullptr || symbol[0] == '\0') { + return ""; } std::lock_guard lock(symbol_mutex); diff --git a/tests/util/demangle.cpp b/tests/util/demangle.cpp index 955f63ad0..2b1cde9cd 100644 --- a/tests/util/demangle.cpp +++ b/tests/util/demangle.cpp @@ -76,7 +76,7 @@ SCENARIO("Test the demangle function correctly demangles symbols", "[util][deman const char* symbol = nullptr; WHEN("Demangle is called") { - std::string result = NUClear::util::demangle(symbol); + const std::string result = NUClear::util::demangle(symbol); THEN("It should return an empty string") { REQUIRE(result.empty());