Я пытаюсь скомпилировать проект c++, ссылающийся на Python, используя CMake. Я использую Cygwin, и у меня есть исходные файлы Python2.7 в Cygwin.
Например:
PyObject *l = PyList_New(0);
В интерактивной справке я добавил флаг компоновщика -lpython2.7. Я не добавляю это правильно в CMake? В противном случае почему я еще не могу использовать библиотеку Python и как я могу это исправить?
Линия компиляции:
C:\cygwin64\bin\cmake.exe --build "C:\Users\...\.clion10\system\cmake\generated\3e6845d6\3e6845d6\Release" --target projectname -- -j 4
Файл CMakeList.txt:
cmake_minimum_required(VERSION 2.8.4)
project(projectname)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lpython2.7")
set(SOURCE_FILES
src/cpp/...
src/cpp/...
src/cpp/..
src/cpp/...
src/cpp/...)
add_executable(projectname ${SOURCE_FILES})
Ошибки...
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaeb4): undefined reference to 'PyDict_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaeb4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol 'PyDict_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaec4): undefined reference to 'PyList_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaec4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol 'PyList_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaf0d): undefined reference to 'PyDict_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaf0d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol 'PyDict_New'
CMakeFiles/spot.dir/src/cpp/OBwrapper.cpp.o:OBwrapper.cpp:(.text+0xaf25): undefined reference to 'PyString_FromString'
...and so on....
Вы неправильно понимаете способ CMake: прежде чем использовать что-то, вы должны его найти! Т.е. убедитесь, что все, что вам нужно для сборки вашего пакета, доступно и доступно на хосте сборки. В противном случае было бы неплохо тратить время (скомпилировать) (скажем, 2 часа), а затем получить сообщение об ошибке, которое не удалось найти в каком-либо заголовке/библиотеке/исполняемом файле. Итак, во время работы CMake вы должны быть уверены, что все, что вам нужно, здесь. Для этого у CMake есть много инструментов.
Рассмотрим ваш конкретный случай: вам нужно найти библиотеки Python, иначе сборка невозможна. Чтобы сделать это, вы должны использовать find_package
следующим образом:
find_package(PythonLibs REQUIRED)
Взгляните на документацию и предоставите другие варианты (например, версию), если вам нужно. Вы не должны использовать hardcoded paths в вашем CMakeLists.txt
, иначе ваш проект не был бы действительно портативным (и, скорее всего, вы будете единственным, кто сможет его построить с большим количеством проблем). Вместо этого, модуль Python libs finder будет предоставлять переменные, которые вам нужно использовать позже, или не удалось выполнить ошибку w/error, если ничего не найдено.
Если CMake заканчивается без ошибок, вы можете использовать найденные библиотеки Python. Прежде всего вам нужно обновить пути #include
:
include_directories(${PYTHON_INCLUDE_DIRS})
Затем сообщите компоновщику, что ваше исполняемое имя projectname
должно быть связано w/Python libs:
add_executable(projectname ${SOURCE_FILES})
target_link_libraries(projectname ${PYTHON_LIBRARIES})
И снова попробуйте избежать CMAKE_CXX_FLAGS
изменения CMAKE_CXX_FLAGS
(и других) - есть множество вызовов, чтобы сделать это глобально и/или на цель. Некоторые из них:
add_definitions
для определения макросов /undefineinclude_directories
для обновления #include
путейadd_compile_options
для добавления других параметров компилятораlink_directories
для обновления путей поиска компоновщикаPyObject *pName, *pModule, *pDict, *pClass, *pInstance=NULL;
Я получаю для pName (например) текст красного цвета и указатель мыши над «не может разрешить переменную pName», но компилируется. Любая идея, которую я мог бы пропустить в CMakeLists.txt
?