diff --git a/CHANGELOG.md b/CHANGELOG.md index 57f3caa9..5cdfff64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `PyObject_Check`, `PySuper_Check`, and `FreeFunc` [#1438](https://github.com/PyO3/pyo3/pull/1438) - Remove pyclass implementation details `Type`, `DESCRIPTION`, and `FLAGS` from `PyTypeInfo`. [#1456](https://github.com/PyO3/pyo3/pull/1456) - Remove `__doc__` from module's `__all__`. [#1509](https://github.com/PyO3/pyo3/pull/1509) +- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality. ### Fixed - Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425) diff --git a/build.rs b/build.rs index 102ff9fe..0d6b333e 100644 --- a/build.rs +++ b/build.rs @@ -2,8 +2,8 @@ use std::{ collections::{HashMap, HashSet}, convert::AsRef, env, - fs::{self, DirEntry, File}, - io::{self, BufRead, BufReader}, + fs::{self, DirEntry}, + io, path::{Path, PathBuf}, process::{Command, Stdio}, str::FromStr, @@ -109,24 +109,15 @@ impl GetPrimitive for HashMap { struct CrossCompileConfig { lib_dir: PathBuf, - include_dir: Option, version: Option, os: String, arch: String, } impl CrossCompileConfig { - fn both() -> Result { - Ok(CrossCompileConfig { - include_dir: env::var_os("PYO3_CROSS_INCLUDE_DIR").map(Into::into), - ..CrossCompileConfig::lib_only()? - }) - } - - fn lib_only() -> Result { + fn new() -> Result { Ok(CrossCompileConfig { lib_dir: CrossCompileConfig::validate_variable("PYO3_CROSS_LIB_DIR")?, - include_dir: None, os: env::var("CARGO_CFG_TARGET_OS").unwrap(), arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(), version: env::var_os("PYO3_CROSS_PYTHON_VERSION").map(|s| s.into_string().unwrap()), @@ -183,13 +174,8 @@ fn cross_compiling() -> Result> { return Ok(None); } - if env::var("CARGO_CFG_TARGET_FAMILY")? == "windows" { - // Windows cross-compile uses both header includes and sysconfig - return Ok(Some(CrossCompileConfig::both()?)); - } - // Cross-compiling on any other platform - Ok(Some(CrossCompileConfig::lib_only()?)) + Ok(Some(CrossCompileConfig::new()?)) } /// A list of python interpreter compile-time preprocessor defines that @@ -300,23 +286,6 @@ impl BuildFlags { } } -/// Attempts to parse the header at the given path, returning a map of definitions to their values. -/// Each entry in the map directly corresponds to a `#define` in the given header. -fn parse_header_defines(header_path: impl AsRef) -> Result> { - let header_reader = BufReader::new(File::open(header_path.as_ref())?); - let mut definitions = HashMap::new(); - for maybe_line in header_reader.lines() { - let line = maybe_line?; - let mut i = line.trim().split_whitespace(); - if i.next() == Some("#define") { - if let (Some(key), Some(value), None) = (i.next(), i.next(), i.next()) { - definitions.insert(key.into(), value.into()); - } - } - } - Ok(definitions) -} - fn parse_script_output(output: &str) -> HashMap { output .lines() @@ -500,36 +469,6 @@ fn load_cross_compile_from_sysconfigdata( Ok((interpreter_config, build_flags)) } -fn load_cross_compile_from_headers( - cross_compile_config: CrossCompileConfig, -) -> Result<(InterpreterConfig, BuildFlags)> { - let python_include_dir = cross_compile_config.include_dir.unwrap(); - let python_include_dir = Path::new(&python_include_dir); - let patchlevel_defines = parse_header_defines(python_include_dir.join("patchlevel.h"))?; - - let major = patchlevel_defines.get_numeric("PY_MAJOR_VERSION")?; - let minor = patchlevel_defines.get_numeric("PY_MINOR_VERSION")?; - - let python_version = PythonVersion { major, minor }; - - let config_data = parse_header_defines(python_include_dir.join("pyconfig.h"))?; - - let interpreter_config = InterpreterConfig { - version: python_version, - libdir: cross_compile_config.lib_dir.to_str().map(String::from), - shared: config_data.get_bool("Py_ENABLE_SHARED").unwrap_or(false), - ld_version: format!("{}.{}", major, minor), - base_prefix: "".to_string(), - executable: PathBuf::new(), - calcsize_pointer: None, - implementation: PythonInterpreterKind::CPython, - }; - - let build_flags = BuildFlags::from_config_map(&config_data); - - Ok((interpreter_config, build_flags)) -} - fn windows_hardcoded_cross_compile( cross_compile_config: CrossCompileConfig, ) -> Result<(InterpreterConfig, BuildFlags)> { @@ -549,7 +488,7 @@ fn windows_hardcoded_cross_compile( } else if let Some(minor_version) = get_abi3_minor_version() { (3, minor_version) } else { - 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!("PYO3_CROSS_PYTHON_VERSION or an abi3-py3* feature must be specified when cross-compiling for Windows.") }; let python_version = PythonVersion { major, minor }; @@ -576,9 +515,6 @@ fn load_cross_compile_info( if target_family == "unix" { // Configure for unix platforms using the sysconfigdata file load_cross_compile_from_sysconfigdata(cross_compile_config) - } else if cross_compile_config.include_dir.is_some() { - // Must configure by headers on windows platform - load_cross_compile_from_headers(cross_compile_config) } else { windows_hardcoded_cross_compile(cross_compile_config) } diff --git a/guide/src/building_and_distribution.md b/guide/src/building_and_distribution.md index 52051814..053cd19b 100644 --- a/guide/src/building_and_distribution.md +++ b/guide/src/building_and_distribution.md @@ -84,17 +84,13 @@ Cross compiling PyO3 modules is relatively straightforward and requires a few pi * The appropriate options in your Cargo `.config` for the platform you're targeting and the toolchain you are using. * A Python interpreter that's already been compiled for your target. * A Python interpreter that is built for your host and available through the `PATH` or setting the [`PYO3_PYTHON`](#python-version) variable. -* The headers that match the above interpreter. -See https://github.com/japaric/rust-cross for a primer on cross compiling Rust in general. +See [github.com/japaric/rust-cross](https://github.com/japaric/rust-cross) for a primer on cross compiling Rust in general. After you've obtained the above, you can build a cross compiled PyO3 module by setting a few extra environment variables: -* `PYO3_CROSS_LIB_DIR`: This variable must be set to the directory containing the target's libpython DSO and the associated `_sysconfigdata*.py` file. -* `PYO3_CROSS_PYTHON_VERSION`: Major and minor version (e.g. 3.9) of the target Python installation. This variable is only needed if pyo3 cannot determine the version to target by other means: - - From `PYO3_CROSS_INCLUDE_DIR` or abi3-py3* features when targeting Windows, or - - if there are multiple versions of python present in `PYO3_CROSS_LIB_DIR` when targeting unix. -* `PYO3_CROSS_INCLUDE_DIR`: This variable can optionally be set to the directory containing the headers for the target's Python interpreter when targeting Windows. +* `PYO3_CROSS_LIB_DIR`: This variable must be set to the directory containing the target's libpython DSO and the associated `_sysconfigdata*.py` file for Unix-like targets, or the Python DLL import libraries for the Windows target. +* `PYO3_CROSS_PYTHON_VERSION`: Major and minor version (e.g. 3.9) of the target Python installation. This variable is only needed if PyO3 cannot determine the version to target from `abi3-py3*` features, or if there are multiple versions of Python present in `PYO3_CROSS_LIB_DIR`. An example might look like the following (assuming your target's sysroot is at `/home/pyo3/cross/sysroot` and that your target is `armv7`): @@ -112,14 +108,16 @@ export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib" cargo build --target armv7-unknown-linux-gnueabihf ``` -Or another example with the same sys root but building for windows: +Or another example with the same sys root but building for Windows: ```sh -export PYO3_CROSS_INCLUDE_DIR="/home/pyo3/cross/sysroot/usr/include" +export PYO3_CROSS_PYTHON_VERSION=3.9 export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib" cargo build --target x86_64-pc-windows-gnu ``` +Any of the `abi3-py3*` features can be enabled instead of setting `PYO3_CROSS_PYTHON_VERSION` in the above examples. + ## Bazel For an example of how to build python extensions using Bazel, see https://github.com/TheButlah/rules_pyo3