-
Notifications
You must be signed in to change notification settings - Fork 2.2k
WIP: Use CMake's own FindPythonLibs instead of vendored FindPythonLibsNew. #2196
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
Conversation
I think this PR could use some feedback -- I am not a CMake expert, and I worry the law of Chesterton's Fence might apply here. I'm sure there is a reason that the FindPythonLibsNew file was added, but I'm not sure what it is. I tested that this enables cross compilation using an SDK generated with the Yocto project and still allows native compilation, but I haven't vetted this thoroughly yet. |
Simply getting rid of the old approach to find Python definitely will not fly, since this library must continue to function on legacy systems with old versions of CMake. What might be an acceptable compromise is to decide on a CMake version where we deem |
Makes sense -- I should be able to udpate this PR soon. If CMake version 3.10 or greater, I'll use the system FindPythonLibs, and fall back to FindPythonLibsNew on older CMake. |
26b1e60
to
dc0d4e3
Compare
I force-pushed the change--now on newer CMake versions the version of PythonLibs shipped with CMake will be used, and the version of |
Rather than just trying on one version and using that, think this will need a bit more investigative work on your part (or somebody else who is willing to help) -- understanding what was broken in the old version of the CMake-supplied scripts, and when it was fixed. |
Sounds like it's time to do a little spelunking for me. Unfortunately the original commit message that adds the version to this repository is
I'll go through CMake's source too to see if I can figure out why this was done, and what about it was more robust. |
From a bit of surfing the net, it looks like this is a pretty common library to be included in CMake-based projects. For example, it's in pyarrow, a random repo from 6 years ago, and other hits as well. Looks like something that's been cop/pasted around for a while now. Still trying to figure out where it actually came from and what problem it was solving that FindPythonLibs.cmake failed to solve. This PR from years ago on a different project gives the only solid info I have found:
(Emphasis mine) The PR has a dead link to the original. @dean0x7d, if you've got the time, do you remember why the original FindPythonLibsNew.cmake was added? I saw that you were the one who originally added it. |
Also just want to point out that the version I used in this PR as it is right now has been deprecated since 3.12 |
Honestly, I don't know the right path here. I also am not a CMake expert. The I'm coming at this from the perspective of a Void Linux packaging, where packages can be cross-compiled for any supported architecture using the Hard-coding the values is probably feasible (but undesirable) for supported architectures in Void, but I wonder if it's worthwhile. The CMake modules provide some convenience to dependent projects, but is otherwise expendible. I'll probably sidestep this issue by forgoing CMake modules in the package. |
@ahesford thanks for the comment. I think one important thing I was missing was that the Python architecture does not have to match the host architecture. When I say "host" here, I mean in terms of cross-compilation, so the host is not the machine doing the build necessariliy, but the machine where the executables will run. In my case my build machine is x86-64 but the host is 32-bit ARM. It's very common in Windows to run a 32-bit Python executable in a 64-bit OS, and I suspect that reasons like that is why Another strategy possibly worth considering is to only call |
It doesn't look like It seems to me a reasonable course of action would be:
This makes If there is a lot of momentum behind the existing variable names in |
ack your last comment. The biggest problem with FindPythonLibsNew is that the way it finds out about the Python interpreter is by running it, which it certainly won't be able to do in a cross-compilation environment. Regardless of anything else we do, when cross-compiling we can't do the check that is being done here: pybind11/tools/FindPythonLibsNew.cmake Lines 77 to 92 in a54eab9
Your suggestions makes sense to me. |
Also want to mention that my PR is still totally broken still for the cross-compile case: it allows for pybind11 itself to build, but actually building modules fails still. i.e. from the pybind repository, running |
My naive implementation here keeps failing in new and exciting ways; added WIP to the title to reflect this. |
One thing to keep in mind is that cross-compilation is an incredibly fringe use case. Running the Python interpreter to query it for its properties is the thing that one should do in 99.9% of cases. When this project was started, FindPythonLibs didn't do that, causing a huge amount of pain, eventually motivating our custom solution here. I am not sure what it does now. We should be very careful to adapt any cmake-provided feature if it relies on other more fragile ways of finding the Python interpreter and associated include paths. Another point is that any changes to this component must continue to work for Python 2.7. |
I wouldn't call cross-compilation "incredibly fringe". For embedded systems it's very normal, and "embedded" systems include dual core 1GHz ARM chips these days :-). But I definitely take your point that it is much less common, and that native compilation must continue working as well as it does today for everyone, and that if anything done in this PR messes up that the PR will not be accepted.
Ack. I need to dive in to CMake's source and figure out how they do things and see what the mismatch is. |
I won't be able to look into much for a couple weeks (in a sprint at work) but here's a list of stuff that I (or someone) need to do still:
Number 1. on that list is probably the most important. I'm using pybind11 in a Yocto-based project, and I wrote a Bitbake recipe that solves these problems for my use case, but it is not robust to be included upstream—for example, it hardcodes " |
I'm still interested in this in theory, but unfortunately I'm unable to work on this any time soon, and rather than just leaving it open I'm going to close it. I've solved it locally for the project I'm working on (patched pybind11 in a bitbake recipe for my Yocto setup), but as I mentioned it's not a robust fix. Thanks everyone who put time and energy into this issue! |
For now, I'm packaging pybind11 for Void without the cmake modules. That gets around the cross-compilation issue for our use case, at the expense of breaking any downstream packages that might assume the pybind11 modules exist. For now, the only dependent in the Void repo is pyopencl, which I also maintain and builds just fine without cmake stuff. If somebody ever comes complaining to me about missing cmake modules, I'll come poking around here to see if the issue has been revived or resolved. In the meantime, this doesn't seem to be a major blocker for anything I'm doing. |
…ind11.h (#3135) * Fixing `pragma warning pop` for `__INTEL_COMPILER`. * Adding push/pop to 3 tests. Removing #878 from top of pybind11.h (it was/is only needed for 1 test). * Trying again after CI failure, moving the push to the top of 2 tests. * Trying more after CI failure, adding push/pop to pybind11_tests.h, constructor_stats.h. * Moving ICC #2196 suppression to CMakeLists.txt * Fixing condition for `pragma GCC diagnostic push` in pybind11.h * Moving `pragma warning disable 2196` to common.h * Revising #ifdef to be more conservative. * Undoing insertion of notes that will hopefully soon be completely obsolete anyway.
…ind11.h (pybind#3135) * Fixing `pragma warning pop` for `__INTEL_COMPILER`. * Adding push/pop to 3 tests. Removing pybind#878 from top of pybind11.h (it was/is only needed for 1 test). * Trying again after CI failure, moving the push to the top of 2 tests. * Trying more after CI failure, adding push/pop to pybind11_tests.h, constructor_stats.h. * Moving ICC pybind#2196 suppression to CMakeLists.txt * Fixing condition for `pragma GCC diagnostic push` in pybind11.h * Moving `pragma warning disable 2196` to common.h * Revising #ifdef to be more conservative. * Undoing insertion of notes that will hopefully soon be completely obsolete anyway.
This enables easy cross-compilation and pybind11 doesn't have to carry
around an old version of FindPythonLibs.