diff --git a/Dockerfile.dropshell-build b/Dockerfile.dropshell-build new file mode 100644 index 0000000..f6fa58c --- /dev/null +++ b/Dockerfile.dropshell-build @@ -0,0 +1,74 @@ +ARG IMAGE_TAG +FROM gitea.jde.nz/public/dropshell-build-base:latest AS builder + +ARG PROJECT +ARG CMAKE_BUILD_TYPE=Debug + +# Set working directory +WORKDIR /app + +SHELL ["/bin/bash", "-c"] + +# Create cache directories +RUN mkdir -p /ccache + +# Set up ccache +ENV CCACHE_DIR=/ccache +ENV CCACHE_COMPILERCHECK=content +ENV CCACHE_MAXSIZE=2G + +# Copy only build files first (for better layer caching) +#COPY CMakeLists.txt cmake_prebuild.sh ./ +#COPY src/version.hpp.in src/ + +# Run prebuild script early (this rarely changes) +#RUN bash cmake_prebuild.sh + +# Copy source files (this invalidates cache when source changes) +COPY src/ src/ +COPY CMakeLists.txt ./ + +# Configure project (this step is cached unless CMakeLists.txt changes) +RUN --mount=type=cache,target=/ccache \ + --mount=type=cache,target=/build \ + mkdir -p /build && \ + cmake -G Ninja -S /app -B /build \ + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold -static -g" \ + -DCMAKE_CXX_FLAGS="-g -fno-omit-frame-pointer" \ + -DCMAKE_C_FLAGS="-g -fno-omit-frame-pointer" \ + -DPROJECT_NAME="${PROJECT}" \ + -DCMAKE_STRIP=OFF \ + ${CMAKE_TOOLCHAIN_FILE:+-DCMAKE_TOOLCHAIN_FILE=$CMAKE_TOOLCHAIN_FILE} + +# Build project (ccache will help here when only some files change) +RUN --mount=type=cache,target=/ccache \ + --mount=type=cache,target=/build \ + cmake --build /build + +# Copy the built executable to a regular directory for the final stage +RUN --mount=type=cache,target=/build \ + mkdir -p /output && \ + if [ -f "/build/${PROJECT}" ]; then \ + echo "Found executable at /build/${PROJECT}" && \ + cp "/build/${PROJECT}" "/output/${PROJECT}"; \ + else \ + echo "Executable not found at /build/${PROJECT}, searching..." && \ + find /build -type f -executable -name "*${PROJECT}*" -exec cp {} /output/${PROJECT} \; || \ + find /build -type f -executable -exec cp {} /output/${PROJECT} \; || \ + (echo "Error: Could not find executable for ${PROJECT}" && ls -la /build && exit 1); \ + fi + +# if we're a release build, then run upx on the binary. +RUN if [ "${CMAKE_BUILD_TYPE}" = "Release" ]; then \ + upx /output/${PROJECT}; \ + fi + +# Final stage that only contains the binary +FROM scratch AS project +ARG PROJECT +# Copy the actual binary from the regular directory +COPY --from=builder /output/${PROJECT} /${PROJECT} + diff --git a/build.sh b/build.sh index fcbb00c..4974f36 100755 --- a/build.sh +++ b/build.sh @@ -1,52 +1,30 @@ #!/bin/bash + set -euo pipefail -# Get script directory - handle different execution contexts SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" PROJECT="$(basename "${SCRIPT_DIR}")" -# Debug output for CI -echo "${PROJECT} build script running from: ${SCRIPT_DIR}" +export CMAKE_BUILD_TYPE="Debug" -# handle running locally, or docker in docker via gitea runner. -if [ -n "${GITEA_CONTAINER_NAME:-}" ]; then - echo "We're in a gitea container: ${GITEA_CONTAINER_NAME}" - VOLUME_OPTS=("--volumes-from=${GITEA_CONTAINER_NAME}") - WORKING_DIR=("-w" "${GITHUB_WORKSPACE}/${PROJECT}") - BUILD_DIR="${GITHUB_WORKSPACE}/${PROJECT}/build" - OUTPUT_DIR="${GITHUB_WORKSPACE}/${PROJECT}/output" -else - VOLUME_OPTS=("-v" "${SCRIPT_DIR}:/app") - WORKING_DIR=("-w" "/app") - BUILD_DIR="${SCRIPT_DIR}/build" - OUTPUT_DIR="${SCRIPT_DIR}/output" +rm -rf "${SCRIPT_DIR}/output" +mkdir -p "${SCRIPT_DIR}/output" + +# make sure we have the latest base image. +docker pull gitea.jde.nz/public/dropshell-build-base:latest + +# Build with or without cache based on NO_CACHE environment variable +CACHE_FLAG="" +if [ "${NO_CACHE:-false}" = "true" ]; then + CACHE_FLAG="--no-cache" fi -# Create output directory -mkdir -p "${OUTPUT_DIR}" +docker build \ + ${CACHE_FLAG} \ + -t "${PROJECT}-build" \ + -f "${SCRIPT_DIR}/Dockerfile.dropshell-build" \ + --build-arg PROJECT="${PROJECT}" \ + --build-arg CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \ + --output "${SCRIPT_DIR}/output" \ + "${SCRIPT_DIR}" -# Run build in container with mounted directories -COMMAND_TO_RUN="cmake -G Ninja -S . -B ./build \ - -DCMAKE_BUILD_TYPE=\${CMAKE_BUILD_TYPE} \ - -DPROJECT_NAME=${PROJECT} && \ - cmake --build ./build" - -echo "Building in new docker container" -docker run --rm \ - --user "$(id -u):$(id -g)" \ - "${VOLUME_OPTS[@]}" \ - "${WORKING_DIR[@]}" \ - -e CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Debug}" \ - gitea.jde.nz/public/dropshell-build-base:latest \ - bash -c "${COMMAND_TO_RUN}" - -# Copy built executable to output directory -if [ -f "${BUILD_DIR}/${PROJECT}" ]; then - cp "${BUILD_DIR}/${PROJECT}" "${OUTPUT_DIR}/" - echo "✓ Build successful - ${PROJECT} copied to ${OUTPUT_DIR}/" -else - echo "✗ Build failed - ${PROJECT} not found in ${BUILD_DIR}/" - exit 1 -fi - -echo "Build complete" diff --git a/contrib/xxhash.hpp b/src/xxhash.hpp similarity index 100% rename from contrib/xxhash.hpp rename to src/xxhash.hpp