diff --git a/Cargo.lock b/Cargo.lock index 412dfa98c..d59e7d3af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -761,7 +761,6 @@ dependencies = [ "shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)", - "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1595,11 +1594,6 @@ dependencies = [ "xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "target_info" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "tempdir" version = "0.3.7" @@ -2219,7 +2213,6 @@ dependencies = [ "checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)" = "b3196bfbffbba3e57481b6ea32249fbaf590396a52505a2615adbb79d9d826d3" -"checksum target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c63f48baada5c52e65a29eef93ab4f8982681b67f9e8d29c7b05abcfec2b9ffe" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83" diff --git a/Cargo.toml b/Cargo.toml index 260aa1c3d..aee75f901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ sha2 = "0.8.0" shlex = "0.1.1" structopt = "0.3.5" tar = "0.4.26" -target_info = "0.1.0" tempfile = "3.1.0" toml = "0.5.5" walkdir = "2.2.8" diff --git a/Readme.md b/Readme.md index e7a5b3e7d..1a3f5dd98 100644 --- a/Readme.md +++ b/Readme.md @@ -41,7 +41,7 @@ pyo3 will set the used python interpreter in the environment variable `PYTHON_SY Cffi wheels are compatible with all python versions, but they need to have `cffi` installed for the python used for building (`pip install cffi`). -maturin will utilize cbindgen to generate a header file. To customize the header file you can either configure cbindgen through a cbindgen.toml file inside your project root or write a setup a build script which writes a header file to `$PROJECT_ROOT/target/header.h`. +maturin will utilize cbindgen to generate a header file. To customize the header file you can either configure cbindgen through a cbindgen.toml file inside your project root or write a setup a build script which writes a header file to `$PROJECT_ROOT/target/header.h`. Based on this header file maturin generates a module which exports an `ffi` and a `lib` object. @@ -178,22 +178,22 @@ maturin can build wheels for pypy with pyo3. Note that pypy [is not compatible w ``` FLAGS: - -h, --help + -h, --help Prints help information - --no-sdist + --no-sdist Don't build a source distribution - --release + --release Pass --release to cargo - --skip-auditwheel + --skip-auditwheel [deprecated, use --manylinux instead] Don't check for manylinux compliance - --strip + --strip Strip the library for minimum file size - -V, --version + -V, --version Prints version information @@ -203,33 +203,35 @@ OPTIONS: --cargo-extra-args ... Extra arguments that will be passed to cargo as `cargo rustc [...] [arg1] [arg2] --` - + Use as `--cargo-extra-args="--my-arg"` -i, --interpreter ... The python versions to build wheels for, given as the names of the interpreters. Uses autodiscovery if not explicitly set. --manylinux Control the platform tag on linux. - + - `1`: Use the manylinux1 tag and check for compliance - `1-unchecked`: Use the manylinux1 tag without checking for compliance - `2010`: Use the manylinux2010 tag and check for compliance - - `2010-unchecked`: Use the manylinux1 tag without checking for compliance + - `2010-unchecked`: Use the manylinux2010 tag without checking for compliance + - `2014`: Use the manylinux2014 tag and check for compliance + - `2014-unchecked`: Use the manylinux2014 tag without checking for compliance - `off`: Use the native linux tag (off) - + This option is ignored on all non-linux platforms [default: 1] [possible values: 1, 1-unchecked, 2010, 2010-unchecked, off] -o, --out The directory to store the built wheels in. Defaults to a new "wheels" directory in the project's target directory - -m, --manifest-path + -m, --manifest-path The path to the Cargo.toml [default: Cargo.toml] --rustc-extra-args ... Extra arguments that will be passed to rustc as `cargo rustc [...] -- [arg1] [arg2]` - + Use as `--rustc-extra-args="--my-arg"` - --target + --target The --target option for cargo ``` @@ -237,22 +239,22 @@ OPTIONS: ``` FLAGS: - --debug + --debug Do not pass --release to cargo - -h, --help + -h, --help Prints help information - --no-sdist + --no-sdist Don't build a source distribution - --no-strip + --no-strip Strip the library for minimum file size - --skip-auditwheel + --skip-auditwheel [deprecated, use --manylinux instead] Don't check for manylinux compliance - -V, --version + -V, --version Prints version information @@ -262,29 +264,31 @@ OPTIONS: --cargo-extra-args ... Extra arguments that will be passed to cargo as `cargo rustc [...] [arg1] [arg2] --` - + Use as `--cargo-extra-args="--my-arg"` -i, --interpreter ... The python versions to build wheels for, given as the names of the interpreters. Uses autodiscovery if not explicitly set. --manylinux Control the platform tag on linux. - + - `1`: Use the manylinux1 tag and check for compliance - `1-unchecked`: Use the manylinux1 tag without checking for compliance - `2010`: Use the manylinux2010 tag and check for compliance - `2010-unchecked`: Use the manylinux1 tag without checking for compliance + - `2014`: Use the manylinux2010 tag and check for compliance + - `2014-unchecked`: Use the manylinux1 tag without checking for compliance - `off`: Use the native linux tag (off) - + This option is ignored on all non-linux platforms [default: 1] [possible values: 1, 1-unchecked, 2010, - 2010-unchecked, off] + 2010-unchecked, 2014, 2014-unchecked, off] -o, --out The directory to store the built wheels in. Defaults to a new "wheels" directory in the project's target directory -p, --password Password for pypi or your custom registry. Note that you can also pass the password through MATURIN_PASSWORD - -m, --manifest-path + -m, --manifest-path The path to the Cargo.toml [default: Cargo.toml] -r, --repository-url @@ -292,12 +296,12 @@ OPTIONS: --rustc-extra-args ... Extra arguments that will be passed to rustc as `cargo rustc [...] -- [arg1] [arg2]` - + Use as `--rustc-extra-args="--my-arg"` - --target + --target The --target option for cargo - -u, --username + -u, --username Username for pypi or your custom registry ``` @@ -305,16 +309,16 @@ OPTIONS: ``` FLAGS: - -h, --help + -h, --help Prints help information - --release + --release Pass --release to cargo - --strip + --strip Strip the library for minimum file size - -V, --version + -V, --version Prints version information @@ -324,14 +328,14 @@ OPTIONS: --cargo-extra-args ... Extra arguments that will be passed to cargo as `cargo rustc [...] [arg1] [arg2] --` - + Use as `--cargo-extra-args="--my-arg"` - -m, --manifest-path + -m, --manifest-path The path to the Cargo.toml [default: Cargo.toml] --rustc-extra-args ... Extra arguments that will be passed to rustc as `cargo rustc [...] -- [arg1] [arg2]` - + Use as `--rustc-extra-args="--my-arg"` ``` diff --git a/src/build_options.rs b/src/build_options.rs index 1955d54f7..6d07c7222 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -22,13 +22,15 @@ pub struct BuildOptions { /// - `1`: Use the manylinux1 tag and check for compliance{n} /// - `1-unchecked`: Use the manylinux1 tag without checking for compliance{n} /// - `2010`: Use the manylinux2010 tag and check for compliance{n} - /// - `2010-unchecked`: Use the manylinux1 tag without checking for compliance{n} + /// - `2010-unchecked`: Use the manylinux2010 tag without checking for compliance{n} + /// - `2014`: Use the manylinux2010 tag and check for compliance{n} + /// - `2014-unchecked`: Use the manylinux2014 tag without checking for compliance{n} /// - `off`: Use the native linux tag (off) /// /// This option is ignored on all non-linux platforms #[structopt( long, - possible_values = &["1", "1-unchecked", "2010", "2010-unchecked", "off"], + possible_values = &["1", "1-unchecked", "2010", "2010-unchecked", "2014", "2014-unchecked", "off"], case_insensitive = true, default_value = "1" )] diff --git a/src/target.rs b/src/target.rs index 03b00a917..379efef4d 100644 --- a/src/target.rs +++ b/src/target.rs @@ -1,13 +1,12 @@ use failure::{bail, format_err, Error}; use platform_info::*; use platforms; -use platforms::target::Arch; use serde::{Deserialize, Serialize}; use std::env; +use std::fmt; use std::path::Path; use std::path::PathBuf; use std::str::FromStr; -use target_info; /// All supported operating system #[derive(Debug, Clone, Eq, PartialEq)] @@ -29,10 +28,28 @@ pub enum Manylinux { Manylinux2010, /// Use the manylinux2010 tag but don't check for compliance Manylinux2010Unchecked, + /// Use manylinux2014 tag and check for compliance + Manylinux2014, + /// Use the manylinux2014 tag but don't check for compliance + Manylinux2014Unchecked, /// Use the native linux tag Off, } +impl fmt::Display for Manylinux { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Manylinux::Manylinux1 => write!(f, "manylinux1"), + Manylinux::Manylinux1Unchecked => write!(f, "manylinux1"), + Manylinux::Manylinux2010 => write!(f, "manylinux2010"), + Manylinux::Manylinux2010Unchecked => write!(f, "manylinux2010"), + Manylinux::Manylinux2014 => write!(f, "manylinux2014"), + Manylinux::Manylinux2014Unchecked => write!(f, "manylinux2014"), + Manylinux::Off => write!(f, "linux"), + } + } +} + impl FromStr for Manylinux { type Err = &'static str; @@ -42,39 +59,42 @@ impl FromStr for Manylinux { "1-unchecked" => Ok(Manylinux::Manylinux1Unchecked), "2010" => Ok(Manylinux::Manylinux2010), "2010-unchecked" => Ok(Manylinux::Manylinux2010Unchecked), + "2014" => Ok(Manylinux::Manylinux2014Unchecked), + "2014-unchecked" => Ok(Manylinux::Manylinux2014Unchecked), "off" => Ok(Manylinux::Off), _ => Err("Invalid value for the manylinux option"), } } } +/// All supported CPU architectures +#[derive(Debug, Clone, Eq, PartialEq)] +enum Arch { + AARCH64, + ARM7L, + X86, + X86_64, +} + +impl fmt::Display for Arch { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Arch::AARCH64 => write!(f, "aarch64"), + Arch::ARM7L => write!(f, "arm7l"), + Arch::X86 => write!(f, "i686"), + Arch::X86_64 => write!(f, "x86_64"), + } + } +} + /// The part of the current platform that is relevant when building wheels and is supported #[derive(Debug, Clone, Eq, PartialEq)] pub struct Target { os: OS, - is_64_bit: bool, + arch: Arch, } impl Target { - /// Returns the target maturin was compiled for - pub fn current() -> Self { - let os = match target_info::Target::os() { - "linux" => OS::Linux, - "windows" => OS::Windows, - "macos" => OS::Macos, - "freebsd" => OS::FreeBSD, - unsupported => panic!("The platform {} is not supported", unsupported), - }; - - let is_64_bit = match target_info::Target::pointer_width() { - "64" => true, - "32" => false, - unsupported => panic!("The pointer width {} is not supported ಠ_ಠ", unsupported), - }; - - Target { os, is_64_bit } - } - /// Uses the given target triple or tries the guess the current target by using the one used /// for compilation /// @@ -96,21 +116,42 @@ impl Target { unsupported => bail!("The operating system {:?} is not supported", unsupported), }; - let is_64_bit = match platform.target_arch { - Arch::X86_64 => true, - Arch::X86 => false, + let arch = match platform.target_arch { + platforms::target::Arch::X86_64 => Arch::X86_64, + platforms::target::Arch::X86 => Arch::X86, + platforms::target::Arch::ARM => Arch::ARM7L, + platforms::target::Arch::AARCH64 => Arch::AARCH64, unsupported => bail!("The architecture {:?} is not supported", unsupported), }; - Ok(Target { os, is_64_bit }) + // bail on any unsupported targets + match (&os, &arch) { + (OS::FreeBSD, Arch::AARCH64) => bail!("aarch64 is not supported for FreeBSD"), + (OS::FreeBSD, Arch::ARM7L) => bail!("arm7l is not supported for FreeBSD"), + (OS::FreeBSD, Arch::X86) => bail!("32-bit wheels are not supported for FreeBSD"), + (OS::FreeBSD, Arch::X86_64) => { + match PlatformInfo::new() { + Ok(_) => {} + Err(error) => bail!(error), + }; + } + (OS::Macos, Arch::AARCH64) => bail!("aarch64 is not supported for macOS"), + (OS::Macos, Arch::ARM7L) => bail!("arm7l is not supported for macOS"), + (OS::Macos, Arch::X86) => bail!("32-bit wheels are not supported for macOS"), + (OS::Windows, Arch::AARCH64) => bail!("aarch64 is not supported for Windows"), + (OS::Windows, Arch::ARM7L) => bail!("arm7l is not supported for Windows"), + (_, _) => {} + } + Ok(Target { os, arch }) } /// Returns whether the platform is 64 bit or 32 bit pub fn pointer_width(&self) -> usize { - if self.is_64_bit { - 64 - } else { - 32 + match self.arch { + Arch::AARCH64 => 64, + Arch::ARM7L => 32, + Arch::X86 => 32, + Arch::X86_64 => 64, } } @@ -141,26 +182,8 @@ impl Target { /// Returns the platform part of the tag for the wheel name for cffi wheels pub fn get_platform_tag(&self, manylinux: &Manylinux) -> String { - match (&self.os, self.is_64_bit, manylinux) { - (&OS::Linux, true, Manylinux::Off) => "linux_x86_64".to_string(), - (&OS::Linux, false, Manylinux::Off) => "linux_i686".to_string(), - (&OS::Linux, true, Manylinux::Manylinux1) => "manylinux1_x86_64".to_string(), - (&OS::Linux, true, Manylinux::Manylinux1Unchecked) => "manylinux1_x86_64".to_string(), - (&OS::Linux, true, Manylinux::Manylinux2010) => "manylinux2010_x86_64".to_string(), - (&OS::Linux, true, Manylinux::Manylinux2010Unchecked) => { - "manylinux2010_x86_64".to_string() - } - (&OS::Linux, false, Manylinux::Manylinux1) => "manylinux1_i686".to_string(), - (&OS::Linux, false, Manylinux::Manylinux1Unchecked) => "manylinux1_i686".to_string(), - (&OS::Linux, false, Manylinux::Manylinux2010) => "manylinux2010_i686".to_string(), - (&OS::Linux, false, Manylinux::Manylinux2010Unchecked) => { - "manylinux2010_i686".to_string() - } - (&OS::Windows, true, _) => "win_amd64".to_string(), - (&OS::Windows, false, _) => "win32".to_string(), - (&OS::Macos, true, _) => "macosx_10_7_x86_64".to_string(), - (&OS::Macos, false, _) => panic!("32-bit wheels are not supported for mac os"), - (&OS::FreeBSD, true, _) => { + match (&self.os, &self.arch) { + (OS::FreeBSD, Arch::X86_64) => { let info = match PlatformInfo::new() { Ok(info) => info, Err(error) => panic!(error), @@ -168,7 +191,11 @@ impl Target { let release = info.release().replace(".", "_").replace("-", "_"); format!("freebsd_{}_amd64", release) } - (&OS::FreeBSD, false, _) => panic!("32-bit wheels are not supported for FreeBSD"), + (OS::Linux, _) => format!("{}_{}", manylinux, self.arch), + (OS::Macos, Arch::X86_64) => "macosx_10_7_x86_64".to_string(), + (OS::Windows, Arch::X86) => "win32".to_string(), + (OS::Windows, Arch::X86_64) => "win_amd64".to_string(), + (_, _) => panic!("unsupported target should not have reached get_platform_tag()"), } } @@ -179,22 +206,20 @@ impl Target { /// Returns the platform for the tag in the shared libaries file name pub fn get_shared_platform_tag(&self) -> &'static str { - match self.os { - OS::Linux => { - if self.is_64_bit { - "x86_64-linux-gnu" - } else { - "i386-linux-gnu" - } + match (&self.os, &self.arch) { + (OS::FreeBSD, _) => "", // according imp.get_suffixes(), there are no such + (OS::Linux, Arch::AARCH64) => "aarch64-linux-gnueabihf", // aka armv8-linux-gnueabihf + (OS::Linux, Arch::ARM7L) => "arm-linux-gnueabihf", + (OS::Linux, Arch::X86) => "i386-linux-gnu", // not i686 + (OS::Linux, Arch::X86_64) => "x86_64-linux-gnu", + (OS::Macos, Arch::X86_64) => "darwin", + (OS::Windows, Arch::X86) => "win32", + (OS::Windows, Arch::X86_64) => "win_amd64", + (OS::Macos, _) => { + panic!("unsupported macOS Arch should not have reached get_shared_platform_tag()") } - OS::Macos => "darwin", - OS::FreeBSD => "", // according imp.get_suffixes(), there are no such - OS::Windows => { - if self.is_64_bit { - "win_amd64" - } else { - "win32" - } + (OS::Windows, _) => { + panic!("unsupported Windows Arch should not have reached get_shared_platform_tag()") } } }