[CMake] Finding Python3

Michael Hertling mhertling at online.de
Tue Jul 20 11:12:30 EDT 2010


On 07/20/2010 03:26 AM, Alan W. Irwin wrote:
> On 2010-07-20 00:51+0200 Michael Hertling wrote:
> 
>> On 07/18/2010 10:14 PM, Alan W. Irwin wrote:
>>> (1) http://public.kitware.com/Bug/view.php?id=10718 is fixed.  In my
>>> view this bug has been the source of much CMake find trouble for a long
>>> time, and I hope the CMake developers make it a high priority to fix
>>> it for CMake-2.8.3.
>>
>> Personally, I'm in doubt if 10718 should be considered as a bug. IMO,
>> the NAMES option of the find commands is meant to denote alternative
>> names of the file/path/program/library to be found but not different
>> versions. Instead, specifying different versions is a misuse of the
>> NAMES option, and that's the actual source of trouble with the find
>> commands in this regard. E.g., if you say
>>
>> FIND_PROGRAM(PYTHON3_EXECUTABLE NAMES python3.1 python3.0 python3 ...)
>>
>> you express that the version doesn't matter to you, so you can't
>> complain later that the interpreter's version doesn't match the
>> libraries' one as this means the version does matter after all.
> 
> Well, fixing 10718 means CMake will use the first directory in the
> super-PATH with any of the specified NAMES which is what I think most
> people would prefer rather than the present case where CMake searches
> all directories in the super-PATH for the first name in NAMES, then
> searchs all directories for the second name, etc.  So the fix would
> reduce the importance of the order of the NAMES, and (in my opinion)
> sort out many Find ills in CMake these days.

If I understand correctly, the intention of 10718 is to denote possibly
non-equivalent alternatives after NAMES and use the super-path to pick
out one of them, and I disbelieve the find commands' NAMES option was
designed with this in mind. Moreover, IMO, it's exactly this kind of
usage, i.e. the idea of picking out a specific alternative from the
NAMES, which causes the problems in connection with that option.

> I think this fix is consistent with your idea that NAMES should
> express (as much as possible) alternatives with as little as possible
> precedence of one name over another. Of course, if more than one of
> the NAMES appears in that "first" directory the order of NAMES will
> matter.  Thus, it is always a good idea to place the generic name
> (python) first in the list and also to have an option that allows the
> user to specify the exact python interpreter (if the default order of
> names in the "first" directory is not what the user desires.)

One can distinguish two mutually exclusive cases:

(1) The alternatives after NAMES are equivalent, i.e. it doesn't matter
which one is found, and so, it also doesn't matter whether the search
proceeds names-before-paths or paths-before-names; what does matter
is that one of the alternatives is found somewhere.

(2) The alternatives after NAMES are not equivalent: Due to their
different names, they may reside in the same directory, so they are
found together and you can't use the super-path to pick out a specific
one. Instead, the order after NAMES matters, and thus, you can always
construct cases which let the find commands fail, i.e. deliver the
wrong alternative.

As an example for (2), consider several python installations under the
same prefix; you will have, e.g., /usr/local/bin/python{2.5,2.6} with
/usr/local/bin/python being a link to, say, python2.6. Even with a
solution to 10718, you wouldn't have a chance to get 2.5 as

FIND_PROGRAM(PYTHON_EXECUTABLE NAMES python python2.6 python2.5 ...)

will always - provided there's no other installation elsewhere - be
directed to /usr/local/bin/python. This is acceptable as long as the
versions don't matter, i.e. they're equivalent, but if you prefer one
to the others, i.e. they're not equivalent anymore, the find commands
may fail and 10718 won't help.

The right approach would be to say FIND_PACKAGE(Python 2.5 ...) with a
FindPython.cmake calling FIND_PROGRAM(PYTHON_EXECUTABLE python2.5 ...)
thereupon finally. Then, you can use the super-path to head CMake to a
python 2.5 installation, and besides, this is just the option for the
user to specify an exact version that you talked about.

Hence, my conclusion is: Do not specify multiple alternatives after
the NAMES option if there is any chance for them to be considered as
non-equivalent, and in particular, do not specify hardcoded versions
after NAMES as different versions tend to become non-equivalent, see

<http://www.mail-archive.com/cmake@cmake.org/msg28878.html>
<http://www.mail-archive.com/cmake@cmake.org/msg27324.html>

and some other threads with discussions about the mismatch of the
python interpreter and the python libraries w.r.t. their versions.

>> [...]
>> Of course, querying the interpreter is quite attractive for gathering
>> information, but you must be prepared for an interpreter being absent
>> or not able to run on your host system, so one of the challenges of a
>> generally usable FindPython.cmake is how to find the python libraries
>> without using an interpreter.
> 
> Good point.
> 
>> For this reason I suggested an external
>> flag PYTHON_NATIVE the user can indicate with if the interpreter may
>> run to reveal the python installation's secrets.
> 
> Shouldn't the flag be reversed so the option is called something like
> NO_PYTHON_INTERPRETER?  I am assuming that no python interpreter is the
> rarer case so that condition should be indicated by the special option
> rather than having a special option for indicating the more common case
> where the python interpreter is present.

Yes, having an interpreter available is probably the most common case,
but OTOH, the default situation is having no flags defined at all, so
I would prefer to play safe and run the interpreter only if the user
has explicitly granted to do so by setting a "positive" flag. Anyhow,
PYTHON_NATIVE as well as PYTHON_ROOT are just thoughts on the basic
structure of a - hopefully - upcoming FindPython.cmake.

Regards,

Michael


More information about the CMake mailing list