【问题标题】:How do you add Boost libraries in CMakeLists.txt?如何在 CMakeLists.txt 中添加 Boost 库?
【发布时间】:2011-10-02 13:11:13
【问题描述】:

我需要将 Boost 库添加到我的 CMakeLists.txt 中。你是怎么做的或者怎么添加的?

【问题讨论】:

  • 见官方文档here

标签: boost cmake


【解决方案1】:

将其放入您的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* 的地方。例如,如果你使用 filesystemregex 库,你会写:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

【讨论】:

  • 请注意,您不需要为仅标头库指定组件,例如lexical_cast。因此您只需要find_packageinclude_directories 命令。
  • 在 Windows 上,将其添加到您的 cmake 文件中也有帮助: ADD_DEFINITIONS( -DBOOST_ALL_NO_LIB ) 否则您可能会遇到stackoverflow.com/questions/28887680/…
  • 是否可以将 BOOST_USE_STATIC_LIBS 设置为 ON 并将 Boost_USE_STATIC_RUNTIME 设置为 OFF?反之亦然。
  • *boost libraries here* 是什么意思?
  • 如果您不知道要使用的 boost 的确切版本,也可以使用FIND_PACKAGE(Boost REQUIRED COMPONENTS system)
【解决方案2】:

您可以使用 find_package 搜索可用的 boost 库。它将搜索 Boost 推迟到 FindBoost.cmake,这是 CMake 默认安装的。

在找到 Boost 后,find_package() 调用将填充许多变量(请查看 FindBoost.cmake 的参考)。其中包括BOOST_INCLUDE_DIRS、Boost_LIBRARIES 和 Boost_XXX_LIBRARY 变量,其中 XXX 被特定的 Boost 库替换。您可以使用这些来指定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 之前指定所需的配置。通过将以下一些变量设置为 On 来执行此操作:Boost_USE_STATIC_LIBSBoost_USE_MULTITHREADEDBoost_USE_STATIC_RUNTIME
  • 在 Windows 上搜索 Boost 时,请注意自动链接。阅读reference 中的“Visual Studio 用户注意事项”。
    • 我的建议是禁用自动链接并使用 cmake 的依赖处理:add_definitions( -DBOOST_ALL_NO_LIB )
    • 在某些情况下,您可能需要明确指定使用动态 Boost:add_definitions( -DBOOST_ALL_DYN_LINK )

【讨论】:

  • 感谢您的一般提示。他们帮了我很多。
  • 非常有用的答案!如果我在两年前找到这个,会为我节省很多时间。写得很棒。
【解决方案3】:

将@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()

请注意,不再需要手动指定包含目录,因为它已经通过导入的目标 Boost::filesystemBoost::regex 处理。
regexfilesystem 可以替换为您需要的任何 boost 库。

【讨论】:

  • 如果你想说链接到所有的提升,这会是什么样子?我的意思是没有列出 boost 中的所有库。
  • 如果你只使用 boost 的 header-only 部分,'Boost::boost' 就足够了。必须明确指定所有编译的 boost 库。
  • @oLen 我在哪里可以找到所有导入的 cmake Boost::* 目标的列表?我怎么知道我必须链接到哪个?
【解决方案4】:

希望这对某些人有所帮助。我有一个顽皮的错误: 对符号“_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()

【讨论】:

    【解决方案5】:

    试着说Boost documentation:

    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 替换为您的项目名称,并将组件替换为您的!

    【讨论】:

      【解决方案6】:

      我同意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 就会触发一个错误,而链接器不久就会触发这个错误。

      【讨论】:

        【解决方案7】:

        为那些仍有问题的人提供上述答案的附加信息。

        1. 最后一个版本的 Cmake 的 FindBoost.cmake 可能没有内容最后 升压版。如果需要,添加它。
        2. 使用 -DBoost_DEBUG=0 配置标志查看问题信息。
        3. 请参阅库naming format。如果需要,请使用 Boost_COMPILERBoost_ARCHITECTURE 后缀变量。

        【讨论】:

        【解决方案8】:

        如果您使用自定义提升路径,请先设置CMAKE_PREFIX_PATH。因此,cmake 可以找到您的客户提升。

        list(FIND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX} _INDEX)
        if (_INDEX EQUAL -1)
            list(APPEND CMAKE_PREFIX_PATH ${CUSTOME_BOOST_DEP_PREFIX})
            # set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
        endif ()
        

        顺便说一句,如果你在子 cmake 文件中运行上面的代码,应该将 CMAKE_PREFIX_PATH 设置回父范围。

        set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
        

        如果您想查找 boost 的所有组件,请使用以下代码。

        find_package(Boost 1.76 COMPONENTS ALL)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-01
          • 1970-01-01
          • 2020-03-06
          • 1970-01-01
          • 2021-06-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多