├── cmake ├── FindCatch2.cmake ├── FindScapix.cmake ├── FindPybind11.cmake ├── FindScapixCore.cmake ├── FindScapixJNI.cmake ├── FindScapixJavaAPI.cmake ├── FindFMT.cmake ├── FindCURL.cmake ├── FindZLIB.cmake ├── FindBZip2.cmake ├── FindScapixBin.cmake ├── FindZstd.cmake └── FindBoost.cmake ├── LICENSE.txt ├── README.md └── CMakeLists.txt /cmake/FindCatch2.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | catch2 3.5.3 5 | URL "https://github.com/catchorg/Catch2/archive/refs/tags/v3.5.3.tar.gz" 6 | URL_HASH SHA256=8d723b0535c94860ef8cf6231580fa47d67a3416757ecb10639e40d748ab6c71 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindScapix.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | scapix 2.0.2 5 | URL "https://github.com/scapix-com/scapix/archive/refs/tags/v2.0.2.tar.gz" 6 | URL_HASH SHA256=b3cda246a1e43a65026e808d04d5c80720ba5f45d681e302354dafcf4c632131 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindPybind11.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | pybind11 2.13.6 5 | URL "https://github.com/pybind/pybind11/archive/refs/tags/v2.13.6.tar.gz" 6 | URL_HASH SHA256=e08cb87f4773da97fa7b5f035de8763abc656d87d5773e62f6da0587d1f0ec20 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindScapixCore.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | scapix_core 2.0.1 5 | URL "https://github.com/scapix-com/scapix-core/archive/refs/tags/v2.0.1.tar.gz" 6 | URL_HASH SHA256=7a0e27431db724c3e45dffb9d01128e39bc75aa43fa4c686ef64b2d5174e7b94 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindScapixJNI.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | scapix_jni 2.0.1 5 | URL "https://github.com/scapix-com/scapix-jni/archive/refs/tags/v2.0.1.tar.gz" 6 | URL_HASH SHA256=8cfe7e3f5bc4554f4380f9fff461102d468c87bc51d1f8f697ab118caa448508 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindScapixJavaAPI.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | cmodule_add( 4 | scapix_java_api 2.0.0 5 | URL "https://github.com/scapix-com/scapix-java-api/archive/refs/tags/v2.0.0.tar.gz" 6 | URL_HASH SHA256=ec9883f9c373dd4fb28e3314897e061dba7747f0a6b61f2b39be5de7baf64d9d 7 | ) 8 | -------------------------------------------------------------------------------- /cmake/FindFMT.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | option(FMT_INSTALL "" OFF) 4 | 5 | cmodule_add( 6 | fmt 12.1.0 7 | URL "https://github.com/fmtlib/fmt/archive/refs/tags/12.1.0.tar.gz" 8 | URL_HASH SHA256=ea7de4299689e12b6dddd392f9896f08fb0777ac7168897a244a6d6085043fea 9 | ) 10 | -------------------------------------------------------------------------------- /cmake/FindCURL.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | set(CURL_ENABLE_EXPORT_TARGET OFF) 4 | 5 | cmodule_add( 6 | curl 8.2.1 7 | URL "https://github.com/curl/curl/releases/download/curl-8_2_1/curl-8.2.1.tar.xz" 8 | URL_HASH SHA256=dd322f6bd0a20e6cebdfd388f69e98c3d183bed792cf4713c8a7ef498cba4894 9 | ) 10 | -------------------------------------------------------------------------------- /cmake/FindZLIB.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | option(ZLIB_BUILD_EXAMPLES "" OFF) 4 | option(SKIP_INSTALL_ALL "zlib" ON) 5 | 6 | cmodule_add( 7 | zlib 1.3.1 8 | URL "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.xz" 9 | URL_HASH SHA256=38ef96b8dfe510d42707d9c781877914792541133e1870841463bfa73f883e32 10 | ) 11 | 12 | if(BUILD_SHARED_LIBS) 13 | add_library(ZLIB::ZLIB ALIAS zlib) 14 | else() 15 | add_library(ZLIB::ZLIB ALIAS zlibstatic) 16 | endif() 17 | -------------------------------------------------------------------------------- /cmake/FindBZip2.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | option(ENABLE_LIB_ONLY "bz2" ON) 4 | 5 | if(BUILD_SHARED_LIBS) 6 | option(ENABLE_STATIC_LIB "bz2" OFF) 7 | option(ENABLE_SHARED_LIB "bz2" ON) 8 | else() 9 | option(ENABLE_STATIC_LIB "bz2" ON) 10 | option(ENABLE_SHARED_LIB "bz2" OFF) 11 | endif() 12 | 13 | cmodule_add( 14 | bzip2 1.0.7-p0 15 | URL "https://gitlab.com/federicomenaquintero/bzip2/-/archive/b7a672291188a6469f71dd13ad14f2f9a7344fc8/bzip2.tar.bz2" 16 | URL_HASH SHA256=739669956b2f7535f4ddaa62d030027785c28d6f9615e232eabb8afe1cc58a10 17 | ) 18 | 19 | if(TARGET bz2) 20 | target_include_directories(bz2 INTERFACE ${CMODULE_bzip2_SOURCE_DIR}) 21 | endif() 22 | 23 | if(TARGET bz2_static) 24 | target_include_directories(bz2_static INTERFACE ${CMODULE_bzip2_SOURCE_DIR}) 25 | endif() 26 | 27 | if(BUILD_SHARED_LIBS) 28 | add_library(BZip2::BZip2 ALIAS bz2) 29 | else() 30 | add_library(BZip2::BZip2 ALIAS bz2_static) 31 | endif() 32 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Boris Rasin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmake/FindScapixBin.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | set(scapix_bin_hash_Darwin-arm64 5c72aed9452d417af38fdad65b1cfee4b4ac7c6cf6efa2869f7229a3a984c514) 4 | set(scapix_bin_hash_Darwin-x86_64 11b98dfde278d33bc1bc39c44f2720e852c341a987eec545eb3d5ae0947b63e6) 5 | set(scapix_bin_hash_Linux-x86_64 604c3dde69248eff137654be90ee32728004fd4d1fd0f9bd4798983f20f2ebec) 6 | set(scapix_bin_hash_Windows-AMD64 7ec2bb45adbc87283b5c1befbe785982cf35e3b5684308107242342620e1f177) 7 | 8 | cmodule_add( 9 | scapix_bin 2.1.1 10 | URL "https://github.com/scapix-com/scapix-bin/archive/refs/tags/v2.1.1-${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz" 11 | URL_HASH SHA256=${scapix_bin_hash_${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}} 12 | ) 13 | 14 | set(SCAPIX_EXE "${CMODULE_scapix_bin_SOURCE_DIR}/${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}/scapix" CACHE INTERNAL "") 15 | 16 | if(NOT EXISTS "${SCAPIX_EXE}") 17 | set(SCAPIX_EXE "${SCAPIX_EXE}.exe" CACHE INTERNAL "") 18 | endif() 19 | 20 | set(SCAPIX_JAVA_EXE "${CMODULE_scapix_bin_SOURCE_DIR}/${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}/scapix_java" CACHE INTERNAL "") 21 | 22 | if(NOT EXISTS "${SCAPIX_JAVA_EXE}") 23 | set(SCAPIX_JAVA_EXE "${SCAPIX_JAVA_EXE}.exe" CACHE INTERNAL "") 24 | endif() 25 | -------------------------------------------------------------------------------- /cmake/FindZstd.cmake: -------------------------------------------------------------------------------- 1 | include_guard(GLOBAL) 2 | 3 | if(BUILD_SHARED_LIBS) 4 | option(ZSTD_BUILD_STATIC "" OFF) 5 | option(ZSTD_BUILD_SHARED "" ON) 6 | else() 7 | option(ZSTD_BUILD_STATIC "" ON) 8 | option(ZSTD_BUILD_SHARED "" OFF) 9 | endif() 10 | 11 | option(ZSTD_LEGACY_SUPPORT "" OFF) 12 | option(ZSTD_BUILD_PROGRAMS "" OFF) 13 | option(ZSTD_BUILD_CONTRIB "" OFF) 14 | option(ZSTD_BUILD_TESTS "" OFF) 15 | 16 | if(MSVC) 17 | option(ZSTD_USE_STATIC_RUNTIME "" ON) 18 | endif() 19 | 20 | cmodule_add( 21 | zstd 1.5.7 22 | URL "https://github.com/facebook/zstd/releases/download/v1.5.7/zstd-1.5.7.tar.gz" 23 | URL_HASH SHA256=eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3 24 | SOURCE_SUBDIR "build/cmake" 25 | ) 26 | 27 | if(TARGET libzstd_shared) 28 | target_include_directories(libzstd_shared INTERFACE ${CMODULE_zstd_SOURCE_DIR}/lib ${CMODULE_zstd_SOURCE_DIR}/lib/common) 29 | add_library(zstd::libzstd_shared ALIAS libzstd_shared) 30 | endif() 31 | 32 | if(TARGET libzstd_static) 33 | target_include_directories(libzstd_static INTERFACE ${CMODULE_zstd_SOURCE_DIR}/lib ${CMODULE_zstd_SOURCE_DIR}/lib/common) 34 | add_library(zstd::libzstd_static ALIAS libzstd_static) 35 | endif() 36 | 37 | if(BUILD_SHARED_LIBS) 38 | add_library(zstd::libzstd ALIAS libzstd_shared) 39 | else() 40 | add_library(zstd::libzstd ALIAS libzstd_static) 41 | endif() 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cmodule 2 | 3 | 🇺🇦 If you like this project, please consider donating to one of the funds helping victims of russian aggression against Ukraine: [ukraine.ua](https://war.ukraine.ua/donate/) 4 | 5 | Non-intrusive CMake dependency management. 6 | 7 | Normally CMake's find_package() looks for packages installed on host system (and compiled for host system). 8 | When using **cmodule**, find_package() downloads packages and compiles them using current CMake toolchain. 9 | This allows using C/C++ libraries (like boost) whether you are building for host system or cross-compiling for Android, iOS, WebAssembly, etc. 10 | 11 | ## CMake integration 12 | 13 | After initializing cmodule, regular find_package() calls will work in top level CMake project and all subprojects: 14 | 15 | ```cmake 16 | include(FetchContent) 17 | FetchContent_Declare( 18 | cmodule 19 | URL "https://github.com/scapix-com/cmodule/archive/refs/tags/v2.0.1.tar.gz" 20 | URL_HASH SHA256=a9477bbefb43b6fabdc2dc044207fe42cca63999c60b6baf06ba0c62fa116ec5 21 | ) 22 | FetchContent_MakeAvailable(cmodule) 23 | 24 | find_package(Boost REQUIRED COMPONENTS filesystem) 25 | target_link_libraries(mytarget PUBLIC Boost::filesystem) 26 | 27 | find_package(Boost REQUIRED COMPONENTS iostreams) 28 | target_link_libraries(mytarget PUBLIC Boost::iostreams) 29 | 30 | find_package(ZLIB REQUIRED) 31 | target_link_libraries(mytarget PRIVATE ZLIB::ZLIB) 32 | 33 | find_package(BZip2 REQUIRED) 34 | target_link_libraries(mytarget PRIVATE BZip2::BZip2) 35 | 36 | find_package(CURL REQUIRED) 37 | target_link_libraries(mytarget PRIVATE CURL::libcurl) 38 | ``` 39 | 40 | ## How cmodule differs from other package managers? 41 | 42 | Instead of providing compiled binaries, cmodule builds libraries as part of your project build. 43 | 44 | This has multiple advantages: 45 | 46 | - libraries seamlessly build for any target, including cross-compiling targets (iOS, Android, etc.) 47 | - libraries build using the same settings (compiler options) as the rest of the project 48 | - non intrusive syntax: automatically works for projects with regular find_package() calls 49 | - downloaded and extracted sources are cached by cmodule to speedup builds for different targets and builds of different projects 50 | 51 | ## More info 52 | 53 | [Documentation](https://www.scapix.com/cmodule)\ 54 | [Example](https://github.com/scapix-com/cmodule_test) 55 | -------------------------------------------------------------------------------- /cmake/FindBoost.cmake: -------------------------------------------------------------------------------- 1 | get_property(__cmodule_boost_guard GLOBAL PROPERTY __cmodule_boost_guard) 2 | if(NOT __cmodule_boost_guard) 3 | set_property(GLOBAL PROPERTY __cmodule_boost_guard ON) 4 | 5 | cmodule_add( 6 | boost 1.89.0 7 | URL https://github.com/boostorg/boost/releases/download/boost-1.89.0/boost-1.89.0-cmake.tar.xz 8 | URL_HASH SHA256=67acec02d0d118b5de9eb441f5fb707b3a1cdd884be00ca24b9a73c995511f74 9 | SOURCE_SUBDIR "nonexistent" 10 | ) 11 | 12 | # Detect Boost version 13 | 14 | file(STRINGS "${CMODULE_boost_SOURCE_DIR}/libs/config/include/boost/version.hpp" __cmodule_boost_version REGEX "define BOOST_VERSION ") 15 | string(REGEX MATCH "[0-9]+" __cmodule_boost_version "${__cmodule_boost_version}") 16 | math(EXPR BOOST_VERSION_MAJOR "${__cmodule_boost_version} / 100000") 17 | math(EXPR BOOST_VERSION_MINOR "${__cmodule_boost_version} / 100 % 1000") 18 | math(EXPR BOOST_VERSION_PATCH "${__cmodule_boost_version} % 100") 19 | set(BOOST_VERSION "${BOOST_VERSION_MAJOR}.${BOOST_VERSION_MINOR}.${BOOST_VERSION_PATCH}") 20 | unset(__cmodule_boost_version) 21 | 22 | function(cmodule_boost_add_libraries) 23 | 24 | set(BUILD_TESTING OFF) 25 | 26 | if(NOT CMAKE_MSVC_RUNTIME_LIBRARY) 27 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") 28 | if(NOT BOOST_RUNTIME_LINK STREQUAL "static") 29 | string(APPEND CMAKE_MSVC_RUNTIME_LIBRARY "DLL") 30 | endif() 31 | endif() 32 | 33 | foreach(lib IN ITEMS ${ARGN}) 34 | get_property(guard GLOBAL PROPERTY __cmodule_boost_${lib}_guard) 35 | if(NOT guard) 36 | set_property(GLOBAL PROPERTY __cmodule_boost_${lib}_guard ON) 37 | 38 | if(lib STREQUAL "headers") 39 | file(GLOB path_list LIST_DIRECTORIES true "${CMODULE_boost_SOURCE_DIR}/libs/*") 40 | foreach(path IN LISTS path_list) 41 | if (IS_DIRECTORY "${path}/include") 42 | get_filename_component(include_dir "${path}/include" ABSOLUTE) 43 | list(APPEND include_list "${include_dir}") 44 | endif() 45 | endforeach() 46 | add_library(boost_headers INTERFACE) 47 | add_library(Boost::headers ALIAS boost_headers) 48 | target_include_directories(boost_headers INTERFACE ${include_list}) 49 | 50 | # Compatibility targets 51 | 52 | add_library(Boost::boost INTERFACE IMPORTED) 53 | set_property(TARGET Boost::boost APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::headers) 54 | 55 | add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) 56 | add_library(Boost::disable_autolinking INTERFACE IMPORTED) 57 | add_library(Boost::dynamic_linking INTERFACE IMPORTED) 58 | 59 | if(WIN32) 60 | set_property(TARGET Boost::diagnostic_definitions PROPERTY INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") 61 | set_property(TARGET Boost::disable_autolinking PROPERTY INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") 62 | set_property(TARGET Boost::dynamic_linking PROPERTY INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") 63 | endif() 64 | 65 | continue() 66 | endif() 67 | 68 | if(lib STREQUAL "boost") 69 | continue() 70 | endif() 71 | 72 | string(REGEX REPLACE "^numeric_" "numeric/" lib ${lib}) 73 | 74 | file(STRINGS "${CMODULE_boost_SOURCE_DIR}/libs/${lib}/CMakeLists.txt" data) 75 | set(dependencies "") 76 | 77 | foreach(line IN LISTS data) 78 | if(line MATCHES "^[ ]*Boost::([A-Za-z0-9_]+)[ ]*$") 79 | set(dep ${CMAKE_MATCH_1}) 80 | string(REGEX REPLACE "^numeric_" "numeric/" dep_path ${dep}) 81 | if(EXISTS "${CMODULE_boost_SOURCE_DIR}/libs/${dep_path}/CMakeLists.txt") 82 | list(APPEND dependencies ${dep}) 83 | endif() 84 | endif() 85 | endforeach() 86 | 87 | cmodule_boost_add_libraries(${dependencies}) 88 | 89 | cmodule_set_local_options() 90 | add_subdirectory(${CMODULE_boost_SOURCE_DIR}/libs/${lib} ${CMAKE_BINARY_DIR}/_deps/cmodule/boost/${lib} EXCLUDE_FROM_ALL) 91 | cmodule_restore_local_options() 92 | 93 | endif() 94 | endforeach() 95 | 96 | endfunction() 97 | endif() 98 | 99 | cmodule_boost_add_libraries(headers ${${CMAKE_FIND_PACKAGE_NAME}_FIND_COMPONENTS}) 100 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14...3.26) 2 | 3 | project(cmodule) 4 | 5 | if(CMAKE_HOST_WIN32) 6 | set(CMODULE_USER_HOME_DIR "$ENV{USERPROFILE}") 7 | else() 8 | set(CMODULE_USER_HOME_DIR "$ENV{HOME}") 9 | endif() 10 | 11 | if(NOT CMODULE_USER_HOME_DIR) 12 | set(CMODULE_USER_HOME_DIR "${CMAKE_SOURCE_DIR}") 13 | endif() 14 | 15 | set(CMODULE_CACHE_SOURCE_DIR ${CMODULE_USER_HOME_DIR}/.cmodule CACHE PATH "Folder to cache sources downloaded by cmodule, empty string to disable") 16 | option(CMODULE_DISABLE_WARNINGS "Disable all compiler warnings and CMake deprecation warnings for libraries built by cmodule" ON) 17 | option(BUILD_SHARED_LIBS "Build shared libraries" OFF) 18 | 19 | set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH} PARENT_SCOPE) 20 | 21 | set_property(GLOBAL PROPERTY USE_FOLDERS ON) 22 | 23 | macro(cmodule_set_local_options) 24 | set(CMODULE_BACKUP_CMAKE_FOLDER ${CMAKE_FOLDER}) 25 | set(CMAKE_FOLDER "cmodule") 26 | 27 | if(CMODULE_DISABLE_WARNINGS) 28 | set(CMODULE_BACKUP_CMAKE_WARN_DEPRECATED ${CMAKE_WARN_DEPRECATED}) 29 | set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "" FORCE) 30 | endif() 31 | 32 | get_property(CMODULE_BACKUP_COMPILE_OPTIONS DIRECTORY PROPERTY COMPILE_OPTIONS) 33 | if(CMODULE_DISABLE_WARNINGS) 34 | if(MSVC) 35 | add_compile_options(/W0) 36 | else() 37 | add_compile_options(-w) 38 | endif() 39 | endif() 40 | endmacro() 41 | 42 | macro(cmodule_restore_local_options) 43 | set(CMAKE_FOLDER ${CMODULE_BACKUP_CMAKE_FOLDER}) 44 | 45 | if(CMODULE_DISABLE_WARNINGS) 46 | set(CMAKE_WARN_DEPRECATED ${CMODULE_BACKUP_CMAKE_WARN_DEPRECATED} CACHE BOOL "" FORCE) 47 | endif() 48 | 49 | set_property(DIRECTORY PROPERTY COMPILE_OPTIONS ${CMODULE_BACKUP_COMPILE_OPTIONS}) 50 | endmacro() 51 | 52 | macro(find_package_next name) 53 | set(TEMP ${CMAKE_MODULE_PATH}) 54 | list(REMOVE_ITEM CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}") 55 | find_package(${name}) 56 | set(CMAKE_MODULE_PATH ${TEMP}) 57 | endmacro() 58 | 59 | include(FetchContent) 60 | 61 | function(cmodule_add name version) 62 | message(STATUS "cmodule: ${name} ${version}") 63 | 64 | cmake_parse_arguments(PARSE_ARGV 2 ARG "" "SOURCE_SUBDIR" "") 65 | 66 | set(content_name cmodule_${name}) 67 | set(content_source_dir "") 68 | 69 | if(CMODULE_CACHE_SOURCE_DIR) 70 | set(source_dir ${CMODULE_CACHE_SOURCE_DIR}/${name}/${version}) 71 | file(LOCK ${source_dir}.lock) 72 | string(TOUPPER ${content_name} upper_content_name) 73 | if (NOT FETCHCONTENT_SOURCE_DIR_${upper_content_name}) 74 | file(GLOB source_dir_files ${source_dir}/*) 75 | if (source_dir_files) 76 | set(FETCHCONTENT_SOURCE_DIR_${upper_content_name} ${source_dir}) 77 | else() 78 | set(content_source_dir SOURCE_DIR ${source_dir}) 79 | endif() 80 | endif() 81 | endif() 82 | 83 | FetchContent_Declare( 84 | ${content_name} 85 | ${content_source_dir} 86 | DOWNLOAD_EXTRACT_TIMESTAMP TRUE 87 | EXCLUDE_FROM_ALL 88 | ${ARGN} 89 | ) 90 | 91 | # We use FetchContent_Populate(name) (deprecated in CMake 3.30) instead of FetchContent_MakeAvailable(), 92 | # because EXCLUDE_FROM_ALL is supported by FetchContent_Declare() only from CMake 3.28 93 | 94 | # cmodule_set_local_options() 95 | # FetchContent_MakeAvailable(${content_name}) 96 | # cmodule_restore_local_options() 97 | # string(TOLOWER ${content_name} lower_content_name) 98 | 99 | FetchContent_GetProperties(${content_name}) 100 | string(TOLOWER ${content_name} lower_content_name) 101 | if(NOT ${lower_content_name}_POPULATED) 102 | cmake_policy(PUSH) 103 | if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.30") 104 | cmake_policy(SET CMP0169 OLD) 105 | endif() 106 | FetchContent_Populate(${content_name}) 107 | cmake_policy(POP) 108 | if(EXISTS "${${lower_content_name}_SOURCE_DIR}/${ARG_SOURCE_SUBDIR}/CMakeLists.txt") 109 | cmodule_set_local_options() 110 | add_subdirectory("${${lower_content_name}_SOURCE_DIR}/${ARG_SOURCE_SUBDIR}" "${${lower_content_name}_BINARY_DIR}" EXCLUDE_FROM_ALL) 111 | cmodule_restore_local_options() 112 | endif() 113 | endif() 114 | 115 | if(CMODULE_CACHE_SOURCE_DIR) 116 | file(LOCK ${source_dir}.lock RELEASE) 117 | endif() 118 | 119 | # Can also use FetchContent_GetProperties(cmodule_${name}), cmodule_${lower_name}_SOURCE_DIR / cmodule_${lower_name}_BINARY_DIR. 120 | set(CMODULE_${name}_SOURCE_DIR ${${lower_content_name}_SOURCE_DIR} PARENT_SCOPE) 121 | set(CMODULE_${name}_BINARY_DIR ${${lower_content_name}_BINARY_DIR} PARENT_SCOPE) 122 | 123 | string(TOUPPER ${CMAKE_FIND_PACKAGE_NAME} upper_find_package_name) 124 | set(${upper_find_package_name}_FOUND TRUE PARENT_SCOPE) 125 | set(${CMAKE_FIND_PACKAGE_NAME}_FOUND TRUE PARENT_SCOPE) 126 | endfunction() 127 | --------------------------------------------------------------------------------