CMake:Visual Studio 构建寻找错误的库

use*_*500 2 c++ boost cmake visual-studio-2010

我有一个使用 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'
Run Code Online (Sandbox Code Playgroud)

果然,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})
...
Run Code Online (Sandbox Code Playgroud)

需要Boost的组件:

set(source_files
  ...)

# Create library from source files.
add_library(lib_target SHARED ${source_files})

target_link_libraries(lib_target ${Boost_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

看起来其他人也遇到了相同(或类似)的问题: cmake 无法找到 boost 库,因为它查找错误的文件名。我用 构建了我的 Boost link=shared

bam*_*s53 5

问题是 Boost 使用 link.exe 的自动链接功能,并且为了在静态链接和动态链接之间进行选择,您需要设置一些预处理器定义。也就是说,标头仍会尝试引入静态库,除非您禁用自动链接或定义-DBOOST_ALL_DYN_LINK(或各种-DBOOST_<WHATEVER>_DYN_LINK预处理器定义)。

要禁用 boost 标头的自动链接,请设置预处理器定义-DBOOST_ALL_NO_LIB。由于 CMake 已经负责查找库和设置标志,因此自动链接对于 CMake 来说确实不是很有用。但是,您不必禁用它即可使动态链接正常工作。

如果要使用动态链接,请设置Boost_USE_STATIC_LIBSOFF并添加预处理器定义-DBOOST_ALL_DYN_LINK-DBOOST_ALL_DYN_LINK都将启用__declspec(dllimport)boost 标头中的声明,并使自动链接功能(如果启用)依赖于 dll 而不是静态库。

请注意,某些 boost 库不提供静态和动态链接之间的选择,并且不会受到-DBOOST_ALL_DYN_LINK. 我还没有尝试过,所以我不知道 CMake FindBoost 模块是否可以处理这个问题。

如果要使用静态链接,请设置Boost_USE_STATIC_LIBSON。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})
Run Code Online (Sandbox Code Playgroud)

这是一个更新的示例,它仅使用目标而不是设置定义和包含目录:

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)
Run Code Online (Sandbox Code Playgroud)