diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index f30a29a..7f2c999 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -77,6 +77,20 @@ jobs: - uses: actions-rs/cargo@v1 with: command: build + - name: macOS - Test build + run: | + rustup target add aarch64-apple-darwin + cargo run zigbuild --target aarch64-apple-darwin + cargo run zigbuild --target aarch64-apple-darwin --release + - name: macOS - Test build with SDKROOT + if: matrix.os == 'ubuntu-latest' + env: + SDK: MacOSX11.3.sdk + run: | + curl -sqL https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/$SDK.tar.xz | tar -Jx + export SDKROOT=$PWD/$SDK + + cargo run zigbuild --target aarch64-apple-darwin --manifest-path tests/hello-tls/Cargo.toml - name: Linux - Test x86_64 build if: matrix.os == 'ubuntu-latest' run: | @@ -85,6 +99,15 @@ jobs: if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} run: | cargo run zigbuild --target x86_64-unknown-linux-gnu.2.17 + - name: Linux - Test x86_64 glibc run + if: ${{ matrix.os == 'ubuntu-latest' && matrix.toolchain == 'nightly' }} + uses: addnab/docker-run-action@v3 + with: + image: centos:7 + options: -v ${{ github.workspace }}:/io -w /io + run: | + ./target/x86_64-unknown-linux-gnu/debug/cargo-zigbuild --help + ldd -r -v ./target/x86_64-unknown-linux-gnu/debug/cargo-zigbuild - name: Linux - Test glibc build run: | rustup target add aarch64-unknown-linux-gnu @@ -111,11 +134,6 @@ jobs: rustup target add aarch64-unknown-linux-musl cargo run zigbuild --target aarch64-unknown-linux-musl cargo run zigbuild --target aarch64-unknown-linux-musl --manifest-path tests/hello-rustls/Cargo.toml - - name: macOS - Test build - run: | - rustup target add aarch64-apple-darwin - cargo run zigbuild --target aarch64-apple-darwin - cargo run zigbuild --target aarch64-apple-darwin --release - name: Windows - Test gnu build run: | rustup target add x86_64-pc-windows-gnu diff --git a/Cargo.lock b/Cargo.lock index 4cbc9f5..7fff6d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "cargo-zigbuild" -version = "0.6.7" +version = "0.6.8" dependencies = [ "anyhow", "cargo_metadata", diff --git a/Cargo.toml b/Cargo.toml index 4787e88..7bfc2d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-zigbuild" -version = "0.6.7" +version = "0.6.8" edition = "2018" description = "Compile Cargo project with zig as linker" license = "MIT" diff --git a/src/build.rs b/src/build.rs index c9227eb..159188d 100644 --- a/src/build.rs +++ b/src/build.rs @@ -105,8 +105,13 @@ pub struct Build { pub no_default_features: bool, /// Build for the target triple - #[clap(long, value_name = "TRIPLE", env = "CARGO_BUILD_TARGET")] - pub target: Option, + #[clap( + long, + value_name = "TRIPLE", + env = "CARGO_BUILD_TARGET", + multiple_occurrences = true + )] + pub target: Vec, /// Directory for all generated artifacts #[clap(long, value_name = "DIRECTORY", parse(from_os_str))] @@ -190,10 +195,11 @@ impl Build { let mut build = Command::new("cargo"); build.arg(subcommand); - let rust_target = self + let rust_targets = self .target - .as_ref() - .map(|target| target.split_once('.').map(|(t, _)| t).unwrap_or(target)); + .iter() + .map(|target| target.split_once('.').map(|(t, _)| t).unwrap_or(target)) + .collect::>(); // collect cargo build arguments if self.quiet { @@ -259,9 +265,11 @@ impl Build { if self.no_default_features { build.arg("--no-default-features"); } - if let Some(rust_target) = rust_target { - build.arg("--target").arg(&rust_target); - } + + rust_targets.iter().for_each(|target| { + build.arg("--target").arg(&target); + }); + if let Some(dir) = self.target_dir.as_ref() { build.arg("--target-dir").arg(dir); } @@ -310,48 +318,53 @@ impl Build { if !self.disable_zig_linker { // setup zig as linker - if let Some(target) = self.target.as_ref() { - let rustc_meta = rustc_version::version_meta()?; - let host_target = &rustc_meta.host; + let rustc_meta = rustc_version::version_meta()?; + let host_target = &rustc_meta.host; + for (parsed_target, raw_target) in rust_targets.iter().zip(&self.target) { // we only setup zig as linker when target isn't exactly the same as host target - if host_target != target { - if let Some(rust_target) = rust_target { - let env_target = rust_target.to_uppercase().replace('-', "_"); - let (zig_cc, zig_cxx) = prepare_zig_linker(target)?; - if is_mingw_shell() { - let zig_cc = zig_cc.to_slash_lossy(); - build.env("TARGET_CC", &zig_cc); - build.env("TARGET_CXX", &zig_cxx.to_slash_lossy()); - build.env(format!("CARGO_TARGET_{}_LINKER", env_target), &zig_cc); - } else { - build.env("TARGET_CC", &zig_cc); - build.env("TARGET_CXX", &zig_cxx); - build.env(format!("CARGO_TARGET_{}_LINKER", env_target), &zig_cc); - } + if host_target != raw_target { + let env_target = parsed_target.replace('-', "_"); + let (zig_cc, zig_cxx) = prepare_zig_linker(raw_target)?; + if is_mingw_shell() { + let zig_cc = zig_cc.to_slash_lossy(); + build.env(format!("CC_{}", env_target), &zig_cc); + build.env(format!("CXX_{}", env_target), &zig_cxx.to_slash_lossy()); + build.env( + format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()), + &zig_cc, + ); + } else { + build.env(format!("CC_{}", env_target), &zig_cc); + build.env(format!("CXX_{}", env_target), &zig_cxx); + build.env( + format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()), + &zig_cc, + ); + } - self.setup_os_deps()?; + self.setup_os_deps()?; - if rust_target.contains("windows-gnu") { - build.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); - } + if raw_target.contains("windows-gnu") { + build.env("WINAPI_NO_BUNDLED_LIBRARIES", "1"); + } - // Enable unstable `target-applies-to-host` option automatically for nightly Rust - // when target is the same as host but may have specified glibc version - if host_target == rust_target - && matches!(rustc_meta.channel, rustc_version::Channel::Nightly) - { - build.env("CARGO_UNSTABLE_TARGET_APPLIES_TO_HOST", "true"); - build.env("CARGO_TARGET_APPLIES_TO_HOST", "false"); - } + // Enable unstable `target-applies-to-host` option automatically for nightly Rust + // when target is the same as host but may have specified glibc version + if host_target == raw_target + && matches!(rustc_meta.channel, rustc_version::Channel::Nightly) + { + build.env("CARGO_UNSTABLE_TARGET_APPLIES_TO_HOST", "true"); + build.env("CARGO_TARGET_APPLIES_TO_HOST", "false"); } } } } + Ok(build) } fn setup_os_deps(&self) -> Result<()> { - if let Some(target) = self.target.as_ref() { + for target in &self.target { if target.contains("apple") { let target_dir = if let Some(target_dir) = self.target_dir.clone() { target_dir.join(target) diff --git a/src/rustc.rs b/src/rustc.rs index 9b026c4..b32ceba 100644 --- a/src/rustc.rs +++ b/src/rustc.rs @@ -88,8 +88,13 @@ pub struct Rustc { pub no_default_features: bool, /// Build for the target triple - #[clap(long, value_name = "TRIPLE", env = "CARGO_BUILD_TARGET")] - pub target: Option, + #[clap( + long, + value_name = "TRIPLE", + env = "CARGO_BUILD_TARGET", + multiple_occurrences = true + )] + pub target: Vec, /// Output compiler information without compiling #[clap(long, value_name = "INFO")] diff --git a/src/zig.rs b/src/zig.rs index 8908c83..792d398 100644 --- a/src/zig.rs +++ b/src/zig.rs @@ -53,6 +53,7 @@ impl Zig { .map(|x| x.contains("windows-gnu")) .unwrap_or_default(); let is_arm = target.map(|x| x.contains("arm")).unwrap_or_default(); + let is_macos = target.map(|x| x.contains("macos")).unwrap_or_default(); let rustc_ver = rustc_version::version()?; @@ -128,6 +129,17 @@ impl Zig { new_cmd_args.push("-Wl,-undefined=dynamic_lookup".to_string()); } + if is_macos { + if let Ok(sdkroot) = env::var("SDKROOT") { + new_cmd_args.extend_from_slice(&[ + format!("--sysroot={}", sdkroot), + "-I/usr/include".to_string(), + "-L/usr/lib".to_string(), + "-F/System/Library/Frameworks".to_string(), + ]); + } + } + let mut child = Self::command()? .arg(cmd) .args(new_cmd_args)