FindPython3 cannot locate python3

My Centos7 has python2.7 in /usr/local/bin.
I installed python3.6.8 in /bin
The PATH variable has “/usr/local/bin:/bin”, so /usr/local/bin is ahead of /bin.

The following command in my script fails:

#Python3.6 or later is needed:
include(FindPython3)
if(NOT Python3_Interpreter_FOUND)
    message(FATAL_ERROR "Python3 is needed, please install it first")
endif()

The error message is:

-- Could NOT find Python3 (missing: Python3_EXECUTABLE Interpreter)
    Reason given by package:
        Interpreter: Wrong major version for the interpreter "/usr/local/bin/python"

CMake Error at CMakeLists.txt:59 (message):
  Python3 is needed, please install it first

It looks like FindPython3 stops at /usr/local/bin, and not searched /bin at all.

How to fix this? Is there a robust way for FindPython3 to work?

I’m using CMake 3.20.0

I don’t think it knows to search for patch versions on the binary name. Is it /bin/python3.6.8 or is it /bin/python3.6? If the latter, could you post the (relevant) output of cmake --debug-find to help see what CMake is searching for.

The following are in /bin:

/bin/python3 -> python3.6
/bin/python3.6
/bin/python3.6m

And here is the relevant log, looks like /bin is not searched at all:

CMake Debug Log at /tools/pmc/swcm/cmake/3.20.0/share/cmake-3.20/Modules/FindPython/Support.cmake:1607 (find_program):
  find_program called with the following settings:

    VAR: _Python3_EXECUTABLE
    NAMES: "python3.10"
           "python3.9"
           "python3.8"
           "python3.7"
           "python3.6"
           "python3.5"
           "python3.4"
           "python3.3"
           "python3.2"
           "python3.1"
           "python3.0"
           "python3"
           "python"
    Documentation: Path to a program.
    Framework
      Only Search Frameworks: 0
      Search Frameworks Last: 0
      Search Frameworks First: 0
    AppBundle
      Only Search AppBundle: 0
      Search AppBundle Last: 0
      Search AppBundle First: 0
    CMAKE_FIND_USE_CMAKE_PATH: 1
    CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 0
    CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 0

  find_program considered the following locations:

  The item was not found.

Call Stack (most recent call first):
  /tools/pmc/swcm/cmake/3.20.0/share/cmake-3.20/Modules/FindPython3.cmake:485 (include)
  CMakeLists.txt:58 (include)


CMake Debug Log at /tools/pmc/swcm/cmake/3.20.0/share/cmake-3.20/Modules/FindPython/Support.cmake:1619 (find_program):
  find_program called with the following settings:

    VAR: _Python3_EXECUTABLE
    NAMES: "python3.10"
           "python3.9"
           "python3.8"
           "python3.7"
           "python3.6"
           "python3.5"
           "python3.4"
           "python3.3"
           "python3.2"
           "python3.1"
           "python3.0"
           "python3"
           "python"
    Documentation: Path to a program.
    Framework
      Only Search Frameworks: 0
      Search Frameworks Last: 0
      Search Frameworks First: 0
    AppBundle
      Only Search AppBundle: 0
      Search AppBundle Last: 0
      Search AppBundle First: 0
    CMAKE_FIND_USE_CMAKE_PATH: 1
    CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH: 1
    CMAKE_FIND_USE_CMAKE_SYSTEM_PATH: 1

  find_program considered the following locations:

    ...
    /tools/lib/configs/setup/bin/python
    /usr/local/bin/bin/python3.10
    /usr/local/bin/bin/python3.9
    /usr/local/bin/bin/python3.8
    /usr/local/bin/bin/python3.7
    /usr/local/bin/bin/python3.6
    /usr/local/bin/bin/python3.5
    /usr/local/bin/bin/python3.4
    /usr/local/bin/bin/python3.3
    /usr/local/bin/bin/python3.2
    /usr/local/bin/bin/python3.1
    /usr/local/bin/bin/python3.0
    /usr/local/bin/bin/python3
    /usr/local/bin/bin/python
    /usr/local/bin/Scripts/python3.10
    /usr/local/bin/Scripts/python3.9
    /usr/local/bin/Scripts/python3.8
    /usr/local/bin/Scripts/python3.7
    /usr/local/bin/Scripts/python3.6
    /usr/local/bin/Scripts/python3.5
    /usr/local/bin/Scripts/python3.4
    /usr/local/bin/Scripts/python3.3
    /usr/local/bin/Scripts/python3.2
    /usr/local/bin/Scripts/python3.1
    /usr/local/bin/Scripts/python3.0
    /usr/local/bin/Scripts/python3
    /usr/local/bin/Scripts/python
    /usr/local/bin/python3.10
    /usr/local/bin/python3.9
    /usr/local/bin/python3.8
    /usr/local/bin/python3.7
    /usr/local/bin/python3.6
    /usr/local/bin/python3.5
    /usr/local/bin/python3.4
    /usr/local/bin/python3.3
    /usr/local/bin/python3.2
    /usr/local/bin/python3.1
    /usr/local/bin/python3.0
    /usr/local/bin/python3

  The item was found at

    /usr/local/bin/python

Call Stack (most recent call first):
  /tools/pmc/swcm/cmake/3.20.0/share/cmake-3.20/Modules/FindPython3.cmake:485 (include)
  CMakeLists.txt:58 (include)


-- Could NOT find Python3 (missing: Python3_EXECUTABLE Interpreter)
    Reason given by package:
        Interpreter: Wrong major version for the interpreter "/usr/local/bin/python"

CMake Error at CMakeLists.txt:60 (message):
  Python3 is needed, please install it first


-- Configuring incomplete, errors occurred!

Hmm. This seems relevant, but maybe it’s just a red herring.

@marc.chevrier Thoughts?

First, the usage of FindPython3 is wrong. To have a correct behavior, please use find_package() command rather than include.

find_package(Python3)

Second, in your case, to ensure correct behavior, you have to ignore unversioned names (i.e. python) because python 2 is located in a path before python 3:

set(Python3_FIND_UNVERSIONED_NAMES NEVER)
find_package(Python3)

Thanks, @marc.chevrier

It works now with a minor fix to your approach: set(Python3_FIND_UNVERSIONED_NAMES NEVER)

You are right, the variable name was erroneous. Fix initial message.

We had issues with Python 2 being found first over Python 3 and they were solved by adding

set(Python3_FIND_STRATEGY VERSION)

That works if the Python you want to find is the newest on the machine. If, e.g., you’re trying to build against a 3.6 but 3.9 is on the system, it’s going to ignore your 3.6. I think it’s best to use the LOCATION strategy in general and set the executable or a prefix/root variable, but that’s me.