我在尝试为我的构建生成配置并在使用不同的 boost 组件时使用上游目标时遇到了这个问题。感觉好像我遗漏了什么,甚至可能误解了我应该如何使用 Config.cmake 文件为上游包生成目标。您必须再次指定 find_dependency 似乎...关闭。
在下面的 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)
上面的方法会起作用,但它让我很痒——感觉我做错了。
最佳答案
结果是我使用了 find_dependency
宏,用 find_package
替换它给了我正确的结果,没有变通办法。
如果我们深入研究 CMakeFindDependencyMacro.cmake
,就会很清楚问题所在。
macro(find_dependency dep)
if (NOT ${dep}_FOUND)
...
如果已经找到包,它将立即停止执行并且不会附加额外的组件。这意味着您可以在任何其他 find_package(Boost)
上游之前调用 find_package(SomePackage)
,但反之则不行。
我认为这不是独立包的问题,但是一旦您拥有可能需要附加到现有目标的组件,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()
关于c++ - cmake boost find_depedency 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52763112/