diff --git a/.github/workflows/cmake-linux.yml b/.github/workflows/cmake-linux.yml index ec2fefd6..aa4efae0 100644 --- a/.github/workflows/cmake-linux.yml +++ b/.github/workflows/cmake-linux.yml @@ -26,6 +26,12 @@ jobs: steps: - uses: actions/checkout@v6 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: ${{ github.job }} + max-size: "5G" + - name: Install required packages shell: bash run: | @@ -47,7 +53,7 @@ jobs: run: | mkdir build_linux cd build_linux - cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. + cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache .. # Build so we have all required .h and .c/.cpp files make -j$(nproc) @@ -75,6 +81,20 @@ jobs: steps: - uses: actions/checkout@v6 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + if: ${{ matrix.os == 'ubuntu-22.04-arm' }} + with: + key: ${{ github.job }}-aarch64 + max-size: "5G" + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + if: ${{ matrix.os == 'ubuntu-22.04' }} + with: + key: ${{ github.job }}-x86_64 + max-size: "5G" + - name: Install LLVM/Clang >=20.0 run: | set -euxo pipefail @@ -144,7 +164,7 @@ jobs: working-directory: ${{github.workspace}} run: | . ./rade-venv/bin/activate - BUILD_TYPE=Release CC=clang-21 CXX=clang++-21 PGO_INSTRUMENT=1 ENABLE_LTO=1 STATIC_LIBGCC=1 ./build_linux.sh + BUILD_TYPE=Release CC=clang-21 CXX=clang++-21 USE_CCACHE=1 PGO_INSTRUMENT=1 ENABLE_LTO=1 STATIC_LIBGCC=1 ./build_linux.sh - name: Generate optimization profile shell: bash @@ -457,6 +477,12 @@ jobs: # with: # detached: true + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.sanitizer }}-${{ matrix.native-audio }} + max-size: "5G" + - name: Install LLVM/Clang >=20.0 if: ${{ matrix.os == 'ubuntu-24.04' || matrix.os == 'ubuntu-24.04-arm' }} run: | @@ -552,7 +578,7 @@ jobs: if: ${{ matrix.sanitizer != 'WITH_ASAN=0' }} run: | . ./rade-venv/bin/activate - UT_ENABLE=1 CC=clang-21 CXX=clang++-21 ${{matrix.native-audio}} ${{matrix.sanitizer}} ./build_linux.sh + UT_ENABLE=1 CC=clang-21 CXX=clang++-21 USE_CCACHE=1 ${{matrix.native-audio}} ${{matrix.sanitizer}} ./build_linux.sh - name: Build freedv-gui shell: bash @@ -560,7 +586,7 @@ jobs: if: ${{ matrix.sanitizer == 'WITH_ASAN=0' }} run: | . ./rade-venv/bin/activate - UT_ENABLE=1 CC=clang-21 CXX=clang++-21 ${{matrix.native-audio}} ${{matrix.sanitizer}} ./build_linux.sh + UT_ENABLE=1 CC=clang-21 CXX=clang++-21 USE_CCACHE=1 ${{matrix.native-audio}} ${{matrix.sanitizer}} ./build_linux.sh - name: Execute unit tests shell: bash diff --git a/.github/workflows/cmake-macos.yml b/.github/workflows/cmake-macos.yml index 985dd35c..2afde805 100644 --- a/.github/workflows/cmake-macos.yml +++ b/.github/workflows/cmake-macos.yml @@ -20,6 +20,12 @@ jobs: steps: - uses: actions/checkout@v6 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: ${{ github.job }} + max-size: "5G" + - name: Install needed packages run: | brew install automake libtool numpy sox wxwidgets speexdsp portaudio libsndfile hamlib libebur128 @@ -42,7 +48,7 @@ jobs: run: | mkdir build_osx cd build_osx - CC=clang CXX=clang++ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. + CC=clang CXX=clang++ cmake -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .. # Build so we have all required .h and .c/.cpp files make -j$(sysctl -n hw.logicalcpu) @@ -64,6 +70,13 @@ jobs: steps: - uses: actions/checkout@v6 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.sanitizer }} + create-symlink: true + max-size: "5G" + #- name: Setup tmate session # uses: mxschmitt/action-tmate@v3 # with: @@ -145,6 +158,25 @@ jobs: # with: # detached: true + # There's a bug where macos-26 ends up downloading macos-26-intel's cache and thus + # having few/no cache hits. To prevent this, we make sure that the cache key is unique + # enough on both platforms to avoid inadvertent matches. + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + if: ${{ matrix.os == 'macos-26-intel' }} + with: + key: ${{ github.job }}-x86_64 + max-size: "5G" + create-symlink: true + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + if: ${{ matrix.os == 'macos-26' }} + with: + key: ${{ github.job }}-aarch64 + max-size: "5G" + create-symlink: true + - name: Install needed packages run: | brew install automake libtool numpy sox llvm@20 lld@20 # note: LLVM 21 introduces incompatibilities - see https://github.com/Homebrew/homebrew-core/issues/235411 @@ -174,7 +206,7 @@ jobs: shell: bash working-directory: ${{github.workspace}} run: | - BUILD_TYPE=Release UT_ENABLE=0 UNIV_BUILD=0 BUILD_DEPS=1 PGO_INSTRUMENT=1 ENABLE_LTO=1 ./build_osx.sh + BUILD_TYPE=Release UT_ENABLE=0 UNIV_BUILD=0 BUILD_DEPS=1 PGO_INSTRUMENT=1 ENABLE_LTO=1 USE_CCACHE=1 ./build_osx.sh - name: Generate optimization profile shell: bash diff --git a/.github/workflows/cmake-windows.yml b/.github/workflows/cmake-windows.yml index 221ba6a4..4e9372ae 100644 --- a/.github/workflows/cmake-windows.yml +++ b/.github/workflows/cmake-windows.yml @@ -28,6 +28,13 @@ jobs: steps: - uses: actions/checkout@v6 + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2.23 + with: + key: ${{ github.job }}-${{ matrix.arch }} + max-size: "5G" + verbose: 2 + - name: Install required packages shell: bash working-directory: ${{github.workspace}} @@ -49,7 +56,7 @@ jobs: export PATH=${{github.workspace}}/llvm-mingw-20251216-ucrt-ubuntu-22.04-x86_64/bin:$PATH mkdir build_windows cd build_windows - cmake -DENABLE_LTO=1 -DPGO_INSTRUMENT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/cross-compile/freedv-mingw-llvm-${{ matrix.arch }}.cmake .. + cmake -DENABLE_LTO=1 -DPGO_INSTRUMENT=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_TOOLCHAIN_FILE=${{github.workspace}}/cross-compile/freedv-mingw-llvm-${{ matrix.arch }}.cmake .. - name: Build freedv-gui (unsigned) shell: bash diff --git a/USER_MANUAL.md b/USER_MANUAL.md index a08ed48f..710b6a19 100644 --- a/USER_MANUAL.md +++ b/USER_MANUAL.md @@ -992,6 +992,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes * Require C++20 to build FreeDV. (PR #1440) * Enable LTO/PGO for macOS .app build. (PR #1456) * Enable PGO for Windows builds. (PR #1457) + * Add support for CCache. (PR #1328) 4. Other: * FlexRadio/KA9Q integrations moved to freedv-integrations repo. (PR #1368) * Improve tab save/load behavior on systems with wxWidgets 3.3+. (PR #1435) diff --git a/build_linux.sh b/build_linux.sh index 886c51ca..6091be9e 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -18,14 +18,21 @@ STATIC_LIBGCC=${STATIC_LIBGCC:-0} ENABLE_LTO=${ENABLE_LTO:-0} PGO_INSTRUMENT=${PGO_INSTRUMENT:-0} PGO_USE_PROFILE=${PGO_USE_PROFILE:-} +USE_CCACHE=${USE_CCACHE:-0} export FREEDVGUIDIR=${PWD} +if [ $USE_CCACHE == 1 ]; then + CCACHE_ARGS="-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache" +else + CCACHE_ARGS="" +fi + # Finally, build freedv-gui cd $FREEDVGUIDIR if [ -d .git ]; then git pull fi mkdir -p build_linux && cd build_linux && rm -Rf * -cmake -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DSTATIC_LIBGCC=${STATIC_LIBGCC} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DUNITTEST=$UT_ENABLE .. +cmake ${CCACHE_ARGS} -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DSTATIC_LIBGCC=${STATIC_LIBGCC} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DUNITTEST=$UT_ENABLE .. make -j$(nproc) diff --git a/build_osx.sh b/build_osx.sh index d390bc73..349bf542 100755 --- a/build_osx.sh +++ b/build_osx.sh @@ -5,7 +5,6 @@ # lpcnet repos so they are available for parallel development. export FREEDVGUIDIR=${PWD} -export HAMLIBDIR=$FREEDVGUIDIR/hamlib export UT_ENABLE=${UT_ENABLE:-0} export UNIV_BUILD=${UNIV_BUILD:-1} export CODESIGN_IDENTITY=${CODESIGN_IDENTITY:--} @@ -19,6 +18,7 @@ export WITH_UBSAN=${WITH_UBSAN:-0} export ENABLE_LTO=${ENABLE_LTO:-0} export PGO_INSTRUMENT=${PGO_INSTRUMENT:-0} export PGO_USE_PROFILE=${PGO_USE_PROFILE:-} +export USE_CCACHE=${USE_CCACHE:-0} # Prerequisite: build dylibbundler if [ ! -d macdylibbundler ]; then @@ -28,25 +28,7 @@ if [ ! -d macdylibbundler ]; then cd .. fi -# Prerequisite: build hamlib -cd $FREEDVGUIDIR -if [ $BUILD_DEPS == 1 ]; then - if [ ! -d hamlib-code ]; then - git clone https://github.com/Hamlib/Hamlib.git hamlib-code - fi - cd hamlib-code && git checkout 4.7.2 && git pull - ./bootstrap - if [ $UNIV_BUILD == 1 ]; then - CFLAGS="-g -O3 -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" CXXFLAGS="-g -O3 -mmacosx-version-min=11.0 -arch x86_64 -arch arm64" ./configure --enable-shared --prefix $HAMLIBDIR --without-libusb - else - CFLAGS="-g -O3 -mmacosx-version-min=11.0" CXXFLAGS="-g -O3 -mmacosx-version-min=11.0" ./configure --enable-shared --prefix $HAMLIBDIR --without-libusb - fi - - make -j$(sysctl -n hw.logicalcpu) - make install -fi - -# Finally, build freedv-gui +# Build freedv-gui cd $FREEDVGUIDIR if [ -d .git ]; then git pull @@ -57,10 +39,16 @@ if [ "$CODESIGN_KEYCHAIN_PROFILE" != "" ]; then export CODESIGN_KEYCHAIN_PROFILE_ARG=-DMACOS_CODESIGN_KEYCHAIN_PROFILE=$CODESIGN_KEYCHAIN_PROFILE fi -if [ $BUILD_DEPS == 1 ]; then - cmake -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DBOOTSTRAP_WXWIDGETS=1 -DUSE_STATIC_SPEEXDSP=1 -DUSE_STATIC_PORTAUDIO=1 -DUSE_STATIC_SAMPLERATE=1 -DUSE_STATIC_SNDFILE=1 -DUSE_STATIC_LIBRESSL=1 -DHAMLIB_INCLUDE_DIR=${HAMLIBDIR}/include -DHAMLIB_LIBRARY=${HAMLIBDIR}/lib/libhamlib.dylib -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} .. +if [ $USE_CCACHE == 1 ]; then + CCACHE_ARGS=-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_OBJCXX_COMPILER_LAUNCHER=ccache else - cmake -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} .. + CCACHE_ARGS= +fi + +if [ $BUILD_DEPS == 1 ]; then + cmake ${CCACHE_ARGS} -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DBOOTSTRAP_WXWIDGETS=1 -DUSE_STATIC_SPEEXDSP=1 -DUSE_STATIC_PORTAUDIO=1 -DUSE_STATIC_SAMPLERATE=1 -DUSE_STATIC_SNDFILE=1 -DUSE_STATIC_LIBRESSL=1 -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} .. +else + cmake ${CCACHE_ARGS} -DCMAKE_AR=/usr/bin/ar -DCMAKE_RANLIB=/usr/bin/ranlib -DPGO_INSTRUMENT=${PGO_INSTRUMENT} -DPGO_USE_PROFILE=${PGO_USE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DENABLE_UBSAN=${WITH_UBSAN} -DENABLE_TSAN=${WITH_TSAN} -DENABLE_RTSAN=${WITH_RTSAN} -DENABLE_ASAN=${WITH_ASAN} -DUSE_NATIVE_AUDIO=$USE_NATIVE_AUDIO -DBUILD_OSX_UNIVERSAL=${UNIV_BUILD} -DUNITTEST=$UT_ENABLE -DMACOS_CODESIGN_IDENTITY=${CODESIGN_IDENTITY} ${CODESIGN_KEYCHAIN_PROFILE_ARG} .. fi make -j$(sysctl -n hw.logicalcpu)