Merge pull request #1469 from PyO3/deny-pypy-and-abi3
Show warning when abi3 is used with PyPy
This commit is contained in:
commit
4c80ce93c3
72
build.rs
72
build.rs
|
@ -23,6 +23,13 @@ macro_rules! bail {
|
||||||
($fmt: literal $(, $args: expr)+) => { return Err(format!($fmt $(,$args)+).into()); };
|
($fmt: literal $(, $args: expr)+) => { return Err(format!($fmt $(,$args)+).into()); };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show warning. If needed, please extend this macro to support arguments.
|
||||||
|
macro_rules! warn {
|
||||||
|
($msg: literal) => {
|
||||||
|
println!(concat!("cargo:warning=", $msg));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/// Information returned from python interpreter
|
/// Information returned from python interpreter
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct InterpreterConfig {
|
struct InterpreterConfig {
|
||||||
|
@ -34,13 +41,23 @@ struct InterpreterConfig {
|
||||||
base_prefix: String,
|
base_prefix: String,
|
||||||
executable: PathBuf,
|
executable: PathBuf,
|
||||||
calcsize_pointer: Option<u32>,
|
calcsize_pointer: Option<u32>,
|
||||||
|
implementation: PythonInterpreterKind,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
impl InterpreterConfig {
|
||||||
|
fn is_pypy(&self) -> bool {
|
||||||
|
self.implementation == PythonInterpreterKind::PyPy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, PartialOrd)]
|
||||||
struct PythonVersion {
|
struct PythonVersion {
|
||||||
major: u8,
|
major: u8,
|
||||||
minor: u8,
|
minor: u8,
|
||||||
implementation: PythonInterpreterKind,
|
}
|
||||||
|
|
||||||
|
impl PythonVersion {
|
||||||
|
const PY37: Self = PythonVersion { major: 3, minor: 7 };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
@ -60,6 +77,10 @@ impl FromStr for PythonInterpreterKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_abi3() -> bool {
|
||||||
|
env::var_os("CARGO_FEATURE_ABI3").is_some()
|
||||||
|
}
|
||||||
|
|
||||||
trait GetPrimitive {
|
trait GetPrimitive {
|
||||||
fn get_bool(&self, key: &str) -> Result<bool>;
|
fn get_bool(&self, key: &str) -> Result<bool>;
|
||||||
fn get_numeric<T: FromStr>(&self, key: &str) -> Result<T>;
|
fn get_numeric<T: FromStr>(&self, key: &str) -> Result<T>;
|
||||||
|
@ -266,16 +287,14 @@ impl BuildFlags {
|
||||||
fn fixup(&mut self, interpreter_config: &InterpreterConfig) {
|
fn fixup(&mut self, interpreter_config: &InterpreterConfig) {
|
||||||
if self.0.contains("Py_DEBUG") {
|
if self.0.contains("Py_DEBUG") {
|
||||||
self.0.insert("Py_REF_DEBUG");
|
self.0.insert("Py_REF_DEBUG");
|
||||||
if interpreter_config.version.major == 3 && interpreter_config.version.minor <= 7 {
|
if interpreter_config.version <= PythonVersion::PY37 {
|
||||||
// Py_DEBUG only implies Py_TRACE_REFS until Python 3.7
|
// Py_DEBUG only implies Py_TRACE_REFS until Python 3.7
|
||||||
self.0.insert("Py_TRACE_REFS");
|
self.0.insert("Py_TRACE_REFS");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WITH_THREAD is always on for Python 3.7, and for PyPy.
|
// WITH_THREAD is always on for Python 3.7, and for PyPy.
|
||||||
if (interpreter_config.version.implementation == PythonInterpreterKind::PyPy)
|
if interpreter_config.is_pypy() || interpreter_config.version >= PythonVersion::PY37 {
|
||||||
|| (interpreter_config.version.major == 3 && interpreter_config.version.minor >= 7)
|
|
||||||
{
|
|
||||||
self.0.insert("WITH_THREAD");
|
self.0.insert("WITH_THREAD");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -455,11 +474,7 @@ fn load_cross_compile_from_sysconfigdata(
|
||||||
};
|
};
|
||||||
let calcsize_pointer = sysconfig_data.get_numeric("SIZEOF_VOID_P").ok();
|
let calcsize_pointer = sysconfig_data.get_numeric("SIZEOF_VOID_P").ok();
|
||||||
|
|
||||||
let python_version = PythonVersion {
|
let python_version = PythonVersion { major, minor };
|
||||||
major,
|
|
||||||
minor,
|
|
||||||
implementation: PythonInterpreterKind::CPython,
|
|
||||||
};
|
|
||||||
|
|
||||||
let interpreter_config = InterpreterConfig {
|
let interpreter_config = InterpreterConfig {
|
||||||
version: python_version,
|
version: python_version,
|
||||||
|
@ -469,6 +484,7 @@ fn load_cross_compile_from_sysconfigdata(
|
||||||
base_prefix: "".to_string(),
|
base_prefix: "".to_string(),
|
||||||
executable: PathBuf::new(),
|
executable: PathBuf::new(),
|
||||||
calcsize_pointer,
|
calcsize_pointer,
|
||||||
|
implementation: PythonInterpreterKind::CPython,
|
||||||
};
|
};
|
||||||
|
|
||||||
let build_flags = BuildFlags::from_config_map(&sysconfig_data);
|
let build_flags = BuildFlags::from_config_map(&sysconfig_data);
|
||||||
|
@ -486,11 +502,7 @@ fn load_cross_compile_from_headers(
|
||||||
let major = patchlevel_defines.get_numeric("PY_MAJOR_VERSION")?;
|
let major = patchlevel_defines.get_numeric("PY_MAJOR_VERSION")?;
|
||||||
let minor = patchlevel_defines.get_numeric("PY_MINOR_VERSION")?;
|
let minor = patchlevel_defines.get_numeric("PY_MINOR_VERSION")?;
|
||||||
|
|
||||||
let python_version = PythonVersion {
|
let python_version = PythonVersion { major, minor };
|
||||||
major,
|
|
||||||
minor,
|
|
||||||
implementation: PythonInterpreterKind::CPython,
|
|
||||||
};
|
|
||||||
|
|
||||||
let config_data = parse_header_defines(python_include_dir.join("pyconfig.h"))?;
|
let config_data = parse_header_defines(python_include_dir.join("pyconfig.h"))?;
|
||||||
|
|
||||||
|
@ -502,6 +514,7 @@ fn load_cross_compile_from_headers(
|
||||||
base_prefix: "".to_string(),
|
base_prefix: "".to_string(),
|
||||||
executable: PathBuf::new(),
|
executable: PathBuf::new(),
|
||||||
calcsize_pointer: None,
|
calcsize_pointer: None,
|
||||||
|
implementation: PythonInterpreterKind::CPython,
|
||||||
};
|
};
|
||||||
|
|
||||||
let build_flags = BuildFlags::from_config_map(&config_data);
|
let build_flags = BuildFlags::from_config_map(&config_data);
|
||||||
|
@ -531,11 +544,7 @@ fn windows_hardcoded_cross_compile(
|
||||||
bail!("One of PYO3_CROSS_INCLUDE_DIR, PYO3_CROSS_PYTHON_VERSION, or an abi3-py3* feature must be specified when cross-compiling for Windows.")
|
bail!("One of PYO3_CROSS_INCLUDE_DIR, PYO3_CROSS_PYTHON_VERSION, or an abi3-py3* feature must be specified when cross-compiling for Windows.")
|
||||||
};
|
};
|
||||||
|
|
||||||
let python_version = PythonVersion {
|
let python_version = PythonVersion { major, minor };
|
||||||
major,
|
|
||||||
minor,
|
|
||||||
implementation: PythonInterpreterKind::CPython,
|
|
||||||
};
|
|
||||||
|
|
||||||
let interpreter_config = InterpreterConfig {
|
let interpreter_config = InterpreterConfig {
|
||||||
version: python_version,
|
version: python_version,
|
||||||
|
@ -545,6 +554,7 @@ fn windows_hardcoded_cross_compile(
|
||||||
base_prefix: "".to_string(),
|
base_prefix: "".to_string(),
|
||||||
executable: PathBuf::new(),
|
executable: PathBuf::new(),
|
||||||
calcsize_pointer: None,
|
calcsize_pointer: None,
|
||||||
|
implementation: PythonInterpreterKind::CPython,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((interpreter_config, BuildFlags::windows_hardcoded()))
|
Ok((interpreter_config, BuildFlags::windows_hardcoded()))
|
||||||
|
@ -609,6 +619,7 @@ fn get_rustc_link_lib(config: &InterpreterConfig) -> String {
|
||||||
let link_name = if env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" {
|
let link_name = if env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() == "windows" {
|
||||||
if env::var("CARGO_CFG_TARGET_ENV").unwrap().as_str() == "gnu" {
|
if env::var("CARGO_CFG_TARGET_ENV").unwrap().as_str() == "gnu" {
|
||||||
// https://packages.msys2.org/base/mingw-w64-python
|
// https://packages.msys2.org/base/mingw-w64-python
|
||||||
|
// TODO: ABI3?
|
||||||
format!(
|
format!(
|
||||||
"pythonXY:python{}.{}",
|
"pythonXY:python{}.{}",
|
||||||
config.version.major, config.version.minor
|
config.version.major, config.version.minor
|
||||||
|
@ -618,7 +629,7 @@ fn get_rustc_link_lib(config: &InterpreterConfig) -> String {
|
||||||
// See https://www.python.org/dev/peps/pep-0384/#linkage
|
// See https://www.python.org/dev/peps/pep-0384/#linkage
|
||||||
//
|
//
|
||||||
// This contains only the limited ABI symbols.
|
// This contains only the limited ABI symbols.
|
||||||
if env::var_os("CARGO_FEATURE_ABI3").is_some() {
|
if is_abi3() {
|
||||||
"pythonXY:python3".to_owned()
|
"pythonXY:python3".to_owned()
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
|
@ -628,7 +639,7 @@ fn get_rustc_link_lib(config: &InterpreterConfig) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match config.version.implementation {
|
match config.implementation {
|
||||||
PythonInterpreterKind::CPython => format!("python{}", config.ld_version),
|
PythonInterpreterKind::CPython => format!("python{}", config.ld_version),
|
||||||
PythonInterpreterKind::PyPy => format!("pypy{}-c", config.version.major),
|
PythonInterpreterKind::PyPy => format!("pypy{}-c", config.version.major),
|
||||||
}
|
}
|
||||||
|
@ -736,8 +747,8 @@ print("calcsize_pointer", struct.calcsize("P"))
|
||||||
version: PythonVersion {
|
version: PythonVersion {
|
||||||
major: map["version_major"].parse()?,
|
major: map["version_major"].parse()?,
|
||||||
minor: map["version_minor"].parse()?,
|
minor: map["version_minor"].parse()?,
|
||||||
implementation: map["implementation"].parse()?,
|
|
||||||
},
|
},
|
||||||
|
implementation: map["implementation"].parse()?,
|
||||||
libdir: map.get("libdir").cloned(),
|
libdir: map.get("libdir").cloned(),
|
||||||
shared,
|
shared,
|
||||||
ld_version: map["ld_version"].clone(),
|
ld_version: map["ld_version"].clone(),
|
||||||
|
@ -781,14 +792,21 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result<()> {
|
||||||
println!("cargo:rustc-cfg=Py_SHARED");
|
println!("cargo:rustc-cfg=Py_SHARED");
|
||||||
}
|
}
|
||||||
|
|
||||||
if interpreter_config.version.implementation == PythonInterpreterKind::PyPy {
|
let is_abi3 = is_abi3();
|
||||||
|
|
||||||
|
if interpreter_config.is_pypy() {
|
||||||
println!("cargo:rustc-cfg=PyPy");
|
println!("cargo:rustc-cfg=PyPy");
|
||||||
|
if is_abi3 {
|
||||||
|
warn!(
|
||||||
|
"PyPy does not yet support abi3 so the resulting wheel will be version-specific. \
|
||||||
|
See https://foss.heptapod.net/pypy/pypy/-/issues/3397 for more information."
|
||||||
|
)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let minor = if env::var_os("CARGO_FEATURE_ABI3").is_some() {
|
let minor = if is_abi3 {
|
||||||
println!("cargo:rustc-cfg=Py_LIMITED_API");
|
println!("cargo:rustc-cfg=Py_LIMITED_API");
|
||||||
// Check any `abi3-py3*` feature is set. If not, use the interpreter version.
|
// Check any `abi3-py3*` feature is set. If not, use the interpreter version.
|
||||||
|
|
||||||
match get_abi3_minor_version() {
|
match get_abi3_minor_version() {
|
||||||
Some(minor) if minor > interpreter_config.version.minor => bail!(
|
Some(minor) if minor > interpreter_config.version.minor => bail!(
|
||||||
"You cannot set a mininimum Python version 3.{} higher than the interpreter version 3.{}",
|
"You cannot set a mininimum Python version 3.{} higher than the interpreter version 3.{}",
|
||||||
|
|
Loading…
Reference in New Issue