CMakeLists.txt'de Boost kitaplıklarını nasıl eklersiniz?


125

CMakeLists.txt dosyama Boost kitaplıkları eklemem gerekiyor. Nasıl yaparsınız veya nasıl eklersiniz?


bu satır rosbuild_add_boost_directories () ne yapar?
laksh

Resmi belgelere buradan
adem

Yanıtlar:


171

Bunu CMakeLists.txtdosyanıza ekleyin ( isterseniz herhangi bir seçeneği KAPALI'dan AÇIK'a değiştirin):

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

Açıkçası istediğin kütüphaneleri koyduğum yere koymalısın *boost libraries here*. Örneğin, filesystemve regexkitaplığını kullanıyorsanız şunu yazarsınız:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
Yalnızca başlık kitaplıkları için bileşen belirtmenize gerek olmadığını unutmayın lexical_cast. Böylece sadece find_packageve include_directorieskomutuna ihtiyacınız var .
miguel.martin

1
Windows'ta, bunu cmake dosyanıza eklemenize de yardımcı olabilir: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB), aksi takdirde stackoverflow.com/questions/28887680/…
Stéphane

BOOST_USE_STATIC_LIBS'ı ON ve Boost_USE_STATIC_RUNTIME OFF olarak ayarlamak mümkün mü? ve ayet.
squid

5
Ne anlama *boost libraries here*geliyor?
IgorGanapolsky

2
Kullanılacak FIND_PACKAGE(Boost REQUIRED COMPONENTS system)artırmanın tam sürümünü bilmiyorsanız da kullanabilirsiniz
smac89

78

Kullanılabilir yükseltme kitaplıklarını aramak için find_package'ı kullanabilirsiniz . CMake ile varsayılan olarak yüklenen FindBoost.cmake için Boost'u aramayı erteliyor .

Boost'u bulduktan sonra, find_package()çağrı birçok değişkeni doldurmuş olacaktır ( FindBoost.cmake için referansı kontrol edin ). Bunlar arasında BOOST_INCLUDE_DIRS, Boost_LIBRARIES ve Boost_XXX_LIBRARY değişkenleri vardır, XXX, belirli Boost kitaplıklarıyla değiştirilmiştir. Bunları include_directories ve target_link_libraries belirtmek için kullanabilirsiniz .

Örneğin, boost :: program_options ve boost :: regex'e ihtiyacınız olduğunu varsayalım, şöyle bir şey yaparsınız:

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} )

Bazı genel ipuçları:

  • FindBoost arama yaparken, $ ENV {BOOST_ROOT} ortam değişkenini kontrol eder. Gerekirse find_package'ı çağırmadan önce bu değişkeni ayarlayabilirsiniz.
  • Güçlendirmenin birden çok yapı sürümüne sahip olduğunuzda (çok iş parçacıklı, statik, paylaşılan, vb.) Find_package'ı çağırmadan önce istediğiniz yapılandırmayı belirtebilirsiniz. Aşağıdaki değişkenlerden bazıları ayarlayarak bunu On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • Windows'ta Boost'u ararken, otomatik bağlantıya dikkat edin. "Visual Studio Kullanıcılar için NOT" Oku referans .
    • Benim tavsiyem, otomatik bağlamayı devre dışı bırakmak ve cmake'nin bağımlılık işlemesini kullanmak: add_definitions( -DBOOST_ALL_NO_LIB )
    • Bazı durumlarda, dinamik bir Boost'un kullanıldığını açıkça belirtmeniz gerekebilir: add_definitions( -DBOOST_ALL_DYN_LINK )

3
Genel ipuçları için teşekkür ederim. Bana çok yardımcı oldular.
Tyler Long

İnanılmaz derecede yardımcı cevap! Bunu iki yıl önce bulsaydım bana çok zaman kazandırırdı. Harika yazı.
Ela782

22

@ LainIwakura'nın modern CMake sözdizimi için cevabını içe aktarılan hedeflerle uyarlayarak, bu şöyle olacaktır:

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

İçerme dizinlerini artık manuel olarak belirtmeye gerek olmadığına dikkat edin, çünkü zaten içe aktarılan hedefler Boost::filesystemve Boost::regex.
regexve filesystemihtiyacınız olan herhangi bir destek kitaplığı ile değiştirilebilir.


1
Tüm güçlendirme ile bağlantı kurmak isteseydin bu nasıl görünürdü? Demek istediğim, tüm kütüphaneleri listelemeden çoğaltılmış.
Toby Brull

4
Arttırmanın yalnızca başlık içeren kısımlarını kullanırsanız, 'Boost :: boost' yeterli olacaktır. Tüm derlenmiş destek kitaplıkları açıkça belirtilmelidir.
oLen

2
@oLen İçe aktarılan tüm cmake Boost :: * hedeflerinin bir listesini nerede bulabilirim? Hangisine bağlanmam gerektiğini nasıl bilebilirim?
Markus

8

Bu bazı insanlara yardımcı olabilir. Yaramaz bir hata yaşadım: '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0: sembol ekleme hatası: komut satırından DSO eksik cmakeList.txt ile ilgili bazı sorunlar vardı ve bir şekilde "sistem" ve "dosya sistemi" kitaplıklarını açıkça dahil etmeyi kaçırmıştım. Bu yüzden bu satırları CMakeLists.txt'ye yazdım

Bu satırlar, projenin yürütülebilir dosyasını oluşturmadan önce başlangıçta yazılır, çünkü bu aşamada boost kitaplığını proje yürütülebilir dosyamıza bağlamamız gerekmez.

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)

Şimdi dosyanın sonuna, bu satırları "KeyPointEvaluation" u projem çalıştırılabilir olarak düşünerek yazdım.

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

Cevap 1 ve 2'ye katılıyorum . Ancak her kitaplığı ayrı ayrı belirtmeyi tercih ediyorum. Bu, büyük projelerde bağımlılıkları daha net hale getirir. Yine de (büyük / küçük harfe duyarlı) değişken adlarının yanlış yazılması tehlikesi vardır. Bu durumda doğrudan bir cmake hatası yoktur, ancak bazı tanımlanmamış referanslar bağlayıcı sorunları daha sonra çözülür ve çözülmesi biraz zaman alabilir. Bu nedenle aşağıdaki cmake işlevini kullanıyorum:

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)

Yukarıda bahsedilen örnek için bu şuna benzer:

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

"BOOST_PROGRAM_OPTIONS_LIBRARY" yazmış olsaydım, cmake tarafından tetiklenen ve daha sonra bağlayıcı tarafından tetiklenmeyen bir hata olurdu.


2

Boost belgelerini söylemeyi deneyin :

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'yu proje adınıza ve bileşenlerini kendi proje adınıza değiştirmeyi unutmayın!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.