Skip to content

Commit 24b0000

Browse files
authored
Merge pull request #1521 from ravenexp/remove-header-parsing
Remove `pyconfig.h` header parsing
2 parents 3bc5caa + eca20fe commit 24b0000

File tree

3 files changed

+13
-78
lines changed

3 files changed

+13
-78
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3737
- `PyObject_Check`, `PySuper_Check`, and `FreeFunc` [#1438](https://github.com/PyO3/pyo3/pull/1438)
3838
- Remove pyclass implementation details `Type`, `DESCRIPTION`, and `FLAGS` from `PyTypeInfo`. [#1456](https://github.com/PyO3/pyo3/pull/1456)
3939
- Remove `__doc__` from module's `__all__`. [#1509](https://github.com/PyO3/pyo3/pull/1509)
40+
- Remove `PYO3_CROSS_INCLUDE_DIR` environment variable and the associated C header parsing functionality.
4041

4142
### Fixed
4243
- Remove FFI definition `PyCFunction_ClearFreeList` for Python 3.9 and later. [#1425](https://github.com/PyO3/pyo3/pull/1425)

build.rs

Lines changed: 5 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use std::{
22
collections::{HashMap, HashSet},
33
convert::AsRef,
44
env,
5-
fs::{self, DirEntry, File},
6-
io::{self, BufRead, BufReader},
5+
fs::{self, DirEntry},
6+
io,
77
path::{Path, PathBuf},
88
process::{Command, Stdio},
99
str::FromStr,
@@ -109,24 +109,15 @@ impl GetPrimitive for HashMap<String, String> {
109109

110110
struct CrossCompileConfig {
111111
lib_dir: PathBuf,
112-
include_dir: Option<PathBuf>,
113112
version: Option<String>,
114113
os: String,
115114
arch: String,
116115
}
117116

118117
impl CrossCompileConfig {
119-
fn both() -> Result<Self> {
120-
Ok(CrossCompileConfig {
121-
include_dir: env::var_os("PYO3_CROSS_INCLUDE_DIR").map(Into::into),
122-
..CrossCompileConfig::lib_only()?
123-
})
124-
}
125-
126-
fn lib_only() -> Result<Self> {
118+
fn new() -> Result<Self> {
127119
Ok(CrossCompileConfig {
128120
lib_dir: CrossCompileConfig::validate_variable("PYO3_CROSS_LIB_DIR")?,
129-
include_dir: None,
130121
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
131122
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
132123
version: env::var_os("PYO3_CROSS_PYTHON_VERSION").map(|s| s.into_string().unwrap()),
@@ -183,13 +174,8 @@ fn cross_compiling() -> Result<Option<CrossCompileConfig>> {
183174
return Ok(None);
184175
}
185176

186-
if env::var("CARGO_CFG_TARGET_FAMILY")? == "windows" {
187-
// Windows cross-compile uses both header includes and sysconfig
188-
return Ok(Some(CrossCompileConfig::both()?));
189-
}
190-
191177
// Cross-compiling on any other platform
192-
Ok(Some(CrossCompileConfig::lib_only()?))
178+
Ok(Some(CrossCompileConfig::new()?))
193179
}
194180

195181
/// A list of python interpreter compile-time preprocessor defines that
@@ -300,23 +286,6 @@ impl BuildFlags {
300286
}
301287
}
302288

303-
/// Attempts to parse the header at the given path, returning a map of definitions to their values.
304-
/// Each entry in the map directly corresponds to a `#define` in the given header.
305-
fn parse_header_defines(header_path: impl AsRef<Path>) -> Result<HashMap<String, String>> {
306-
let header_reader = BufReader::new(File::open(header_path.as_ref())?);
307-
let mut definitions = HashMap::new();
308-
for maybe_line in header_reader.lines() {
309-
let line = maybe_line?;
310-
let mut i = line.trim().split_whitespace();
311-
if i.next() == Some("#define") {
312-
if let (Some(key), Some(value), None) = (i.next(), i.next(), i.next()) {
313-
definitions.insert(key.into(), value.into());
314-
}
315-
}
316-
}
317-
Ok(definitions)
318-
}
319-
320289
fn parse_script_output(output: &str) -> HashMap<String, String> {
321290
output
322291
.lines()
@@ -500,36 +469,6 @@ fn load_cross_compile_from_sysconfigdata(
500469
Ok((interpreter_config, build_flags))
501470
}
502471

503-
fn load_cross_compile_from_headers(
504-
cross_compile_config: CrossCompileConfig,
505-
) -> Result<(InterpreterConfig, BuildFlags)> {
506-
let python_include_dir = cross_compile_config.include_dir.unwrap();
507-
let python_include_dir = Path::new(&python_include_dir);
508-
let patchlevel_defines = parse_header_defines(python_include_dir.join("patchlevel.h"))?;
509-
510-
let major = patchlevel_defines.get_numeric("PY_MAJOR_VERSION")?;
511-
let minor = patchlevel_defines.get_numeric("PY_MINOR_VERSION")?;
512-
513-
let python_version = PythonVersion { major, minor };
514-
515-
let config_data = parse_header_defines(python_include_dir.join("pyconfig.h"))?;
516-
517-
let interpreter_config = InterpreterConfig {
518-
version: python_version,
519-
libdir: cross_compile_config.lib_dir.to_str().map(String::from),
520-
shared: config_data.get_bool("Py_ENABLE_SHARED").unwrap_or(false),
521-
ld_version: format!("{}.{}", major, minor),
522-
base_prefix: "".to_string(),
523-
executable: PathBuf::new(),
524-
calcsize_pointer: None,
525-
implementation: PythonInterpreterKind::CPython,
526-
};
527-
528-
let build_flags = BuildFlags::from_config_map(&config_data);
529-
530-
Ok((interpreter_config, build_flags))
531-
}
532-
533472
fn windows_hardcoded_cross_compile(
534473
cross_compile_config: CrossCompileConfig,
535474
) -> Result<(InterpreterConfig, BuildFlags)> {
@@ -549,7 +488,7 @@ fn windows_hardcoded_cross_compile(
549488
} else if let Some(minor_version) = get_abi3_minor_version() {
550489
(3, minor_version)
551490
} else {
552-
bail!("One of PYO3_CROSS_INCLUDE_DIR, PYO3_CROSS_PYTHON_VERSION, or an abi3-py3* feature must be specified when cross-compiling for Windows.")
491+
bail!("PYO3_CROSS_PYTHON_VERSION or an abi3-py3* feature must be specified when cross-compiling for Windows.")
553492
};
554493

555494
let python_version = PythonVersion { major, minor };
@@ -576,9 +515,6 @@ fn load_cross_compile_info(
576515
if target_family == "unix" {
577516
// Configure for unix platforms using the sysconfigdata file
578517
load_cross_compile_from_sysconfigdata(cross_compile_config)
579-
} else if cross_compile_config.include_dir.is_some() {
580-
// Must configure by headers on windows platform
581-
load_cross_compile_from_headers(cross_compile_config)
582518
} else {
583519
windows_hardcoded_cross_compile(cross_compile_config)
584520
}

guide/src/building_and_distribution.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,13 @@ Cross compiling PyO3 modules is relatively straightforward and requires a few pi
8484
* The appropriate options in your Cargo `.config` for the platform you're targeting and the toolchain you are using.
8585
* A Python interpreter that's already been compiled for your target.
8686
* A Python interpreter that is built for your host and available through the `PATH` or setting the [`PYO3_PYTHON`](#python-version) variable.
87-
* The headers that match the above interpreter.
8887

89-
See https://github.com/japaric/rust-cross for a primer on cross compiling Rust in general.
88+
See [github.com/japaric/rust-cross](https://github.com/japaric/rust-cross) for a primer on cross compiling Rust in general.
9089

9190
After you've obtained the above, you can build a cross compiled PyO3 module by setting a few extra environment variables:
9291

93-
* `PYO3_CROSS_LIB_DIR`: This variable must be set to the directory containing the target's libpython DSO and the associated `_sysconfigdata*.py` file.
94-
* `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:
95-
- From `PYO3_CROSS_INCLUDE_DIR` or abi3-py3* features when targeting Windows, or
96-
- if there are multiple versions of python present in `PYO3_CROSS_LIB_DIR` when targeting unix.
97-
* `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.
92+
* `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.
93+
* `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`.
9894

9995
An example might look like the following (assuming your target's sysroot is at `/home/pyo3/cross/sysroot` and that your target is `armv7`):
10096

@@ -112,14 +108,16 @@ export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib"
112108
cargo build --target armv7-unknown-linux-gnueabihf
113109
```
114110

115-
Or another example with the same sys root but building for windows:
111+
Or another example with the same sys root but building for Windows:
116112
```sh
117-
export PYO3_CROSS_INCLUDE_DIR="/home/pyo3/cross/sysroot/usr/include"
113+
export PYO3_CROSS_PYTHON_VERSION=3.9
118114
export PYO3_CROSS_LIB_DIR="/home/pyo3/cross/sysroot/usr/lib"
119115

120116
cargo build --target x86_64-pc-windows-gnu
121117
```
122118

119+
Any of the `abi3-py3*` features can be enabled instead of setting `PYO3_CROSS_PYTHON_VERSION` in the above examples.
120+
123121
## Bazel
124122

125123
For an example of how to build python extensions using Bazel, see https://github.com/TheButlah/rules_pyo3

0 commit comments

Comments
 (0)