मैं इस मुद्दे में भाग गया जब मेरे निर्माण के लिए कॉन्फ़िगरेशन उत्पन्न करने का प्रयास कर रहा था और विभिन्न बूस्ट घटकों का उपयोग करते समय लक्ष्य अपस्ट्रीम का उपभोग करता था। ऐसा लगता है कि मुझे कुछ याद आ रहा है या शायद यह भी गलत समझा गया है कि मुझे अपस्ट्रीम पैकेज के लिए लक्ष्य उत्पन्न करने के लिए Config.cmake फ़ाइल का उपयोग कैसे करना चाहिए। आपको find_dependency निर्दिष्ट करना होगा फिर से लगता है ... बंद।

नीचे SomeProjectConfig.cmake फ़ाइल में मुझे यह जांचना है कि क्या अपस्ट्रीम पैकेज ने कुछ प्रोजेक्ट के काम करने के लिए आवश्यक लक्ष्य लोड किए हैं, अगर मुझे आवश्यक घटकों के साथ फिर से बूस्ट खोजने की आवश्यकता नहीं है।

# SomeProjectConfig.cmake.in

# Avoid repeatedly including the targets 
if(NOT TARGET SomeProject::SomeProject)

  # Provide path for package module scripts, CMAKE_CURRENT_LIST_DIR is the
  # directory of the currently executing cmake file. 
  list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})

  include(CMakeFindDependencyMacro)

  # -------------------------------------------------------------------------- 
  # Boost

  # The way I choose to go about it is to simply check if the dependency boost
  # targets are defined - if they are we don't have to do anything and just let
  # everything pass through. However if they are missing we need to set
  # Boost_FOUND back to FALSE so it'll resolve the dependencies...
  list(APPEND SomeProject_Boost_COMPONENTS system thread)
  foreach(_comp ${SomeProject_Boost_COMPONENTS})
    if(NOT TARGET Boost::${_comp})
      set(Boost_FOUND 0)
      break()
    endif()
  endforeach()

  # Additionally we record the BOOST_ROOT - but we try to respect the upstream
  # package if specifies it.
  if(NOT BOOST_ROOT)
    set(BOOST_ROOT "@BOOST_ROOT@"
  endif()

  # We want to handle this quietly, upstream packages might want to include more
  # componentes and if we ask for components first Boost will handle it as if
  # we've already done all the necessary work.
  find_dependency(Boost 1.55 QUIET REQUIRED COMPONENTS ${SomeProject_Boost_COMPONENTS})

  # We can never leave without setting Boost_FOUND to FALSE - if the upstream
  # package has find_package(Boost) after find_package(SomeProject) it'll
  # break if Boost_FOUND is TRUE
  set(Boost_FOUND 0)

  # // Boost
  # -------------------------------------------------------------------------- 

  find_dependency(SomeOtherDependency 1.0 QUIET REQUIRED)

  include("${CMAKE_CURRENT_LIST_DIR}/SomeProjectTargets.cmake")

  # Clean up module path after we're done
  list(REMOVE_AT CMAKE_MODULE_PATH -1)
endif()

उपरोक्त के साथ समस्या जैसा कि मैंने देखा है कि हम Boost_FOUND को 0 पर सेट कर रहे हैं और मेरे दृष्टिकोण से इसे नियंत्रित करना वाकई मुश्किल है, ऐसा भी लगता है कि मैं वास्तव में कॉन्फ़िगर पैकेज प्रक्रिया को सही ढंग से समझ नहीं पा रहा हूं।

# CMakeLists.txt upstream
find_package(Boost 1.55 REQUIRED COMPONENTS filesystem)

set(SomePackage_DIR "/path/to/Config/location")
find_package(SomePackage REQUIRED)

add_library(UpstreamTarget SHARED ${sources})
target_link_libraries(UpstreamTarget PUBLIC Boost::filesystem SomeProject::SomeProject)

उपरोक्त काम करेगा, लेकिन यह मुझे एक बुरी खुजली के साथ छोड़ देता है - ऐसा लगता है कि मैं इसे गलत कर रहा हूं।

1
Arubertoson 11 अक्टूबर 2018, 17:52

1 उत्तर

सबसे बढ़िया उत्तर

पता चला कि यह find_dependency मैक्रो का मेरा उपयोग था, इसे find_package के साथ बदलने से मुझे बिना वर्कअराउंड के सही परिणाम मिले।

अगर हम CMakeFindDependencyMacro.cmake में गोता लगाएँ तो यह बिल्कुल स्पष्ट हो जाता है कि समस्या क्या है।

macro(find_dependency dep)
  if (NOT ${dep}_FOUND)
  ...

यदि पैकेज पहले से ही मिल गया है तो यह निष्पादन को वहीं रोक देगा और अतिरिक्त घटकों को नहीं जोड़ेगा। मतलब आप किसी भी अतिरिक्त find_package(Boost) अपस्ट्रीम से पहले find_package(SomePackage) कॉल कर सकते हैं, लेकिन दूसरी तरफ नहीं।

मुझे नहीं लगता कि यह अलग-अलग पैकेजों के लिए एक समस्या है, लेकिन एक बार आपके पास ऐसे घटक हैं जिन्हें आपको पहले से मौजूद लक्ष्य find_dependency में जोड़ने की आवश्यकता हो सकती है, तो ऐसा लगता है कि अगर कथन के कारण टूटना है। के संबंध में एक अन्य उत्तर से निर्णय लेना एक *Config.cmake फ़ाइल किसी और चीज़ की तुलना में।

पूर्णता के लिए यहाँ कॉन्फ़िग फ़ाइल का एक कार्यशील उदाहरण है जहाँ मैंने वर्कअराउंड को हटा दिया है:

# SomeProjectConfig.cmake.in

# Avoid repeatedly including the targets 
if(NOT TARGET SomeProject::SomeProject)

  # Provide path for package module scripts, CMAKE_CURRENT_LIST_DIR is the
  # directory of the currently executing cmake file. 
  list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})

  include(CMakeFindDependencyMacro)
  # Additionally we record the BOOST_ROOT - but we try to respect the upstream
  # package if it specifies it.
  if(NOT BOOST_ROOT)
    set(BOOST_ROOT "@BOOST_ROOT@"
  endif()
  find_package(Boost 1.55 QUIET REQUIRED COMPONENTS system thread)
  find_dependency(SomeOtherDependency 1.0 QUIET REQUIRED)

  include("${CMAKE_CURRENT_LIST_DIR}/SomeProjectTargets.cmake")

  # Clean up module path after we're done
  list(REMOVE_AT CMAKE_MODULE_PATH -1)
endif()
0
Arubertoson 15 अक्टूबर 2018, 14:00