【问题标题】:Undefined Python references in C++ using CMake使用 CMake 在 C++ 中未定义的 Python 引用
【发布时间】:2014-11-16 02:19:42
【问题描述】:

我正在尝试使用 CMake 编译一个引用 Python 的 c++ 项目。我正在使用 Cygwin,并且在 Cygwin 中有 Python2.7 源文件。

例如:

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....

【问题讨论】:

  • 能否显示编译行
  • 更新了编译行。
  • 你没有看到包含 -lpython2.7 的行吗?
  • 没有包含 -lpython2.7 或我使用的任何其他库标志的行,但我知道它们在那里(stdlib 工作并将标志设置为我没有的东西会引发错误)。顺便说一句,我正在使用 CMake 和 CLion。
  • 编译时使用CXX_COMPILE_FLAGS,需要在linker flags中加上-lpython2.7

标签: c++ cmake cython clion


【解决方案1】:

你误解了 CMake 的方式:在使用之前你应该找到它! IE。确保构建包所需的一切都在构建主机上可用和可用。否则,浪费(编译)时间(比如 2 小时)然后得到一个找不到某些头文件/库/可执行文件的错误是不好的。因此,在 CMake 运行时,您最好确保您需要的一切都在这里。为此,CMake 有很多工具。

考虑您的特殊情况:您需要找到 Python 库,否则无法构建。为此,您应该像这样使用find_package

find_package(PythonLibs REQUIRED)

查看documentation 并在需要时提供其他选项(如版本)。你不应该在你的CMakeLists.txt 中使用硬编码路径,否则你的项目不会是真正可移植的(很可能你将是唯一可以构建它而没有很多问题的人) .相反,Python libs finder 模块将提供您以后需要使用的变量,如果没有找到,则会失败并出现错误。

如果 CMake 结束时没有错误,您可以使用找到的 Python 库。首先你需要更新#include 路径:

 include_directories(${PYTHON_INCLUDE_DIRS})

然后告诉链接器您的可执行文件 projectname 需要与 Python 库链接:

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

再一次,尽量避免直接修改CMAKE_CXX_FLAGS(和其他人) - 有很多调用可以全局和/或每个目标执行此操作。其中一些是:

【讨论】:

  • 成功了,谢谢!一个小的修改,对于 find_packages 的标志应该是“REQUIRED”而不是“REQUIRE”。
  • 在 CLion 上,所有具有:PyObject *pName, *pModule, *pDict, *pClass, *pInstance=NULL; 我得到的 pName 的行(例如)文本为红色,鼠标悬停在提示上是“无法解析变量‘pName’;但是编译。我在CMakeLists.txt 中可能遗漏的任何想法?
猜你喜欢
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-05-21
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多