Compare commits

..

20 Commits

Author SHA1 Message Date
Lars Melchior
6b5cd6f190 add removed test cases 2023-04-13 17:59:08 +02:00
Lars Melchior
a49358ef34 refactor empty argument passing to not require eval 2023-04-13 17:49:13 +02:00
Craig Hutchinson
f4fd660d09 Maintain key-value CMake formatting 2023-03-23 20:55:19 +00:00
Craig Hutchinson
5c1ce67e3b Fix docs typo 2023-03-23 20:55:19 +00:00
Craig Hutchinson
b847af65c0 Support EVAL CODE on CMake <3.18 2023-03-23 20:55:18 +00:00
Craig Hutchinson
cbe5144f79 Preserving forwarding of empty string arguments
Also:
- Support cmake-format on Windows by using auto lione-ending
2023-03-23 20:55:18 +00:00
Craig Hutchinson
b70460aca4 Test forwarding of arguments to FetchCOntent_Declare 2023-03-23 20:55:18 +00:00
Claus Klein
a02a9601da SOURCE_DIR option disable call to find_package() (#456) 2023-02-28 19:25:01 +01:00
Craig Hutchinson
af3f1ca814 Prevent check variable leaking into caller scope (#457) 2023-02-27 12:48:00 +01:00
Lars Melchior
b9b512a869 Add CMake version as workflow matrix parameter (#451)
* add CMake version as workflow matrix parameter

* change system test behaviour based on specified CMake version

* use explicit version strings

* set CMake version for both test steps

* exclude windows-2022, cmake 3.16 combination
2023-02-22 17:33:50 +01:00
Lars Melchior
e23bd4c0c3 Update Readme to match default SYSTEM behaviour (#452) 2023-02-21 20:00:20 +02:00
Lars Melchior
5f3005ab7c Move section on adding CPM higher in the Readme (#454)
Repositions the "Adding CPM" section higher in the Readme to increase incentive to try it out and make it easier to find for updating CPM in existing projects.
2023-02-21 19:59:57 +02:00
Lars Melchior
12daf366c7 Add SYSTEM option (#449)
* add system property for cpm_add_subdirectory

* add test case for system property

* lock CMake version in test workflow

* refactor to make SYSTEM an extra config option and update tests

* remove old comment change

* use consistent CMake version and extension for all workflows

* make warning more specific and try to trigger on windows

* another attempt to trigger warning on MSVC

* update readme

* simplify test case and use git tag

* add SYSTEM option to .cmake-format

* forward system arg for source overrides

* enable system implicitly for the single argument syntax

* Use SYSTEM option for FetchContent and add_subdirectory (#441)

* Use SYSTEM option for FetchContent and add_subdirectory

* Add SYSTEM option to syntax and doku

* Update CPM.cmake

* Update .cmake-format

---------

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>

---------

Co-authored-by: Claus Klein <claus.klein@arcormail.de>
2023-02-21 15:51:33 +01:00
PercentBoat4164
0938e8fde7 Improve Multi-threaded Performance. (#450)
* Optimized multi-threading.

* Remove old multi-threading implementation.

* Release files instead of removing.

* Lock before choosing to check cache or download.

* Unlock directly after verifying directory exists.
2023-02-21 15:47:15 +01:00
PercentBoat4164
09b056ae20 Add file locking to support parallel runs. (#427)
* Add file locking to support parallel runs.

* Fixed formatting.

* Prevent double locking file.

* Fix SegFault from test 2.

* Remove unnecessary debugging messages.

* Lock the package directory rather than the cache directory.
Only synchronize if CPM_SOURCE_CACHE is defined.

* Lock the version specific cache entry rather than the package specific entry.

* Remove unnecessary arguments in conditional statements.

* Change back to locking entire cache directory.

* Only check CPM_HAS_CACHE_LOCK.

* Lock on a per-package basis rather than the entire cache.

* Clean up the locked file.

* Unlock then remove to fix Windows.

* Specify use of cmake.lock as the lock file.

* - Changed CPM_HAS_CACHE_LOCK to ${CPM_ARGS_NAME}_CPM_HAS_CACHE_LOCK.
- Removed redundant variable initialization.

* Add unit test.

* Actually test if resulting git cache is clean in unit test.

* - Added comments
- Fixed formatting
- Removed unnecessary imports

* convert parallelism test to integration test

* remove comment

* - Removed now unnecessary variable.
 - Only delete file instead of unlocking it then deleting it.

* Forgot to change variable name.

* Add similar changes to the missed section.

* Fixed formatting.

* Unlock the file, but do not delete it.

* Only unlock the file if it exists.

* Changed cache.cmake test to ignore non-directory entries.

* Integration test lib make_project:
* keyword args
* 'name' arg to allow multiple projects from the same test

* - Moved checks to function.
- Fixed small grammatical errors.

* - Fix formatting

* Switch to snake case.

---------

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
Co-authored-by: Lars Melchior <lars.melchior@gmail.com>
Co-authored-by: Borislav Stanimirov <b.stanimirov@abv.bg>
2023-01-28 14:36:44 +01:00
Jan Niklas Hasse
d34d2a8730 Add JNGL to "Built with CPM.cmake" (#434)
Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2023-01-10 15:48:29 +00:00
Lars Melchior
6fc2170d5d Update example dependency versions (#430)
* update example versions

* update doctest

* update lua

* update google benchmark

* update catch2

* update readme to match updated dependencies

Co-authored-by: Lars Melchior <lars@Larss-Laptop.local>
2023-01-10 15:31:57 +01:00
haenkel
1184a6e6e7 get_cpm: Recover from failed download (#426)
* get_cpm: Recover from failed download

If the download fails during the cmake config step
an empty `CPM_<version>.cmake` file is created.
So far the script only checks the files existence,
so there is no second try until the empty file is deleted manually.

This adds a check if the file is empty
and resumes the download on next config if it is.

* More descriptive function name
2022-11-29 17:30:22 +00:00
flagarde
c53417bd65 Small helper function for logging : (#422)
* Small helper function for logging :

This PR add an helper function only when `message(STATUS ...)` as the other are `backtracing` and adding the helper function add on stack.

It should fix #328 #342 with a few line of code.

* Formatting
2022-11-29 17:50:19 +01:00
Jan Niklas Hasse
50e9b9edb8 Instead of spdlog's bundled fmt re-use it from CPM.cmake (#364)
* Instead of spdlog's bundled fmt re-use it from CPM.cmake

* Add comment about re-using fmt for spdlog

* Update examples/spdlog/CMakeLists.txt

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>

* run cmake-format

* disable cmake-format around code block

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2022-11-09 11:23:09 +00:00
29 changed files with 446 additions and 129 deletions

View File

@@ -1,6 +1,7 @@
format:
tab_size: 2
line_width: 100
line_ending: auto
dangle_parens: true
parse:
@@ -34,6 +35,7 @@ parse:
HTTP_USERNAME: 1
HTTP_PASSWORD: 1
EXCLUDE_FROM_ALL: 1
SYSTEM: 1
SOURCE_SUBDIR: 1
OPTIONS: +
cpmfindpackage:

View File

@@ -12,7 +12,7 @@ jobs:
gcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: build all
env:
CC: gcc
@@ -22,7 +22,7 @@ jobs:
clang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: build all
env:
CC: clang

View File

@@ -10,7 +10,7 @@ jobs:
name: Publish CPM.cmake
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Set CPM version by tag
run: |

View File

@@ -14,7 +14,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/checkout@v3
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.13
with:
cmake-version: '3.25.x'
- name: Install format dependencies
run: pip3 install clang-format==14.0.6 cmake_format==0.6.11 pyyaml

View File

@@ -17,17 +17,32 @@ jobs:
# we need at least ruby 2.7 for the tests
# instead of dealing with installing a modern version of ruby on 2019, we'll just use windows-2022 here
os: [ubuntu-latest, windows-2022, macos-latest]
# we want to ensure compatibility with a recent CMake version as well as the lowest officially supported
# legacy version that we define as the default version of the second-latest Ubuntu LTS release currently available
cmake_version: ['3.16.3', '3.25.1']
exclude:
# there seems to be an issue with CMake 3.16 not finding a C++ compiler on windows-2022
- os: windows-2022
cmake_version: '3.16.3'
steps:
- name: clone
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.13
with:
cmake-version: ${{ matrix.cmake_version }}
- name: unit tests
run: |
cmake -Stest -Bbuild/test
cmake --build build/test --target test-verbose
env:
CMAKE_VERSION: ${{ matrix.cmake_version }}
- name: integration tests
run: ruby test/integration/runner.rb
env:
CPM_INTEGRATION_TEST_DIR: ./build/integration
CMAKE_VERSION: ${{ matrix.cmake_version }}

View File

@@ -37,14 +37,26 @@ include(cmake/CPM.cmake)
CPMAddPackage("gh:fmtlib/fmt#7.1.3")
CPMAddPackage("gh:nlohmann/json@3.10.5")
CPMAddPackage("gh:catchorg/Catch2@2.5.0")
CPMAddPackage("gh:catchorg/Catch2@3.2.1")
# link dependencies
target_link_libraries(main fmt::fmt nlohmann_json::nlohmann_json Catch2::Catch2)
target_link_libraries(main fmt::fmt nlohmann_json::nlohmann_json Catch2::Catch2WithMain)
```
See the [examples directory](https://github.com/cpm-cmake/CPM.cmake/tree/master/examples) for complete examples with source code and check [below](#snippets) or in the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/More-Snippets) for example snippets.
## Adding CPM
To add CPM to your current project, simply add the [latest release](https://github.com/cpm-cmake/CPM.cmake/releases/latest) of `CPM.cmake` or `get_cpm.cmake` to your project's `cmake` directory.
The command below will perform this automatically.
```bash
mkdir -p cmake
wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake
```
You can also download CPM.cmake directly from your project's `CMakeLists.txt`. See the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/Downloading-CPM.cmake-in-CMake) for more details.
## Usage
After `CPM.cmake` has been [added](#adding-cpm) to your project, the function `CPMAddPackage` can be used to fetch and configure a dependency.
@@ -68,6 +80,10 @@ On the other hand, if `VERSION` hasn't been explicitly specified, CPM can automa
If an additional optional parameter `EXCLUDE_FROM_ALL` is set to a truthy value, then any targets defined inside the dependency won't be built by default. See the [CMake docs](https://cmake.org/cmake/help/latest/prop_tgt/EXCLUDE_FROM_ALL.html) for details.
If an additional optional parameter `SYSTEM` is set to a truthy value, the SYSTEM directory property of the subdirectory added will be set to true.
See the [add_subdirectory ](https://cmake.org/cmake/help/latest/command/add_subdirectory.html?highlight=add_subdirectory)
and [SYSTEM](https://cmake.org/cmake/help/latest/prop_tgt/SYSTEM.html#prop_tgt:SYSTEM) target property for details.
A single-argument compact syntax is also supported:
```cmake
@@ -79,7 +95,7 @@ CPMAddPackage("uri#tag")
CPMAddPackage("uri@version#tag")
```
In the shorthand syntax if the URI is of the form `gh:user/name`, it is interpreted as GitHub URI and converted to `https://github.com/user/name.git`. If the URI is of the form `gl:user/name`, it is interpreted as a [GitLab](https://gitlab.com/explore/) URI and converted to `https://gitlab.com/user/name.git`. If the URI is of the form `bb:user/name`, it is interpreted as a [Bitbucket](https://bitbucket.org/) URI and converted to `https://bitbucket.org/user/name.git`. Otherwise the URI used verbatim as a git URL. All packages added using the shorthand syntax will be added using the [EXCLUDE_FROM_ALL](https://cmake.org/cmake/help/latest/prop_tgt/EXCLUDE_FROM_ALL.html) flag.
In the shorthand syntax if the URI is of the form `gh:user/name`, it is interpreted as GitHub URI and converted to `https://github.com/user/name.git`. If the URI is of the form `gl:user/name`, it is interpreted as a [GitLab](https://gitlab.com/explore/) URI and converted to `https://gitlab.com/user/name.git`. If the URI is of the form `bb:user/name`, it is interpreted as a [Bitbucket](https://bitbucket.org/) URI and converted to `https://bitbucket.org/user/name.git`. Otherwise the URI used verbatim as a git URL. All packages added using the shorthand syntax will be added using the [EXCLUDE_FROM_ALL](https://cmake.org/cmake/help/latest/prop_tgt/EXCLUDE_FROM_ALL.html) and [SYSTEM](https://cmake.org/cmake/help/latest/prop_tgt/SYSTEM.html#prop_tgt:SYSTEM) flag.
The single-argument syntax also works for URLs:
@@ -103,21 +119,9 @@ For using CPM.cmake projects with external package managers, such as conan or vc
In rare cases, this behaviour may be desirable by default. The function `CPMFindPackage` will try to find a local dependency via CMake's `find_package` and fallback to `CPMAddPackage`, if the dependency is not found.
## Adding CPM
To add CPM to your current project, simply add the [latest release](https://github.com/cpm-cmake/CPM.cmake/releases/latest) of `CPM.cmake` or `get_cpm.cmake` to your project's `cmake` directory.
The command below will perform this automatically.
```bash
mkdir -p cmake
wget -O cmake/CPM.cmake https://github.com/cpm-cmake/CPM.cmake/releases/latest/download/get_cpm.cmake
```
You can also download CPM.cmake directly from your project's `CMakeLists.txt`. See the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/Downloading-CPM.cmake-in-CMake) for more details.
## Updating CPM
To update CPM to the newest version, update the script in the project's root directory, for example by running the command above.
To update CPM to the newest version, update the script in the project's root directory, for example by running the same command as for [adding CPM](#adding-cpm).
Dependencies using CPM will automatically use the updated script of the outermost project.
## Advantages
@@ -195,11 +199,14 @@ This can be controlled on a per package basis with the `CPM_DOWNLOAD_<dependency
### CPM_USE_LOCAL_PACKAGES
CPM can be configured to use `find_package` to search for locally installed dependencies first by setting the CMake option `CPM_USE_LOCAL_PACKAGES`.
If the option `CPM_LOCAL_PACKAGES_ONLY` is set, CPM will emit an error if the dependency is not found locally.
These options can also be set as environmental variables.
In the case that `find_package` requires additional arguments, the parameter `FIND_PACKAGE_ARGUMENTS` may be specified in the `CPMAddPackage` call. The value of this parameter will be forwarded to `find_package`.
Note that this does not apply to dependencies that have been defined with a truthy `FORCE` parameter. These will be added as defined.
### CPM_USE_NAMED_CACHE_DIRECTORIES
If set, CPM use additional directory level in cache to improve readability of packages names in IDEs like CLion. It changes cache structure, so all dependencies are downloaded again. There is no problem to mix both structures in one cache directory but then there may be 2 copies of some dependencies.
@@ -308,6 +315,18 @@ If you know others, feel free to add them here through a PR.
</a>
</td>
</tr>
<tr>
<td>
<a href="https://github.com/jhasse/jngl">
<p align="center">
<img src="https://github.com/jhasse/jngl/raw/master/doc/jngl-logo.svg" alt="JNGL" width="100pt" />
</p>
<p align="center"><b>JNGL - easy to use cross-platform 2D game library</b></p>
</a>
</td>
<td/>
<td/>
</tr>
</table>
## Snippets
@@ -353,9 +372,9 @@ CPMAddPackage(
# using `CPM_SOURCE_CACHE` is strongly recommended
CPMAddPackage(
NAME Boost
VERSION 1.77.0
VERSION 1.81.0
GITHUB_REPOSITORY "boostorg/boost"
GIT_TAG "boost-1.77.0"
GIT_TAG "boost-1.81.0"
)
```

View File

@@ -28,6 +28,20 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
# Initialize logging prefix
if(NOT CPM_INDENT)
set(CPM_INDENT
"CPM:"
CACHE INTERNAL ""
)
endif()
if(NOT COMMAND cpm_message)
function(cpm_message)
message(${ARGV})
endfunction()
endif()
set(CURRENT_CPM_VERSION 1.0.0-development-version)
get_filename_component(CPM_CURRENT_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}" REALPATH)
@@ -59,7 +73,8 @@ See https://github.com/cpm-cmake/CPM.cmake for more information."
endif()
if(CURRENT_CPM_VERSION MATCHES "development-version")
message(WARNING "Your project is using an unstable development version of CPM.cmake. \
message(
WARNING "${CPM_INDENT} Your project is using an unstable development version of CPM.cmake. \
Please update to a recent release if possible. \
See https://github.com/cpm-cmake/CPM.cmake for details."
)
@@ -223,14 +238,6 @@ function(cpm_package_name_and_ver_from_url url outName outVer)
endif()
endfunction()
# Initialize logging prefix
if(NOT CPM_INDENT)
set(CPM_INDENT
"CPM:"
CACHE INTERNAL ""
)
endif()
function(cpm_find_package NAME VERSION)
string(REPLACE " " ";" EXTRA_ARGS "${ARGN}")
find_package(${NAME} ${VERSION} ${EXTRA_ARGS} QUIET)
@@ -238,7 +245,7 @@ function(cpm_find_package NAME VERSION)
if(DEFINED ${CPM_ARGS_NAME}_VERSION)
set(VERSION ${${CPM_ARGS_NAME}_VERSION})
endif()
message(STATUS "${CPM_INDENT} using local package ${CPM_ARGS_NAME}@${VERSION}")
cpm_message(STATUS "${CPM_INDENT} Using local package ${CPM_ARGS_NAME}@${VERSION}")
CPMRegisterPackage(${CPM_ARGS_NAME} "${VERSION}")
set(CPM_PACKAGE_FOUND
YES
@@ -309,7 +316,7 @@ function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION)
if("${CPM_PACKAGE_VERSION}" VERSION_LESS "${CPM_ARGS_VERSION}")
message(
WARNING
"${CPM_INDENT} requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION})."
"${CPM_INDENT} Requires a newer version of ${CPM_ARGS_NAME} (${CPM_ARGS_VERSION}) than currently included (${CPM_PACKAGE_VERSION})."
)
endif()
cpm_get_fetch_properties(${CPM_ARGS_NAME})
@@ -366,7 +373,7 @@ function(cpm_parse_add_package_single_arg arg outArgs)
set(packageType "git")
else()
# Give up
message(FATAL_ERROR "CPM: Can't determine package type of '${arg}'")
message(FATAL_ERROR "${CPM_INDENT} Can't determine package type of '${arg}'")
endif()
endif()
@@ -386,7 +393,7 @@ function(cpm_parse_add_package_single_arg arg outArgs)
else()
# We should never get here. This is an assertion and hitting it means there's a bug in the code
# above. A packageType was set, but not handled by this if-else.
message(FATAL_ERROR "CPM: Unsupported package type '${packageType}' of '${arg}'")
message(FATAL_ERROR "${CPM_INDENT} Unsupported package type '${packageType}' of '${arg}'")
endif()
set(${outArgs}
@@ -419,7 +426,7 @@ function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean)
)
if(resultGitStatus)
# not supposed to happen, assume clean anyway
message(WARNING "Calling git status on folder ${repoPath} failed")
message(WARNING "${CPM_INDENT} Calling git status on folder ${repoPath} failed")
set(${isClean}
TRUE
PARENT_SCOPE
@@ -464,7 +471,7 @@ endfunction()
function(cpm_override_fetchcontent contentName)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "SOURCE_DIR;BINARY_DIR" "")
if(NOT "${arg_UNPARSED_ARGUMENTS}" STREQUAL "")
message(FATAL_ERROR "Unsupported arguments: ${arg_UNPARSED_ARGUMENTS}")
message(FATAL_ERROR "${CPM_INDENT} Unsupported arguments: ${arg_UNPARSED_ARGUMENTS}")
endif()
string(TOLOWER ${contentName} contentNameLower)
@@ -498,6 +505,60 @@ function(cpm_override_fetchcontent contentName)
set_property(GLOBAL PROPERTY ${propertyName} TRUE)
endfunction()
# replaces empty arguments with a placeholder to compensate CMake issues with handling empty
# arguments
function(cpm_encode_empty_arguments args outVar)
set(out "")
# note: we don't use string replacement for ';;' -> ';__CPM_EMPTY_ARG;' here, as it would
# interfere with nested arguments
foreach(ARG IN LISTS args)
if(NOT out STREQUAL "")
string(APPEND out ";")
endif()
if(ARG STREQUAL "")
string(APPEND out "__CPM_EMPTY_ARG")
else()
# prevent escaped characters from getting resolved early
string(REPLACE "\\" "\\\\\\" ARG "${ARG}")
string(APPEND out "${ARG}")
endif()
endforeach()
set("${outVar}"
"${out}"
PARENT_SCOPE
)
endfunction()
function(cpm_decode_empty_argument arg outVar)
if("${arg}" STREQUAL "__CPM_EMPTY_ARG")
set("${outVar}"
""
PARENT_SCOPE
)
else()
set("${outVar}"
"${arg}"
PARENT_SCOPE
)
endif()
endfunction()
# replaces placeholder arguments from `cpm_encode_empty_arguments` with empty arguments
function(cpm_decode_empty_arguments args outVar)
set(out "")
foreach(ARG IN LISTS args)
if(NOT out STREQUAL "")
string(APPEND out ";")
endif()
cpm_decode_empty_argument("${ARG}" ARG)
string(APPEND out "${ARG}")
endforeach()
set("${outVar}"
"${out}"
PARENT_SCOPE
)
endfunction()
# Download and add a package from source
function(CPMAddPackage)
cpm_set_policies()
@@ -505,9 +566,8 @@ function(CPMAddPackage)
list(LENGTH ARGN argnLength)
if(argnLength EQUAL 1)
cpm_parse_add_package_single_arg("${ARGN}" ARGN)
# The shorthand syntax implies EXCLUDE_FROM_ALL
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES")
# The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;")
endif()
set(oneValueArgs
@@ -524,6 +584,7 @@ function(CPMAddPackage)
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS
NO_CACHE
SYSTEM
GIT_SHALLOW
EXCLUDE_FROM_ALL
SOURCE_SUBDIR
@@ -531,10 +592,26 @@ function(CPMAddPackage)
set(multiValueArgs URL OPTIONS)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
# Encode arguments for `cmake_parse_arguments`
cpm_encode_empty_arguments("${ARGN}" "PARSE_ARGS")
# Parse arguments
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${PARSE_ARGS}")
# Decode arguments
foreach(ARG IN LISTS oneValueArgs)
if(DEFINED CPM_ARGS_${ARG})
cpm_decode_empty_argument("${CPM_ARGS_${ARG}}" CPM_ARGS_${ARG})
endif()
endforeach()
foreach(ARG IN LISTS multiValueArgs)
if(DEFINED CPM_ARGS_${ARG})
cpm_decode_empty_arguments("${CPM_ARGS_${ARG}}" CPM_ARGS_${ARG})
endif()
endforeach()
cpm_decode_empty_arguments("${CPM_ARGS_UNPARSED_ARGUMENTS}" CPM_ARGS_UNPARSED_ARGUMENTS)
# Set default values for arguments
if(NOT DEFINED CPM_ARGS_VERSION)
if(DEFINED CPM_ARGS_GIT_TAG)
cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION)
@@ -600,7 +677,7 @@ function(CPMAddPackage)
if(NOT DEFINED CPM_ARGS_NAME)
message(
FATAL_ERROR
"CPM: 'NAME' was not provided and couldn't be automatically inferred for package added with arguments: '${ARGN}'"
"${CPM_INDENT} 'NAME' was not provided and couldn't be automatically inferred for package added with arguments: '${ARGN}'"
)
endif()
@@ -619,6 +696,7 @@ function(CPMAddPackage)
NAME "${CPM_ARGS_NAME}"
SOURCE_DIR "${PACKAGE_SOURCE}"
EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}"
SYSTEM "${CPM_ARGS_SYSTEM}"
OPTIONS "${CPM_ARGS_OPTIONS}"
SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}"
DOWNLOAD_ONLY "${DOWNLOAD_ONLY}"
@@ -639,19 +717,21 @@ function(CPMAddPackage)
return()
endif()
if(CPM_USE_LOCAL_PACKAGES OR CPM_LOCAL_PACKAGES_ONLY)
cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS})
if(NOT CPM_ARGS_FORCE)
if(CPM_USE_LOCAL_PACKAGES OR CPM_LOCAL_PACKAGES_ONLY)
cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS})
if(CPM_PACKAGE_FOUND)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
if(CPM_PACKAGE_FOUND)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
if(CPM_LOCAL_PACKAGES_ONLY)
message(
SEND_ERROR
"CPM: ${CPM_ARGS_NAME} not found via find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})"
)
if(CPM_LOCAL_PACKAGES_ONLY)
message(
SEND_ERROR
"${CPM_INDENT} ${CPM_ARGS_NAME} not found via find_package(${CPM_ARGS_NAME} ${CPM_ARGS_VERSION})"
)
endif()
endif()
endif()
@@ -705,7 +785,16 @@ function(CPMAddPackage)
# relative paths.
get_filename_component(download_directory ${download_directory} ABSOLUTE)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory})
if(CPM_SOURCE_CACHE)
file(LOCK ${download_directory}/../cmake.lock)
endif()
if(EXISTS ${download_directory})
if(CPM_SOURCE_CACHE)
file(LOCK ${download_directory}/../cmake.lock RELEASE)
endif()
cpm_store_fetch_properties(
${CPM_ARGS_NAME} "${download_directory}"
"${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build"
@@ -716,14 +805,20 @@ function(CPMAddPackage)
# warn if cache has been changed since checkout
cpm_check_git_working_dir_is_clean(${download_directory} ${CPM_ARGS_GIT_TAG} IS_CLEAN)
if(NOT ${IS_CLEAN})
message(WARNING "Cache for ${CPM_ARGS_NAME} (${download_directory}) is dirty")
message(
WARNING "${CPM_INDENT} Cache for ${CPM_ARGS_NAME} (${download_directory}) is dirty"
)
endif()
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}" "${CPM_ARGS_OPTIONS}"
"${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_ARGS_SYSTEM}"
"${CPM_ARGS_OPTIONS}"
)
set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}")
@@ -762,8 +857,8 @@ function(CPMAddPackage)
endif()
endif()
message(
STATUS "${CPM_INDENT} adding package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION} (${PACKAGE_INFO})"
cpm_message(
STATUS "${CPM_INDENT} Adding package ${CPM_ARGS_NAME}@${CPM_ARGS_VERSION} (${PACKAGE_INFO})"
)
if(NOT CPM_SKIP_FETCH)
@@ -771,11 +866,18 @@ function(CPMAddPackage)
"${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}"
)
cpm_fetch_package("${CPM_ARGS_NAME}" populated)
if(CPM_CACHE_SOURCE AND download_directory)
file(LOCK ${download_directory}/../cmake.lock RELEASE)
endif()
if(${populated})
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_ARGS_OPTIONS}"
"${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_ARGS_SYSTEM}"
"${CPM_ARGS_OPTIONS}"
)
endif()
cpm_get_fetch_properties("${CPM_ARGS_NAME}")
@@ -790,7 +892,7 @@ macro(CPMGetPackage Name)
if(DEFINED "CPM_DECLARATION_${Name}")
CPMAddPackage(NAME ${Name})
else()
message(SEND_ERROR "Cannot retrieve package ${Name}: no declaration available")
message(SEND_ERROR "${CPM_INDENT} Cannot retrieve package ${Name}: no declaration available")
endif()
endmacro()
@@ -880,11 +982,10 @@ endfunction()
# declares a package in FetchContent_Declare
function(cpm_declare_fetch PACKAGE VERSION INFO)
if(${CPM_DRY_RUN})
message(STATUS "${CPM_INDENT} package not declared (dry run)")
cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)")
return()
endif()
FetchContent_Declare(${PACKAGE} ${ARGN})
FetchContent_Declare(${PACKAGE} "${ARGN}")
endfunction()
# returns properties for a package previously defined by cpm_declare_fetch
@@ -926,13 +1027,18 @@ function(
SOURCE_DIR
BINARY_DIR
EXCLUDE
SYSTEM
OPTIONS
)
if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt)
set(addSubdirectoryExtraArgs "")
if(EXCLUDE)
set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL)
else()
set(addSubdirectoryExtraArgs "")
list(APPEND addSubdirectoryExtraArgs EXCLUDE_FROM_ALL)
endif()
if("${SYSTEM}" AND "${CMAKE_VERSION}" VERSION_GREATER_EQUAL "3.25")
# https://cmake.org/cmake/help/latest/prop_dir/SYSTEM.html#prop_dir:SYSTEM
list(APPEND addSubdirectoryExtraArgs SYSTEM)
endif()
if(OPTIONS)
foreach(OPTION ${OPTIONS})
@@ -955,7 +1061,7 @@ function(cpm_fetch_package PACKAGE populated)
PARENT_SCOPE
)
if(${CPM_DRY_RUN})
message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)")
cpm_message(STATUS "${CPM_INDENT} Package ${PACKAGE} not fetched (dry run)")
return()
endif()
@@ -1063,10 +1169,11 @@ function(cpm_prettify_package_arguments OUT_VAR IS_IN_COMMENT)
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS
NO_CACHE
SYSTEM
GIT_SHALLOW
)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
cmake_parse_arguments(PARSE_ARGV 2 CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}")
foreach(oneArgName ${oneValueArgs})
if(DEFINED CPM_ARGS_${oneArgName})

View File

@@ -10,12 +10,24 @@ endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
function(download_cpm)
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION}
)
endfunction()
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
download_cpm()
else()
# resume download if it previously failed
file(READ ${CPM_DOWNLOAD_LOCATION} check)
if("${check}" STREQUAL "")
download_cpm()
endif()
unset(check)
endif()
include(${CPM_DOWNLOAD_LOCATION})

View File

@@ -11,7 +11,7 @@ CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage(
NAME benchmark
GITHUB_REPOSITORY google/benchmark
VERSION 1.5.2
VERSION 1.7.1
OPTIONS "BENCHMARK_ENABLE_TESTING Off"
)

View File

@@ -13,9 +13,9 @@ include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME Boost
VERSION 1.77.0
VERSION 1.81.0
GITHUB_REPOSITORY "boostorg/boost"
GIT_TAG "boost-1.77.0"
GIT_TAG "boost-1.81.0"
)
target_link_libraries(CPMExampleBoost PRIVATE Boost::asio)

View File

@@ -7,12 +7,12 @@ project(CPMExampleCatch2)
include(../../cmake/CPM.cmake)
CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage("gh:catchorg/Catch2@2.13.4")
CPMAddPackage("gh:catchorg/Catch2@3.2.1")
# ---- Create binary ----
add_executable(CPMExampleCatch2 main.cpp)
target_link_libraries(CPMExampleCatch2 fibonacci Catch2)
target_link_libraries(CPMExampleCatch2 fibonacci Catch2::Catch2WithMain)
target_compile_features(CPMExampleCatch2 PRIVATE cxx_std_17)
# ---- Enable testing ----

View File

@@ -1,8 +1,6 @@
#define CATCH_CONFIG_MAIN
#include <fibonacci.h>
#include <catch2/catch.hpp>
#include <catch2/catch_test_macros.hpp>
TEST_CASE("fibonacci") {
REQUIRE(fibonacci(0) == 0);

View File

@@ -7,7 +7,7 @@ project(CPMExampleDoctest)
include(../../cmake/CPM.cmake)
CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage("gh:onqtam/doctest#2.4.5")
CPMAddPackage("gh:onqtam/doctest@2.4.9")
# ---- Create binary ----

View File

@@ -11,8 +11,8 @@ CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage(
NAME googletest
GITHUB_REPOSITORY google/googletest
GIT_TAG release-1.10.0
VERSION 1.10.0
GIT_TAG release-1.12.1
VERSION 1.12.1
OPTIONS "INSTALL_GTEST OFF" "gtest_force_shared_crt"
)

View File

@@ -15,29 +15,16 @@ CPMAddPackage(
if(lua_ADDED)
# lua has no CMakeLists, so we create our own target
file(GLOB lua_sources ${lua_SOURCE_DIR}/*.c)
list(REMOVE_ITEM lua_sources "${lua_SOURCE_DIR}/lua.c" "${lua_SOURCE_DIR}/luac.c")
add_library(lua STATIC ${lua_sources})
target_include_directories(lua SYSTEM PUBLIC $<BUILD_INTERFACE:${lua_SOURCE_DIR}>)
endif()
CPMAddPackage(
NAME sol2
URL https://github.com/ThePhD/sol2/archive/v3.0.2.zip
VERSION 3.0.2
DOWNLOAD_ONLY YES
)
if(sol2_ADDED)
add_library(sol2 INTERFACE IMPORTED)
target_include_directories(sol2 SYSTEM INTERFACE ${sol2_SOURCE_DIR}/include)
target_link_libraries(sol2 INTERFACE lua)
endif()
CPMAddPackage("gh:ThePhD/sol2@3.3.0")
# ---- Executable ----
add_executable(CPMSol2Example main.cpp)
target_compile_features(CPMSol2Example PRIVATE cxx_std_17)
target_link_libraries(CPMSol2Example sol2)
target_link_libraries(CPMSol2Example sol2 lua)

View File

@@ -8,6 +8,20 @@ include(../../cmake/CPM.cmake)
CPMAddPackage("gh:gabime/spdlog@1.8.2")
# spdlog uses fmt and bundles that dependency. If you want to use fmt in your project as well, you
# can let spdlog re-use fmt from CPM.cmake like this:
#
# cmake-format: off
#
# CPMAddPackage("gh:fmtlib/fmt#7.1.3")
# CPMAddPackage(
# GITHUB_REPOSITORY gabime/spdlog
# VERSION 1.8.2
# OPTIONS "SPDLOG_FMT_EXTERNAL 1"
# )
#
# cmake-format: on
# ---- Executable ----
add_executable(CPMSpdlogExample main.cpp)

View File

@@ -12,7 +12,7 @@ To run all tests from the repo root execute:
$ ruby test/integration/runner.rb
```
The runner will run all tests and generate a report of the exeuction.
The runner will run all tests and generate a report of the execution.
The current working directory doesn't matter. If you are in `<repo-root>/test/integration`, you can run simply `$ ruby runner.rb`.

View File

@@ -157,6 +157,11 @@ class IntegrationTest < Test::Unit::TestCase
assert_block(msg) { res.status.success? }
end
def assert_failure(res)
msg = build_message(nil, "command status was expected to be a failure, but succeeded")
assert_block(msg) { !res.status.success? }
end
def assert_same_path(a, b)
msg = build_message(nil, "<?> expected but was\n<?>", a, b)
assert_block(msg) { File.identical? a, b }
@@ -180,19 +185,20 @@ class IntegrationTest < Test::Unit::TestCase
@@test_dir
end
def make_project(template_dir = nil)
def make_project(name: nil, from_template: nil)
test_name = local_name
test_name = test_name[5..] if test_name.start_with?('test_')
base = File.join(cur_test_dir, test_name)
base += "-#{name}" if name
src_dir = base + '-src'
FileUtils.mkdir_p src_dir
if template_dir
template_dir = File.join(TestLib::TEMPLATES_DIR, template_dir)
raise "#{template_dir} is not a directory" if !File.directory?(template_dir)
FileUtils.copy_entry template_dir, src_dir
if from_template
from_template = File.join(TestLib::TEMPLATES_DIR, from_template)
raise "#{from_template} is not a directory" if !File.directory?(from_template)
FileUtils.copy_entry from_template, src_dir
end
Project.new src_dir, base + '-bin'

View File

@@ -1,4 +1,4 @@
# Integration Test Framework Refernce
# Integration Test Framework Reference
## `TestLib`
@@ -60,6 +60,7 @@ The class which must be a parent of all integration test case classes. It itself
### Utils
* `cur_test_dir` - the directory of the current test case. A subdirectory of `TestLib::TMP_DIR`
* `make_project(template_dir = nil)` - create a project from a test method. Will create a the project's source and binary directories as subdirectories of `cur_test_dir`.
* Optionally work with a template directory, in which case it will copy the contents of the template directory (one from `templates`) in the project's source directory.
* `make_project(name: nil, from_template: nil)` - create a project from a test method. Will create the project's source and binary directories as subdirectories of `cur_test_dir`.
* Optionally provide a name which will be concatenated to the project directory. This allows creating multiple projects in a test
* Optionally work with a template, in which case it will copy the contents of the template directory (one from `templates`) in the project's source directory.

View File

@@ -5,7 +5,7 @@ require_relative './lib'
class Basics < IntegrationTest
# Test cpm caches with no cpm-related env vars
def test_cpm_default
prj = make_project 'no-deps'
prj = make_project from_template: 'no-deps'
prj.create_lists_from_default_template
assert_success prj.configure
@@ -38,7 +38,7 @@ class Basics < IntegrationTest
def test_env_cpm_source_cache
ENV['CPM_SOURCE_CACHE'] = cur_test_dir
prj = make_project 'no-deps'
prj = make_project from_template: 'no-deps'
prj.create_lists_from_default_template
assert_success prj.configure

View File

@@ -9,8 +9,8 @@ class FetchContentCompatibility < IntegrationTest
end
def test_add_dependency_cpm_and_fetchcontent
prj = make_project 'using-adder'
prj = make_project from_template: 'using-adder'
prj.create_lists_from_default_template package: <<~PACK
CPMAddPackage(
NAME testpack-adder

View File

@@ -0,0 +1,21 @@
require_relative './lib'
class Parallelism < IntegrationTest
def setup
@cache_dir = File.join(cur_test_dir, 'cpmcache')
ENV['CPM_SOURCE_CACHE'] = @cache_dir
end
def test_populate_cache_in_parallel
4.times.map { |i|
prj = make_project name: i.to_s, from_template: 'using-fibadder'
prj.create_lists_from_default_template package: 'CPMAddPackage("gh:cpm-cmake/testpack-fibadder@1.0.0")'
prj
}.map { |prj|
Thread.new do
assert_success prj.configure
assert_success prj.build
end
}.map(&:join)
end
end

View File

@@ -2,8 +2,8 @@ require_relative './lib'
class RemoveSourceDir < IntegrationTest
def test_remove_source_dir
prj = make_project 'using-adder'
prj = make_project from_template: 'using-adder'
prj.create_lists_from_default_template package: <<~PACK
CPMAddPackage(
NAME testpack-adder

View File

@@ -4,7 +4,7 @@ class Simple < IntegrationTest
ADDER_PACKAGE_NAME = 'testpack-adder'
def test_update_single_package
prj = make_project 'using-adder'
prj = make_project from_template: 'using-adder'
adder_cache0 = nil
adder_ver_file = nil

View File

@@ -9,7 +9,7 @@ class SourceCache < IntegrationTest
end
def test_add_remove_dependency
prj = make_project 'using-fibadder'
prj = make_project from_template: 'using-fibadder'
###################################
# create
@@ -45,7 +45,7 @@ class SourceCache < IntegrationTest
end
def test_second_project
prj = make_project 'using-fibadder'
prj = make_project from_template: 'using-fibadder'
prj.create_lists_from_default_template package: 'CPMAddPackage("gh:cpm-cmake/testpack-fibadder@1.1.0")'
assert_success prj.configure

View File

@@ -0,0 +1,57 @@
require_relative './lib'
class SystemWarnings < IntegrationTest
def setup
# system is only supported for CMake >= 3.25
@system_supported = (!ENV['CMAKE_VERSION']) || (Gem::Version.new(ENV['CMAKE_VERSION']) >= Gem::Version.new('3.25'))
end
def test_dependency_added_using_system
for use_system in [true, false] do
prj = make_project name: use_system ? "system" : "no_system", from_template: 'using-adder'
prj.create_lists_from_default_template package: <<~PACK
# this commit has a warning in a public header
CPMAddPackage(
NAME Adder
GITHUB_REPOSITORY cpm-cmake/testpack-adder
GIT_TAG v1.0.1-warnings
SYSTEM #{use_system ? "YES" : "NO"}
)
# all packages using `adder` will error on warnings
target_compile_options(adder INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:/Wall /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Werror>
)
PACK
assert_success prj.configure
if use_system and @system_supported
assert_success prj.build
else
assert_failure prj.build
end
end
end
def test_dependency_added_implicitly_using_system
prj = make_project from_template: 'using-adder'
prj.create_lists_from_default_template package: <<~PACK
# this commit has a warning in a public header
CPMAddPackage("gh:cpm-cmake/testpack-adder@1.0.1-warnings")
# all packages using `adder` will error on warnings
target_compile_options(adder INTERFACE
$<$<CXX_COMPILER_ID:MSVC>:/Wall /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Werror>
)
PACK
assert_success prj.configure
if @system_supported
assert_success prj.build
else
assert_failure prj.build
end
end
end

View File

@@ -26,6 +26,17 @@ function(reset_test)
update_cmake_lists()
endfunction()
function(assert_cache_directory_count directory count)
set(version_count 0)
file(GLOB potential_versions ${directory})
foreach(entry ${potential_versions})
if(IS_DIRECTORY ${entry})
math(EXPR version_count "${version_count} + 1")
endif()
endforeach()
assert_equal("${version_count}" "${count}")
endfunction()
set(FIBONACCI_VERSION 1.0)
# Read CPM_SOURCE_CACHE from arguments
@@ -40,13 +51,7 @@ execute_process(
assert_equal(${ret} "0")
assert_exists("${CPM_SOURCE_CACHE_DIR}/fibonacci")
file(GLOB FIBONACCI_VERSIONs "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
list(LENGTH FIBONACCI_VERSIONs FIBONACCI_VERSION_count)
assert_equal(${FIBONACCI_VERSION_count} "1")
file(GLOB fibonacci_versions "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
list(LENGTH fibonacci_versions fibonacci_version_count)
assert_equal(${fibonacci_version_count} "1")
assert_cache_directory_count("${CPM_SOURCE_CACHE_DIR}/fibonacci/*" 1)
# Update dependency and keep CPM_SOURCE_CACHE
@@ -54,12 +59,9 @@ set(FIBONACCI_VERSION 2.0)
update_cmake_lists()
execute_process(COMMAND ${CMAKE_COMMAND} ${TEST_BUILD_DIR} RESULT_VARIABLE ret)
assert_equal(${ret} "0")
file(GLOB FIBONACCI_VERSIONs "${CPM_SOURCE_CACHE_DIR}/fibonacci/*")
list(LENGTH FIBONACCI_VERSIONs FIBONACCI_VERSION_count)
assert_equal(${FIBONACCI_VERSION_count} "2")
assert_cache_directory_count("${CPM_SOURCE_CACHE_DIR}/fibonacci/*" 2)
# Clear cache and update

View File

@@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
include(${CPM_PATH}/CPM.cmake)
include(${CPM_PATH}/testing.cmake)
set(input "a;;b;c;;;;def;g;;")
cpm_encode_empty_arguments("${input}" encoded)
foreach(arg IN LISTS encoded)
assert_not_equal("${arg}" "")
endforeach()
assert_equal("${contains_empty_arg}" "")
cpm_decode_empty_arguments("${encoded}" decoded)
assert_equal("${decoded}" "${input}")
# ignore source cache if set
set(CPM_SOURCE_CACHE "")
# Intercept underlying `FetchContent_Declare`
function(FetchContent_Declare)
set_property(GLOBAL PROPERTY last_FetchContent_Declare_ARGN "${ARGN}")
endfunction()
cpm_declare_fetch(PACKAGE VERSION INFO EMPTY "" ANOTHER)
# TEST:`cpm_declare_fetch` shall forward empty arguments
get_property(last_FetchContent_Declare_ARGN GLOBAL PROPERTY last_FetchContent_Declare_ARGN)
assert_equal("${last_FetchContent_Declare_ARGN}" "PACKAGE;EMPTY;;ANOTHER")
# TEST:`CPMDeclarePackage` shall store all including empty
CPMDeclarePackage(FOO EMPTY "" ANOTHER)
assert_equal("${CPM_DECLARATION_FOO}" "EMPTY;;ANOTHER")
# Stub the actual fetch
set(fibonacci_POPULATED YES)
set(fibonacci_SOURCE_DIR ".")
set(fibonacci_BINARY_DIR ".")
macro(FetchContent_GetProperties)
endmacro()
# TEST:`CPMAddPackage` shall call `FetchContent_declare` with unmodified arguments including any
# Empty-string arguments
CPMAddPackage(
NAME fibonacci
GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git
VERSION 1.2.3 EMPTY_OPTION "" COMMAND_WITH_EMPTY_ARG foo "" bar
)
get_property(last_FetchContent_Declare_ARGN GLOBAL PROPERTY last_FetchContent_Declare_ARGN)
assert_equal(
"${last_FetchContent_Declare_ARGN}"
"fibonacci;EMPTY_OPTION;;COMMAND_WITH_EMPTY_ARG;foo;;bar;GIT_REPOSITORY;https://github.com/cpm-cmake/testpack-fibonacci.git;GIT_TAG;v1.2.3"
)
# Intercept underlying `cpm_add_package_multi_arg`
function(CPMAddPackage)
set_property(GLOBAL PROPERTY last_cpmaddpackage_argn "${ARGN}")
endfunction()
# TEST: CPM Module file shall store all arguments including empty strings
include(${CPM_MODULE_PATH}/Findfibonacci.cmake)
get_property(last_cpmaddpackage_argn GLOBAL PROPERTY last_cpmaddpackage_argn)
assert_equal(
"${last_cpmaddpackage_argn}"
"NAME;fibonacci;GIT_REPOSITORY;https://github.com/cpm-cmake/testpack-fibonacci.git;VERSION;1.2.3;EMPTY_OPTION;;COMMAND_WITH_EMPTY_ARG;foo;;bar"
)
# remove generated files
file(REMOVE_RECURSE ${CPM_MODULE_PATH})
file(REMOVE ${CPM_PACKAGE_LOCK_FILE})

View File

@@ -2,6 +2,8 @@ include(CMakePackageConfigHelpers)
include(${CPM_PATH}/testing.cmake)
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir)
# clean existing build if it exists
file(REMOVE_RECURSE "${TEST_BUILD_DIR}")
set(TEST_DEPENDENCY_NAME Dependency)