FindPython is looking prematurely in System frameworks locations on macOS
Situation:
- macOS with Python installed by homebrew (
/usr/local/Frameworks/Python.framework/
) - conda is installed, and default python points to the conda-provided one (so conda's python is the default)
- calling CMake 3.12 from within a conda environment
Behaviour in 3.12:
find_package(Python 3.6 COMPONENTS Interpreter Development)
This finds the python3 distribution provided by homebrew, rather than the default for the current environment, which is the one provided by conda.
I believe the problem is in Modules/FindPython/Support.cmake
.
There is a block of code where there are consecutive calls to find_program
.
The first one being:
find_program (${_PYTHON_PREFIX}_EXECUTABLE
NAMES python${_${_PYTHON_PREFIX}_VERSION}
NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES bin
NO_SYSTEM_ENVIRONMENT_PATH
NO_CMAKE_SYSTEM_PATH)
The arguments NO_SYSTEM_ENVIRONMENT_PATH
an NO_CMAKE_SYSTEM_PATH
are significant as this tells the purpose of this call is to look specifically in the hinted location (which can be defined prior to calling find_package
).
However, the line PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
seems to defeat the purpose, as it is looking in paths provided by the variable ${Python_FRAMEWORKS}
which is set early on by:
# Apple frameworks handling
include (${CMAKE_CURRENT_LIST_DIR}/../CMakeFindFrameworks.cmake)
cmake_find_frameworks (Python)
A closer look at CMakeFindFrameworks.cmake
reveals that it is looking in what I would consider "system" locations: https://gitlab.kitware.com/cmake/cmake/blob/master/Modules/CMakeFindFrameworks.cmake
I guess this was added to adapt the behaviour of find_program
, which according to the documentation (https://cmake.org/cmake/help/v3.12/variable/CMAKE_SYSTEM_FRAMEWORK_PATH.html), seems to be the only find_ command that does not look inside frameworks on macOS.
Would it make more sense to move the PATHS
line with the frameworks paths to the second call of find_program
(the one with "try in standard paths") in the comments?
This should fix the problem of finding the python distribution provided by conda (or indeed any that can be found by inspecting the PATH
environment variable), but should also be consistent with having python inside frameworks? There is typically a symlink from /usr/local/bin
to the python executable inside the framework anyway, so my guess is that if they are "active" they will be found before find_program
explicitly looks there.
And two side notes:
- is
PATH_SUFFIXES bin
not redundant infind_program
? Does it not look in the bin subdirectory by default for all search locations? - Should
CMakeFindFrameworks.cmake
at the very least try the paths inCMAKE_SYSTEM_FRAMEWORK_PATH
rather than hardcoding them?