Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature gate zig and xwin based cross compiling #1324

Merged
merged 1 commit into from
Dec 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ jobs:
# Caching
- name: Cache cargo build
uses: Swatinem/rust-cache@v2
- run: cargo build --no-default-features
- name: cargo build
run: cargo build --all

Expand Down
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ base64 = "0.13.0"
glob = "0.3.0"
cargo_metadata = "0.15.2"
cargo-options = "0.5.2"
cargo-zigbuild = "0.14.1"
cargo-xwin = { version = "0.13.0", default-features = false }
cargo-zigbuild = { version = "0.14.1", optional = true }
cargo-xwin = { version = "0.13.0", default-features = false, optional = true }
cbindgen = { version = "0.24.2", default-features = false }
uniffi_bindgen = "0.21.0"
flate2 = "1.0.18"
Expand Down Expand Up @@ -88,12 +88,16 @@ rustversion = "1.0.9"
trycmd = "0.14.0"

[features]
default = ["log", "upload", "rustls"]
default = ["cross-compile", "log", "upload", "rustls"]
upload = ["ureq", "multipart", "rpassword", "configparser", "bytesize"]
password-storage = ["upload", "keyring"]
log = ["tracing-subscriber"]
rustls = ["ureq/tls", "cargo-xwin/rustls-tls"]
native-tls = ["ureq/native-tls", "native-tls-crate", "cargo-xwin/native-tls"]
# cross compile using zig or xwin
cross-compile = ["zig", "xwin"]
zig = ["cargo-zigbuild"]
xwin = ["cargo-xwin"]
# Internal feature to speed up the tests significantly
faster-tests = []
# Deprecated features, keep it now for compatibility
Expand Down
1 change: 1 addition & 0 deletions src/build_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ pub struct BuildContext {
/// Skip checking the linked libraries for manylinux/musllinux compliance
pub skip_auditwheel: bool,
/// When compiling for manylinux, use zig as linker to ensure glibc version compliance
#[cfg(feature = "zig")]
pub zig: bool,
/// Whether to use the the manylinux/musllinux or use the native linux tag (off)
pub platform_tag: Vec<PlatformTag>,
Expand Down
8 changes: 7 additions & 1 deletion src/build_options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ pub struct BuildOptions {
/// Default to manylinux2014/manylinux_2_17 if you do not specify an `--compatibility`
///
/// Make sure you installed zig with `pip install maturin[zig]`
#[cfg(feature = "zig")]
#[arg(long)]
pub zig: bool,

Expand Down Expand Up @@ -598,14 +599,18 @@ impl BuildOptions {
let skip_auditwheel =
pyproject.map(|x| x.skip_auditwheel()).unwrap_or_default() || self.skip_auditwheel;
let platform_tags = if self.platform_tag.is_empty() {
#[cfg(feature = "zig")]
let use_zig = self.zig;
#[cfg(not(feature = "zig"))]
let use_zig = false;
let compatibility = pyproject
.and_then(|x| {
if x.compatibility().is_some() {
pyproject_toml_maturin_options.push("compatibility");
}
x.compatibility()
})
.or(if self.zig {
.or(if use_zig {
if target.is_musl_target() {
// Zig bundles musl 1.2
Some(PlatformTag::Musllinux { x: 1, y: 2 })
Expand Down Expand Up @@ -714,6 +719,7 @@ impl BuildOptions {
release,
strip,
skip_auditwheel,
#[cfg(feature = "zig")]
zig: self.zig,
platform_tag: platform_tags,
interpreter,
Expand Down
65 changes: 44 additions & 21 deletions src/compile.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::build_context::BridgeModel;
use crate::target::RUST_1_64_0;
use crate::{BuildContext, PlatformTag, PythonInterpreter, Target};
#[cfg(feature = "zig")]
use crate::PlatformTag;
use crate::{BuildContext, PythonInterpreter, Target};
use anyhow::{anyhow, bail, Context, Result};
use fat_macho::FatWriter;
use fs_err::{self as fs, File};
Expand Down Expand Up @@ -305,34 +307,55 @@ fn compile_target(

let target_triple = target.target_triple();
let mut build_command = if target.is_msvc() && target.cross_compiling() {
let mut build = cargo_xwin::Rustc::from(cargo_rustc);
#[cfg(feature = "xwin")]
{
let mut build = cargo_xwin::Rustc::from(cargo_rustc);

build.target = vec![target_triple.to_string()];
build.build_command()?
} else {
let mut build = cargo_zigbuild::Rustc::from(cargo_rustc);
if !context.zig {
build.disable_zig_linker = true;
build.target = vec![target_triple.to_string()];
build.build_command()?
}
#[cfg(not(feature = "xwin"))]
{
if target.user_specified {
build.target = vec![target_triple.to_string()];
cargo_rustc.target = vec![target_triple.to_string()];
}
} else {
build.enable_zig_ar = true;
let zig_triple = if target.is_linux() && !target.is_musl_target() {
match context.platform_tag.iter().find(|tag| tag.is_manylinux()) {
Some(PlatformTag::Manylinux { x, y }) => {
format!("{}.{}.{}", target_triple, x, y)
}
_ => target_triple.to_string(),
cargo_rustc.command()
}
} else {
#[cfg(feature = "zig")]
{
let mut build = cargo_zigbuild::Rustc::from(cargo_rustc);
if !context.zig {
build.disable_zig_linker = true;
if target.user_specified {
build.target = vec![target_triple.to_string()];
}
} else {
target_triple.to_string()
};
build.target = vec![zig_triple];
build.enable_zig_ar = true;
let zig_triple = if target.is_linux() && !target.is_musl_target() {
match context.platform_tag.iter().find(|tag| tag.is_manylinux()) {
Some(PlatformTag::Manylinux { x, y }) => {
format!("{}.{}.{}", target_triple, x, y)
}
_ => target_triple.to_string(),
}
} else {
target_triple.to_string()
};
build.target = vec![zig_triple];
}
build.build_command()?
}
#[cfg(not(feature = "zig"))]
{
if target.user_specified {
cargo_rustc.target = vec![target_triple.to_string()];
}
cargo_rustc.command()
}
build.build_command()?
};

#[cfg(feature = "zig")]
if context.zig {
// Pass zig command to downstream, eg. python3-dll-a
if let Ok((zig_cmd, zig_args)) = cargo_zigbuild::Zig::find_zig() {
Expand Down
1 change: 1 addition & 0 deletions src/develop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub fn develop(
bindings,
out: Some(wheel_dir.path().to_path_buf()),
skip_auditwheel: false,
#[cfg(feature = "zig")]
zig: false,
universal2: false,
cargo: CargoOptions {
Expand Down
28 changes: 17 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! Run with --help for usage information

use anyhow::{bail, Context, Result};
#[cfg(feature = "zig")]
use cargo_zigbuild::Zig;
use clap::{CommandFactory, Parser, Subcommand};
use maturin::{
Expand Down Expand Up @@ -153,6 +154,7 @@ enum Opt {
shell: clap_complete_command::Shell,
},
/// Zig linker wrapper
#[cfg(feature = "zig")]
#[command(subcommand, hide = true)]
Zig(Zig),
}
Expand Down Expand Up @@ -278,17 +280,20 @@ fn run() -> Result<()> {
#[cfg(feature = "log")]
tracing_subscriber::fmt::init();

// Allow symlink `maturin` to `ar` to invoke `zig ar`
// See https://github.com/messense/cargo-zigbuild/issues/52
let mut args = env::args();
let program_path = PathBuf::from(args.next().expect("no program path"));
let program_name = program_path.file_stem().expect("no program name");
if program_name.eq_ignore_ascii_case("ar") {
let zig = Zig::Ar {
args: args.collect(),
};
zig.execute()?;
return Ok(());
#[cfg(feature = "zig")]
{
// Allow symlink `maturin` to `ar` to invoke `zig ar`
// See https://github.com/messense/cargo-zigbuild/issues/52
let mut args = env::args();
let program_path = PathBuf::from(args.next().expect("no program path"));
let program_name = program_path.file_stem().expect("no program name");
if program_name.eq_ignore_ascii_case("ar") {
let zig = Zig::Ar {
args: args.collect(),
};
zig.execute()?;
return Ok(());
}
}

let opt = Opt::parse();
Expand Down Expand Up @@ -402,6 +407,7 @@ fn run() -> Result<()> {
Opt::Completions { shell } => {
shell.generate(&mut Opt::command(), &mut io::stdout());
}
#[cfg(feature = "zig")]
Opt::Zig(subcommand) => {
subcommand
.execute()
Expand Down
6 changes: 3 additions & 3 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,9 +779,9 @@ pub(crate) fn rustc_macosx_target_version(target: &str) -> (u16, u16) {
.context("rustc output does not contain llvm-target")?
.as_str()
.context("llvm-target is not a string")?;
let triple: Triple = llvm_target.parse()?;
let (major, minor) = match triple.operating_system {
OperatingSystem::MacOSX { major, minor, .. } => (major, minor),
let triple = llvm_target.parse::<Triple>();
let (major, minor) = match triple.map(|t| t.operating_system) {
Ok(OperatingSystem::MacOSX { major, minor, .. }) => (major, minor),
_ => fallback_version,
};
Ok((major, minor))
Expand Down