आप CMakeLists.txt में बूस्ट लाइब्रेरी कैसे जोड़ते हैं?


125

मुझे अपने CMakeLists.txt में बूस्ट लाइब्रेरी जोड़ने की जरूरत है। आप इसे कैसे करते हैं या आप इसे कैसे जोड़ते हैं?


यह पंक्ति rosbuild_add_boost_directories () क्या करती है?
लाकष

आधिकारिक दस्तावेज़ देखें यहाँ
आडेम

जवाबों:


171

इसे अपनी CMakeLists.txtफ़ाइल में रखें (यदि आप चाहें तो किसी भी विकल्प को ऑफ़ से चालू करें):

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*। उदाहरण के लिए, यदि आप पुस्तकालय filesystemऔर regexपुस्तकालय का उपयोग कर रहे हैं तो आप लिखेंगे:

find_package(Boost 1.45.0 COMPONENTS filesystem regex)

2
ध्यान दें कि आपको शीर्ष लेख के लिए घटकों को केवल पुस्तकालयों के लिए निर्दिष्ट करने की आवश्यकता नहीं है, जैसे कि lexical_cast। इस प्रकार आपको केवल find_packageऔर include_directoriesकमांड की आवश्यकता है ।
मिगेलमार्टिन

1
Windows पर, इसे अपनी cmake फ़ाइल में जोड़ने में भी मदद मिल सकती है: ADD_DEFINITIONS (-DBOOST_ALL_NO_LIB) अन्यथा आप stackoverflow.com/questions/28887680/ ... पर
स्टीफन

क्या BOOST_USE_STATIC_LIBS को ON और Boost_USE_STATIC_RUNT ऑफ पर सेट करना संभव है? & विपरीत क्रम में।
स्क्वीड

5
क्या *boost libraries here*मतलब है?
इगोरगानपोलस्की

2
FIND_PACKAGE(Boost REQUIRED COMPONENTS system)यदि आप उपयोग करने के लिए बढ़ावा देने का सटीक संस्करण नहीं जानते हैं, तो आप इसका उपयोग भी कर सकते हैं
smac89

78

आप उपलब्ध बूस्ट लाइब्रेरी को खोजने के लिए find_package का उपयोग कर सकते हैं । यह Boost से FindBoost.cmake को खोजने में चूक करता है, जो डिफ़ॉल्ट रूप से CMake के साथ स्थापित है।

बूस्ट खोजने पर, find_package()कॉल में कई चर भरे होंगे ( FindBoost.cmake के लिए संदर्भ देखें )। इनमें BOOST_INCLUDE_DIRSBoost_LIBRARIES और Boost_XXX_LIBRARY वैरिएबल्स हैं, जिनमें XXX को विशिष्ट Boost पुस्तकालयों से बदल दिया गया है। आप यह निर्दिष्ट करने के लिए इन का उपयोग कर सकते include_directories और target_link_libraries

उदाहरण के लिए, मान लें कि आपको बढ़ावा देने की आवश्यकता होगी :: program_options और बढ़ावा :: 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 कॉल करने से पहले आप इस चर को सेट कर सकते हैं।
  • जब आपके पास बढ़ावा देने के कई बिल्ड-वर्जन (मल्टी-थ्रेडेड, स्टैटिक, शेयर्ड आदि) होते हैं, तो आप फाइंडपेकिंग को कॉल करने से पहले वांछित कॉन्फ़िगरेशन निर्दिष्ट कर सकते हैं। करने के लिए निम्न चर के कुछ सेट करके ऐसा करते हैं On: Boost_USE_STATIC_LIBS, Boost_USE_MULTITHREADED,Boost_USE_STATIC_RUNTIME
  • विंडोज पर बूस्ट की खोज करते समय, ऑटो-लिंकिंग के साथ ध्यान रखें। संदर्भ में "विज़ुअल स्टूडियो उपयोगकर्ताओं के लिए नोट" पढ़ें ।
    • मेरी सलाह ऑटो-लिंकिंग को अक्षम करना और सीमेक की निर्भरता से निपटने का उपयोग करना है: add_definitions( -DBOOST_ALL_NO_LIB )
    • कुछ मामलों में, आपको यह स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता हो सकती है कि एक गतिशील बूस्ट का उपयोग किया जाता है: add_definitions( -DBOOST_ALL_DYN_LINK )

3
सामान्य सुझावों के लिए धन्यवाद। उन्होंने मेरी बहुत मदद की।
टायलर लॉन्ग

अविश्वसनीय रूप से उपयोगी उत्तर! मुझे बचा लिया है बहुत समय मुझे दो साल पहले मिल गया था। महान लेखन।
इला El२ El२

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
यदि आप सभी को बढ़ावा देने के खिलाफ लिंक करना चाहते हैं तो यह कैसा लगेगा? मेरा मतलब है कि सभी पुस्तकालयों को सूचीबद्ध किए बिना वहां बढ़ावा मिल रहा है।
टोबी ब्रूल

4
यदि आप केवल हेडर-बूस्ट के कुछ हिस्सों का उपयोग करते हैं, तो 'बूस्ट :: बूस्ट' पर्याप्त होगा। सभी संकलित बढ़ावा पुस्तकालयों को स्पष्ट रूप से निर्दिष्ट किया जाना चाहिए।
oLen

2
@ मुझे पता है कि मुझे सभी आयातित cmake बूस्ट की एक सूची कहां मिल रही है :: * लक्ष्य? मुझे कैसे पता चलेगा कि मुझे किस से लिंक करना है?
मार्कस

8

यह कुछ लोगों के लिए मददगार हो सकता है। मेरे पास एक शरारती त्रुटि थी: प्रतीक के लिए अपरिभाषित संदर्भ '_ZN5boost6system15system_categoryEv' //usr/lib/x86_64-linux-gnu/libboost-system.so.1.58.0: प्रतीक जोड़ने में त्रुटि: DSO कमांड लाइन से कुछ समस्याएँ गायब थीं। और किसी तरह मैं स्पष्ट रूप से "सिस्टम" और "फाइलसिस्टम" पुस्तकालयों को शामिल करने के लिए गायब था। तो, मैंने ये लाइनें 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)

अब फ़ाइल के अंत में, मैंने "परियोजना को निष्पादित करने योग्य" के रूप में विचार करके इन पंक्तियों को लिखा।

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

मैं उत्तर 1 और 2 से सहमत हूं । हालांकि, मैं प्रत्येक लाइब्रेरी को अलग से निर्दिष्ट करना पसंद करता हूं। यह बड़ी परियोजनाओं में स्पष्टता को स्पष्ट करता है। फिर भी, (केस-संवेदी) चर नामों के गलत होने का खतरा है। उस मामले में कोई प्रत्यक्ष 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

बूस्ट प्रलेखन के रूप में कहने की कोशिश करें :

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

अपने प्रोजेक्ट के नाम और घटकों को फू को बदलने के लिए मत भूलना!

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.