From 32b063eba5c754f833725ed4b9e5f352bc3ca959 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Thu, 25 Mar 2021 10:42:51 +0100 Subject: [PATCH] Fix support for source subdirectories (#238) * add support for source subdirectories * style fixes * remove debug log * grammar fix in comment --- cmake/CPM.cmake | 60 ++++++++++++------- .../local_dependency/SubdirCMakeLists.txt.in | 17 ++++++ .../dependency/inner/CMakeLists.txt | 3 + test/unit/subdir.cmake | 17 ++++++ 4 files changed, 74 insertions(+), 23 deletions(-) create mode 100644 test/unit/local_dependency/SubdirCMakeLists.txt.in create mode 100644 test/unit/local_dependency/dependency/inner/CMakeLists.txt create mode 100644 test/unit/subdir.cmake diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 9e81789..ce263e2 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -388,6 +388,7 @@ function(CPMAddPackage) NO_CACHE GIT_SHALLOW EXCLUDE_FROM_ALL + SOURCE_SUBDIR ) set(multiValueArgs URL OPTIONS) @@ -549,11 +550,11 @@ function(CPMAddPackage) set(${CPM_ARGS_NAME}_BINARY_DIR ${CMAKE_BINARY_DIR}/_deps/${lower_case_name}-build) set(${CPM_ARGS_NAME}_ADDED YES) set(${CPM_ARGS_NAME}_SOURCE_DIR ${download_directory}) - if(NOT CPM_ARGS_DOWNLOAD_ONLY AND EXISTS ${download_directory}/CMakeLists.txt) - cpm_add_subdirectory( - ${download_directory} ${${CPM_ARGS_NAME}_BINARY_DIR} "${CPM_ARGS_EXCLUDE_FROM_ALL}" - ) - endif() + cpm_add_subdirectory( + "${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" + "${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}" + "${CPM_ARGS_EXCLUDE_FROM_ALL}" + ) set(CPM_SKIP_FETCH TRUE) set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}") else() @@ -592,7 +593,12 @@ function(CPMAddPackage) cpm_declare_fetch( "${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}" ) - cpm_fetch_package("${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" "${CPM_ARGS_EXCLUDE_FROM_ALL}") + cpm_fetch_package("${CPM_ARGS_NAME}") + cpm_add_subdirectory( + "${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" + "${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}" + "${CPM_ARGS_EXCLUDE_FROM_ALL}" + ) cpm_get_fetch_properties("${CPM_ARGS_NAME}") endif() @@ -715,36 +721,44 @@ function(cpm_get_fetch_properties PACKAGE) ) endfunction() -function(cpm_add_subdirectory SOURCE_DIR BINARY_DIR EXCLUDE) - if(EXCLUDE) - set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL) - else() - set(addSubdirectoryExtraArgs "") +# adds a package as a subdirectory if viable, according to provided options +function(cpm_add_subdirectory PACKAGE DOWNLOAD_ONLY SOURCE_DIR BINARY_DIR EXCLUDE) + if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt) + if(EXCLUDE) + set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL) + else() + set(addSubdirectoryExtraArgs "") + endif() + set(CPM_OLD_INDENT "${CPM_INDENT}") + set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:") + add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs}) + set(CPM_INDENT "${CPM_OLD_INDENT}") endif() - add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs}) endfunction() -# downloads a previously declared package via FetchContent -function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY EXCLUDE) +# downloads a previously declared package via FetchContent and exports the variables +# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope +function(cpm_fetch_package PACKAGE) if(${CPM_DRY_RUN}) message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)") return() endif() FetchContent_GetProperties(${PACKAGE}) - string(TOLOWER "${PACKAGE}" lower_case_name) if(NOT ${lower_case_name}_POPULATED) FetchContent_Populate(${PACKAGE}) - if(NOT DOWNLOAD_ONLY AND EXISTS ${${lower_case_name}_SOURCE_DIR}/CMakeLists.txt) - set(CPM_OLD_INDENT "${CPM_INDENT}") - set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:") - cpm_add_subdirectory( - ${${lower_case_name}_SOURCE_DIR} ${${lower_case_name}_BINARY_DIR} "${EXCLUDE}" - ) - set(CPM_INDENT "${CPM_OLD_INDENT}") - endif() endif() + + string(TOLOWER "${PACKAGE}" lower_case_name) + set(${PACKAGE}_SOURCE_DIR + ${${lower_case_name}_SOURCE_DIR} + PARENT_SCOPE + ) + set(${PACKAGE}_BINARY_DIR + ${${lower_case_name}_BINARY_DIR} + PARENT_SCOPE + ) endfunction() # splits a package option diff --git a/test/unit/local_dependency/SubdirCMakeLists.txt.in b/test/unit/local_dependency/SubdirCMakeLists.txt.in new file mode 100644 index 0000000..f0838bd --- /dev/null +++ b/test/unit/local_dependency/SubdirCMakeLists.txt.in @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +project(CPMTest) + +# ---- Dependencies ---- + +include(@CPM_PATH@/CPM.cmake) + +CPMAddPackage( + NAME Dependency + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency + SOURCE_SUBDIR inner +) + +# ---- Call inner dependency method to validate correct addition of subdirectory ---- + +inner_dependency_function() diff --git a/test/unit/local_dependency/dependency/inner/CMakeLists.txt b/test/unit/local_dependency/dependency/inner/CMakeLists.txt new file mode 100644 index 0000000..1115b80 --- /dev/null +++ b/test/unit/local_dependency/dependency/inner/CMakeLists.txt @@ -0,0 +1,3 @@ +function(inner_dependency_function) + message("called inner method") +endfunction() diff --git a/test/unit/subdir.cmake b/test/unit/subdir.cmake new file mode 100644 index 0000000..a136860 --- /dev/null +++ b/test/unit/subdir.cmake @@ -0,0 +1,17 @@ +include(CMakePackageConfigHelpers) +include(${CPM_PATH}/testing.cmake) + +set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir) + +configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/local_dependency/SubdirCMakeLists.txt.in" + "${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt" + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk +) + +execute_process( + COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/local_dependency" "-B${TEST_BUILD_DIR}" + RESULT_VARIABLE ret +) + +assert_equal(${ret} "0")