include(CMakeParseArguments) # Resolve a dependency in this order: # 1) already-defined target(s) # 2) find_package() system package(s) # 3) FetchContent fallback function(hdk_resolve_dependency) set(_opts "") set(_one_value NAME MIN_VERSION USE_SYSTEM FETCH_FALLBACK GIT_REPOSITORY GIT_TAG FETCHCONTENT_NAME OUT_VAR) set(_multi_value TARGETS PACKAGE_NAMES) cmake_parse_arguments(HDK_DEP "${_opts}" "${_one_value}" "${_multi_value}" ${ARGN}) if(NOT HDK_DEP_NAME) message(FATAL_ERROR "hdk_resolve_dependency requires NAME") endif() if(NOT HDK_DEP_TARGETS) message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) requires TARGETS") endif() if(NOT HDK_DEP_FETCHCONTENT_NAME) message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) requires FETCHCONTENT_NAME") endif() set(_hdk_dep_resolved_target "") foreach(_target IN LISTS HDK_DEP_TARGETS) if(TARGET ${_target}) set(_hdk_dep_resolved_target ${_target}) break() endif() endforeach() if(NOT _hdk_dep_resolved_target AND HDK_DEP_USE_SYSTEM) foreach(_pkg IN LISTS HDK_DEP_PACKAGE_NAMES) if(HDK_DEP_MIN_VERSION) find_package(${_pkg} ${HDK_DEP_MIN_VERSION} QUIET CONFIG) else() find_package(${_pkg} QUIET CONFIG) endif() foreach(_target IN LISTS HDK_DEP_TARGETS) if(TARGET ${_target}) set(_hdk_dep_resolved_target ${_target}) break() endif() endforeach() if(_hdk_dep_resolved_target) break() endif() endforeach() endif() if(NOT _hdk_dep_resolved_target) if(NOT HDK_DEP_FETCH_FALLBACK) if(HDK_DEP_MIN_VERSION) message(FATAL_ERROR "${HDK_DEP_NAME} >= ${HDK_DEP_MIN_VERSION} not found and fallback is disabled") else() message(FATAL_ERROR "${HDK_DEP_NAME} not found and fallback is disabled") endif() endif() if(NOT HDK_DEP_GIT_REPOSITORY) message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) fallback requires GIT_REPOSITORY") endif() if(NOT HDK_DEP_GIT_TAG) message(FATAL_ERROR "hdk_resolve_dependency(${HDK_DEP_NAME}) fallback requires GIT_TAG") endif() include(FetchContent) FetchContent_Declare( ${HDK_DEP_FETCHCONTENT_NAME} GIT_REPOSITORY ${HDK_DEP_GIT_REPOSITORY} GIT_TAG ${HDK_DEP_GIT_TAG} ) FetchContent_MakeAvailable(${HDK_DEP_FETCHCONTENT_NAME}) foreach(_target IN LISTS HDK_DEP_TARGETS) if(TARGET ${_target}) set(_hdk_dep_resolved_target ${_target}) break() endif() endforeach() endif() if(NOT _hdk_dep_resolved_target) message(FATAL_ERROR "${HDK_DEP_NAME} could not be resolved to any expected target: ${HDK_DEP_TARGETS}") endif() if(HDK_DEP_OUT_VAR) set(${HDK_DEP_OUT_VAR} ${_hdk_dep_resolved_target} PARENT_SCOPE) endif() endfunction()