From 97bbe3336049cfd1f343b14f52bc6261b4715f1d Mon Sep 17 00:00:00 2001 From: fooly Date: Wed, 22 Jul 2026 14:08:22 +0900 Subject: [PATCH] build: cache incremental Docker builds --- .dockerignore | 11 ++++++++++- CMakeLists.txt | 44 ++++++++++++++++++++++++++------------------ Dockerfile | 33 +++++++++++++++++++++------------ docker-build.sh | 11 +++++++---- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/.dockerignore b/.dockerignore index c7def876..54cdf072 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,7 +2,16 @@ build/ cmake-build-*/ out/ .cache/ -result +result/ +.git +!.git/ +.git/* +!.git/modules/ +.git/modules/* +!.git/modules/dependencies/ +.git/modules/dependencies/* +!.git/modules/dependencies/vcpkg/ +!.git/modules/dependencies/vcpkg/** bin/Cemu_* bin/*.pdb bin/*.ilk diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac61207..63165a40 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,20 +13,26 @@ set(EMULATOR_VERSION_PATCH "0" CACHE STRING "") set(THREADS_PREFER_PTHREAD_FLAG true) # needs to be set before vcpkg -execute_process( - COMMAND git log --format=%h -1 - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - OUTPUT_VARIABLE GIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE -) +set(GIT_HASH "" CACHE STRING "Git revision used in the build") +if (NOT GIT_HASH) + execute_process( + COMMAND git log --format=%h -1 + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() add_definitions(-DEMULATOR_HASH=${GIT_HASH}) -execute_process( - COMMAND git rev-parse HEAD - WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} - OUTPUT_VARIABLE CEMU_EXTEND_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE -) +set(CEMU_EXTEND_COMMIT_HASH "" CACHE STRING "Full Git revision used in the build") +if (NOT CEMU_EXTEND_COMMIT_HASH) + execute_process( + COMMAND git rev-parse HEAD + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE CEMU_EXTEND_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) +endif() if (NOT CEMU_EXTEND_COMMIT_HASH) set(CEMU_EXTEND_COMMIT_HASH ${GIT_HASH}) endif() @@ -34,12 +40,14 @@ add_compile_definitions(CEMU_EXTEND_COMMIT_HASH="${CEMU_EXTEND_COMMIT_HASH}") if (ENABLE_VCPKG) # check if vcpkg is shallow and unshallow it if necessary - execute_process( - COMMAND git rev-parse --is-shallow-repository - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/dependencies/vcpkg - OUTPUT_VARIABLE is_vcpkg_shallow - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + if (EXISTS "${CMAKE_SOURCE_DIR}/dependencies/vcpkg/.git") + execute_process( + COMMAND git rev-parse --is-shallow-repository + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/dependencies/vcpkg + OUTPUT_VARIABLE is_vcpkg_shallow + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() if(is_vcpkg_shallow STREQUAL "true") message(STATUS "vcpkg is shallow. Unshallowing it now...") diff --git a/Dockerfile b/Dockerfile index 6c1f0b35..d608c786 100644 --- a/Dockerfile +++ b/Dockerfile @@ -68,31 +68,40 @@ RUN apt-get update \ libglm-dev \ && rm -rf /var/lib/apt/lists/* +FROM cemu-extend-base AS dev + WORKDIR /workspace/CemuExtend COPY . . - -# CemuExtend keeps most third-party sources in git submodules. Initializing -# them here also makes a checkout with empty submodule directories usable as a -# Docker build context. -RUN test -e .git \ - && git submodule update --init --recursive \ +RUN test -f dependencies/vcpkg/bootstrap-vcpkg.sh \ && bash ./dependencies/vcpkg/bootstrap-vcpkg.sh -disableMetrics -FROM cemu-extend-base AS dev - CMD ["bash"] -FROM dev AS build +FROM cemu-extend-base AS build ARG BUILD_TYPE=Release +ARG GIT_HASH=unknown +ARG CEMU_EXTEND_COMMIT_HASH=unknown -RUN --mount=type=cache,target=/root/.cache/vcpkg/archives \ - cmake -S . -B build/docker \ +WORKDIR /workspace/CemuExtend + +# The source is a bind mount, so source changes do not create a multi-gigabyte +# image layer. The writable mount is discarded after the artifact is copied +# out, while CMake/Ninja state is retained in the cache mount. +RUN --mount=type=bind,source=.,target=/workspace/CemuExtend,rw \ + --mount=type=cache,id=cemu-extend-vcpkg,target=/root/.cache/vcpkg/archives,sharing=locked \ + --mount=type=cache,id=cemu-extend-cmake,target=/workspace/CemuExtend/build/docker,sharing=locked \ + bash ./dependencies/vcpkg/bootstrap-vcpkg.sh -disableMetrics \ + && cmake -S . -B build/docker \ -G Ninja \ -DCMAKE_BUILD_TYPE=${BUILD_TYPE} \ + -DGIT_HASH=${GIT_HASH} \ + -DCEMU_EXTEND_COMMIT_HASH=${CEMU_EXTEND_COMMIT_HASH} \ -DENABLE_VCPKG=ON \ -DALLOW_PORTABLE=OFF \ -DVCPKG_INSTALL_OPTIONS=--clean-after-build \ - && cmake --build build/docker --parallel + && cmake --build build/docker --parallel \ + && ctest --test-dir build/docker --output-on-failure \ + && cp bin/Cemu_release /Cemu_release CMD ["bash"] diff --git a/docker-build.sh b/docker-build.sh index aa4396c8..8bd8b499 100755 --- a/docker-build.sh +++ b/docker-build.sh @@ -5,16 +5,19 @@ project_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" image_name="${CEMU_DOCKER_IMAGE:-cemu-extend:build}" artifact_dir="${project_dir}/result/bin" temporary_name=".Cemu_release.$$.tmp" +git_hash="$(git -C "${project_dir}" log --format=%h -1 2>/dev/null || printf unknown)" +commit_hash="$(git -C "${project_dir}" rev-parse HEAD 2>/dev/null || printf unknown)" -docker build --progress=plain --target build -t "${image_name}" "${project_dir}" -docker run --rm "${image_name}" \ - ctest --test-dir /workspace/CemuExtend/build/docker --output-on-failure +docker build --progress=plain --target build \ + --build-arg "GIT_HASH=${git_hash}" \ + --build-arg "CEMU_EXTEND_COMMIT_HASH=${commit_hash}" \ + -t "${image_name}" "${project_dir}" mkdir -p "${artifact_dir}" docker run --rm --user "$(id -u):$(id -g)" \ -v "${artifact_dir}:/artifacts" \ "${image_name}" \ - cp /workspace/CemuExtend/bin/Cemu_release "/artifacts/${temporary_name}" + cp /Cemu_release "/artifacts/${temporary_name}" mv -f "${artifact_dir}/${temporary_name}" "${artifact_dir}/Cemu_release" printf 'Docker release build: %s\n' "${artifact_dir}/Cemu_release"