2011-10-05 3 views
15

Я новичок в CMake и не понимаю понимания некоторых концепций использования.cmake находит неправильные библиотеки python

Я звоню питон скрипт из C++ программе:

#include <Python.h> 
... 
Py_Initialize(); 
PyRun_SimpleFile(...); 
Py_Finalize(); 

Соответствующие записи CMake в моем файле Cmake являются:

FIND_PACKAGE(PythonLibs REQUIRED) 
... 
TARGET_LINK_LIBRARIES(MyApplication ${PYTHON_LIBRARIES}) 

Это работает до тех пор, как мой питон скрипт ISN» t используя любые модули, установленные в каталог сайтов-пакетов, иначе я получаю ImportError. This question показывает, как найти расположение каталога сайтов-пакетов с помощью CMake, но что я должен сказать CMake об этом?

EDIT: проблема решена. Оказывается FIND_PACKAGE (PythonLibs) находит другую установку python из того, что я обычно использую (/usr/local/lib/libpython2.7.dylib вместо /Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2. 7.dylib - я нахожусь на mac), вот как я получаю стандартные модули python, но ни один из них я не установил сам. Для того, чтобы изменить PYTHONPATH вернуться к нормальной жизни, я добавил

try: 
    import some_package 
except ImportError: 
    if "my_python_path" in sys.path: raise 
    sys.path.append("my_python_path") 

в верхней части моего питона сценария.

+0

На какой платформе вы используете? Поскольку пути поиска разрешаются очень по-разному в зависимости от платформы. – David

+0

Вы не должны добавлять ответ на свой вопрос. Вместо этого вы можете добавить фактический ответ ниже с вашим решением. – Joakim

ответ

12

Вы можете сказать CMake, где найти этот PythonLibs, указав путь к вашему питону библиотеке это:

cmake -DPYTHON_LIBRARIES=/Library/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib . 

Это будет установить $ {PYTHON_LIBRARIES} внутри CMake на правильный путь.

Чтобы выяснить, какие другие возможные варианты (кроме PYTHON_LIBRARIES) вы можете дать CMake (с -DARG вариант) попробуйте запустить

ccmake . 

Затем нажмите c для настройки и t для продвинутых опций.

Например, вы также можете установить

-DPYTHON_LIBRARY='/softwarepath/Python/Python2.7/lib/libpython2.7.so' 
-DPYTHON_INCLUDE='/softwarepath/Python/Python2.7/include' 
+1

Интересно, что каталог include был правильно найден в моем случае, но был связан с неправильной версией Python! – dashesy

+3

Я думаю, что теперь флаги CMake (проверены с 2.8.12.1) -DPYTHON_INCLUDE_DIR = $ PYTHON_ROOT/include/pythonX.Y и -DPYTHON_LIBRARY = $ PYTHON_ROOT/lib/libpythonX.Y.so (из описания модуля FindPythonLibs.cmake) – Ax3l

0

Вы эффективно внедряете python в свою программу, когда вы это делаете. Вы пишете Py_Initialize() перед PyRun_SimpleFile? Посмотрите на Embedding Python in Another Application.

Py_Initialize() установит sys.path и должен установить среду python.

Если вы можете узнать, где установлен python, можно установить, что python home переопределяет вычисления пути python. Используйте Py_SetPythonHome() перед Py_Initialize().

На операционке Posix типа, вот комментарий в getpath.c (реализация CPython по пути решение):

/* Search in some common locations for the associated Python libraries. 
* 
* Two directories must be found, the platform independent directory 
* (prefix), containing the common .py and .pyc files, and the platform 
* dependent directory (exec_prefix), containing the shared library 
* modules. Note that prefix and exec_prefix can be the same directory, 
* but for some installations, they are different. 
* 
* Py_GetPath() carries out separate searches for prefix and exec_prefix. 
* Each search tries a number of different locations until a ``landmark'' 
* file or directory is found. If no prefix or exec_prefix is found, a 
* warning message is issued and the preprocessor defined PREFIX and 
* EXEC_PREFIX are used (even though they will not work); python carries on 
* as best as is possible, but most imports will fail. 
* 
* Before any searches are done, the location of the executable is 
* determined. If argv[0] has one or more slashes in it, it is used 
* unchanged. Otherwise, it must have been invoked from the shell's path, 
* so we search $PATH for the named executable and use that. If the 
* executable was not found on $PATH (or there was no $PATH environment 
* variable), the original argv[0] string is used. 
* 
* Next, the executable location is examined to see if it is a symbolic 
* link. If so, the link is chased (correctly interpreting a relative 
* pathname if one is found) and the directory of the link target is used. 
* 
* Finally, argv0_path is set to the directory containing the executable 
* (i.e. the last component is stripped). 
* 
* With argv0_path in hand, we perform a number of steps. The same steps 
* are performed for prefix and for exec_prefix, but with a different 
* landmark. 
* 
* Step 1. Are we running python out of the build directory? This is 
* checked by looking for a different kind of landmark relative to 
* argv0_path. For prefix, the landmark's path is derived from the VPATH 
* preprocessor variable (taking into account that its value is almost, but 
* not quite, what we need). For exec_prefix, the landmark is 
* Modules/Setup. If the landmark is found, we're done. 
* 
* For the remaining steps, the prefix landmark will always be 
* lib/python$VERSION/os.py and the exec_prefix will always be 
* lib/python$VERSION/lib-dynload, where $VERSION is Python's version 
* number as supplied by the Makefile. Note that this means that no more 
* build directory checking is performed; if the first step did not find 
* the landmarks, the assumption is that python is running from an 
* installed setup. 
* 
* Step 2. See if the $PYTHONHOME environment variable points to the 
* installed location of the Python libraries. If $PYTHONHOME is set, then 
* it points to prefix and exec_prefix. $PYTHONHOME can be a single 
* directory, which is used for both, or the prefix and exec_prefix 
* directories separated by a colon. 
* 
* Step 3. Try to find prefix and exec_prefix relative to argv0_path, 
* backtracking up the path until it is exhausted. This is the most common 
* step to succeed. Note that if prefix and exec_prefix are different, 
* exec_prefix is more likely to be found; however if exec_prefix is a 
* subdirectory of prefix, both will be found. 
* 
* Step 4. Search the directories pointed to by the preprocessor variables 
* PREFIX and EXEC_PREFIX. These are supplied by the Makefile but can be 
* passed in as options to the configure script. 
* 
* That's it! 
* 
* Well, almost. Once we have determined prefix and exec_prefix, the 
* preprocessor variable PYTHONPATH is used to construct a path. Each 
* relative path on PYTHONPATH is prefixed with prefix. Then the directory 
* containing the shared library modules is appended. The environment 
* variable $PYTHONPATH is inserted in front of it all. Finally, the 
* prefix and exec_prefix globals are tweaked so they reflect the values 
* expected by other code, by stripping the "lib/python$VERSION/..." stuff 
* off. If either points to the build directory, the globals are reset to 
* the corresponding preprocessor variables (so sys.prefix will reflect the 
* installation location, even though sys.path points into the build 
* directory). This seems to make more sense given that currently the only 
* known use of sys.prefix and sys.exec_prefix is for the ILU installation 
* process to find the installed Python tree. 
*/ 
+0

Извините, я был слишком краток в описании. Py_Initialize() и Py_Finalize() есть: как я уже сказал, скрипт python, который я вызываю, работает нормально - до тех пор, пока он не полагается на модуль сайта-пакета. – margold

12

лучший способ решить эту проблему, что неправильная версия найдена (например, 3,0 вместо 2,7), чтобы определить минимальную версию find_package (это выберет любую версию> = 2.7):

FIND_PACKAGE(PythonLibs 2.7 REQUIRED) 

или получить точную версию:

FIND_PACKAGE(PythonLibs 2.7.5 EXACT REQUIRED) 
1

Вы можете настроить вручную на CMake LIBS \usr\share\cmake-3.2.3\Modules\FindPythonLibs.cmake:

set(PYTHON_LIBRARY "\\usr\\lib\\python2.7") 
set(PYTHON_INCLUDE_DIR "\\usr\\include\\python2.7") 
Смежные вопросы