Skip to content

CMake: react to python version changes #3299

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

Merged
merged 3 commits into from
Sep 24, 2021
Merged

CMake: react to python version changes #3299

merged 3 commits into from
Sep 24, 2021

Conversation

wjakob
Copy link
Member

@wjakob wjakob commented Sep 24, 2021

Description

The new FindPython-based variant of the CMake scripts caches information
about the chosen Python version that can become stale. For example,
suppose I configure a simple pybind11-based project as follows

cmake -S . -B build -GNinja -DPython_ROOT=<path to python 3.8>

which will generate my_extension.cpython-38-x86_64-linux-gnu.so.
A subsequent change to the python version like

cmake -S . -B build -GNinja -DPython_ROOT=<path to python 3.9>

does not update all necessary build system information. In particular,
the compiled file is still called
my_extension.cpython-38-x86_64-linux-gnu.so.

This commit fixes the problem by detecting changes in
Python_EXECUTABLE and re-running Python as needed.

Note that the previous way of detecting Python does not seem to be
affected, it always specifies the right suffix.

Suggested changelog entry:

* Cached Python version information could become stale when CMake was re-run with a different Python version. The build system now detects this and updates this information.

The new FindPython-based variant of the CMake scripts caches information
about the chosen Python version that can become stale. For example,
suppose I configure a simple pybind11-based project as follows

```
cmake -S . -B build -GNinja -DPython_ROOT=<path to python 3.8>
```

which will generate `my_extension.cpython-38-x86_64-linux-gnu.so`.
A subsequent change to the python version like

```
cmake -S . -B build -GNinja -DPython_ROOT=<path to python 3.9>
```

does not update all necessary build system information. In particular,
the compiled file is still called
`my_extension.cpython-38-x86_64-linux-gnu.so`.

This commit fixes the problem by detecting changes in
`Python_EXECUTABLE` and re-running Python as needed.

Note that the previous way of detecting Python does not seem to be
affected, it always specifies the right suffix.
@wjakob wjakob requested a review from henryiii as a code owner September 24, 2021 11:12
@wjakob
Copy link
Member Author

wjakob commented Sep 24, 2021

Amazing! (the pre-commit fixes :D)

Comment on lines 85 to 89
if(NOT ${_Python}_EXECUTABLE STREQUAL ${_Python}_EXECUTABLE_LAST)
# Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
unset(PYTHON_IS_DEBUG CACHE)
unset(PYTHON_MODULE_EXTENSION CACHE)
set(${_Python}_EXECUTABLE_LAST
Copy link
Collaborator

@henryiii henryiii Sep 24, 2021

Choose a reason for hiding this comment

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

Suggested change
if(NOT ${_Python}_EXECUTABLE STREQUAL ${_Python}_EXECUTABLE_LAST)
# Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
unset(PYTHON_IS_DEBUG CACHE)
unset(PYTHON_MODULE_EXTENSION CACHE)
set(${_Python}_EXECUTABLE_LAST
if(NOT ${_Python}_EXECUTABLE STREQUAL PYTHON_EXECUTABLE_LAST)
# Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed
unset(PYTHON_IS_DEBUG CACHE)
unset(PYTHON_MODULE_EXTENSION CACHE)
set(PYTHON_EXECUTABLE_LAST

If you change from Python2 to Python3, then this should still be regenerated, since these variables are not tied to ${_Python}. (_PYTHON_EXECUTABLE_LAST would also be fine as a name)

Copy link
Collaborator

@Skylion007 Skylion007 left a comment

Choose a reason for hiding this comment

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

Agree with @henryiii, otherwise this looks good.

@wjakob
Copy link
Member Author

wjakob commented Sep 24, 2021

(Thanks for the feedback, I plan to merge this once CI passes.)

@wjakob
Copy link
Member Author

wjakob commented Sep 24, 2021

Thanks, I wondered how this actually managed to pass my (local) testing. Now it makes sense, I'm again removing the FORCE flag.

@wjakob wjakob merged commit 09e0583 into master Sep 24, 2021
@wjakob wjakob deleted the cmake-py-stale branch September 24, 2021 15:41
@github-actions github-actions bot added the needs changelog Possibly needs a changelog entry label Sep 24, 2021
@skoslowski
Copy link
Contributor

This is great.

May I suggest to use a prefixed name, e.g. PYBIND11_PYTHON_EXECUTABLE_LAST, instead? This makes it easier to identify in bigger trees and avoids collisions.

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