From fd539b8ff36a518d8f54c7117037adb826b42495 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Tue, 16 Feb 2021 11:26:16 +0100 Subject: [PATCH] Add dependencies using EXCLUDE_FROM_ALL flag (#198) * add dependencies using EXCLUDE_FROM_ALL flag * respect DOWNLOAD_ONLY flag * set EXCLUDE_FROM_ALL as an optional flag * use one value arg for consistency * fix argument passing * add unit test * update cmake-format --- .cmake-format | 1 + cmake/CPM.cmake | 39 +++++++++++++------ cmake/testing.cmake | 12 ++++++ test/unit/broken_dependency/.gitignore | 2 + test/unit/broken_dependency/CMakeLists.txt.in | 13 +++++++ .../dependency/CMakeLists.txt | 3 ++ test/unit/exclude_from_all.cmake | 35 +++++++++++++++++ 7 files changed, 93 insertions(+), 12 deletions(-) create mode 100644 test/unit/broken_dependency/.gitignore create mode 100644 test/unit/broken_dependency/CMakeLists.txt.in create mode 100644 test/unit/broken_dependency/dependency/CMakeLists.txt create mode 100644 test/unit/exclude_from_all.cmake diff --git a/.cmake-format b/.cmake-format index 787f6a7..6ddff7c 100644 --- a/.cmake-format +++ b/.cmake-format @@ -33,6 +33,7 @@ parse: DOWNLOAD_NO_EXTRACT: 1 HTTP_USERNAME: 1 HTTP_PASSWORD: 1 + EXCLUDE_FROM_ALL: 1 OPTIONS: + cpmfindpackage: pargs: diff --git a/cmake/CPM.cmake b/cmake/CPM.cmake index 6315d31..d8d0b1e 100644 --- a/cmake/CPM.cmake +++ b/cmake/CPM.cmake @@ -257,6 +257,7 @@ function(CPMAddPackage) FIND_PACKAGE_ARGUMENTS NO_CACHE GIT_SHALLOW + EXCLUDE_FROM_ALL ) set(multiValueArgs OPTIONS) @@ -387,7 +388,9 @@ function(CPMAddPackage) 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) - add_subdirectory(${download_directory} ${${CPM_ARGS_NAME}_BINARY_DIR}) + cpm_add_subdirectory( + ${download_directory} ${${CPM_ARGS_NAME}_BINARY_DIR} "${CPM_ARGS_EXCLUDE_FROM_ALL}" + ) endif() set(CPM_SKIP_FETCH TRUE) set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}") @@ -427,7 +430,7 @@ 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_fetch_package("${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" "${CPM_ARGS_EXCLUDE_FROM_ALL}") cpm_get_fetch_properties("${CPM_ARGS_NAME}") endif() @@ -550,23 +553,35 @@ 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 "") + endif() + add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs}) +endfunction() + # downloads a previously declared package via FetchContent -function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY) +function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY EXCLUDE) if(${CPM_DRY_RUN}) message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)") return() endif() - if(DOWNLOAD_ONLY) - FetchContent_GetProperties(${PACKAGE}) - if(NOT ${PACKAGE}_POPULATED) - FetchContent_Populate(${PACKAGE}) + 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() - else() - set(CPM_OLD_INDENT "${CPM_INDENT}") - set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:") - FetchContent_MakeAvailable(${PACKAGE}) - set(CPM_INDENT "${CPM_OLD_INDENT}") endif() endfunction() diff --git a/cmake/testing.cmake b/cmake/testing.cmake index 9f072cd..9af7946 100644 --- a/cmake/testing.cmake +++ b/cmake/testing.cmake @@ -10,6 +10,18 @@ function(ASSERT_EQUAL) endif() endfunction() +function(ASSERT_NOT_EQUAL) + if(NOT ARGC EQUAL 2) + message(FATAL_ERROR "assertion failed: invalid argument count: ${ARGC}") + endif() + + if(${ARGV0} STREQUAL ${ARGV1}) + message(FATAL_ERROR "assertion failed: '${ARGV0}' == '${ARGV1}'") + else() + message(STATUS "test passed: '${ARGV0}' != '${ARGV1}'") + endif() +endfunction() + function(ASSERT_EMPTY) if(NOT ARGC EQUAL 0) message(FATAL_ERROR "assertion failed: input ${ARGC} not empty: '${ARGV}'") diff --git a/test/unit/broken_dependency/.gitignore b/test/unit/broken_dependency/.gitignore new file mode 100644 index 0000000..9c10a8f --- /dev/null +++ b/test/unit/broken_dependency/.gitignore @@ -0,0 +1,2 @@ +/CMakeLists.txt +/package-lock.cmake \ No newline at end of file diff --git a/test/unit/broken_dependency/CMakeLists.txt.in b/test/unit/broken_dependency/CMakeLists.txt.in new file mode 100644 index 0000000..9350e48 --- /dev/null +++ b/test/unit/broken_dependency/CMakeLists.txt.in @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +project(CPMTest) + +# ---- Dependencies ---- + +include(@CPM_PATH@/CPM.cmake) + +CPMAddPackage( + NAME BrokenDependency + SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency + EXCLUDE_FROM_ALL @EXCLUDE_FROM_ALL@ +) diff --git a/test/unit/broken_dependency/dependency/CMakeLists.txt b/test/unit/broken_dependency/dependency/CMakeLists.txt new file mode 100644 index 0000000..02f31c2 --- /dev/null +++ b/test/unit/broken_dependency/dependency/CMakeLists.txt @@ -0,0 +1,3 @@ +project(BrokenDependency) + +add_custom_target(error ALL ${CMAKE_COMMAND} -E false) diff --git a/test/unit/exclude_from_all.cmake b/test/unit/exclude_from_all.cmake new file mode 100644 index 0000000..5a8b6f4 --- /dev/null +++ b/test/unit/exclude_from_all.cmake @@ -0,0 +1,35 @@ +include(CMakePackageConfigHelpers) +include(${CPM_PATH}/testing.cmake) + +set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/exclude_from_all) + +function(init_project EXCLUDE_FROM_ALL) + configure_package_config_file( + "${CMAKE_CURRENT_LIST_DIR}/broken_dependency/CMakeLists.txt.in" + "${CMAKE_CURRENT_LIST_DIR}/broken_dependency/CMakeLists.txt" + INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk + ) + + execute_process( + COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/broken_dependency" "-B${TEST_BUILD_DIR}" + RESULT_VARIABLE ret + ) + + assert_equal(${ret} "0") +endfunction() + +function(build_project expected_success) + execute_process(COMMAND ${CMAKE_COMMAND} "--build" "${TEST_BUILD_DIR}" RESULT_VARIABLE ret) + + if(expected_success) + assert_equal(${ret} 0) + else() + assert_not_equal(${ret} 0) + endif() +endfunction() + +init_project(FALSE) +build_project(FALSE) + +init_project(TRUE) +build_project(TRUE)