build: support emitting arbitrary lines from pyo3 build script
PyOxidizer needs to do some... questionable things with regards to configuring how the Python interpreter is linked. The way I solved this problem for the `cpython` / `python3-sys` crates was by adding a bunch of crate features to control what `cargo:` lines were emitted by the build scripts. This added a lot of complexity to the those crates for a target audience of ~1. Now that PyO3 has support for config files to control settings, this provides a richer mechanism than crate features to influence the build script. This commit defines a new field on the `InterpreterConfig` struct to hold an arbitrary list of strings/lines that should be emitted by the build script. This field is only every populated when parsing config files and it is only read by pyo3's build script to `println!()` additional values. My intended use case for this is to have PyOxidizer effectively control the interpreter link settings via the config file (at my own peril) while having minimal impact on the maintainability of PyO3's code base. Given the complexity of the link hacks employed, you probably don't want this polluting pyo3's code base.
This commit is contained in:
parent
b7c62b8a53
commit
04c77e35c5
5
build.rs
5
build.rs
|
@ -152,6 +152,11 @@ fn configure_pyo3() -> Result<()> {
|
|||
println!("cargo:rustc-cfg=addr_of");
|
||||
}
|
||||
|
||||
// Extra lines come last, to support last write wins.
|
||||
for line in &interpreter_config.extra_build_script_lines {
|
||||
println!("{}", line);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ pub fn abi3_config() -> Option<InterpreterConfig> {
|
|||
pointer_width: None,
|
||||
executable: None,
|
||||
shared: true,
|
||||
extra_build_script_lines: vec![],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,18 @@ pub struct InterpreterConfig {
|
|||
///
|
||||
/// Serialized to `build_flags`.
|
||||
pub build_flags: BuildFlags,
|
||||
|
||||
/// Additional lines to `println!()` from Cargo build scripts.
|
||||
///
|
||||
/// This field can be populated to enable the `pyo3` crate to emit additional lines from its
|
||||
/// its Cargo build script.
|
||||
///
|
||||
/// This crate doesn't populate this field itself. Rather, it is intended to be used with
|
||||
/// externally provided config files to give them significant control over how the crate
|
||||
/// is build/configured.
|
||||
///
|
||||
/// Serialized to multiple `extra_build_script_line` values.
|
||||
pub extra_build_script_lines: Vec<String>,
|
||||
}
|
||||
|
||||
impl InterpreterConfig {
|
||||
|
@ -232,6 +244,7 @@ print("mingw", get_platform() == "mingw")
|
|||
executable: map.get("executable").cloned(),
|
||||
pointer_width: Some(calcsize_pointer * 8),
|
||||
build_flags: BuildFlags::from_interpreter(interpreter)?.fixup(version, implementation),
|
||||
extra_build_script_lines: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -271,6 +284,7 @@ print("mingw", get_platform() == "mingw")
|
|||
let mut executable = None;
|
||||
let mut pointer_width = None;
|
||||
let mut build_flags = None;
|
||||
let mut extra_build_script_lines = vec![];
|
||||
|
||||
for (i, line) in lines.enumerate() {
|
||||
let line = line.context("failed to read line from config")?;
|
||||
|
@ -293,6 +307,9 @@ print("mingw", get_platform() == "mingw")
|
|||
"executable" => parse_value!(executable, value),
|
||||
"pointer_width" => parse_value!(pointer_width, value),
|
||||
"build_flags" => parse_value!(build_flags, value),
|
||||
"extra_build_script_line" => {
|
||||
extra_build_script_lines.push(value.to_string());
|
||||
}
|
||||
unknown => bail!("unknown config key `{}`", unknown),
|
||||
}
|
||||
}
|
||||
|
@ -318,6 +335,7 @@ print("mingw", get_platform() == "mingw")
|
|||
}
|
||||
.fixup(version, implementation)
|
||||
}),
|
||||
extra_build_script_lines,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -356,6 +374,10 @@ print("mingw", get_platform() == "mingw")
|
|||
write_option_line!(executable)?;
|
||||
write_option_line!(pointer_width)?;
|
||||
write_line!(build_flags)?;
|
||||
for line in &self.extra_build_script_lines {
|
||||
writeln!(writer, "extra_build_script_line={}", line)
|
||||
.context("failed to write extra_build_script_line")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -928,6 +950,7 @@ fn load_cross_compile_from_sysconfigdata(
|
|||
executable: None,
|
||||
pointer_width,
|
||||
build_flags: BuildFlags::from_config_map(&sysconfig_data).fixup(version, implementation),
|
||||
extra_build_script_lines: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -947,6 +970,7 @@ fn windows_hardcoded_cross_compile(
|
|||
executable: None,
|
||||
pointer_width: None,
|
||||
build_flags: BuildFlags::windows_hardcoded(),
|
||||
extra_build_script_lines: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1150,6 +1174,7 @@ mod tests {
|
|||
lib_dir: Some("lib_dir".into()),
|
||||
shared: true,
|
||||
version: MINIMUM_SUPPORTED_VERSION,
|
||||
extra_build_script_lines: vec!["cargo:test1".to_string(), "cargo:test2".to_string()],
|
||||
};
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
config.to_writer(&mut buf).unwrap();
|
||||
|
@ -1179,6 +1204,7 @@ mod tests {
|
|||
major: 3,
|
||||
minor: 10,
|
||||
},
|
||||
extra_build_script_lines: vec![],
|
||||
};
|
||||
let mut buf: Vec<u8> = Vec::new();
|
||||
config.to_writer(&mut buf).unwrap();
|
||||
|
@ -1204,6 +1230,7 @@ mod tests {
|
|||
executable: None,
|
||||
pointer_width: None,
|
||||
build_flags: BuildFlags::default(),
|
||||
extra_build_script_lines: vec![],
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1313,7 +1340,8 @@ mod tests {
|
|||
lib_dir: Some("C:\\some\\path".into()),
|
||||
executable: None,
|
||||
pointer_width: None,
|
||||
build_flags: BuildFlags::windows_hardcoded()
|
||||
build_flags: BuildFlags::windows_hardcoded(),
|
||||
extra_build_script_lines: vec![],
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1379,6 +1407,7 @@ mod tests {
|
|||
lib_name: None,
|
||||
shared: true,
|
||||
version: PythonVersion { major: 3, minor: 7 },
|
||||
extra_build_script_lines: vec![],
|
||||
};
|
||||
|
||||
fixup_config_for_abi3(&mut config, Some(PythonVersion { major: 3, minor: 6 })).unwrap();
|
||||
|
@ -1397,6 +1426,7 @@ mod tests {
|
|||
lib_name: None,
|
||||
shared: true,
|
||||
version: PythonVersion { major: 3, minor: 6 },
|
||||
extra_build_script_lines: vec![],
|
||||
};
|
||||
|
||||
assert!(
|
||||
|
|
Loading…
Reference in New Issue