This uses an approach that, arguably, the upstream CMake project should use for >= 3.18, in which we gained the ability to eval. Instead of a convoluted CMake script to try to query the Python config settings, we just have a Python script that does so and spits out CMake set commands as needed. This has several advantages:
- Python is good at introspecting itself. It is better to code it there than have CMake firing off a bunch of one liners and string splicing everywhere.
- If it breaks, people just run the Python script and see exactly what was detected (I used this to get it working on Windows without even running CMake).
- Does not introduce the longstanding bug where there are cache and hint races with Development.Module.
- Invokes Python once, not a bunch of times. This has a significant impact on configure time, especially on Windows.
I just implemented the variables, targets and commands as documented in the CMake manual: https://cmake.org/cmake/help/latest/module/FindPython.html. I left out a lot of excessive generality related to Python 2.
If we go with this eventually, the overall CMake scripts can be substantially simplified (with just an old-version fallback to find_package the Development component.
I can add some caching and such in the future, but since that is notoriously difficult to get right, I'll do that with a downstream in view (which is where it matters: layered projects). I believe that as I have written this, it should support switching the Python interpreter between CMake invocations (without nuking the cache), which will help both dev and deployment flows (which currently need to start fresh because the CMake find_package stuff doesn't reliably let you switch Python interpreters on subsequent calls).
Looks like this needs to be _type, not type?