From 87855464037cf295c33cd0f41c61c5793315939c Mon Sep 17 00:00:00 2001 From: Zack3D Date: Tue, 23 Sep 2025 20:47:16 -0700 Subject: [PATCH] bu --- .gitea/workflows/ci-reusable.yml | 139 +++++++++++----------------- .gitea/workflows/multi-platform.yml | 20 +++- 2 files changed, 68 insertions(+), 91 deletions(-) diff --git a/.gitea/workflows/ci-reusable.yml b/.gitea/workflows/ci-reusable.yml index 5ba41b1..01c8cb4 100644 --- a/.gitea/workflows/ci-reusable.yml +++ b/.gitea/workflows/ci-reusable.yml @@ -6,6 +6,11 @@ on: os: required: true type: string + target: + description: "The Rust compilation target (e.g., x86_64-pc-windows-gnu). Empty for native." + required: false + type: string + default: '' upload-artifacts: required: false type: boolean @@ -26,6 +31,7 @@ jobs: with: components: clippy, rustfmt + # Steps for linting, testing, etc. These are skipped in 'package-only' mode. - name: Build if: ${{ !inputs.package-only }} run: cargo build --all-features @@ -40,8 +46,7 @@ jobs: - name: Fmt check if: ${{ !inputs.package-only }} - run: | - cargo fmt --all -- --check + run: cargo fmt --all -- --check - name: Security audit (Linux only) if: ${{ !inputs.package-only && runner.os == 'Linux' }} @@ -49,121 +54,81 @@ jobs: cargo install cargo-audit cargo audit - - name: Build FFI library - if: inputs.upload-artifacts + # --- Build & Package Logic --- + + - name: Set up Windows cross-compilation environment + if: inputs.target == 'x86_64-pc-windows-gnu' + run: | + sudo apt-get update + sudo apt-get install -y gcc-mingw-w64-x86-64 + rustup target add x86_64-pc-windows-gnu + + - name: Build FFI library (Native) + if: inputs.upload-artifacts && inputs.target == '' run: cargo build --release --features ffi - - name: Extract version and create package (non-Windows) - if: inputs.upload-artifacts && runner.os != 'Windows' + - name: Build FFI library (Cross-compile for Windows) + if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu' + run: cargo build --release --features ffi --target=${{ inputs.target }} + env: + CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER: x86_64-w64-mingw32-gcc + + - name: Extract version and create package (Linux) + if: inputs.upload-artifacts && inputs.target == '' shell: bash run: | VERSION=$(sed -n 's/^version\s*=\s*"\([^"]\+\)"/\1/p' Cargo.toml | head -n1) - - # Determine target directory and library extension - TARGET_DIR="target/release" # Map runner.arch to Rust target arch case "${{ runner.arch }}" in ARM64) ARCH_TRIPLE="aarch64" ;; X64) ARCH_TRIPLE="x86_64" ;; *) ARCH_TRIPLE="unknown" ;; esac - - # Compose package basename with OS + arch - case "${{ runner.os }}" in - Linux) PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-unknown-linux-gnu" ;; - macOS) PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-apple-darwin" ;; - *) PKG_BASENAME="medicallib_rust-v${VERSION}-native" ;; - esac - + PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-unknown-linux-gnu" PKG_DIR="dist/${PKG_BASENAME}" echo "Creating package ${PKG_BASENAME}..." - mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib" "${PKG_DIR}/examples/c" - - # Copy header and example + mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib" cp ffi/medicallib.h "${PKG_DIR}/include/" - cp examples/c/ffi_example.c "${PKG_DIR}/examples/c/" - cp README.md INSTALL.md MIGRATION.md ARCHITECTURE.md "${PKG_DIR}/" || true + cp "target/release/libmedicallib_rust.so" "${PKG_DIR}/lib/" - # Copy library with proper extension detection - if [[ "${{ runner.os }}" == "macOS" ]]; then - cp "${TARGET_DIR}/libmedicallib_rust.dylib" "${PKG_DIR}/lib/" - else - cp "${TARGET_DIR}/libmedicallib_rust.so" "${PKG_DIR}/lib/" - fi - - # Create archives tar -C dist -czf "dist/${PKG_BASENAME}.tar.gz" "${PKG_BASENAME}" - if command -v zip >/dev/null 2>&1; then - (cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}") - fi + (cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}") - - name: Extract version and create package (Windows) - if: inputs.upload-artifacts && runner.os == 'Windows' - shell: pwsh + - name: Extract version and create package (Cross-compiled Windows) + if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu' + shell: bash run: | - $versionMatch = (Get-Content Cargo.toml | Select-String -Pattern '^version\s*=\s*"([^"]+)"' -AllMatches | ForEach-Object { $_.Matches } | Select-Object -First 1) - if (-not $versionMatch) { Write-Error "Unable to parse version from Cargo.toml"; exit 1 } - $VERSION = $versionMatch.Groups[1].Value + VERSION=$(sed -n 's/^version\s*=\s*"\([^"]\+\)"/\1/p' Cargo.toml | head -n1) + ARCH_TRIPLE="x86_64" + PKG_BASENAME="medicallib_rust-v${VERSION}-${ARCH_TRIPLE}-pc-windows-gnu" + PKG_DIR="dist/${PKG_BASENAME}" - switch ("${{ runner.arch }}") { - 'ARM64' { $ARCH_TRIPLE = 'aarch64' } - 'X64' { $ARCH_TRIPLE = 'x86_64' } - default { $ARCH_TRIPLE = 'unknown' } - } + echo "Creating package ${PKG_BASENAME}..." + mkdir -p "${PKG_DIR}/include" "${PKG_DIR}/lib" + cp ffi/medicallib.h "${PKG_DIR}/include/" + + # The output path is different for cross-compilation + cp "target/x86_64-pc-windows-gnu/release/medicallib_rust.dll" "${PKG_DIR}/lib/" - $PKG_BASENAME = "medicallib_rust-v$VERSION-$ARCH_TRIPLE-pc-windows-msvc" - $PKG_DIR = Join-Path 'dist' $PKG_BASENAME - Write-Host "Creating package $PKG_BASENAME..." - New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'include') | Out-Null - New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'lib') | Out-Null - New-Item -ItemType Directory -Force -Path (Join-Path $PKG_DIR 'examples' 'c') | Out-Null + (cd dist && zip -r9 "${PKG_BASENAME}.zip" "${PKG_BASENAME}") - Copy-Item -Force -Path 'ffi/medicallib.h' -Destination (Join-Path $PKG_DIR 'include') - Copy-Item -Force -Path 'examples/c/ffi_example.c' -Destination (Join-Path $PKG_DIR 'examples/c') - Copy-Item -Force -Path 'README.md','INSTALL.md','MIGRATION.md','ARCHITECTURE.md' -Destination $PKG_DIR -ErrorAction SilentlyContinue + # --- Artifact Upload Logic --- - $TARGET_DIR = 'target\release' - $dllCandidates = @( - (Join-Path $TARGET_DIR 'medicallib_rust.dll'), - (Join-Path $TARGET_DIR 'libmedicallib_rust.dll') - ) - $copied = $false - foreach ($file in $dllCandidates) { - if (Test-Path $file) { - Copy-Item -Force -Path $file -Destination (Join-Path $PKG_DIR 'lib') - $copied = $true - break - } - } - if (-not $copied) { - $found = Get-ChildItem -Path $TARGET_DIR -Filter '*medicallib_rust*.dll' -ErrorAction SilentlyContinue | Select-Object -First 1 - if ($found) { - Copy-Item -Force $found.FullName -Destination (Join-Path $PKG_DIR 'lib') - $copied = $true - } - } - if (-not $copied) { Write-Error "Could not locate built DLL in $TARGET_DIR"; exit 1 } - - $zipPath = Join-Path 'dist' ("{0}.zip" -f $PKG_BASENAME) - Compress-Archive -Path $PKG_DIR -DestinationPath $zipPath -Force - - - name: Upload Linux/macOS Artifacts - if: inputs.upload-artifacts && runner.os != 'Windows' + - name: Upload Linux Artifact + if: inputs.upload-artifacts && inputs.target == '' uses: https://github.com/christopherHX/gitea-upload-artifact@v4 with: - name: medicallib-rust-${{ runner.os }}-${{ github.run_number }} + name: medicallib-rust-Linux-${{ runner.arch }}-${{ github.run_number }} path: | dist/*.tar.gz dist/*.zip if-no-files-found: error - overwrite: false - name: Upload Windows Artifact - if: inputs.upload-artifacts && runner.os == 'Windows' + if: inputs.upload-artifacts && inputs.target == 'x86_64-pc-windows-gnu' uses: https://github.com/christopherHX/gitea-upload-artifact@v4 with: - name: medicallib-rust-${{ runner.os }}-${{ github.run_number }} - path: dist/*.zip # <-- Only look for the .zip file - if-no-files-found: error - overwrite: false + name: medicallib-rust-Windows-x86_64-${{ github.run_number }} + path: dist/*.zip + if-no-files-found: error \ No newline at end of file diff --git a/.gitea/workflows/multi-platform.yml b/.gitea/workflows/multi-platform.yml index e9c9c42..3b25dc8 100644 --- a/.gitea/workflows/multi-platform.yml +++ b/.gitea/workflows/multi-platform.yml @@ -26,14 +26,26 @@ jobs: package: if: github.event_name == 'push' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') needs: [test-platforms] + # Both jobs run on ubuntu, but with different targets + runs-on: ubuntu-22.04 strategy: + fail-fast: false matrix: include: - - os: ubuntu-22.04 - - os: windows-latest + # Configuration for the native Linux build + - name: Linux + target: '' # An empty target means native build + # Configuration for the Windows cross-compile build + - name: Windows (Cross-Compiled) + target: 'x86_64-pc-windows-gnu' + + name: Package for ${{ matrix.name }} uses: ./.gitea/workflows/ci-reusable.yml with: - os: ${{ matrix.os }} + # Both jobs are sent to an ubuntu runner + os: ubuntu-22.04 + # The target is passed to the reusable workflow + target: ${{ matrix.target }} upload-artifacts: true - package-only: true + package-only: true \ No newline at end of file