Skip to content

Commit 845e117

Browse files
committed
feat: Add support for the 32-bit target architecture
Add a new global function `generate_implib_for_target()`, which allows the user to specify the compile target architecture and environment ABI tags. Keep the existing `generate_implib()` function for backwards compatibility and clarify that it only generates import libraries for the default `x86_64-pc-windows-gnu` cross-compile target. TODO: Documentation
1 parent 46671d8 commit 845e117

File tree

1 file changed

+39
-5
lines changed

1 file changed

+39
-5
lines changed

src/lib.rs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! -------------------------
1414
//!
1515
//! The following script can be used to cross-compile Stable ABI
16-
//! PyO3 extension modules for Windows:
16+
//! PyO3 extension modules for Windows (64-bit):
1717
//!
1818
//! ```no_run
1919
//! fn main() {
@@ -57,17 +57,26 @@ const DEF_FILE: &str = "python3.def";
5757
/// Canonical MinGW-w64 `dlltool` program name
5858
const DLLTOOL: &str = "x86_64-w64-mingw32-dlltool";
5959

60+
/// Canonical MinGW-w64 `dlltool` program name (32-bit version)
61+
const DLLTOOL_32: &str = "i686-w64-mingw32-dlltool";
62+
6063
/// Python Stable ABI symbol defs from the CPython repository
6164
///
6265
/// Upstream source: <https://github.com/python/cpython/blob/main/Misc/stable_abi.txt>
6366
const STABLE_ABI_DEFS: &str = include_str!("../Misc/stable_abi.txt");
6467

6568
/// Generates `python3.dll` import library directly from the embedded
66-
/// Python Stable ABI definitions data.
69+
/// Python Stable ABI definitions data for the specified compile target.
6770
///
6871
/// The import library file named `python3.dll.a` is created
6972
/// in directory `out_dir`.
70-
pub fn generate_implib(out_dir: &str) -> Result<()> {
73+
///
74+
/// The compile target architecture name (as in `CARGO_CFG_TARGET_ARCH`)
75+
/// is passed in `arch`.
76+
///
77+
/// The compile target environment ABI name (as in `CARGO_CFG_TARGET_ENV`)
78+
/// is passed in `env`.
79+
pub fn generate_implib_for_target(out_dir: &str, arch: &str, env: &str) -> Result<()> {
7180
create_dir_all(out_dir)?;
7281

7382
let mut libpath = PathBuf::from(out_dir);
@@ -82,7 +91,19 @@ pub fn generate_implib(out_dir: &str) -> Result<()> {
8291
write_export_defs(&mut writer, DLL_FILE, &stable_abi_exports)?;
8392
drop(writer);
8493

85-
let status = Command::new(DLLTOOL)
94+
// Try to guess the `dlltool` executable name from the target triple.
95+
let dlltool = match (arch, env) {
96+
// 64-bit MinGW-w64 (aka x86_64-pc-windows-gnu)
97+
("x86_64", "gnu") => DLLTOOL,
98+
// 32-bit MinGW-w64 (aka i686-pc-windows-gnu)
99+
("x86", "gnu") => DLLTOOL_32,
100+
_ => {
101+
let msg = format!("Unsupported target arch '{arch}' or env ABI '{env}'");
102+
return Err(Error::new(ErrorKind::Other, msg));
103+
}
104+
};
105+
106+
let status = Command::new(dlltool)
86107
.arg("--input-def")
87108
.arg(defpath)
88109
.arg("--output-lib")
@@ -92,11 +113,24 @@ pub fn generate_implib(out_dir: &str) -> Result<()> {
92113
if status.success() {
93114
Ok(())
94115
} else {
95-
let msg = format!("{DLLTOOL} failed with {status}");
116+
let msg = format!("{dlltool} failed with {status}");
96117
Err(Error::new(ErrorKind::Other, msg))
97118
}
98119
}
99120

121+
/// Generates `python3.dll` import library directly from the embedded
122+
/// Python Stable ABI definitions data for the default 64-bit MinGW-w64
123+
/// compile target.
124+
///
125+
/// The import library file named `python3.dll.a` is created
126+
/// in directory `out_dir`.
127+
///
128+
/// The import library is generated for the default `x86_64-pc-windows-gnu`
129+
/// cross-compile target.
130+
pub fn generate_implib(out_dir: &str) -> Result<()> {
131+
generate_implib_for_target(out_dir, "x86_64", "gnu")
132+
}
133+
100134
/// Exported DLL symbol definition
101135
struct DllExport {
102136
/// Export symbol name

0 commit comments

Comments
 (0)