Skip to content

Commit dd1ee97

Browse files
ognevnychirizxc
andcommitted
fix python abi library name for mingw
usually mingw version of python are shipped with `lib` prefix, so we need to add it for proper linking Co-authored-by: chiri <chirizxc@proton.me>
1 parent d01e618 commit dd1ee97

4 files changed

Lines changed: 62 additions & 25 deletions

File tree

noxfile.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,16 +1363,27 @@ def _check_raw_dylib_macro(session: nox.Session):
13631363
max_minor = int(max_version.split(".")[1])
13641364

13651365
# Build the set of DLL names that default_lib_name_windows can produce
1366-
expected_dlls = {"python3", "python3_d"}
1366+
expected_dlls = {
1367+
"python3",
1368+
"python3_d",
1369+
"libpython3",
1370+
"libpython3_d",
1371+
}
13671372
for minor in range(min_minor, max_minor + 1):
13681373
expected_dlls.add(f"python3{minor}")
13691374
expected_dlls.add(f"python3{minor}_d")
1375+
expected_dlls.add(f"libpython3.{minor}")
1376+
expected_dlls.add(f"libpython3.{minor}_d")
13701377
if minor >= 13:
13711378
expected_dlls.add(f"python3{minor}t")
13721379
expected_dlls.add(f"python3{minor}t_d")
1380+
expected_dlls.add(f"libpython3.{minor}t")
1381+
expected_dlls.add(f"libpython3.{minor}t_d")
13731382
if minor >= 15:
13741383
expected_dlls.add("python3t")
13751384
expected_dlls.add("python3t_d")
1385+
expected_dlls.add("libpython3t")
1386+
expected_dlls.add("libpython3t_d")
13761387

13771388
# PyPy DLL names (libpypy3.X-c.dll)
13781389
pypy_min, pypy_max = _parse_supported_interpreter_version("pypy")
@@ -1383,7 +1394,7 @@ def _check_raw_dylib_macro(session: nox.Session):
13831394

13841395
# Parse the DLL name list in the extern_libpython!(@impl ...) invocation
13851396
lib_rs = (PYO3_DIR / "pyo3-ffi" / "src" / "impl_" / "macros.rs").read_text()
1386-
found_dlls = set(re.findall(r'"((?:python|libpypy)[^"]+)"', lib_rs))
1397+
found_dlls = set(re.findall(r'"((?:python|libpython|libpypy)[^"]+)"', lib_rs))
13871398

13881399
missing = expected_dlls - found_dlls
13891400
extra = found_dlls - expected_dlls

pyo3-build-config/src/impl_.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,7 +2302,12 @@ const WINDOWS_STABLE_ABI_DEBUG_LIB_NAME: &str = "python3_d";
23022302
#[allow(dead_code)]
23032303
fn default_lib_name_for_target(abi: PythonAbi, target: &Triple) -> String {
23042304
if target.operating_system == OperatingSystem::Windows {
2305-
default_lib_name_windows(abi, false, false).unwrap()
2305+
default_lib_name_windows(
2306+
abi,
2307+
matches!(target.environment, Environment::Gnu | Environment::GnuLlvm),
2308+
false,
2309+
)
2310+
.unwrap()
23062311
} else {
23072312
default_lib_name_unix(
23082313
abi,
@@ -2314,6 +2319,10 @@ fn default_lib_name_for_target(abi: PythonAbi, target: &Triple) -> String {
23142319
}
23152320

23162321
fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result<String> {
2322+
// set `lib` prefix for mingw, as its python abi library is shipped prefixed. also mingw
2323+
// library has the version separated by dot
2324+
let (lib_prefix, separator) = if mingw { ("lib", ".") } else { ("", "") };
2325+
23172326
if abi.implementation.is_pypy() {
23182327
// PyPy on Windows ships `libpypy3.X-c.dll` (e.g. `libpypy3.11-c.dll`),
23192328
// not CPython's `pythonXY.dll`. With raw-dylib linking we need the real
@@ -2326,7 +2335,7 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result<
23262335
// CPython bug: linking against python3_d.dll raises error
23272336
// https://github.com/python/cpython/issues/101614
23282337
Ok(format!(
2329-
"python{}{}_d",
2338+
"{lib_prefix}python{}{separator}{}_d",
23302339
abi.version.major, abi.version.minor
23312340
))
23322341
} else if abi.kind == PythonAbiKind::Stable(StableAbi::Abi3)
@@ -2340,34 +2349,43 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result<
23402349
if abi.kind == PythonAbiKind::Stable(StableAbi::Abi3t) {
23412350
lib_name = lib_name.replace("python3", "python3t");
23422351
}
2343-
Ok(lib_name)
2352+
Ok(format!("{lib_prefix}{lib_name}"))
23442353
} else if mingw {
23452354
ensure!(
23462355
!abi.kind.is_free_threaded(),
23472356
"MinGW free-threaded builds are not currently tested or supported"
23482357
);
23492358
// https://packages.msys2.org/base/mingw-w64-python
2350-
Ok(format!("python{}.{}", abi.version.major, abi.version.minor))
2359+
Ok(format!(
2360+
"{lib_prefix}python{}.{}",
2361+
abi.version.major, abi.version.minor
2362+
))
23512363
} else if abi.kind().is_free_threaded() {
23522364
#[expect(deprecated, reason = "using constant internally")]
23532365
{
23542366
ensure!(abi.version() >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor);
23552367
}
23562368
if debug {
23572369
Ok(format!(
2358-
"python{}{}t_d",
2370+
"{lib_prefix}python{}{separator}{}t_d",
23592371
abi.version.major, abi.version.minor
23602372
))
23612373
} else {
2362-
Ok(format!("python{}{}t", abi.version.major, abi.version.minor))
2374+
Ok(format!(
2375+
"{lib_prefix}python{}{separator}{}t",
2376+
abi.version.major, abi.version.minor
2377+
))
23632378
}
23642379
} else if debug {
23652380
Ok(format!(
2366-
"python{}{}_d",
2381+
"{lib_prefix}python{}{separator}{}_d",
23672382
abi.version.major, abi.version.minor
23682383
))
23692384
} else {
2370-
Ok(format!("python{}{}", abi.version.major, abi.version.minor))
2385+
Ok(format!(
2386+
"{lib_prefix}python{}{separator}{}",
2387+
abi.version.major, abi.version.minor
2388+
))
23712389
}
23722390
}
23732391

@@ -3091,7 +3109,7 @@ mod tests {
30913109
let implementation = PythonImplementation::CPython;
30923110
let version = PythonVersion::PY39;
30933111
let config = InterpreterConfigBuilder::new(implementation, version)
3094-
.lib_name("python39".to_string())
3112+
.lib_name("libpython3.9".to_string())
30953113
.lib_dir("/usr/lib/mingw".to_string())
30963114
.finalize()
30973115
.unwrap();
@@ -3290,7 +3308,7 @@ mod tests {
32903308
false,
32913309
)
32923310
.unwrap(),
3293-
"python3.9",
3311+
"libpython3.9",
32943312
);
32953313
assert_eq!(
32963314
super::default_lib_name_windows(
@@ -3302,7 +3320,7 @@ mod tests {
33023320
false,
33033321
)
33043322
.unwrap(),
3305-
"python3",
3323+
"libpython3",
33063324
);
33073325
assert_eq!(
33083326
super::default_lib_name_windows(

pyo3-build-config/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,21 @@ pub fn print_expected_cfgs() {
171171
"python3_d".to_string(),
172172
"python3t".to_string(),
173173
"python3t_d".to_string(),
174+
"libpython3".to_string(),
175+
"libpython3_d".to_string(),
176+
"libpython3t".to_string(),
177+
"libpython3t_d".to_string(),
174178
];
175179
for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 {
176180
dll_names.push(format!("python3{i}"));
177181
dll_names.push(format!("python3{i}_d"));
182+
dll_names.push(format!("libpython3{i}"));
183+
dll_names.push(format!("libpython3{i}_d"));
178184
if i >= 13 {
179185
dll_names.push(format!("python3{i}t"));
180186
dll_names.push(format!("python3{i}t_d"));
187+
dll_names.push(format!("libpython3{i}t"));
188+
dll_names.push(format!("libpython3{i}t_d"));
181189
}
182190
}
183191
// PyPy DLL names (libpypy3.X-c.dll)

pyo3-ffi/src/impl_/macros.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -257,21 +257,21 @@ macro_rules! extern_libpython {
257257
($abi:literal { $($body:tt)* }) => {
258258
extern_libpython!(@impl $abi { $($body)* }
259259
// abi3
260-
"python3", "python3_d",
260+
"python3", "python3_d", "libpython3", "libpython3_d",
261261
// abi3t
262-
"python3t", "python3t_d",
262+
"python3t", "python3t_d", "libpython3t", "libpython3t_d",
263263
// Python 3.9 - 3.15
264-
"python39", "python39_d",
265-
"python310", "python310_d",
266-
"python311", "python311_d",
267-
"python312", "python312_d",
268-
"python313", "python313_d",
269-
"python314", "python314_d",
270-
"python315", "python315_d",
264+
"python39", "python39_d", "libpython3.9", "libpython3.9_d",
265+
"python310", "python310_d", "libpython3.10", "libpython3.10_d",
266+
"python311", "python311_d", "libpython3.11", "libpython3.11_d",
267+
"python312", "python312_d", "libpython3.12", "libpython3.12_d",
268+
"python313", "python313_d", "libpython3.13", "libpython3.13_d",
269+
"python314", "python314_d", "libpython3.14", "libpython3.14_d",
270+
"python315", "python315_d", "libpython3.15", "libpython3.15_d",
271271
// free-threaded builds (3.13+)
272-
"python313t", "python313t_d",
273-
"python314t", "python314t_d",
274-
"python315t", "python315t_d",
272+
"python313t", "python313t_d", "libpython3.13t", "libpython3.13t_d",
273+
"python314t", "python314t_d", "libpython3.14t", "libpython3.14t_d",
274+
"python315t", "python315t_d", "libpython3.15t", "libpython3.15t_d",
275275
// PyPy (DLL is libpypy3.X-c.dll, not pythonXY.dll)
276276
"libpypy3.11-c",
277277
);

0 commit comments

Comments
 (0)