diff --git a/.github/workflows/build-shared-spanner-lib.yml b/.github/workflows/build-shared-spanner-lib.yml index e25726f7..1c5dd0c9 100644 --- a/.github/workflows/build-shared-spanner-lib.yml +++ b/.github/workflows/build-shared-spanner-lib.yml @@ -9,20 +9,17 @@ permissions: jobs: build: - name: Build ${{ matrix.target }} + name: Build on ${{ matrix.os }} runs-on: ${{ matrix.os }} timeout-minutes: 10 strategy: matrix: go-version: ['1.25.x'] - os: [ubuntu-latest, macos-latest, windows-latest] - include: - - os: ubuntu-latest - target: linux - - os: macos-latest - target: macos - - os: windows-latest - target: windows + # Consolidated matrix: Linux handles Linux+Windows; macOS handles macOS + os: [ubuntu-latest, macos-latest] + + # Use a container for the Linux build to ensure older glibc compatibility + container: ${{ matrix.os == 'ubuntu-latest' && 'ubuntu:20.04' || '' }} steps: - uses: actions/checkout@v6 @@ -33,35 +30,48 @@ jobs: go-version: ${{ matrix.go-version }} cache: true - - name: Install Dependencies (Linux) - if: matrix.target == 'linux' + - name: Install Cross-Compilers (Ubuntu) + if: matrix.os == 'ubuntu-latest' run: | - sudo apt-get update - sudo apt-get install -y gcc-aarch64-linux-gnu + apt-get update + # Install ARM64 cross-compiler and MinGW for Windows cross-compilation + apt-get install -y git build-essential gcc-aarch64-linux-gnu gcc-mingw-w64 curl - name: Build Binaries shell: bash run: | + # Mark the directory as safe for git inside container + git config --global --add safe.directory "$GITHUB_WORKSPACE" + cd spannerlib/shared - if [ "${{ matrix.target }}" == "linux" ]; then - export SKIP_MACOS=true - export SKIP_WINDOWS=true - # Enable ARM64 build + + # Configure Environment based on OS + if [ "${{ matrix.os }}" == "ubuntu-latest" ]; then + echo "Configuring for Linux & Windows build..." + + # Enable Linux ARM64 export BUILD_LINUX_ARM64=true export CC_LINUX_ARM64=aarch64-linux-gnu-gcc - elif [ "${{ matrix.target }}" == "macos" ]; then + + # Enable Windows Build (MinGW) + # The script automatically detects x86_64-w64-mingw32-gcc if SKIP_WINDOWS is not set + export SKIP_WINDOWS=false + + # Skip macOS (Can't easily build Mac on Linux) + export SKIP_MACOS=true + + elif [ "${{ matrix.os }}" == "macos-latest" ]; then + echo "Configuring for macOS build..." export SKIP_LINUX=true export SKIP_WINDOWS=true - # Enable AMD64 build (if possible) export BUILD_MACOS_AMD64=true - elif [ "${{ matrix.target }}" == "windows" ]; then - export SKIP_LINUX=true - export SKIP_MACOS=true fi + + # Run the build script ./build-binaries.sh - name: Upload Artifacts uses: actions/upload-artifact@v6 with: - name: spannerlib-binaries-${{ matrix.target }} + name: spannerlib-binaries-${{ matrix.os }} path: spannerlib/shared/binaries/ diff --git a/spannerlib/shared/build-binaries.sh b/spannerlib/shared/build-binaries.sh index 3973f371..0005459b 100755 --- a/spannerlib/shared/build-binaries.sh +++ b/spannerlib/shared/build-binaries.sh @@ -33,6 +33,7 @@ build_artifact() { unset CC fi + # Run the build GOOS="$os" GOARCH="$arch" CGO_ENABLED=1 go build -o "$output_dir/$output_file" -buildmode=c-shared shared_lib.go log "Successfully built $output_dir/$output_file" } @@ -47,38 +48,36 @@ log "Skip Linux cross compile: ${SKIP_LINUX_CROSS_COMPILE:-false}" log "Skip Windows: ${SKIP_WINDOWS:-false}" # --- MacOS Builds --- -if [ -z "$SKIP_MACOS" ]; then - # MacOS ARM64 (Apple Silicon) - build_artifact "darwin" "arm64" "binaries/osx-arm64" "spannerlib.dylib" "" +if [ "${SKIP_MACOS:-false}" != "true" ]; then + # Only build Mac if we are actually on Darwin (macOS) + if [ "$CURRENT_OS" == "Darwin" ]; then + # MacOS ARM64 (Apple Silicon) + build_artifact "darwin" "arm64" "binaries/osx-arm64" "spannerlib.dylib" "" - # MacOS AMD64 (Intel) - if [ -n "$BUILD_MACOS_AMD64" ]; then - build_artifact "darwin" "amd64" "binaries/osx-x64" "spannerlib.dylib" "" + # MacOS AMD64 (Intel) + if [ -n "$BUILD_MACOS_AMD64" ]; then + build_artifact "darwin" "amd64" "binaries/osx-x64" "spannerlib.dylib" "" + fi + else + log "Skipping macOS build (Not on macOS host)" fi fi # --- Linux Builds --- -if [ -z "$SKIP_LINUX" ]; then +if [ "${SKIP_LINUX:-false}" != "true" ]; then # Linux x64 # Logic: If we are on Linux, we prefer native build. # If we are NOT on Linux (e.g. Mac), we try cross-compile unless skipped. - + if [ "$CURRENT_OS" == "Linux" ]; then # Native Linux build build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "" else - # Cross-compile for Linux x64 (e.g. from Mac) - if [ -z "$SKIP_LINUX_CROSS_COMPILE" ]; then - # Check for cross-compiler - if command -v x86_64-unknown-linux-gnu-gcc >/dev/null 2>&1; then - build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "x86_64-unknown-linux-gnu-gcc" - else - log "WARNING: x86_64-unknown-linux-gnu-gcc not found. Skipping Linux x64 cross-compile." - fi - elif [ -z "$SKIP_LINUX" ]; then - # Fallback to standard build if cross-compile explicitly skipped but Linux not skipped - # This might fail if no suitable compiler is found, but we'll try. - build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "" + # Cross-compile for Linux x64 from Mac + if [ "${SKIP_LINUX_CROSS_COMPILE:-false}" != "true" ] && command -v x86_64-unknown-linux-gnu-gcc >/dev/null 2>&1; then + build_artifact "linux" "amd64" "binaries/linux-x64" "spannerlib.so" "x86_64-unknown-linux-gnu-gcc" + else + log "Skipping Linux x64 cross-compile (compiler not found or skipped)." fi fi @@ -94,8 +93,9 @@ if [ -z "$SKIP_LINUX" ]; then fi # --- Windows Builds --- -if [ -z "$SKIP_WINDOWS" ]; then +if [ "${SKIP_WINDOWS:-false}" != "true" ]; then # Windows x64 + # Standard MinGW compiler name on Ubuntu/Debian CC_WIN="x86_64-w64-mingw32-gcc" # If running on Windows (Git Bash/MSYS2), we might not need the cross-compiler prefix or it might be different.