From c99ee1820e5f6d2fe77f7e120942be2f4125254a Mon Sep 17 00:00:00 2001 From: Nils Wentzell Date: Fri, 24 Apr 2020 17:52:27 -0400 Subject: [PATCH] [cmake] Handle dependencies with external_dependency(...) function + doc --- CMakeLists.txt | 6 ++-- deps/CMakeLists.txt | 53 ++++++++++++++++++++++++---------- deps/download.sh | 1 - deps/external_dependency.cmake | 39 +++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 20 deletions(-) delete mode 100755 deps/download.sh create mode 100644 deps/external_dependency.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8208e33f..1e54976f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -55,9 +55,6 @@ if(NOT IS_SUBPROJECT) endif() set(APP4TRIQS_BINARY_DIR ${PROJECT_BINARY_DIR} CACHE STRING "Binary directory of the APP4TRIQS Project") -# ############ -# Dependencies -add_subdirectory(deps) # ############ # Options @@ -102,6 +99,9 @@ install(TARGETS project_warnings EXPORT app4triqs-targets) # ############# # Build Project +# Find / Build dependencies +add_subdirectory(deps) + # Build and install the app4triqs library add_subdirectory(c++/app4triqs) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 13b691e8..9a5ef9e9 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -1,18 +1,39 @@ -# Each dependency should be either -# * a cmake subproject in this directory -# * found in the system using find_package -# Provide either a download.sh script to get all sources -# or use e.g. git subtree/submodule or softlinks +include(external_dependency.cmake) -# Add all subdirectories as CMake Sub-Projects -file(GLOB allfiles CONFIGURE_DEPENDS *) -foreach(file ${allfiles}) - if(IS_DIRECTORY ${file}) - add_subdirectory(${file}) - endif() -endforeach() +# Add your dependencies with the function +# +# external_dependency(name +# [VERSION ] +# [GIT_REPO ] +# [TAG ] +# [EXCLUDE_FROM_ALL] +# ) +# +# Resolve the dependency using the following steps in order. +# If a step was successful, skip the remaining ones. +# +# 1. Use find_package(name []) +# to locate the package in the system. +# Skip this step if Build_Deps option is set. +# 2. Try to find a directory containing the sources +# at ${CMAKE_SOURCE_DIR}/deps/name. If found +# build it as a cmake sub-project. +# 3. If GIT_REPO is provided, git clone the sources, +# and build them as a cmake sub-project. +# +# Addtional options: +# +# TAG - Use this keyword to specify the git tag or branch +# +# EXCLUDE_FROM_ALL - If set, targets of the dependency cmake subproject +# will not be included in the ALL target of the project. +# In particular the dependency will not be installed. -# -- googletest -- -if(NOT TARGET gtest) - find_package(GTest REQUIRED) -endif() +option(Build_Deps "Build dependencies from source" OFF) + +# -- GTest -- +external_dependency(GTest + GIT_REPO github:google/googletest + TAG release-1.10.0 + EXCLUDE_FROM_ALL +) diff --git a/deps/download.sh b/deps/download.sh deleted file mode 100755 index 0034e2cd..00000000 --- a/deps/download.sh +++ /dev/null @@ -1 +0,0 @@ -[ ! -d 'googletest' ] && git clone https://github.com/google/googletest --branch v1.10.x --depth 1 diff --git a/deps/external_dependency.cmake b/deps/external_dependency.cmake new file mode 100644 index 00000000..52ef9201 --- /dev/null +++ b/deps/external_dependency.cmake @@ -0,0 +1,39 @@ + +function(external_dependency) + cmake_parse_arguments(ARG "EXCLUDE_FROM_ALL" "VERSION;GIT_REPO;TAG" "" ${ARGN}) + + # Was dependency already found? + if(${ARGV0}_FOUND) + message(STATUS "Dependency ${ARGV0} was already resolved") + endif() + + if(NOT Build_Deps) + find_package(${ARGV0} ${${ARGV0}_VERSION} QUIET) + endif() + if(${ARGV0}_FOUND) + message(STATUS "Found dependency ${ARGV0} with find_package command") + else() + message(STATUS "Building Dependency ${ARGV0} from source.") + if(ARG_EXCLUDE_FROM_ALL) + set(subdir_opts EXCLUDE_FROM_ALL) + endif() + if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${ARGV0}) + message(STATUS "Found sources for dependency ${ARGV0} at ${CMAKE_CURRENT_SOURCE_DIR}/${ARGV0}.") + add_subdirectory(${ARGV0} ${subdir_opts}) + set(${ARGV0}_FOUND TRUE CACHE BOOL "Was dependency ${ARGV0} found?") + elseif(ARG_GIT_REPO) + set(bin_dir ${CMAKE_CURRENT_BINARY_DIR}/${ARGV0}) + set(src_dir ${bin_dir}_src) + if(NOT IS_DIRECTORY ${src_dir}) + if(ARG_TAG) + set(clone_opts --branch ${ARG_TAG} -c advice.detachedHead=false) + endif() + execute_process(COMMAND git clone ${ARG_GIT_REPO} --depth 1 ${clone_opts} ${src_dir}) + endif() + add_subdirectory(${src_dir} ${bin_dir} ${subdir_opts}) + set(${ARGV0}_FOUND TRUE CACHE BOOL "Was dependency ${ARGV0} found?") + else() + message(FATAL_ERROR "Could not find dependency ${ARGV0}") + endif() + endif() +endfunction()