mirror of
https://github.com/Xahau/xahaud.git
synced 2025-11-04 10:45:50 +00:00
Mount OverlayFS with metacopy=on option (kernel 4.2+, supported on ubuntu-22.04). This prevents full file copy-up when files are opened with O_RDWR but not modified. Expected behavior: - ccache opens cache files with write access - OverlayFS creates metadata-only entry in upper layer - Full copy-up only happens if data is actually written - Should dramatically reduce delta sizes from ~324 MB to ~KB Re-enabled use-deltas for ccache to test this optimization. Conan remains base-only (hash-based keys mean exact match most of the time). If successful, deltas should be tiny for cache hit scenarios.
200 lines
8.1 KiB
YAML
200 lines
8.1 KiB
YAML
name: build
|
||
description: 'Builds the project with ccache integration'
|
||
|
||
inputs:
|
||
generator:
|
||
description: 'CMake generator to use'
|
||
required: true
|
||
configuration:
|
||
description: 'Build configuration (Debug, Release, etc.)'
|
||
required: true
|
||
build_dir:
|
||
description: 'Directory to build in'
|
||
required: false
|
||
default: '.build'
|
||
cc:
|
||
description: 'C compiler to use'
|
||
required: false
|
||
default: ''
|
||
cxx:
|
||
description: 'C++ compiler to use'
|
||
required: false
|
||
default: ''
|
||
compiler-id:
|
||
description: 'Unique identifier: compiler-version-stdlib[-gccversion] (e.g. clang-14-libstdcxx-gcc11, gcc-13-libstdcxx)'
|
||
required: false
|
||
default: ''
|
||
cache_version:
|
||
description: 'Cache version for invalidation'
|
||
required: false
|
||
default: '1'
|
||
ccache_enabled:
|
||
description: 'Whether to use ccache'
|
||
required: false
|
||
default: 'true'
|
||
main_branch:
|
||
description: 'Main branch name for restore keys'
|
||
required: false
|
||
default: 'dev'
|
||
stdlib:
|
||
description: 'C++ standard library to use'
|
||
required: true
|
||
type: choice
|
||
options:
|
||
- libstdcxx
|
||
- libcxx
|
||
clang_gcc_toolchain:
|
||
description: 'GCC version to use for Clang toolchain (e.g. 11, 13)'
|
||
required: false
|
||
default: ''
|
||
aws-access-key-id:
|
||
description: 'AWS Access Key ID for S3 cache storage'
|
||
required: true
|
||
aws-secret-access-key:
|
||
description: 'AWS Secret Access Key for S3 cache storage'
|
||
required: true
|
||
|
||
runs:
|
||
using: 'composite'
|
||
steps:
|
||
- name: Generate safe branch name
|
||
if: inputs.ccache_enabled == 'true'
|
||
id: safe-branch
|
||
shell: bash
|
||
run: |
|
||
SAFE_BRANCH=$(echo "${{ github.ref_name }}" | tr -c 'a-zA-Z0-9_.-' '-')
|
||
echo "name=${SAFE_BRANCH}" >> $GITHUB_OUTPUT
|
||
|
||
- name: Restore ccache directory
|
||
if: inputs.ccache_enabled == 'true'
|
||
id: ccache-restore
|
||
uses: ./.github/actions/xahau-actions-cache-restore
|
||
with:
|
||
path: ~/.ccache
|
||
key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ steps.safe-branch.outputs.name }}
|
||
restore-keys: |
|
||
${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }}
|
||
${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-
|
||
${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
|
||
use-deltas: 'true' # Testing: metacopy=on should prevent copy-up for files opened-but-not-written
|
||
aws-access-key-id: ${{ inputs.aws-access-key-id }}
|
||
aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
|
||
|
||
- name: Configure project
|
||
shell: bash
|
||
run: |
|
||
mkdir -p ${{ inputs.build_dir }}
|
||
cd ${{ inputs.build_dir }}
|
||
|
||
# Set compiler environment variables if provided
|
||
if [ -n "${{ inputs.cc }}" ]; then
|
||
export CC="${{ inputs.cc }}"
|
||
fi
|
||
|
||
if [ -n "${{ inputs.cxx }}" ]; then
|
||
export CXX="${{ inputs.cxx }}"
|
||
fi
|
||
|
||
# Create wrapper toolchain that overlays ccache on top of Conan's toolchain
|
||
# This enables ccache for the main app build without affecting Conan dependency builds
|
||
if [ "${{ inputs.ccache_enabled }}" = "true" ]; then
|
||
cat > wrapper_toolchain.cmake <<'EOF'
|
||
# Include Conan's generated toolchain first (sets compiler, flags, etc.)
|
||
# Note: CMAKE_CURRENT_LIST_DIR is the directory containing this wrapper (.build/)
|
||
include(${CMAKE_CURRENT_LIST_DIR}/build/generators/conan_toolchain.cmake)
|
||
|
||
# Overlay ccache configuration for main application build
|
||
# This does NOT affect Conan dependency builds (already completed)
|
||
set(CMAKE_C_COMPILER_LAUNCHER ccache CACHE STRING "C compiler launcher" FORCE)
|
||
set(CMAKE_CXX_COMPILER_LAUNCHER ccache CACHE STRING "C++ compiler launcher" FORCE)
|
||
EOF
|
||
TOOLCHAIN_FILE="wrapper_toolchain.cmake"
|
||
echo "✅ Created wrapper toolchain with ccache enabled"
|
||
else
|
||
TOOLCHAIN_FILE="build/generators/conan_toolchain.cmake"
|
||
echo "ℹ️ Using Conan toolchain directly (ccache disabled)"
|
||
fi
|
||
|
||
# Configure C++ standard library if specified
|
||
# libstdcxx used for clang-14/16 to work around missing lexicographical_compare_three_way in libc++
|
||
# libcxx can be used with clang-17+ which has full C++20 support
|
||
# Note: -stdlib flag is Clang-specific, GCC always uses libstdc++
|
||
CMAKE_CXX_FLAGS=""
|
||
if [[ "${{ inputs.cxx }}" == clang* ]]; then
|
||
# Only Clang needs the -stdlib flag
|
||
if [ "${{ inputs.stdlib }}" = "libstdcxx" ]; then
|
||
CMAKE_CXX_FLAGS="-stdlib=libstdc++"
|
||
elif [ "${{ inputs.stdlib }}" = "libcxx" ]; then
|
||
CMAKE_CXX_FLAGS="-stdlib=libc++"
|
||
fi
|
||
fi
|
||
# GCC always uses libstdc++ and doesn't need/support the -stdlib flag
|
||
|
||
# Configure GCC toolchain for Clang if specified
|
||
if [ -n "${{ inputs.clang_gcc_toolchain }}" ] && [[ "${{ inputs.cxx }}" == clang* ]]; then
|
||
# Extract Clang version from compiler executable name (e.g., clang++-14 -> 14)
|
||
clang_version=$(echo "${{ inputs.cxx }}" | grep -oE '[0-9]+$')
|
||
|
||
# Clang 16+ supports --gcc-install-dir (precise path specification)
|
||
# Clang <16 only has --gcc-toolchain (uses discovery heuristics)
|
||
if [ -n "$clang_version" ] && [ "$clang_version" -ge "16" ]; then
|
||
# Clang 16+ uses --gcc-install-dir (canonical, precise)
|
||
CMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS --gcc-install-dir=/usr/lib/gcc/x86_64-linux-gnu/${{ inputs.clang_gcc_toolchain }}"
|
||
else
|
||
# Clang 14-15 uses --gcc-toolchain (deprecated but necessary)
|
||
# Note: This still uses discovery, so we hide newer GCC versions in the workflow
|
||
CMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS --gcc-toolchain=/usr"
|
||
fi
|
||
fi
|
||
|
||
# Run CMake configure
|
||
# Note: conanfile.py hardcodes 'build/generators' as the output path.
|
||
# If we're in a 'build' folder, Conan detects this and uses just 'generators/'
|
||
# If we're in '.build' (non-standard), Conan adds the full 'build/generators/'
|
||
# So we get: .build/build/generators/ with our non-standard folder name
|
||
cmake .. \
|
||
-G "${{ inputs.generator }}" \
|
||
${CMAKE_CXX_FLAGS:+-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"} \
|
||
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${TOOLCHAIN_FILE} \
|
||
-DCMAKE_BUILD_TYPE=${{ inputs.configuration }}
|
||
|
||
- name: Build project
|
||
shell: bash
|
||
run: |
|
||
cd ${{ inputs.build_dir }}
|
||
# TEMPORARY: Add -v to see compile commands for ccache debugging
|
||
cmake --build . --config ${{ inputs.configuration }} --parallel $(nproc) -- -v
|
||
|
||
- name: Debug ccache directory
|
||
if: inputs.ccache_enabled == 'true'
|
||
shell: bash
|
||
run: |
|
||
echo "=== ccache directory contents ==="
|
||
ls -laR ~/.ccache || echo "Directory doesn't exist"
|
||
echo ""
|
||
echo "=== Disk space ==="
|
||
df -h ~
|
||
echo ""
|
||
echo "=== ccache config ==="
|
||
ccache --show-config | head -30
|
||
echo ""
|
||
echo "=== Directory sizes ==="
|
||
du -sh ~/.ccache 2>/dev/null || echo "No directory"
|
||
find ~/.ccache -type f -name "*.conf" -o -type f ! -name "*.conf" 2>/dev/null | head -20 || true
|
||
echo ""
|
||
|
||
- name: Show ccache statistics
|
||
if: inputs.ccache_enabled == 'true'
|
||
shell: bash
|
||
run: ccache -s
|
||
|
||
- name: Save ccache directory
|
||
if: always() && inputs.ccache_enabled == 'true'
|
||
uses: ./.github/actions/xahau-actions-cache-save
|
||
with:
|
||
path: ~/.ccache
|
||
key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ steps.safe-branch.outputs.name }}
|
||
use-deltas: 'true' # Testing: metacopy=on should prevent copy-up for files opened-but-not-written
|
||
aws-access-key-id: ${{ inputs.aws-access-key-id }}
|
||
aws-secret-access-key: ${{ inputs.aws-secret-access-key }}
|