Skip to content

Commit

Permalink
Feature gate zig and xwin based cross compiling
Browse files Browse the repository at this point in the history
* `cargo build`: 34.26s
* `cargo build --no-default-features`: 26.25s
  • Loading branch information
messense committed Dec 3, 2022
1 parent d567cfb commit d995b50
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 39 deletions.
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

0 comments on commit d995b50

Please sign in to comment.