diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 096f623..2a59fa4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,14 +45,19 @@ jobs: run: | # On Windows, we'll use rust-lld as the linker for musl targets rustup component add llvm-tools-preview + # Find rust-lld location + $rustc_sysroot = rustc --print sysroot + $rust_lld = "$rustc_sysroot\lib\rustlib\x86_64-pc-windows-msvc\bin\rust-lld.exe" + Write-Host "rust-lld location: $rust_lld" # Create cargo config directory New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.cargo" - # Create config file + # Create config file with full path to rust-lld Add-Content -Path "$env:USERPROFILE\.cargo\config.toml" -Value "[target.x86_64-unknown-linux-musl]" - Add-Content -Path "$env:USERPROFILE\.cargo\config.toml" -Value 'linker = "rust-lld"' - - name: Set up Docker (Windows and macOS) - if: matrix.os == 'windows-latest' || matrix.os == 'macos-latest' - uses: docker-practice/actions-setup-docker@v1 + Add-Content -Path "$env:USERPROFILE\.cargo\config.toml" -Value "linker = `"$rust_lld`"" + - name: Set up Docker for all platforms + uses: docker/setup-buildx-action@v3 + with: + install: true - name: Cache cargo registry uses: actions/cache@v4 with: @@ -68,7 +73,8 @@ jobs: with: path: target key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} - - name: Verify cross-compilation setup + - name: Verify cross-compilation setup (Unix) + if: matrix.os != 'windows-latest' run: | echo "Installed targets:" rustup target list --installed @@ -83,6 +89,26 @@ jobs: which rust-lld || echo "rust-lld not found" echo "Cargo config:" cat ~/.cargo/config.toml || echo "No cargo config found" + - name: Verify cross-compilation setup (Windows) + if: matrix.os == 'windows-latest' + shell: pwsh + run: | + Write-Host "Installed targets:" + rustup target list --installed + Write-Host "Cargo version:" + cargo --version + Write-Host "Rustc version:" + rustc --version + Write-Host "rust-lld location:" + $rustc_sysroot = rustc --print sysroot + $rust_lld = "$rustc_sysroot\lib\rustlib\x86_64-pc-windows-msvc\bin\rust-lld.exe" + if (Test-Path $rust_lld) { + Write-Host "$rust_lld exists" + } else { + Write-Host "$rust_lld not found" + } + Write-Host "Cargo config:" + Get-Content "$env:USERPROFILE\.cargo\config.toml" -ErrorAction SilentlyContinue || Write-Host "No cargo config found" - name: Build run: cargo build --verbose - name: Run unit tests diff --git a/src/builder/mod.rs b/src/builder/mod.rs index 4919ab9..28e3961 100644 --- a/src/builder/mod.rs +++ b/src/builder/mod.rs @@ -50,10 +50,42 @@ impl RustBuilder { if cfg!(not(target_os = "linux")) && self.target.contains("linux") { // Check if we have a musl cross-compiler available if self.target.contains("x86_64-unknown-linux-musl") { - // On Windows, prefer rust-lld + // On Windows, use rust-lld with full path if cfg!(target_os = "windows") { - cmd.env("CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER", "rust-lld"); - debug!("Using linker: rust-lld"); + // Get the rust sysroot to find rust-lld + let sysroot_output = Command::new("rustc") + .arg("--print") + .arg("sysroot") + .output() + .context("Failed to get rustc sysroot")?; + + if sysroot_output.status.success() { + let sysroot = String::from_utf8_lossy(&sysroot_output.stdout) + .trim() + .to_string(); + let rust_lld = PathBuf::from(&sysroot) + .join("lib") + .join("rustlib") + .join("x86_64-pc-windows-msvc") + .join("bin") + .join("rust-lld.exe"); + + if rust_lld.exists() { + cmd.env( + "CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER", + rust_lld.to_string_lossy().to_string(), + ); + debug!("Using linker: {}", rust_lld.display()); + } else { + // Fallback to just "rust-lld" and hope it's in PATH + cmd.env("CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER", "rust-lld"); + debug!("Using linker: rust-lld (in PATH)"); + } + } else { + // Fallback to just "rust-lld" + cmd.env("CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER", "rust-lld"); + debug!("Using linker: rust-lld (fallback)"); + } } else { // Try common linker names on other platforms let linkers = if cfg!(target_os = "macos") { diff --git a/tests/integration_test.rs b/tests/integration_test.rs index 9647568..37e7d39 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -134,8 +134,15 @@ fn test_verbose_logging() -> Result<()> { #[cfg_attr(not(ci), ignore)] // Run in CI, but allow skipping locally fn test_full_build_and_run_workflow() -> Result<()> { // This test requires Docker - if StdCommand::new("docker").arg("version").output().is_err() { - panic!("Docker is required for this test but is not available"); + let docker_check = StdCommand::new("docker").arg("version").output(); + match docker_check { + Ok(output) if output.status.success() => { + // Docker is available, proceed with test + } + _ => { + // Docker not available or not working + panic!("Docker is required for this test but is not available"); + } } // Get the example project directory