[英]CMake: Visual Studio build looks for wrong library
我有一个使用CMake在Linux和Windows平台上执行构建的项目。 项目的某些组件需要一些Boost库。 许多组件都是作为共享库(.dll / .so)构建的。 安装Boost时,我选择构建共享库。
这是问题所在:
在Windows上运行CMake,打开生成的VS解决方案并运行构建后,依赖Boost的组件将失败,并显示找不到库的错误。 例如:
LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc100-mt-gd-1_58.lib'
果然,Boost lib目录中没有该名称的文件。 有共享库文件对于库: boost_thread-vc100-mt-gd-1_58.dll
(和.lib
)。
我假设“ lib ...”变体表示一个静态库。 当我指定不使用Boost中的静态库时,为什么要查找呢? Linux方面似乎没有问题。
以下是我的CMakeLists.txt文件的摘录:
项目级别:
...
# Set to use shared libraries from Boost.
set(Boost_USE_STATIC_LIBS OFF)
#set(Boost_USE_STATIC_RUNTIME OFF) <- I also tried with this uncommented - no difference
#set(Boost_DEBUG ON)
if(WIN32)
find_package(Boost 1.58 REQUIRED system thread date_time chrono)
elseif(UNIX)
find_package(Boost 1.58 REQUIRED)
endif()
include_directories(${Boost_INCLUDE_DIRS})
...
需要Boost的组件:
set(source_files
...)
# Create library from source files.
add_library(lib_target SHARED ${source_files})
target_link_libraries(lib_target ${Boost_LIBRARIES})
似乎其他人有相同(或相似)的问题: cmake找不到boost库,因为它查找错误的文件名 。 我用link=shared
建立了我的Boost。
问题是Boost使用了link.exe的自动链接功能,并且为了在静态链接和动态链接之间进行选择,您需要设置一些预处理器定义。 也就是说,除非禁用自动链接或定义-DBOOST_ALL_DYN_LINK
(或各种-DBOOST_<WHATEVER>_DYN_LINK
预处理程序定义),否则标头仍将尝试拉入静态库。
要禁用Boost头的自动链接,请设置预处理器定义-DBOOST_ALL_NO_LIB
。 由于CMake已经负责查找库和设置标志,因此自动链接对于CMake确实不是很有用。 但是,您不必禁用它即可使动态链接起作用。
如果要使用动态链接,则将Boost_USE_STATIC_LIBS
设置为OFF
并添加预处理器定义-DBOOST_ALL_DYN_LINK
。 -DBOOST_ALL_DYN_LINK
都将在boost头中的声明上启用__declspec(dllimport)
,并使自动链接功能(如果启用)依赖于dll,而不是静态库。
请注意,某些Boost库无法在静态链接和动态链接之间进行选择,并且不会受到-DBOOST_ALL_DYN_LINK
影响。 我还没有尝试过,所以我不知道CMake FindBoost模块是否可以解决这个问题。
如果要使用静态链接,请将Boost_USE_STATIC_LIBS
设置为ON
。 Boost标头默认情况下使用静态链接,因此,如果要静态链接,则是否启用自动链接都没关系。
如果要查看Boost的自动链接需要哪些库,请设置预处理器定义-DBOOST_LIB_DIAGNOSTIC
或使用FindBoost模块的${Boost_LIB_DIAGNOSTIC_DEFINITIONS}"
。这将使标头在处理时输出要求的库名称。 。
CMakeLists.txt片段示例:
set(Boost_USE_STATIC_LIBS OFF)
find_package(Boost 1.58 REQUIRED system thread date_time chrono)
set(source_files ...)
add_library(lib_target SHARED ${source_files})
target_compile_definitions(lib_target PRIVATE -DBOOST_ALL_NO_LIB -DBOOST_ALL_DYN_LINK)
target_include_directories(lib_target PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(lib_target PRIVATE ${Boost_LIBRARIES})
这是一个更新的示例,该示例仅使用目标而不是设置定义和包含目录:
find_package(Boost 1.67 REQUIRED system thread date_time chrono)
set(source_files ...)
add_library(lib_target SHARED ${source_files})
target_link_libraries(lib_target PRIVATE
Boost::disable_autolinking
Boost::dynamic_linking
Boost::boost Boost::system Boost::thread Boost::date_time Boost::chrono)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.