Skip to content

Commit 6f3aeca

Browse files
author
Aliaksandr Adziareika
committed
Introduce ccache-setup action
1 parent 27c6b1f commit 6f3aeca

File tree

2 files changed

+201
-0
lines changed

2 files changed

+201
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
name: Setup ccache
2+
description: Configure ccache for faster builds with caching
3+
4+
inputs:
5+
cmake-config-args:
6+
description: 'CMake configure arguments (used to extract compiler for cache key)'
7+
required: false
8+
default: ''
9+
cmake-build-type:
10+
description: 'Build type (Release, Debug) for cache key'
11+
required: false
12+
default: ''
13+
target-arch:
14+
description: 'Target architecture for cross-compilation (e.g., x86-32, arm64). If not set, detected from host.'
15+
required: false
16+
default: ''
17+
cache-key-prefix:
18+
description: 'Prefix for cache key (e.g., opendaq, test). If not set, no prefix is used.'
19+
required: false
20+
default: ''
21+
22+
outputs:
23+
cache-hit:
24+
description: 'Whether cache was restored'
25+
value: ${{ steps.cache.outputs.cache-hit }}
26+
cache-key:
27+
description: 'The cache key used'
28+
value: ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.arch }}-${{ steps.ccache-key.outputs.compiler }}-${{ steps.ccache-key.outputs.build-type }}-${{ steps.ccache-key.outputs.short-sha }}
29+
30+
runs:
31+
using: composite
32+
steps:
33+
- name: Install ccache
34+
shell: bash
35+
run: |
36+
if ! command -v ccache &> /dev/null; then
37+
echo "Installing ccache..."
38+
if command -v apt-get &> /dev/null; then
39+
sudo apt-get update && sudo apt-get install -y ccache
40+
elif command -v brew &> /dev/null; then
41+
HOMEBREW_NO_AUTO_UPDATE=1 brew install ccache
42+
elif command -v choco &> /dev/null; then
43+
choco install ccache -y --no-progress
44+
else
45+
echo "::error::✗ Cannot install ccache: no supported package manager found"
46+
exit 1
47+
fi
48+
fi
49+
echo "ccache version: $(ccache --version | head -1)"
50+
51+
- name: Calculate ccache key
52+
id: ccache-key
53+
shell: bash
54+
env:
55+
CMAKE_CONFIG_ARGS: ${{ inputs.cmake-config-args }}
56+
CMAKE_BUILD_TYPE: ${{ inputs.cmake-build-type }}
57+
run: |
58+
CCACHE_DIR="${{ github.workspace }}/.ccache"
59+
echo "dir=$CCACHE_DIR" >> "$GITHUB_OUTPUT"
60+
echo "CCACHE_DIR=$CCACHE_DIR" >> "$GITHUB_ENV"
61+
62+
# Get OS and version (e.g., ubuntu-22.04, macos-14.0, windows-2022)
63+
if [[ "$OSTYPE" == "darwin"* ]]; then
64+
DISTRO="macos"
65+
VERSION=$(sw_vers -productVersion | cut -d. -f1,2)
66+
elif [[ "$OSTYPE" == "msys"* ]] || [[ "$OSTYPE" == "cygwin"* ]] || [[ -n "$WINDIR" ]]; then
67+
DISTRO="windows"
68+
VERSION="nt$(powershell -Command "[System.Environment]::OSVersion.Version.Major")"
69+
else
70+
DISTRO=$(lsb_release -is | tr '[:upper:]' '[:lower:]')
71+
VERSION=$(lsb_release -rs)
72+
fi
73+
echo "distro=${DISTRO}-${VERSION}" >> "$GITHUB_OUTPUT"
74+
75+
# Get architecture (e.g., x86-64, arm64, x86-32)
76+
# Priority: 1) target-arch input, 2) -A flag from cmake args, 3) detect from host
77+
if [ -n "${{ inputs.target-arch }}" ]; then
78+
ARCH="${{ inputs.target-arch }}"
79+
else
80+
# Try to extract from CMake -A flag (e.g., -A Win32, -A x64, -A ARM64)
81+
CMAKE_ARCH=$(echo "$CMAKE_CONFIG_ARGS" | grep -oE '\-A\s*(Win32|x64|ARM64|ARM)' | awk '{print $2}')
82+
if [ -n "$CMAKE_ARCH" ]; then
83+
case "$CMAKE_ARCH" in
84+
x64) ARCH="x86-64" ;;
85+
Win32) ARCH="x86-32" ;;
86+
ARM64) ARCH="arm64" ;;
87+
ARM) ARCH="arm32" ;;
88+
esac
89+
else
90+
ARCH=$(uname -m)
91+
case "$ARCH" in
92+
x86_64) ARCH="x86-64" ;;
93+
aarch64) ARCH="arm64" ;;
94+
armv7l) ARCH="arm32" ;;
95+
i686) ARCH="x86-32" ;;
96+
esac
97+
fi
98+
fi
99+
echo "arch=$ARCH" >> "$GITHUB_OUTPUT"
100+
101+
# Extract compiler from cmake-config-args (e.g., gcc-12, clang-14)
102+
# Using sed instead of grep -P for cross-platform compatibility (Windows Git Bash lacks Perl regex)
103+
COMPILER=$(echo "$CMAKE_CONFIG_ARGS" | sed -n 's/.*-DCMAKE_CXX_COMPILER=\([^ ]*\).*/\1/p' | sed 's/+//g')
104+
if [ -z "$COMPILER" ]; then
105+
COMPILER="unknown"
106+
fi
107+
echo "compiler=$COMPILER" >> "$GITHUB_OUTPUT"
108+
109+
# Build type in lowercase (e.g., release, debug)
110+
BUILD_TYPE=$(echo "$CMAKE_BUILD_TYPE" | tr '[:upper:]' '[:lower:]')
111+
echo "build-type=$BUILD_TYPE" >> "$GITHUB_OUTPUT"
112+
113+
# Short commit hash
114+
SHORT_SHA=$(echo "${{ github.sha }}" | head -c 7)
115+
echo "short-sha=$SHORT_SHA" >> "$GITHUB_OUTPUT"
116+
117+
# Cache key prefix (e.g., opendaq, test)
118+
PREFIX="${{ inputs.cache-key-prefix }}"
119+
if [ -n "$PREFIX" ]; then
120+
echo "prefix=${PREFIX}-" >> "$GITHUB_OUTPUT"
121+
else
122+
echo "prefix=" >> "$GITHUB_OUTPUT"
123+
fi
124+
125+
- name: Restore ccache
126+
id: cache
127+
uses: actions/cache@v4
128+
with:
129+
path: ${{ steps.ccache-key.outputs.dir }}
130+
key: ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.arch }}-${{ steps.ccache-key.outputs.compiler }}-${{ steps.ccache-key.outputs.build-type }}-${{ steps.ccache-key.outputs.short-sha }}
131+
restore-keys: |
132+
ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.arch }}-${{ steps.ccache-key.outputs.compiler }}-${{ steps.ccache-key.outputs.build-type }}-
133+
ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.arch }}-${{ steps.ccache-key.outputs.compiler }}-
134+
ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.compiler }}-${{ steps.ccache-key.outputs.build-type }}-
135+
ccache-${{ steps.ccache-key.outputs.prefix }}${{ steps.ccache-key.outputs.distro }}-${{ steps.ccache-key.outputs.compiler }}-
136+
137+
- name: Configure ccache
138+
shell: bash
139+
run: |
140+
ccache --set-config=cache_dir="$CCACHE_DIR"
141+
ccache --set-config=max_size=2G
142+
ccache --set-config=compression=true
143+
ccache -z # Zero statistics
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Test ccache-setup action
2+
3+
on:
4+
push:
5+
branches: [actions/ccache-setup]
6+
7+
jobs:
8+
test:
9+
strategy:
10+
fail-fast: false
11+
matrix:
12+
include:
13+
- os: ubuntu-latest
14+
compiler: g++-12
15+
- os: ubuntu-24.04-arm
16+
compiler: g++-12
17+
- os: macos-latest
18+
compiler: clang++
19+
- os: windows-latest
20+
compiler: cl
21+
runs-on: ${{ matrix.os }}
22+
name: Test on ${{ matrix.os }}
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- name: Run ccache-setup
29+
id: ccache
30+
uses: ./.github/actions/ccache-setup
31+
with:
32+
cmake-config-args: '-DCMAKE_CXX_COMPILER=${{ matrix.compiler }}'
33+
cmake-build-type: Release
34+
cache-key-prefix: test
35+
36+
- name: Verify ccache installed
37+
shell: bash
38+
run: |
39+
echo "=== ccache version ==="
40+
ccache --version
41+
42+
- name: Verify environment
43+
shell: bash
44+
run: |
45+
echo "=== CCACHE_DIR ==="
46+
echo "$CCACHE_DIR"
47+
48+
echo "=== Cache key ==="
49+
echo "${{ steps.ccache.outputs.cache-key }}"
50+
51+
echo "=== Cache hit ==="
52+
echo "${{ steps.ccache.outputs.cache-hit }}"
53+
54+
- name: Verify ccache configuration
55+
shell: bash
56+
run: |
57+
echo "=== ccache config ==="
58+
ccache -p | grep -E '(cache_dir|max_size|compression)'

0 commit comments

Comments
 (0)