CMakeLists.txt에 Boost 라이브러리를 어떻게 추가합니까?


124

CMakeLists.txt에 Boost 라이브러리를 추가해야합니다. 당신은 그것을 어떻게하거나 어떻게 추가합니까?


이 줄 rosbuild_add_boost_directories ()는 무엇을합니까?
laksh

답변:


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*합니다. 예를 들어 filesystemregex라이브러리를 사용하는 경우 다음 과 같이 작성합니다.

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
.NET Framework와 같은 헤더 전용 라이브러리에 대해서는 구성 요소를 지정할 필요가 없습니다 lexical_cast. 따라서 find_packageinclude_directories명령 만 필요합니다 .
miguel.martin

1
Windows에서는 cmake 파일에 다음을 추가하는 것도 도움이 될 수 있습니다. ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) 그렇지 않으면 stackoverflow.com/questions/28887680/…에
Stéphane

BOOST_USE_STATIC_LIBS를 ON 및 Boost_USE_STATIC_RUNTIME OFF로 설정할 수 있습니까? & 부절.
squid

5
무슨 *boost libraries here*뜻이야?
IgorGanapolsky

2
사용할 FIND_PACKAGE(Boost REQUIRED COMPONENTS system)부스트의 정확한 버전을 모르는 경우 에도 사용할 수 있습니다
smac89

78

find_package 를 사용하여 사용 가능한 부스트 라이브러리를 검색 할 수 있습니다. FindBoost.cmake에 대한 Boost 검색을 연기합니다. , 이는 기본적으로 CMake와 함께 설치됩니다.

Boost를 찾으면 find_package()호출이 많은 변수를 채웠을 것 입니다 ( FindBoost.cmake에 대한 참조 확인 ). 이 중에는 BOOST_INCLUDE_DIRSBoost_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를 호출하기 전에이 변수를 설정할 수 있습니다.
  • 여러 빌드 버전의 부스트 (다중 스레드, 정적, 공유 등)가있는 경우 find_package를 호출하기 전에 원하는 구성을 지정할 수 있습니다. 에 다음 변수 중 일부를 설정하여이 작업을 수행 On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Windows에서 Boost를 검색 할 때 자동 연결에주의하십시오. 에서 "비주얼 스튜디오 사용자를위한 참고"내용을 읽어 참조 .
    • 내 조언은 자동 연결을 비활성화하고 cmake의 종속성 처리를 사용하는 것입니다. add_definitions( -DBOOST_ALL_NO_LIB )
    • 경우에 따라 동적 부스트를 사용하도록 명시 적으로 지정해야 할 수 있습니다. add_definitions( -DBOOST_ALL_DYN_LINK )

3
일반적인 팁에 감사드립니다. 그들은 나를 많이 도왔습니다.
Tyler Long

매우 유용한 답변입니다! 2 년 전에 이것을 찾았 더라면 많은 시간을 절약 할 수 있었을 것입니다. 대단한 글.
Ela782 2014

22

가져온 대상이있는 최신 CMake 구문에 대한 @LainIwakura의 답변을 적용하면 다음과 같습니다.

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::filesystem및 을 통해 처리되었으므로 포함 디렉터리를 수동으로 지정할 필요가 없습니다 Boost::regex.
regex그리고 filesystem당신이 필요로하는 모든 부스트 라이브러리로 대체 될 수있다.


1
모든 부스트에 대해 링크하고 싶다면 어떻게 보일까요? 내 말은 모든 라이브러리를 나열하지 않고는 부스트에 있습니다.
토비 Brull

4
부스트의 헤더 전용 부분 만 사용하는 경우 'Boost :: boost'로 충분합니다. 컴파일 된 모든 부스트 라이브러리는 명시 적으로 지정해야합니다.
oLen

2
@oLen 가져온 모든 cmake Boost :: * 대상 목록은 어디에서 찾을 수 있습니까? 링크해야하는 대상을 어떻게 알 수 있습니까?
Markus

8

이것이 어떤 사람들에게 도움이 될 수 있기를 바랍니다. 장난 꾸러기 오류 : '_ZN5boost6system15system_categoryEv'기호에 대한 정의되지 않은 참조 //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0 : 기호 추가 오류 : DSO가 명령 줄에서 누락 됨 cmakeList.txt 문제가있었습니다. 그리고 어떻게 든 "시스템"과 "파일 시스템"라이브러리를 명시 적으로 포함하지 못했습니다. 그래서 저는 CMakeLists.txt에이 줄을 썼습니다.

이 줄은 프로젝트 실행 파일을 만들기 전에 처음에 작성됩니다.이 단계에서는 부스트 라이브러리를 프로젝트 실행 파일에 연결할 필요가 없습니다.

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를 프로젝트 이름으로 바꾸고 구성 요소를 자신의 것으로 바꾸는 것을 잊지 마십시오!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.