Skip to content

cmake: Improve compatibility with Python version managers

This PR resolves the issue highlighted in https://github.com/bitcoin/bitcoin/pull/31411:

Here's another case where CMake just picks some other Python...

The fix leverages two hints for the CMake FindPython3 module:

  1. Python3_FIND_FRAMEWORK is set to LAST. This ensures that Unix-style package components are preferred over frameworks on macOS. As a side effect, the FindPython3 module reports a shim or symlink (e.g., from pyenv) rather than the underlying framework's binary. The module's output aligns with the result of the which command.
  2. Python3_FIND_UNVERSIONED_NAMES is set to FIRST. This supports scenarios where tools like pyenv—which use shims—have multiple Python versions installed.

Here are examples of output on my macOS 15.1.1 (Intel) with installed Homebrew's Python 3.13.0:

  • without any Python version manager:
% which -a python3                
/usr/local/bin/python3
/usr/bin/python3
% cmake -B build
<snip>
-- Found Python3: /usr/local/bin/python3 (found suitable version "3.13.0", minimum required is "3.10") found components: Interpreter
<snip>
  • using pyenv:
% pyenv versions       
  system
* 3.10.14 (set by /Users/hebasto/dev/bitcoin/.python-version)
  3.12.8
  3.13.1
% which -a python3
/Users/hebasto/.pyenv/shims/python3
/usr/local/bin/python3
/usr/bin/python3
% cmake -B build
<snip>
-- Found Python3: /Users/hebasto/.pyenv/shims/python3 (found suitable version "3.10.14", minimum required is "3.10") found components: Interpreter
<snip>

Both variables, Python3_FIND_FRAMEWORK and Python3_FIND_UNVERSIONED_NAMES, can still be overridden by the user via the command line if needed.

Merge request reports

Loading