Конфигурация cmake boost find_depedency - PullRequest
0 голосов
/ 11 октября 2018

Я столкнулся с этой проблемой, когда пытался сгенерировать Config для моей сборки и использовать целевой апстрим при использовании различных компонентов повышения.Такое ощущение, что я что-то упустил или, может быть, даже неправильно понял, как я должен использовать файл Config.cmake для генерации целей для вышестоящего пакета.То, что вы должны указать find_dependency, снова кажется ... off.

В приведенном ниже файле SomeProjectConfig.cmake я должен проверить, загрузил ли вышестоящий пакет необходимые цели для работы SomeProject, если он этого не сделалнужно снова вызвать find boost с необходимыми компонентами.

# 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, и с моей точки зрения это действительно трудно контролироватьМне также кажется, что я на самом деле не правильно понимаю процесс пакета Config.

# 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 Ответ

0 голосов
/ 15 октября 2018

Оказывается, это было мое использование макроса find_dependency, замена его на find_package дала мне правильные результаты без обходных путей.

Если мы погрузимся в CMakeFindDependencyMacro.cmake, станет совершенно ясно, чтовопрос есть.

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

Если пакет уже найден, он сразу же остановит выполнение и не добавит дополнительные компоненты.Это означает, что вы можете сделать вызов find_package(SomePackage) перед любым дополнительным find_package(Boost) восходящим потоком, но не наоборот.

Я не думаю, что это проблема для изолированных пакетов, но как только у вас есть компоненты, которые вам может понадобиться добавить к уже существующей цели, find_dependency, похоже, ломается из-за оператора if.Судя по другому ответу в отношении 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...