Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: cleanup code #17

Merged
merged 2 commits into from
May 11, 2022
Merged

refactor: cleanup code #17

merged 2 commits into from
May 11, 2022

Conversation

@messense
Copy link
Member Author

@ravenexp
Copy link
Collaborator

While this change is technically correct, this also makes it impossible to build wheels for Windows by just adding --target x86_64-pc-windows-gnu. This is very unfortunate, because x86_64-pc-windows-msvc is a pain to use on Linux.

Sadly, MinGW Python is not a thing since version 3.5. Since it is not supported by the upstream at all, it is not possible to publish and distribute wheels for it.
Then there is the MinGW-w64 software distribution, which has it's own Python build, but it's a Unix Python that happens to run on Windows. And this one uses python3.y.dll library names in place of python3y.dll used by the official Windows build.

Ideally, the standard Windows Python DLL name should be used when cross-compiling, and the MinGW one should be selected only when building things for the MinGW distribution on Windows, i.e. when python3-dll-a is also being built with x86_64-pc-windows-gnu (as a part of the build script). pyo3-build-config could then also be updated to use the same heuristic by default.

What do you think?

src/lib.rs Outdated
Comment on lines 158 to 163
if self.env == "msvc" {
format!("python{}{}{}", major, minor, impllib_ext)
} else {
// https://packages.msys2.org/base/mingw-w64-python
format!("python{}.{}{}", major, minor, impllib_ext)
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need something less surprising for the users here...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder whether this link is strictly necessary: I have been building extensions using MinGW but targeting the libraries from the MSVC-based upstream CPython releases.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just noticed that you explained all of this in #17 (comment). Sorry for noise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been building extensions using MinGW but targeting the libraries from the MSVC-based upstream CPython releases.

Same here actually 😅

@adamreichold
Copy link
Member

Ideally, the standard Windows Python DLL name should be used when cross-compiling, and the MinGW one should be selected only when building things for the MinGW distribution on Windows, i.e. when python3-dll-a is also being built with x86_64-pc-windows-gnu (as a part of the build script). pyo3-build-config could then also be updated to use the same heuristic by default.

At a first glance, this sounds reasonable to me. It should definitely be documented though as it does feel a bit brittle.

@ravenexp
Copy link
Collaborator

At a first glance, this sounds reasonable to me. It should definitely be documented though as it does feel a bit brittle.

Yes, this looks super convoluted, but it's my best guess wrt what the users would expect to get when they type cargo build --target. Most Rust users do not associate the x86_64-pc-windows-gnu rustc target with MSYS2 specifically.

@messense
Copy link
Member Author

Admittedly I don't quite understand the issue here since personally I don't build wheels using mingw64.

I've checked locally on Ubuntu that this works with PyO3/pyo3#2364, all of the following commands succeeded

# abi3
cargo build --manifest-path examples/maturin-starter/Cargo.toml --features abi3 --target x86_64-pc-windows-gnu
cargo xwin build --manifest-path examples/maturin-starter/Cargo.toml --features abi3 --target x86_64-pc-windows-msvc
# non-abi3
export PYO3_CROSS_PYTHON_VERSION=3.9
cargo build --manifest-path examples/maturin-starter/Cargo.toml --features generate-import-lib --target x86_64-pc-windows-gnu
cargo xwin build --manifest-path examples/maturin-starter/Cargo.toml --features generate-import-lib --target x86_64-pc-windows-msvc

Another idea, can we change it to generate both python3y.dll.a and python3.y.dll.a? (Or just copy python3y.dll.a to python3.y.dll.a).

@adamreichold
Copy link
Member

I've checked locally on Ubuntu that this works with PyO3/pyo3#2364, all of the following commands succeeded

I think the problem would manifest when loading such an extension using the official CPython builds under Windows (providing python3x.dll) instead of the MinGW builds (which provide python3.x.dll).

@ravenexp
Copy link
Collaborator

Another idea, can we change it to generate both python3y.dll.a and python3.y.dll.a? (Or just copy python3y.dll.a to python3.y.dll.a).

This will not work because on Windows, the import library name and the DLL library name do not actually have to match (crazy!).
The DLL file name the linker output will link to is determined by the LIBRARY statement in the original .DEF file, not the import library file name, as I thought before:

LIBRARY "python39.dll"

@ravenexp
Copy link
Collaborator

I think the problem would manifest when loading such an extension using the official CPython builds under Windows (providing python3x.dll) instead of the MinGW builds (which provide python3.x.dll)

Yes, this is what I'm worrying about, given that 3 out of 4 commenters in this thread have been using the MinGW cross target to build Python wheels for Windows, not for MSYS2.

I double checked and found out that the MSYS2 Python build actually provides libpython3.y.dll, not python3.y.dll, as I wrote above. What is more interesting, on Arch Linux, which I use, the Python DLL is named either python3y.dll or libpython3.y.dll depending on whether you install the binary package or the source package:

https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mingw-w64-python-bin#n54
https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=mingw-w64-python

On the up side, it looks like the distributions that use libpython3.y.dll also install _sysconfigdata*.py, which can be used by PyO3 to cross-compile via PYO3_CROSS_LIB_DIR. Native compilation should also work on MSYS2 using the provided Python interpreter to query the build config.

So my proposal here is to change the PyO3 defaults instead to always assume python3y.dll for Windows targets, and to leave the python3-dll-a configuration as is. MSYS2 Python should be treated as a custom build, which requires either a working interpreter or a library directory with _sysconfigdata*.py. Actually, this is exactly how PyO3 worked before the python3-dll-a patches were merged, so I don't think we are breaking much backwards compatibility here.

@messense messense changed the title fix: Fix mingw import library name refactor: cleanup code May 11, 2022
@messense
Copy link
Member Author

OK, I've repurposed this PR as a code cleanup.

Copy link
Collaborator

@ravenexp ravenexp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@messense
Copy link
Member Author

So my proposal here is to change the PyO3 defaults instead to always assume python3y.dll for Windows targets

Done in PyO3/pyo3@ea37acb

@ravenexp ravenexp merged commit d3794f5 into PyO3:main May 11, 2022
@messense messense deleted the fix-mingw branch May 11, 2022 07:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants