如何在CMakeLists.txt中添加Boost库?


Answers:


171

将其放入CMakeLists.txt文件中(如果需要,可将任何选项从OFF更改为ON):

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS *boost libraries here*) 

if(Boost_FOUND)
    include_directories(${Boost_INCLUDE_DIRS}) 
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname ${Boost_LIBRARIES})
endif()

显然,您需要将所需的库放在我放置的位置*boost libraries here*。例如,如果您使用filesystemand regex库,则应编写:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
请注意,您无需为仅标头库指定组件,例如lexical_cast。因此,您只需要find_packageand include_directories命令。
miguel.martin 2015年

1
在Windows上,它也可以帮助它添加到您的cmake的文件:ADD_DEFINITIONS(-DBOOST_ALL_NO_LIB),否则你可能会碰到stackoverflow.com/questions/28887680/...
斯特凡

是否可以将BOOST_USE_STATIC_LIBS设置为ON,将Boost_USE_STATIC_RUNTIME设置为OFF?& 反之亦然。
鱿鱼2015年

5
什么*boost libraries here*意思
IgorGanapolsky '16

2
您也可以使用FIND_PACKAGE(Boost REQUIRED COMPONENTS system),如果你不知道提振使用精确的版本
smac89

78

您可以使用find_package搜索可用的增强库。它将搜索推迟到FindBoost.cmake,默认与CMake一起安装。

找到Boost后,该find_package()调用将填充许多变量(请参阅FindBoost.cmake的参考)。其中有BOOST_INCLUDE_DIRSBoost_LIBRARIES和Boost_XXX_LIBRARY变量,用特定的Boost库替换了XXX。您可以使用它们来指定include_directoriestarget_link_libraries

例如,假设您需要boost :: program_options和boost :: regex,则需要执行以下操作:

find_package( Boost REQUIRED COMPONENTS program_options regex )
include_directories( ${Boost_INCLUDE_DIRS} )
add_executable( run main.cpp ) # Example application based on main.cpp

# Alternatively you could use ${Boost_LIBRARIES} here.
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

一些一般性提示:

  • 搜索时,FindBoost将检查环境变量$ ENV {BOOST_ROOT}。如果需要,可以在调用find_package之前设置此变量。
  • 当您具有boost的多个构建版本(多线程,静态,共享等)时,可以在调用find_package之前指定所需的配置。通过下面的一些变量的设置要做到这一点OnBoost_USE_STATIC_LIBSBoost_USE_MULTITHREADEDBoost_USE_STATIC_RUNTIME
  • 在Windows上搜索Boost时,请注意自动链接。阅读参考资料中的“ Visual Studio用户注意” 。
    • 我的建议是禁用自动链接并使用cmake的依赖项处理: add_definitions( -DBOOST_ALL_NO_LIB )
    • 在某些情况下,您可能需要明确指定使用动态Boost: add_definitions( -DBOOST_ALL_DYN_LINK )

3
感谢您的一般提示。他们帮了我很多忙。
泰勒·朗

很有帮助的答案!如果我两年前发现了这个,本可以为我节省很多时间。伟大的写作。
Ela782 2014年

22

用导入的目标修改@LainIwakura对现代CMake语法的答案,这将是:

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
find_package(Boost 1.45.0 COMPONENTS filesystem regex) 

if(Boost_FOUND)
    add_executable(progname file1.cxx file2.cxx) 
    target_link_libraries(progname Boost::filesystem Boost::regex)
endif()

请注意,不再需要手动指定include目录,因为已经通过导入的目标Boost::filesystem和进行了处理Boost::regex
regexfilesystem可以替换为您需要的任何Boost库。


1
如果您想说要与所有boost链接起来,会是什么样?我的意思是没有列出所有库都在提升。
Toby Brull

4
如果仅使用boost的仅标头部分,则'Boost :: boost'就足够了。必须明确指定所有已编译的boost库。

2
@oLen在哪里可以找到所有导入的cmake Boost :: *目标的列表?我怎么知道必须链接到哪个?
马库斯

8

可能对某些人有帮助。我有一个调皮的错误: 对符号'_ZN5boost6system15system_categoryEv'的未定义引用//usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0:添加符号错误:命令行缺少DSO cmakeList.txt出现了一些问题以及以某种方式我没有明确包含“系统”和“文件系统”库。所以,我在CMakeLists.txt中写了这些行

这些行是在创建项目可执行文件之前写的,因为在此阶段,我们不需要将boost库链接到我们的项目可执行文件。

set(Boost_USE_STATIC_LIBS OFF) 
set(Boost_USE_MULTITHREADED ON)  
set(Boost_USE_STATIC_RUNTIME OFF) 
set(Boost_NO_SYSTEM_PATHS TRUE) 

if (Boost_NO_SYSTEM_PATHS)
  set(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../3p/boost")
  set(BOOST_INCLUDE_DIRS "${BOOST_ROOT}/include")
  set(BOOST_LIBRARY_DIRS "${BOOST_ROOT}/lib")
endif (Boost_NO_SYSTEM_PATHS)


find_package(Boost COMPONENTS regex date_time system filesystem thread graph program_options) 

find_package(Boost REQUIRED regex date_time system filesystem thread graph program_options)
find_package(Boost COMPONENTS program_options REQUIRED)

现在,在文件末尾,我将“ KeyPointEvaluation”视为我的项目可执行文件来编写这些行。

if(Boost_FOUND)
    include_directories(${BOOST_INCLUDE_DIRS})
    link_directories(${Boost_LIBRARY_DIRS})
    add_definitions(${Boost_DEFINITIONS})

    include_directories(${Boost_INCLUDE_DIRS})  
    target_link_libraries(KeyPointEvaluation ${Boost_LIBRARIES})
    target_link_libraries( KeyPointEvaluation ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_REGEX_LIBRARY} ${Boost_SYSTEM_LIBRARY})
endif()

2

我同意答案12。但是,我更愿意分别指定每个库。这使得大型项目中的依赖关系更加清晰。但是,存在混淆(区分大小写)变量名称的危险。在那种情况下,没有直接的cmake错误,但是稍后会出现一些未定义的引用链接程序问题,这可能需要一些时间才能解决。因此,我使用以下cmake函数:

function(VerifyVarDefined)
  foreach(lib ${ARGV}) 
    if(DEFINED ${lib})
    else(DEFINED ${lib})
      message(SEND_ERROR "Variable ${lib} is not defined")
    endif(DEFINED ${lib})
  endforeach()
endfunction(VerifyVarDefined)

对于上面提到的示例,它看起来像:

VerifyVarDefined(Boost_PROGRAM_OPTIONS_LIBRARY Boost_REGEX_LIBRARY)
target_link_libraries( run ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_REGEX_LIBRARY} )

如果我写了“ BOOST_PROGRAM_OPTIONS_LIBRARY”,那么cmake会触发一个错误,而链接器会在稍后触发一个错误。


2

尝试说Boost文档

set(Boost_USE_STATIC_LIBS        ON)  # only find static libs
set(Boost_USE_DEBUG_LIBS         OFF) # ignore debug libs and 
set(Boost_USE_RELEASE_LIBS       ON)  # only find release libs 
set(Boost_USE_MULTITHREADED      ON)
set(Boost_USE_STATIC_RUNTIME    OFF) 
find_package(Boost 1.66.0 COMPONENTS date_time filesystem system ...)
if(Boost_FOUND)   
    include_directories(${Boost_INCLUDE_DIRS})
    add_executable(foo foo.cc)   
    target_link_libraries(foo ${Boost_LIBRARIES})
endif()

不要忘记将foo替换为您的项目名称,并将组件替换为您的项目名称!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.