From 917dacf41d0de124d234bf6ae4484676aaa3d1c1 Mon Sep 17 00:00:00 2001 From: Denis Avvakumov Date: Mon, 21 Jul 2025 15:19:57 +0300 Subject: [PATCH] Build static artifacts for Linux --- .github/workflows/spz.yml | 40 +++++++++++++++++++++++++++++++++------ CMakeLists.txt | 39 ++++++++++++++++++++++++++++++++++++-- Dockerfile.static-musl | 33 ++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 8 deletions(-) create mode 100644 Dockerfile.static-musl diff --git a/.github/workflows/spz.yml b/.github/workflows/spz.yml index 26fa383..8595b7d 100644 --- a/.github/workflows/spz.yml +++ b/.github/workflows/spz.yml @@ -1,4 +1,7 @@ name: CI +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true on: push: @@ -14,8 +17,8 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - fail-fast: false + os: [ubuntu-latest, macos-15, windows-latest] + fail-fast: true steps: - name: Checkout repository @@ -70,7 +73,7 @@ jobs: - name: Azure Trusted Signing if: runner.os == 'Windows' - uses: azure/trusted-signing-action@v0.5.1 + uses: azure/trusted-signing-action@v0.5.9 with: azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }} azure-client-id: ${{ secrets.AZURE_CLIENT_ID }} @@ -91,13 +94,38 @@ jobs: ${{ github.workspace }}/build/Release/*.exe ${{ github.workspace }}/build/Release/*.dll + build-static-linux: + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build Docker image + run: | + docker build -t spz-builder -f Dockerfile.static-musl . + + - name: Extract artifacts + run: | + docker create --name spz-container spz-builder /spz + mkdir -p artifacts + docker cp spz-container:/spz artifacts/spz + docker cp spz-container:/libspz_shared.so artifacts/libspz_shared.so + + - name: Upload Linux binaries + uses: actions/upload-artifact@v4 + with: + name: spz-linux + path: | + artifacts/spz + artifacts/libspz_shared.so + build-wheels: needs: build runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest, windows-latest, macos-14] - fail-fast: false + os: [ubuntu-latest, windows-latest, macos-15] steps: - uses: actions/checkout@v4 @@ -135,7 +163,7 @@ jobs: arch: x64 - name: Build wheels - uses: pypa/cibuildwheel@v3.0.0 + uses: pypa/cibuildwheel@v3.0.1 env: CIBW_BUILD: "cp310-* cp311-* cp312-* cp313-*" CIBW_ARCHS_LINUX: "x86_64" diff --git a/CMakeLists.txt b/CMakeLists.txt index 643814e..b34f68e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.29) project(spz VERSION 1.0.0 - LANGUAGES CXX + LANGUAGES CXX C DESCRIPTION "SPZ Library and Tools" ) @@ -23,6 +23,18 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +include(CheckCSourceCompiles) +check_c_source_compiles(" +#include +#if defined(__GLIBC__) +#error \"This is glibc, not musl\" +#endif +#include +int main() { return 0; } +" IS_MUSL) + +option(ALPINE_STATIC "Force fully static build when using musl/Alpine" ${IS_MUSL}) + if(MSVC) if(NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm|ARM64)") add_compile_options(/arch:AVX2) @@ -109,7 +121,22 @@ set(EXECUTABLE_SOURCES # Shared library target if(NOT IS_WASM) - add_library(spz_shared SHARED ${LIBRARY_SOURCES}) + if(ALPINE_STATIC) + message(STATUS "musl detected, producing shared library with static musl linking") + add_library(spz_shared SHARED ${LIBRARY_SOURCES}) + add_definitions(-D_FORTIFY_SOURCE=0) + target_link_options(spz_shared PRIVATE + -static + -static-libgcc + -static-libstdc++ + -fPIC + ) + target_compile_options(spz_shared PRIVATE -fPIC) + else() + message(STATUS "musl not detected, building shared library with dynamic glibc") + add_library(spz_shared SHARED ${LIBRARY_SOURCES}) + endif() + set_target_properties(spz_shared PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} @@ -148,6 +175,14 @@ if(NOT IS_WASM) target_include_directories(spz_exe PRIVATE src src/cc) target_link_libraries(spz_exe PRIVATE spz_static zstd::zstd) + if(ALPINE_STATIC) + target_link_options(spz_exe PRIVATE + -static + -static-libgcc + -static-libstdc++ + ) + endif() + # Sanitizer configuration (only for traditional builds) if(ENABLE_ASAN OR ENABLE_UBSAN) set(SANITIZER_FLAGS "") diff --git a/Dockerfile.static-musl b/Dockerfile.static-musl new file mode 100644 index 0000000..d74c7ae --- /dev/null +++ b/Dockerfile.static-musl @@ -0,0 +1,33 @@ +FROM alpine:3.22 AS build + +RUN apk add --no-cache \ + build-base \ + clang \ + lld \ + llvm \ + cmake \ + ninja \ + musl-dev \ + binutils \ + git + +WORKDIR /src + +COPY . . + +RUN cmake -S . -B build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_PYTHON_BINDINGS=OFF \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" \ + -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld" \ + && ninja -C build -v \ + && strip --strip-unneeded build/spz \ + && strip --strip-unneeded build/libspz_shared.so \ + && echo "Library dependencies:" && ldd build/libspz_shared.so + +FROM scratch AS artifact + +COPY --from=build /src/build/libspz_shared.so /libspz_shared.so +COPY --from=build /src/build/spz /spz \ No newline at end of file