A. *_*lma 5 python cmake boost-python visual-studio-2017
我正在使用 Boost Python 为 Linux 和 Windows (Visual Studio) 开发 C++ 库的 Python 绑定。
在 Windows 中,静态 Boost Python 库依赖于 Python(这是另一个线程的动机,此处),因此,在我的 CMake 配置中,我需要执行以下操作:
if((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") OR APPLE)
target_link_libraries(my_python_module ${Boost_LIBRARIES})
elseif(WIN32 AND MSVC)
add_definitions(/DBOOST_PYTHON_STATIC_LIB)
target_link_libraries(my_python_module ${Boost_LIBRARIES}) #This includes the Boost Python library
# Even though Boost Python library is included statically, in Windows it has a dependency to the Python library.
target_link_libraries(my_python_module ${Python_LIBRARIES})
endif()
Run Code Online (Sandbox Code Playgroud)
这在 Linux 中工作得很好,但在 Windows 中,它只能在发布模式下工作,而不能在调试模式下工作,在这种情况下我总是得到:
LINK : fatal error LNK1104: Can't open file 'python37.lib'
经过一番努力后,我注意到问题是由 CMake 指示 Visual Studio 链接而'python37_d.lib'不是'python37.lib'在调试模式下引起的。
然而,正如我在链接问题中所述,官方提供的Boost Python调试库是与 Python发布库链接的,而不是调试库。因此,解决方案是强制链接到 Python 发布库,无论构建类型如何。不幸的是,${Python_LIBRARIES}根据模式自动设置库,并且我不想在代码中显式指定 python37.lib (因为我可以升级 Python 并且我不想因此而更改我的 CMake 脚本)。
我在这里和这里发现了一些类似的问题,但这并不能反映我所面临的确切情况。基于这些,我尝试设置:
target_link_libraries(my_python_module optimized ${Python_LIBRARIES})
但这也不起作用。所以,问题是:
有没有一种方法可以强制在调试模式下使用 Python 发布库,而不必显式设置它并让 Python CMake 包自动执行此操作。我所说的明确的意思是:
target_link_libraries(my_python_module python37)
非常感谢你的帮助。
小智 5
看来,set(Python_FIND_ABI "OFF" "ANY" "ANY")正如 kanstar 的评论中所建议的那样,这是执行此操作的正确方法。然而,虽然Python_FIND_ABI它在 CMake master中,但最新版本(截至撰写本文时为 v3.15.2)尚未发布。
同时,还有一些依赖于CMake版本的解决方案。
CMake 3.12 及以上版本
可以链接FindPython的Python_LIBRARY_RELEASE,它并不意味着成为模块公共接口的一部分,但该变量仍然设置正确。
cmake_minimum_required (VERSION 3.12)
find_package(Python ..<choose your COMPONENTS; refer to FindPython docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${Python_LIBRARY_RELEASE})
endif()
Run Code Online (Sandbox Code Playgroud)
CMake 3.0.4 至 3.11
感谢@Phil 的评论,我们可以扩展答案以包括早期的 CMake 版本,该版本具有设置变量的FindPythonLibsPYTHON_LIBRARY_RELEASE模块。
cmake_minimum_required (VERSION 3.0)
find_package(PythonLibs ..<refer to FindPythonLibs docs>..)
if(WIN32 AND MSVC)
target_link_libraries(my_python_module ${PYTHON_LIBRARY_RELEASE})
endif()
Run Code Online (Sandbox Code Playgroud)