From b517964e2b512fef3426c6327617746100a361dd Mon Sep 17 00:00:00 2001 From: kngwyu Date: Sat, 31 Oct 2020 16:35:14 +0900 Subject: [PATCH] Add abi3-py* features --- Cargo.toml | 8 ++++++-- build.rs | 25 ++++++++++++++++++++----- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 72a907135a7..270b9390302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,9 +35,13 @@ rustversion = "1.0" [features] default = ["macros"] macros = ["ctor", "indoc", "inventory", "paste", "pyo3cls", "unindent"] -# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for -# more. +# Use the Python limited API. See https://www.python.org/dev/peps/pep-0384/ for more. abi3 = [] +# With abi3, we can manually set the minimum Python version. +abi3-py36 = ["abi3"] +abi3-py37 = ["abi3-py36"] +abi3-py38 = ["abi3-py37"] +abi3-py39 = ["abi3-py38"] # Optimizes PyObject to Vec conversion and so on. nightly = [] diff --git a/build.rs b/build.rs index 1d4d78f61ab..60e6a2b6511 100644 --- a/build.rs +++ b/build.rs @@ -9,7 +9,10 @@ use std::{ str::FromStr, }; -const PY3_MIN_MINOR: u8 = 5; +/// Minimum required Python version. +const PY3_MIN_MINOR: u8 = 6; +/// Maximum Python version that can be used as minimum required Python version with abi3. +const ABI3_MAX_MIN_MINOR: u8 = 9; const CFG_KEY: &str = "py_sys_config"; type Result = std::result::Result>; @@ -770,12 +773,24 @@ fn configure(interpreter_config: &InterpreterConfig) -> Result { bail!("Python 2 is not supported"); } - if env::var_os("CARGO_FEATURE_ABI3").is_some() { - println!("cargo:rustc-cfg=Py_LIMITED_API"); + fn get_abi3_min_python() -> Option { + for i in PY3_MIN_MINOR..=ABI3_MAX_MIN_MINOR { + if env::var_os(format!("CARGO_FEATURE_ABI{}", i)).is_some() { + return Some(i); + } + } + None } - if let Some(minor) = interpreter_config.version.minor { - for i in 6..=minor { + let minor = if env::var_os("CARGO_FEATURE_ABI3").is_some() { + println!("cargo:rustc-cfg=Py_LIMITED_API"); + get_abi3_min_python().and(interpreter_config.version.minor) + } else { + interpreter_config.version.minor + }; + + if let Some(minor) = minor { + for i in PY3_MIN_MINOR..=minor { println!("cargo:rustc-cfg=Py_3_{}", i); flags += format!("CFG_Py_3_{},", i).as_ref(); }