我正在使用Boost Python在Linux和Windows(Visual Studio)上为C ++库开发Python绑定。
在Windows中,静态Boost Python库对Python具有依赖性(这是另一个线程here的动机),因此,在我的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()
这在Linux上工作正常,但是在Windows中,它仅在Release模式下有效,而在Debug下不起作用,在这种情况下,我总是得到:
LINK : fatal error LNK1104: Can't open file 'python37.lib'
拔掉头发后,我注意到问题是由CMake指示Visual Studio在调试中链接到 'python37_d.lib'
而不是 'python37.lib'
引起的模式。
但是,正如我在linked issue中所述,officially provided Boost Python debug 库是与Python release 库链接的,而不是调试一个。因此,解决方案将是针对构建版本强制使用针对Python发布库的链接。不幸的是, ${Python_LIBRARIES}
会根据模式自动设置库,并且我不想在代码中显式指定python37.lib(因为我可以升级Python,但我不想因此必须更改我的CMake脚本。)
我发现了一些类似的问题here和here,但这并不能反映我面临的确切情况。基于这些,我尝试设置:
target_link_libraries(my_python_module optimized ${Python_LIBRARIES})
但是那也不起作用。因此,问题是:
是否有一种方法可以强制在调试模式 WITHOUT 中使用Python发布库,而不必明确设置它,而让Python CMake软件包自动执行它。明确地说,我的意思是:
target_link_libraries(my_python_module python37)
非常感谢您的帮助。
答案 0 :(得分:1)
似乎kanstar评论中建议的set(Python_FIND_ABI "OFF" "ANY" "ANY")
是正确的方法。但是,尽管Python_FIND_ABI
在CMake master中,但尚未在latest version中发布(截至撰写本文时为v3.15.2)。
同时,有些解决方案取决于CMake版本。
CMake 3.12及更高版本
可以链接到FindPython的Python_LIBRARY_RELEASE
,这并不意味着它是模块public interface的一部分,但是仍然正确设置了变量。
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()
CMake 3.0.4至3.11
感谢@Phil的评论,我们可以扩展答案,以包括具有FindPythonLibs模块的早期CMake版本,该模块改为设置PYTHON_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()