Неопределенные ссылки на Python в C ++ с использованием CMake

Я пытаюсь скомпилировать проект 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....

0

Решение

Вы неправильно понимаете путь CMake: перед тем, как использовать то, что вам следует находить Это! То есть Убедитесь, что все, что вам нужно для сборки вашего пакета, доступно и доступно на хосте сборки. В противном случае было бы нецелесообразно тратить время на компиляцию (скажем, 2 часа), а затем получить ошибку, что не найден какой-либо заголовок / библиотека / исполняемый файл. Итак, во время запуска CMake вам лучше быть уверенным, что все, что вам нужно, здесь. Для этого в CMake есть много инструментов.

Рассмотрим ваш конкретный случай: вам нужно найти библиотеки Python, иначе сборка невозможна. Для этого вы должны использовать find_package как это:

find_package(PythonLibs REQUIRED)

Посмотрите на документация и предоставьте другие варианты (например, версию), если вам нужно. Вы не должен использовать жестко закодированные пути в вашем CMakeLists.txtиначе ваш проект не был бы действительно переносимым (и, скорее всего, вы будете единственным, кто может создать его без множества проблем). Вместо этого модуль поиска библиотек Python предоставит переменные, которые вам понадобятся позже, или потерпел неудачу с ошибкой, если ничего не найдено.

Если CMake завершает работу без ошибок, вы можете использовать найденные библиотеки Python. Прежде всего вам необходимо обновить #include пути:

 include_directories(${PYTHON_INCLUDE_DIRS})

Тогда скажите компоновщику, что ваш исполняемый файл projectname должен быть связан с библиотеками Python:

add_executable(projectname ${SOURCE_FILES})
target_link_libraries(projectname ${PYTHON_LIBRARIES})

И снова постарайтесь не изменять CMAKE_CXX_FLAGS (и другие) напрямую — существует множество вызовов, чтобы сделать это глобально и / или для каждой цели. Некоторые из них:

4

Другие решения