繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM