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

0

Я пытаюсь скомпилировать проект 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
    Можете ли вы показать строку компиляции
  • 0
    Обновлено с строкой компиляции.
Показать ещё 3 комментария
Теги:
cmake
cython
clion

1 ответ

4
Лучший ответ

Вы неправильно понимаете способ 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 (и других) - есть множество вызовов, чтобы сделать это глобально и/или на цель. Некоторые из них:

  • 0
    Это сработало, спасибо! Одна небольшая модификация, для find_packages флаг должен быть «REQUIRED», а не «REQUIRE».
  • 0
    На CLion все строки, имеющие: PyObject *pName, *pModule, *pDict, *pClass, *pInstance=NULL; Я получаю для pName (например) текст красного цвета и указатель мыши над «не может разрешить переменную pName», но компилируется. Любая идея, которую я мог бы пропустить в CMakeLists.txt ?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню