我有一个包含可视调试器的项目,只有在找到一组软件包时我才想构建它。我不想强制只想构建基础应用程序的用户安装所有调试器依赖项,因此在运行find_package()时我不会将其标记为REQUIRED。
现在我的构建看起来像这样:
./ CMakeList
find_package(gazebo)
find_package(OpenGL)
find_package(GLUT)
add_subdirectory(debugger)
./调试器/ CMakeList
if(NOT gazebo_FOUND OR NOT OpenGL_FOUND OR NOT GLUT_FOUND)
return()
endif()
这很好用,但随着调试器依赖项列表的增长,使用 if 来启用/禁用调试器构建看起来很笨拙。
是否有更好的替代方法可以根据find_package()的结果启用此子目录的构建?
调试器不是我项目中唯一能够以这种方式启用/禁用的东西,所以我需要一个通用的解决方案来根据找到的包启用功能。
答案 0 :(得分:1)
CMake已经没有已经制作了一个宏或一个函数来一次检查变量列表。
但编写一个能够做到这一点的函数并不困难。 E.g:
# Usage: feature_check(FEATURE_VAR REQUIRED_VAR [REQUIRED_VAR2 ...])
#
# Set FEATURE_VAR to TRUE if all required vars are TRUE,
# Otherwise set FEATURE_VAR to FALSE.
function(feature_check FEATURE_VAR REQUIRED_VAR)
foreach(var ${REQUIRED_VAR} ${ARGN})
if(NOT ${var})
set(${FEATURE_VAR} "FALSE" PARENT_SCOPE)
return()
endif(NOT ${var})
endforeach(var ${REQUIRED_VAR} ${ARGN})
set(${FEATURE_VAR} "TRUE" PARENT_SCOPE)
endfunction(feature_check FEATURE_VAR REQUIRED_VAR)
所以,在你的情况下你可以使用
# In CMakeList.txt, after find_package()
feature_check(USE_DEBUGGER gazebo_FOUND OpenGL_FOUND GLUT_FOUND)
# In debugger/CMakeList.txt
if(NOT USE_DEBUGGER)
return()
endif(NOT USE_DEBUGGER)
...
答案 1 :(得分:0)
将我的评论转化为答案
我看到三种选择:
使用FindPkgConfig
模块将搜索包合并为一个调用/结果变量?类似的东西:
pkg_check_modules(DEBUGGER_DEPS gazebo gl glu)
会在pkg-config
的平台上 - 通过使用上述调用的结果也使find_package()
调用过时:
target_compile_options(debugger PUBLIC ${DEBUGGER_DEPS_CFLAGS})
target_link_libraries(debugger PUBLIC ${DEBUGGER_DEPS_LDFLAGS})
使用CMakeDependentOption
模块将布尔值组合成一个选项,以检查
CMAKE_DEPENDENT_OPTION(
BUILD_DEBUGGER "Build debugger" ON
"gazebo_FOUND;OpenGL_FOUND;GLUT_FOUND" OFF
)
或者 - 如果项目很大 - 也许只编写我自己的my_target_link_libraries()
函数,其中包含必要的if (TARGET ...)
依赖项检查,如果失败则从所有/默认构建中删除主目标:
function(my_target_link_libraries _target)
foreach(_dep IN ITEMS ${ARGN})
if (TARGET _dep)
target_link_libraries(${_target} ${_dep})
else()
message(STATUS "No target '${_dep}' found. Disabling '${_target}' build")
set_target_properties(${_target} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD 1)
endif()
endforach()
endfunction()
my_target_link_libraries(debugger GLUT::GLUT ...)