diff --git a/Cargo.lock b/Cargo.lock index 9cec09b41..48e2da6a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1275,6 +1275,7 @@ dependencies = [ "regex", "rpassword", "rustc_version", + "semver", "serde", "serde_json", "sha2 0.10.2", diff --git a/Cargo.toml b/Cargo.toml index 4d1df2274..20068f96a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ fs-err = "2.5.0" fat-macho = { version = "0.4.5", default-features = false } once_cell = "1.7.2" rustc_version = "0.4.0" +semver = "1.0.13" target-lexicon = "0.12.0" pyproject-toml = "0.3.0" python-pkginfo = "0.5.4" diff --git a/Changelog.md b/Changelog.md index d79b65fea..ed0a40b06 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +* Deprecate manylinux 2010 support in [#858](https://github.com/PyO3/maturin/pull/858). + The [manylinux](https://github.com/pypa/manylinux) project already dropped its support + and the rustc compiler will [drop glibc 2.12 support in 1.64.0](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html). * Add Linux mips64el architecture support in [#1023](https://github.com/PyO3/maturin/pull/1023) * Add Linux mipsel architecture support in [#1024](https://github.com/PyO3/maturin/pull/1024) * Add Linux 32-bit powerpc architecture support in [#1026](https://github.com/PyO3/maturin/pull/1026) diff --git a/Readme.md b/Readme.md index 8d94fd37d..1f1dbb198 100644 --- a/Readme.md +++ b/Readme.md @@ -234,10 +234,10 @@ There's a `maturin sdist` command for only building a source distribution as wor ## Manylinux and auditwheel For portability reasons, native python modules on linux must only dynamically link a set of very few libraries which are installed basically everywhere, hence the name manylinux. -The pypa offers special docker images and a tool called [auditwheel](https://github.com/pypa/auditwheel/) to ensure compliance with the [manylinux rules](https://www.python.org/dev/peps/pep-0571/#the-manylinux2010-policy). +The pypa offers special docker images and a tool called [auditwheel](https://github.com/pypa/auditwheel/) to ensure compliance with the [manylinux rules](https://peps.python.org/pep-0599/#the-manylinux2014-policy). If you want to publish widely usable wheels for linux pypi, **you need to use a manylinux docker image**. -The Rust compiler since version 1.47 [requires at least glibc 2.11](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1470-2020-10-08), so you need to use at least manylinux2010. +The Rust compiler since version 1.64 [requires at least glibc 2.17](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html), so you need to use at least manylinux2014. For publishing, we recommend enforcing the same manylinux version as the image with the manylinux flag, e.g. use `--manylinux 2014` if you are building in `quay.io/pypa/manylinux2014_x86_64`. The [messense/maturin-action](https://github.com/messense/maturin-action) github action already takes care of this if you set e.g. `manylinux: 2014`. @@ -245,7 +245,7 @@ maturin contains a reimplementation of auditwheel automatically checks the gener If your system's glibc is too new or you link other shared libraries, it will assign the `linux` tag. You can also manually disable those checks and directly use native linux target with `--manylinux off`. -For full manylinux compliance you need to compile in a CentOS docker container. The [pyo3/maturin](https://ghcr.io/pyo3/maturin) image is based on the manylinux2010 image, +For full manylinux compliance you need to compile in a CentOS docker container. The [pyo3/maturin](https://ghcr.io/pyo3/maturin) image is based on the manylinux2014 image, and passes arguments to the `maturin` binary. You can use it like this: ``` diff --git a/guide/src/distribution.md b/guide/src/distribution.md index da59195e8..018d843a7 100644 --- a/guide/src/distribution.md +++ b/guide/src/distribution.md @@ -42,10 +42,10 @@ sdist-include = ["path/**/*"] ## Build Wheels For portability reasons, native python modules on linux must only dynamically link a set of very few libraries which are installed basically everywhere, hence the name manylinux. -The pypa offers special docker images and a tool called [auditwheel](https://github.com/pypa/auditwheel/) to ensure compliance with the [manylinux rules](https://www.python.org/dev/peps/pep-0571/#the-manylinux2010-policy). +The pypa offers special docker images and a tool called [auditwheel](https://github.com/pypa/auditwheel/) to ensure compliance with the [manylinux rules](https://peps.python.org/pep-0599/#the-manylinux2014-policy)). If you want to publish widely usable wheels for linux pypi, **you need to use a manylinux docker image** or [build with zig](#use-zig). -The Rust compiler since version 1.47 [requires at least glibc 2.11](https://github.com/rust-lang/rust/blob/master/RELEASES.md#version-1470-2020-10-08), so you need to use at least manylinux2010. +The Rust compiler since version 1.64 [requires at least glibc 2.17](https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html), so you need to use at least manylinux2014. For publishing, we recommend enforcing the same manylinux version as the image with the manylinux flag, e.g. use `--manylinux 2014` if you are building in `quay.io/pypa/manylinux2014_x86_64`. The [messense/maturin-action](https://github.com/messense/maturin-action) github action already takes care of this if you set e.g. `manylinux: 2014`. @@ -93,9 +93,9 @@ OPTIONS: Options are `manylinux` tags (for example `manylinux2014`/`manylinux_2_24`) or `musllinux` tags (for example `musllinux_1_2`) and `linux` for the native linux tag. - Note that `manylinux1` is unsupported by the rust compiler. Wheels with the native - `linux` tag will be rejected by pypi, unless they are separately validated by - `auditwheel`. + Note that `manylinux1` and `manylinux2010` is unsupported by the rust compiler. + Wheels with the native `linux` tag will be rejected by pypi, unless they are separately + validated by `auditwheel`. The default is the lowest compatible `manylinux` tag, or plain `linux` if nothing matched @@ -122,7 +122,7 @@ OPTIONS: --zig For manylinux targets, use zig to ensure compliance for the chosen manylinux version - Default to manylinux2010/manylinux_2_12 if you do not specify an `--compatibility` + Default to manylinux2014/manylinux_2_17 if you do not specify an `--compatibility` Make sure you installed zig with `pip install maturin[zig]` diff --git a/guide/src/platform_support.md b/guide/src/platform_support.md index f4e68b1a1..522690313 100644 --- a/guide/src/platform_support.md +++ b/guide/src/platform_support.md @@ -13,9 +13,9 @@ GitHub action and these three platforms. The following targets are built into wheels and downloadable binaries: - * windows: 32-bit and 64-bit x86 - * linux 32-bit and 64-bit x86 as well as armv7 and aarch64 (musl) - * macOS: 64-bit and aarch64 + * Windows: 32-bit and 64-bit x86 as well as arm64 + * Linux: x86, x86_64, armv7, aarch64 and ppc64le (musl), as well as s390x (gnu) + * macOS: x86_64 and aarch64 ## Other Operating Systems @@ -37,3 +37,11 @@ CPython 3.7 to 3.10 are supported and tested on CI, though the entire 3.x series This will be changed as new python versions are released and others have their end of life. PyPy 3.6 and later also works. + +## Manylinux/Musllinux + +`manylinux2014` and its newer versions as well as `musllinux_1_1` and its newer versions +are supported. + +Since Rust and the manylinux project drop support for old manylinux/musllinux versions sometimes, +after maturin 1.0 manylinux version bumps will be minor versions rather than major versions. diff --git a/src/auditwheel/audit.rs b/src/auditwheel/audit.rs index 1934a5358..d4cb11593 100644 --- a/src/auditwheel/audit.rs +++ b/src/auditwheel/audit.rs @@ -363,14 +363,13 @@ pub fn auditwheel_rs( /// /// Currently only gcc is supported, clang doesn't have a `--print-sysroot` option pub fn get_sysroot_path(target: &Target) -> Result { - use crate::target::get_host_target; use std::process::{Command, Stdio}; if let Some(sysroot) = std::env::var_os("TARGET_SYSROOT") { return Ok(PathBuf::from(sysroot)); } - let host_triple = get_host_target()?; + let host_triple = target.host_triple(); let target_triple = target.target_triple(); if host_triple != target_triple { let mut build = cc::Build::new(); @@ -379,7 +378,7 @@ pub fn get_sysroot_path(target: &Target) -> Result { .cargo_metadata(false) // opt_level, host and target are required .opt_level(0) - .host(&host_triple) + .host(host_triple) .target(target_triple); let compiler = build .try_get_compiler() diff --git a/src/auditwheel/platform_tag.rs b/src/auditwheel/platform_tag.rs index 2ad45d3dc..cb9a198e3 100644 --- a/src/auditwheel/platform_tag.rs +++ b/src/auditwheel/platform_tag.rs @@ -71,6 +71,15 @@ impl PlatformTag { pub fn is_musllinux(&self) -> bool { matches!(self, PlatformTag::Musllinux { .. }) } + + /// Is it supported by Rust compiler and manylinux project + pub fn is_supported(&self) -> bool { + match self { + PlatformTag::Manylinux { x, y } => (*x, *y) >= (2, 17), + PlatformTag::Musllinux { .. } => true, + PlatformTag::Linux => true, + } + } } impl fmt::Display for PlatformTag { diff --git a/src/build_options.rs b/src/build_options.rs index b32c641ed..ea55c69e0 100644 --- a/src/build_options.rs +++ b/src/build_options.rs @@ -137,8 +137,9 @@ pub struct BuildOptions { /// or `musllinux` tags (for example `musllinux_1_2`) /// and `linux` for the native linux tag. /// - /// Note that `manylinux1` is unsupported by the rust compiler. Wheels with the native `linux` tag - /// will be rejected by pypi, unless they are separately validated by `auditwheel`. + /// Note that `manylinux1` and `manylinux2010` is unsupported by the rust compiler. + /// Wheels with the native `linux` tag will be rejected by pypi, + /// unless they are separately validated by `auditwheel`. /// /// The default is the lowest compatible `manylinux` tag, or plain `linux` if nothing matched /// @@ -177,7 +178,7 @@ pub struct BuildOptions { /// For manylinux targets, use zig to ensure compliance for the chosen manylinux version /// - /// Default to manylinux2010/manylinux_2_12 if you do not specify an `--compatibility` + /// Default to manylinux2014/manylinux_2_17 if you do not specify an `--compatibility` /// /// Make sure you installed zig with `pip install maturin[zig]` #[clap(long)] @@ -606,11 +607,14 @@ impl BuildOptions { } else { self.platform_tag }; - if platform_tags - .iter() - .any(|tag| tag == &PlatformTag::manylinux1()) - { - eprintln!("⚠️ Warning: manylinux1 is unsupported by the Rust compiler."); + + for platform_tag in &platform_tags { + if !platform_tag.is_supported() { + eprintln!( + "⚠️ Warning: {} is unsupported by the Rust compiler.", + platform_tag + ); + } } match bridge { diff --git a/src/cross_compile.rs b/src/cross_compile.rs index f9cc8adc4..643cdca4d 100644 --- a/src/cross_compile.rs +++ b/src/cross_compile.rs @@ -1,4 +1,3 @@ -use crate::target::get_host_target; use crate::{PythonInterpreter, Target}; use anyhow::{bail, Result}; use fs_err::{self as fs, DirEntry}; @@ -8,7 +7,7 @@ use std::path::{Path, PathBuf}; pub fn is_cross_compiling(target: &Target) -> Result { let target_triple = target.target_triple(); - let host = get_host_target()?; + let host = target.host_triple(); if target_triple == host { // Not cross-compiling return Ok(false); diff --git a/src/python_interpreter/mod.rs b/src/python_interpreter/mod.rs index b4378cb5a..3e1a1634e 100644 --- a/src/python_interpreter/mod.rs +++ b/src/python_interpreter/mod.rs @@ -458,7 +458,7 @@ impl PythonInterpreter { } InterpreterKind::PyPy => { // pypy uses its version as part of the ABI, e.g. - // pypy 3.7 7.3 => numpy-1.20.1-pp37-pypy37_pp73-manylinux2010_x86_64.whl + // pypy 3.7 7.3 => numpy-1.20.1-pp37-pypy37_pp73-manylinux2014_x86_64.whl format!( "pp{major}{minor}-pypy{major}{minor}_{abi_tag}-{platform}", major = self.major, diff --git a/src/target.rs b/src/target.rs index b8fcce278..6b01e2827 100644 --- a/src/target.rs +++ b/src/target.rs @@ -3,6 +3,7 @@ use crate::python_interpreter::InterpreterKind; use crate::{PlatformTag, PythonInterpreter}; use anyhow::{anyhow, bail, format_err, Context, Result}; use platform_info::*; +use rustc_version::VersionMeta; use serde::Deserialize; use std::env; use std::fmt; @@ -132,8 +133,8 @@ pub struct Target { env: Environment, triple: String, cross_compiling: bool, - /// Host machine target triple - pub(crate) host_triple: String, + /// rustc version information + pub(crate) rustc_version: VersionMeta, /// Is user specified `--target` pub(crate) user_specified: bool, } @@ -148,7 +149,8 @@ impl Target { Architecture, ArmArchitecture, Mips32Architecture, Mips64Architecture, OperatingSystem, }; - let host_triple = get_host_target()?; + let rustc_version = rustc_version_meta()?; + let host_triple = &rustc_version.host; let (platform, triple) = if let Some(ref target_triple) = target_triple { let platform: Triple = target_triple .parse() @@ -204,7 +206,7 @@ impl Target { arch, env: platform.environment, triple, - host_triple, + rustc_version, user_specified: target_triple.is_some(), cross_compiling: false, }; @@ -411,7 +413,16 @@ impl Target { Arch::Aarch64 | Arch::Armv7L | Arch::Powerpc64 | Arch::Powerpc64Le | Arch::S390X => { PlatformTag::manylinux2014() } - Arch::X86 | Arch::X86_64 => PlatformTag::manylinux2010(), + Arch::X86 | Arch::X86_64 => { + let rust_1_64 = semver::Version::new(1, 64, 0); + // rustc 1.64.0 bumps glibc requirement to 2.17 + // see https://blog.rust-lang.org/2022/08/01/Increasing-glibc-kernel-requirements.html + if self.rustc_version.semver >= rust_1_64 { + PlatformTag::manylinux2014() + } else { + PlatformTag::manylinux2010() + } + } Arch::Armv6L | Arch::Wasm32 | Arch::Riscv64 @@ -442,11 +453,16 @@ impl Target { } } - /// Returns target triple string + /// Returns target triple as string pub fn target_triple(&self) -> &str { &self.triple } + /// Returns host triple as string + pub fn host_triple(&self) -> &str { + &self.rustc_version.host + } + /// Returns true if the current platform is not windows pub fn is_unix(&self) -> bool { match self.os { @@ -624,22 +640,20 @@ impl Target { } } -pub(crate) fn get_host_target() -> Result { - let host = rustc_version::version_meta() - .map(|meta| meta.host) - .map_err(|err| match err { - rustc_version::Error::CouldNotExecuteCommand(e) - if e.kind() == std::io::ErrorKind::NotFound => - { - anyhow!( - "rustc, the rust compiler, is not installed or not in PATH. \ +fn rustc_version_meta() -> Result { + let meta = rustc_version::version_meta().map_err(|err| match err { + rustc_version::Error::CouldNotExecuteCommand(e) + if e.kind() == std::io::ErrorKind::NotFound => + { + anyhow!( + "rustc, the rust compiler, is not installed or not in PATH. \ This package requires Rust and Cargo to compile extensions. \ Install it through the system's package manager or via https://rustup.rs/.", - ) - } - err => anyhow!(err).context("Failed to run rustc to get the host target"), - })?; - Ok(host) + ) + } + err => anyhow!(err).context("Failed to run rustc to get the host target"), + })?; + Ok(meta) } fn macosx_deployment_target( diff --git a/test-crates/cargo-mock/Cargo.lock b/test-crates/cargo-mock/Cargo.lock index bf1be8068..751187ac7 100644 --- a/test-crates/cargo-mock/Cargo.lock +++ b/test-crates/cargo-mock/Cargo.lock @@ -1,10 +1,12 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "508b352bb5c066aac251f6daf6b36eccd03e8a88e8081cd44959ea277a3af9a8" [[package]] name = "cargo-mock" @@ -17,9 +19,9 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0226944a63d1bf35a3b5f948dd7c59e263db83695c9e8bffc4037de02e30f1d7" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ "serde", ] @@ -39,42 +41,43 @@ dependencies = [ [[package]] name = "itoa" -version = "0.4.7" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754" [[package]] name = "pest" -version = "2.1.3" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "69486e2b8c2d2aeb9762db7b4e00b0331156393555cff467f4163ff06821eef8" dependencies = [ + "thiserror", "ucd-trie", ] [[package]] name = "proc-macro2" -version = "1.0.26" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" dependencies = [ "proc-macro2", ] [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" [[package]] name = "semver" @@ -97,18 +100,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.125" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" +checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.125" +version = "1.0.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" +checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391" dependencies = [ "proc-macro2", "quote", @@ -117,9 +120,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7" dependencies = [ "itoa", "ryu", @@ -128,23 +131,43 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.69" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "syn", ] [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "89570599c4fe5585de2b388aab47e99f7fa4e9238a1399f707a02e356058141c" [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-ident" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"