Compare commits

..

24 Commits

Author SHA1 Message Date
Scott B
d416d9b22c Adding PATCHES keyword. (#558)
* Adding PATCHES keyword.

* Formatting fix.

* Move cpm_add_patches() outside if/else scopes.

* cmake-format: add PATCHES to CPMAddPackage.

* Integration tests for PATCHES command.

* Use get_filename_component() in place of cmake_path() for use with all cmake versions 3.14 and above.

* Added an example and improved comment for cpm_add_patches.
2024-06-12 15:43:27 +02:00
PercentBoat4164
76ca48690b Remove 'bug' from comment (#555)
* Remove 'bug' from comment

* Fix the styling

Oh gosh, I messed up the style...

* Line endings
2024-04-21 21:12:30 +02:00
Gerhard Olsson
0370507fed Custom cache directory name (#543)
* Custom cache directory name

Enable setting a custom directory name for cached packages.
Required if e.g. patch_command uses external variables or
just to set a human readable name.

* fixup! review comment CUSTOM_CACHE_DIR -> CUSTOM_CACHE_KEY

* run cmake-format

---------

Co-authored-by: Olsson Gerhard <gerhard.olsson@volvo.com>
Co-authored-by: Lars Melchior <lars.melchior@gmail.com>
2024-04-08 18:24:10 +02:00
Project D.D
c0855c9543 Add xxHash example (#549)
* Add xxHash example

* Fix link error

* run code formatters

---------

Co-authored-by: Lars Melchior <lars.melchior@gmail.com>
2024-04-08 16:14:14 +00:00
black-desk
7e81149c1e Use cpm_find_package to check if a package added (#552)
If I have a project, which has:

1. /CMakeLists.txt:

   ```cmake
   cmake_minimum_required(VERSION 3.29)
   project(test)
   include(./cmake/CPM.cmake)
   add_subdirectory(subdir)
   cpmfindpackage(
     NAME
     nlohmann_json
     VERSION
     3.11.2
     URL
     "https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz"
     EXCLUDE_FROM_ALL
     ON)

   if(NOT TARGET nlohmann_json::nlohmann_json)
     message(FATAL_ERROR "BUG")
   endif()
   ```
2. /subdir/CMakeLists.txt

   ```cmake
   cpmfindpackage(
     NAME
     nlohmann_json
     VERSION
     3.11.2
     URL
     "https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz"
     EXCLUDE_FROM_ALL
     ON)
   ```

When nlohmann_json is first founded by find_package,
CPM.cmake register this package and later call to CPMFindPackage will
not actually perform a find_package again, which leads to this buggy
behavior.

As CPM write a FindXXX.cmake file for packages added by CPM to pervert
find_package to get local package, I think directly use cpm_find_package
to check if a package is already added is good enough.
2024-04-07 23:40:46 +02:00
Simon Gene Gottlieb
0e450ef450 fix,doc: spelling errors (#551) 2024-04-07 21:36:07 +00:00
Scott B
a8144f511d Update Boost example (#531)
* Update CMake and main to add another library and download FASTER.

* Apply style formatters

* Update README.md's boost example and add information on determining source archive location at GitHub.

* Update README.md

---------

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2024-02-02 18:25:34 +00:00
Claus Klein
3c25130ffa Feature/add missing packageproject options (#524)
* Add missing packageproject options

* Fix typos with codespell

* Update test/style/CMakeLists.txt

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

* fix-cmake-format

---------

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2024-01-17 09:06:16 +01:00
Chris Wright
369f1316f6 Treat relative paths as relative to parent project's remote (#522)
* Treat relative paths as relative to parent project's remote

* replace unit test case with integration test

* run relative URL test only on supported CMake versions (3.27)

* omit cmake 2.25.x test runner as replaced by 2.27.x

---------

Co-authored-by: Chris Wright <chris.wright@mqa.co.uk>
Co-authored-by: Lars Melchior <lars.melchior@gmail.com>
2023-11-30 20:01:03 +01:00
Daniel Lemire
a9c8c6fe1b Adding simdjson example (#516)
* Adding simdjson example

* Update README.md

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

* cmake format

---------

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2023-11-06 17:19:06 +00:00
Daniel Lemire
2fa48378e2 new users (#515) 2023-11-06 17:13:56 +00:00
Lars Melchior
4276c79d28 update catch2 to 3.4.0 (#517) 2023-11-06 18:04:37 +01:00
Alfi Maulana
ee6d879a50 Includes missing arguments in the cpm_prettify_package_arguments function (#511) 2023-10-08 17:48:42 +00:00
Lars Melchior
d6d5d0d5ab Remove logs in get_cpm.cmake script (#508)
* remove all logs from get_cpm.cmake

* simplify get_cpm.cmake script
2023-09-18 16:11:03 +02:00
Lars Melchior
16c6a3b0af Fix download_command by declaring it a multi-value option (#473) 2023-09-18 15:37:35 +02:00
Lars Melchior
52ee7c9d53 Fix new release script to use correct version and hash sum (#507)
* fix new release script to use correct version and hash sum

* update logging behaviour
2023-09-18 15:01:57 +02:00
Tobias Schmidl
699c7a0038 Added download status, added comparison by hash sum (#474) 2023-09-18 14:01:34 +02:00
Vincent Hamp
daf9d766c6 Add ZIMO-Elektronik to "Built with CPM.cmake" (#490) 2023-09-18 11:45:33 +02:00
Carlo Corradini
439bfcf134 chore(license): update license year (#504) 2023-09-17 19:35:11 +00:00
Alois Klink
02ecc4608a Add SPDX tags to get_cpm.cmake to comply with MIT (#496)
Add [SPDX][1] licensing/copyright tags to the `get_cpm.cmake` script,
so that anybody that copies the `get_cpm.cmake` script into their repo
(following the instructions in the README.md)
will automatically comply with CPM's MIT license.

[1]: https://spdx.dev/
2023-08-19 12:53:28 +00:00
Johel Ernesto Guerrero Peña
4608688d85 docs: fix spelling of "through" (#489) 2023-08-19 13:29:57 +02:00
Johel Ernesto Guerrero Peña
cda03b434e ci(cmake): split additional_commands to its own file (#486) 2023-08-19 12:57:47 +02:00
Andreas K
ee556fc555 fix(lock): fix typo: CPM_CACHE_SOURCE -> CPM_SOURCE_CACHE (#485) 2023-07-12 15:43:48 +02:00
Asger Gitz-Johansen
1b59cb6b16 Add AALTITOAD to "Built with CPM.cmake" (#463) 2023-04-13 09:58:49 +00:00
37 changed files with 646 additions and 282 deletions

View File

@@ -1,75 +1,5 @@
include: ["cmake/.cmake-format-additional_commands-cpm"]
format:
tab_size: 2
line_width: 100
line_ending: auto
dangle_parens: true
parse:
additional_commands:
cpmaddpackage:
pargs:
nargs: '*'
flags: []
spelling: CPMAddPackage
kwargs: &cpmaddpackagekwargs
NAME: 1
FORCE: 1
VERSION: 1
GIT_TAG: 1
DOWNLOAD_ONLY: 1
GITHUB_REPOSITORY: 1
GITLAB_REPOSITORY: 1
GIT_REPOSITORY: 1
SVN_REPOSITORY: 1
SVN_REVISION: 1
SOURCE_DIR: 1
DOWNLOAD_COMMAND: 1
FIND_PACKAGE_ARGUMENTS: 1
NO_CACHE: 1
GIT_SHALLOW: 1
URL: 1
URL_HASH: 1
URL_MD5: 1
DOWNLOAD_NAME: 1
DOWNLOAD_NO_EXTRACT: 1
HTTP_USERNAME: 1
HTTP_PASSWORD: 1
EXCLUDE_FROM_ALL: 1
SYSTEM: 1
SOURCE_SUBDIR: 1
OPTIONS: +
cpmfindpackage:
pargs:
nargs: '*'
flags: []
spelling: CPMFindPackage
kwargs: *cpmaddpackagekwargs
cpmdeclarepackage:
pargs:
nargs: '*'
flags: []
spelling: CPMDeclarePackage
kwargs: *cpmaddpackagekwargs
packageproject:
pargs:
nargs: '*'
flags: []
spelling: packageProject
kwargs:
NAME: 1
VERSION: 1
INCLUDE_DIR: 1
INCLUDE_DESTINATION: 1
BINARY_DIR: 1
COMPATIBILITY: 1
VERSION_HEADER: 1
DEPENDENCIES: +
cpmusepackagelock:
pargs: 1
spelling: CPMUsePackageLock
cpmregisterpackage:
pargs: 1
spelling: CPMRegisterPackage
cpmgetpackageversion:
pargs: 2
spelling: CPMGetPackageVersion

View File

@@ -15,8 +15,9 @@ jobs:
- name: Set CPM version by tag
run: |
mkdir dist
sed "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" cmake/CPM.cmake > dist/CPM.cmake
sed "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" cmake/get_cpm.cmake > dist/get_cpm.cmake
sed -e "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" cmake/CPM.cmake > dist/CPM.cmake
sed -e "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" \
-e "s/CPM_HASH_SUM_PLACEHOLDER/$(sha256sum dist/CPM.cmake | cut -d' ' -f1)/" cmake/get_cpm.cmake > dist/get_cpm.cmake
- name: Upload CPM.cmake to release
uses: svenstaro/upload-release-action@v1-release

View File

@@ -19,7 +19,7 @@ jobs:
- name: Setup cmake
uses: jwlawson/actions-setup-cmake@v1.13
with:
cmake-version: '3.25.x'
cmake-version: '3.27.x'
- name: Install format dependencies
run: pip3 install clang-format==14.0.6 cmake_format==0.6.11 pyyaml

View File

@@ -19,7 +19,7 @@ jobs:
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']
cmake_version: ['3.16.3', '3.27.5']
exclude:
# there seems to be an issue with CMake 3.16 not finding a C++ compiler on windows-2022
- os: windows-2022

View File

@@ -104,7 +104,7 @@ Please try to keep your individual changes as minimal and focussed on the issue
If you discover that the scope of your contribution is growing larger than expected you might want to split the changes into multiple separate contributions to allow a more focussed discussion and review.
It is usually a great idea and often required to add tests for your changes.
This allows us to quickly validate that the changes are working as intended and also guarantees that they wont be broken by other future updates.
This allows us to quickly validate that the changes are working as intended and also guarantees that they won't be broken by other future updates.
For small and targeted functional changes, e.g. supporting a new URL schema, a [unit test](#unit-tests) may be enough.
For contributions that change large-scale behaviour, such as dependency caching features, an [integration test](#integration-tests) is more suited.
Depending on the changes, a combination of both test types may also be appropriate.

155
README.md
View File

@@ -12,7 +12,7 @@ It's built as a thin wrapper around CMake's [FetchContent](https://cmake.org/cma
## Manage everything
Any downloadable project or resource can be added as a version-controlled dependency though CPM, it is not necessary to modify or package anything.
Any downloadable project or resource can be added as a version-controlled dependency through CPM, it is not necessary to modify or package anything.
Projects using modern CMake are automatically configured and their targets can be used immediately.
For everything else, the targets can be created manually after the dependency has been downloaded (see the [snippets](#snippets) below for examples).
@@ -37,7 +37,7 @@ include(cmake/CPM.cmake)
CPMAddPackage("gh:fmtlib/fmt#7.1.3")
CPMAddPackage("gh:nlohmann/json@3.10.5")
CPMAddPackage("gh:catchorg/Catch2@3.2.1")
CPMAddPackage("gh:catchorg/Catch2@3.4.0")
# link dependencies
target_link_libraries(main fmt::fmt nlohmann_json::nlohmann_json Catch2::Catch2WithMain)
@@ -67,6 +67,7 @@ Afterwards, any targets defined in the dependency can be used directly.
CPMAddPackage(
NAME # The unique name of the dependency (should be the exported target's name)
VERSION # The minimum version of the dependency (optional, defaults to 0)
PATCHES # Patch files to be applied sequentially using patch and PATCH_OPTIONS (optional)
OPTIONS # Configuration options passed to the dependency (optional)
DOWNLOAD_ONLY # If set, the project is downloaded, but not configured (optional)
[...] # Origin parameters forwarded to FetchContent_Declare, see below
@@ -78,6 +79,8 @@ If `GIT_TAG` hasn't been explicitly specified it defaults to `v(VERSION)`, a com
On the other hand, if `VERSION` hasn't been explicitly specified, CPM can automatically identify the version from the git tag in some common cases.
`GIT_TAG` can also be set to a specific commit or a branch name such as `master`, however this isn't recommended, as such packages will only be updated when the cache is cleared.
`PATCHES` takes a list of patch files to apply sequentially. For a basic example, see [Highway](examples/highway/CMakeLists.txt).
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.
@@ -142,6 +145,7 @@ Dependencies using CPM will automatically use the updated script of the outermos
- **Some CMake policies set to `NEW`** Including CPM.cmake will lead to several CMake policies being set to `NEW`. Users which need the old behavior will need to manually modify their CMake code to ensure they're set to `OLD` at the appropriate places. The policies are:
- [CMP0077](https://cmake.org/cmake/help/latest/policy/CMP0077.html) and [CMP0126](https://cmake.org/cmake/help/latest/policy/CMP0126.html). They make setting package options from `CMPAddPackage` possible.
- [CMP0135](https://cmake.org/cmake/help/latest/policy/CMP0135.html) It allows for proper package rebuilds of packages which are archives, source cache is not used, and the package URL is changed to an older version.
- [CMP0150](https://cmake.org/cmake/help/latest/policy/CMP0150.html) Relative paths provided to `GIT_REPOSITORY` are treated as relative to the parent project's remote.
For projects with more complex needs and where an extra setup step doesn't matter, it may be worth to check out an external C++ package manager such as [vcpkg](https://github.com/microsoft/vcpkg), [conan](https://conan.io) or [hunter](https://github.com/ruslo/hunter).
Dependencies added with `CPMFindPackage` should work with external package managers.
@@ -189,6 +193,9 @@ Note that passing the variable as a configure option to CMake will always overri
You can use `CPM_SOURCE_CACHE` on GitHub Actions workflows [cache](https://github.com/actions/cache) and combine it with ccache, to make your CI faster. See the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/Caching-with-CPM.cmake-and-ccache-on-GitHub-Actions) for more info.
The directory where the version for a project is stored is by default the hash of the arguments to `CPMAddPackage()`.
If for instance the patch command uses external files, the directory name can be set with the argument `CUSTOM_CACHE_KEY`.
### CPM_DOWNLOAD_ALL
If set, CPM will forward all calls to `CPMFindPackage` as `CPMAddPackage`.
@@ -324,8 +331,48 @@ If you know others, feel free to add them here through a PR.
<p align="center"><b>JNGL - easy to use cross-platform 2D game library</b></p>
</a>
</td>
<td/>
<td/>
<td>
<a href="https://github.com/sillydan1/aaltitoad">
<p align="center">
<img src="https://github.com/sillydan1/aaltitoad/raw/v1.1.0/.github/resources/logo/toad_only.svg" alt="aaltitoad" width="100pt" />
</p>
<p align="center"><b>AALTITOAD - verifier and simulator for Tick Tock Automata</b></p>
</a>
</td>
<td>
<a href="https://github.com/ZIMO-Elektronik">
<p align="center">
<img src="https://avatars.githubusercontent.com/u/117935012?s=400&u=9a871a46dd13437f0adcae166e9efbe518ff0b99&v=4" alt="ZIMO-Elektronik" width="100pt" />
</p>
<p align="center"><b>ZIMO-Elektronik</b></p>
</a>
</td>
</tr>
<tr>
<td>
<a href="https://github.com/ada-url/ada">
<p align="center">
<img src="https://avatars.githubusercontent.com/u/120840559?s=200&v=4" alt="ada" width="100pt" />
</p>
<p align="center"><b>ada - WHATWG-compliant and fast URL parser written in modern C++</b></p>
</a>
</td>
<td>
<a href="https://github.com/exaloop/codon">
<p align="center">
<img src="https://github.com/exaloop/codon/blob/develop/docs/img/logo.png?raw=true" alt="codon" width="100pt" />
</p>
<p align="center"><b>codon - A high-performance, zero-overhead, extensible Python compiler using LLVM</b></p>
</a>
</td>
<td>
<a href="https://github.com/RoaringBitmap/CRoaring">
<p align="center">
<img src="https://avatars.githubusercontent.com/u/16548876?s=200&v=4" alt="CRoaring" width="100pt" />
</p>
<p align="center"><b>CRoaring - Roaring bitmaps in C (and C++), with SIMD (AVX2, AVX-512 and NEON) optimizations: used by Apache Doris, ClickHouse, and StarRocks</b></p>
</a>
</td>
</tr>
</table>
@@ -367,17 +414,25 @@ CPMAddPackage(
### [Boost](https://github.com/boostorg/boost)
Boost is a large project and will take a while to download. Using
`CPM_SOURCE_CACHE` is strongly recommended. Cloning moves much more
data than a source archive, so this sample will use a compressed
source archive (tar.xz) release from Boost's github page.
```CMake
# boost is a huge project and will take a while to download
# using `CPM_SOURCE_CACHE` is strongly recommended
# boost is a huge project and directly downloading the 'alternate release'
# from github is much faster than recursively cloning the repo.
CPMAddPackage(
NAME Boost
VERSION 1.81.0
GITHUB_REPOSITORY "boostorg/boost"
GIT_TAG "boost-1.81.0"
VERSION 1.84.0
URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz
URL_HASH SHA256=2e64e5d79a738d0fa6fb546c6e5c2bd28f88d268a2a080546f74e5ff98f29d0e
OPTIONS "BOOST_ENABLE_CMAKE ON"
)
```
For a working example of using CPM to download and configure the Boost C++ Libraries see [here](examples/boost).
### [cxxopts](https://github.com/jarro2783/cxxopts)
```cmake
@@ -434,3 +489,85 @@ For a full example on using CPM to download and configure lua with sol2 see [her
### Full Examples
See the [examples directory](https://github.com/cpm-cmake/CPM.cmake/tree/master/examples) for full examples with source code and check out the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/More-Snippets) for many more example snippets.
## Source Archives from GitHub
Using a compressed source archive is usually much faster than a shallow
clone. Optionally, you can verify the integrity using
[SHA256](https://en.wikipedia.org/wiki/SHA-2) or similar. Setting the hash is useful to ensure a
specific source is imported, especially since tags, branches, and
archives can change.
Let's look at adding [spdlog](https://github.com/gabime/spdlog) to a project:
```cmake
CPMAddPackage(
NAME spdlog
URL https://github.com/gabime/spdlog/archive/refs/tags/v1.12.0.zip
URL_HASH SHA256=6174bf8885287422a6c6a0312eb8a30e8d22bcfcee7c48a6d02d1835d7769232
)
```
URL_HASH is optional, but it's a good idea for releases.
### Identifying the URL
Information for determining the URL is found
[here](https://docs.github.com/en/repositories/working-with-files/using-files/downloading-source-code-archives#source-code-archive-urls).
#### Release
Not every software package provides releases, but for those that do,
they can be found on the release page of the project. In a browser,
the URL of the specific release is determined in a browser is
determined by right clicking and selecting `Copy link address` (or
similar) for the desired release. This is the value you will use in
the URL section.
This is the URL for spdlog release 1.13.0 in zip format:
`https://github.com/gabime/spdlog/archive/refs/tags/v1.13.0.zip`
#### Branch
The URL for branches is non-obvious from a browser. But it's still fairly easy to figure it out. The format is as follows:
`https://github.com/<user>/<name>/archive/refs/heads/<branch-name>.<archive-type>`
Archive type can be one of `tar.gz` or `zip`.
The URL for branch `v2.x` of spdlog is:
`https://github.com/gabime/spdlog/archive/refs/heads/v2.x.tar.gz`
#### Tag
Tags are similar, but with this format:
`https://github.com/<user>/<name>/archive/refs/tags/<tag-name>.<archive-type>`
Tag `v1.8.5` of spdlog is this:
`https://github.com/gabime/spdlog/archive/refs/tags/v1.8.5.tar.gz`
Exactly like the release.
#### Commit
If a specific commit contains the code you need, it's defined as follows:
`https://github.com/<user>/<name>/archive/<commit-hash>.<archive-type>`
Example:
`https://github.com/gabime/spdlog/archive/c1569a3d293a6b511ecb9c18b2298826c9578d9f.tar.gz`
### Determining the Hash
The following snippet illustrates determining the SHA256 hash on a linux machine using `wget` and `sha256sum`:
```bash
wget https://github.com/gabime/spdlog/archive/refs/tags/v1.13.0.zip -O - | sha256sum
```

View File

@@ -0,0 +1,75 @@
parse:
additional_commands:
cpmaddpackage:
pargs:
nargs: '*'
flags: []
spelling: CPMAddPackage
kwargs: &cpmaddpackagekwargs
NAME: 1
FORCE: 1
VERSION: 1
GIT_TAG: 1
DOWNLOAD_ONLY: 1
GITHUB_REPOSITORY: 1
GITLAB_REPOSITORY: 1
GIT_REPOSITORY: 1
SVN_REPOSITORY: 1
SVN_REVISION: 1
SOURCE_DIR: 1
DOWNLOAD_COMMAND: 1
FIND_PACKAGE_ARGUMENTS: 1
NO_CACHE: 1
GIT_SHALLOW: 1
URL: 1
URL_HASH: 1
URL_MD5: 1
DOWNLOAD_NAME: 1
DOWNLOAD_NO_EXTRACT: 1
HTTP_USERNAME: 1
HTTP_PASSWORD: 1
EXCLUDE_FROM_ALL: 1
SYSTEM: 1
SOURCE_SUBDIR: 1
PATCHES: +
OPTIONS: +
cpmfindpackage:
pargs:
nargs: '*'
flags: []
spelling: CPMFindPackage
kwargs: *cpmaddpackagekwargs
cpmdeclarepackage:
pargs:
nargs: '*'
flags: []
spelling: CPMDeclarePackage
kwargs: *cpmaddpackagekwargs
packageproject:
pargs:
nargs: '*'
flags: []
spelling: packageProject
kwargs:
NAME: 1
VERSION: 1
NAMESPACE: 1
INCLUDE_DIR: 1
INCLUDE_DESTINATION: 1
INCLUDE_HEADER_PATTERN: 1
BINARY_DIR: 1
COMPATIBILITY: 1
VERSION_HEADER: 1
EXPORT_HEADER: 1
DISABLE_VERSION_SUFFIX: 1
CPACK: 1
DEPENDENCIES: +
cpmusepackagelock:
pargs: 1
spelling: CPMUsePackageLock
cpmregisterpackage:
pargs: 1
spelling: CPMRegisterPackage
cpmgetpackageversion:
pargs: 2
spelling: CPMGetPackageVersion

View File

@@ -5,7 +5,7 @@
# MIT License
# -----------
#[[
Copyright (c) 2019-2022 Lars Melchior and contributors
Copyright (c) 2019-2023 Lars Melchior and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -99,6 +99,12 @@ macro(cpm_set_policies)
cmake_policy(SET CMP0135 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0135 NEW)
endif()
# treat relative git repository paths as being relative to the parent project's remote
if(POLICY CMP0150)
cmake_policy(SET CMP0150 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0150 NEW)
endif()
endmacro()
cpm_set_policies()
@@ -294,12 +300,6 @@ function(CPMFindPackage)
return()
endif()
cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}")
if(CPM_PACKAGE_ALREADY_ADDED)
cpm_export_variables(${CPM_ARGS_NAME})
return()
endif()
cpm_find_package(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" ${CPM_ARGS_FIND_PACKAGE_ARGUMENTS})
if(NOT CPM_PACKAGE_FOUND)
@@ -391,8 +391,8 @@ function(cpm_parse_add_package_single_arg arg outArgs)
# We don't try to parse the version if it's not provided explicitly. cpm_get_version_from_url
# should do this at a later point
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.
# We should never get here. This is an assertion and hitting it means there's a problem with the
# code above. A packageType was set, but not handled by this if-else.
message(FATAL_ERROR "${CPM_INDENT} Unsupported package type '${packageType}' of '${arg}'")
endif()
@@ -464,6 +464,69 @@ function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean)
endfunction()
# Add PATCH_COMMAND to CPM_ARGS_UNPARSED_ARGUMENTS. This method consumes a list of files in ARGN
# then generates a `PATCH_COMMAND` appropriate for `ExternalProject_Add()`. This command is appended
# to the parent scope's `CPM_ARGS_UNPARSED_ARGUMENTS`.
function(cpm_add_patches)
# Return if no patch files are supplied.
if(NOT ARGN)
return()
endif()
# Find the patch program.
find_program(PATCH_EXECUTABLE patch)
if(WIN32 AND NOT PATCH_EXECUTABLE)
# The Windows git executable is distributed with patch.exe. Find the path to the executable, if
# it exists, then search `../../usr/bin` for patch.exe.
find_package(Git QUIET)
if(GIT_EXECUTABLE)
get_filename_component(extra_search_path ${GIT_EXECUTABLE} DIRECTORY)
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY)
get_filename_component(extra_search_path ${extra_search_path} DIRECTORY)
find_program(PATCH_EXECUTABLE patch HINTS "${extra_search_path}/usr/bin")
endif()
endif()
if(NOT PATCH_EXECUTABLE)
message(FATAL_ERROR "Couldn't find `patch` executable to use with PATCHES keyword.")
endif()
# Create a temporary
set(temp_list ${CPM_ARGS_UNPARSED_ARGUMENTS})
# Ensure each file exists (or error out) and add it to the list.
set(first_item True)
foreach(PATCH_FILE ${ARGN})
# Make sure the patch file exists, if we can't find it, try again in the current directory.
if(NOT EXISTS "${PATCH_FILE}")
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}")
message(FATAL_ERROR "Couldn't find patch file: '${PATCH_FILE}'")
endif()
set(PATCH_FILE "${CMAKE_CURRENT_LIST_DIR}/${PATCH_FILE}")
endif()
# Convert to absolute path for use with patch file command.
get_filename_component(PATCH_FILE "${PATCH_FILE}" ABSOLUTE)
# The first patch entry must be preceded by "PATCH_COMMAND" while the following items are
# preceded by "&&".
if(first_item)
set(first_item False)
list(APPEND temp_list "PATCH_COMMAND")
else()
list(APPEND temp_list "&&")
endif()
# Add the patch command to the list
list(APPEND temp_list "${PATCH_EXECUTABLE}" "-p1" "<" "${PATCH_FILE}")
endforeach()
# Move temp out into parent scope.
set(CPM_ARGS_UNPARSED_ARGUMENTS
${temp_list}
PARENT_SCOPE
)
endfunction()
# method to overwrite internal FetchContent properties, to allow using CPM.cmake to overload
# FetchContent calls. As these are internal cmake properties, this method should be used carefully
# and may need modification in future CMake versions. Source:
@@ -505,60 +568,6 @@ 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()
@@ -566,6 +575,7 @@ 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 and SYSTEM
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;")
endif()
@@ -581,37 +591,21 @@ function(CPMAddPackage)
BITBUCKET_REPOSITORY
GIT_REPOSITORY
SOURCE_DIR
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS
NO_CACHE
SYSTEM
GIT_SHALLOW
EXCLUDE_FROM_ALL
SOURCE_SUBDIR
CUSTOM_CACHE_KEY
)
set(multiValueArgs URL OPTIONS)
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND PATCHES)
# 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)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}")
# 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)
@@ -697,6 +691,7 @@ function(CPMAddPackage)
SOURCE_DIR "${PACKAGE_SOURCE}"
EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}"
SYSTEM "${CPM_ARGS_SYSTEM}"
PATCHES "${CPM_ARGS_PATCHES}"
OPTIONS "${CPM_ARGS_OPTIONS}"
SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}"
DOWNLOAD_ONLY "${DOWNLOAD_ONLY}"
@@ -752,6 +747,8 @@ function(CPMAddPackage)
set(CPM_FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps)
endif()
cpm_add_patches(${CPM_ARGS_PATCHES})
if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND})
elseif(DEFINED CPM_ARGS_SOURCE_DIR)
@@ -774,7 +771,10 @@ function(CPMAddPackage)
string(TOLOWER ${CPM_ARGS_NAME} lower_case_name)
set(origin_parameters ${CPM_ARGS_UNPARSED_ARGUMENTS})
list(SORT origin_parameters)
if(CPM_USE_NAMED_CACHE_DIRECTORIES)
if(CPM_ARGS_CUSTOM_CACHE_KEY)
# Application set a custom unique directory name
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${CPM_ARGS_CUSTOM_CACHE_KEY})
elseif(CPM_USE_NAMED_CACHE_DIRECTORIES)
string(SHA1 origin_hash "${origin_parameters};NEW_CACHE_STRUCTURE_TAG")
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}/${CPM_ARGS_NAME})
else()
@@ -866,7 +866,7 @@ 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)
if(CPM_SOURCE_CACHE AND download_directory)
file(LOCK ${download_directory}/../cmake.lock RELEASE)
endif()
if(${populated})
@@ -985,7 +985,8 @@ function(cpm_declare_fetch PACKAGE VERSION INFO)
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
@@ -1164,16 +1165,18 @@ function(cpm_prettify_package_arguments OUT_VAR IS_IN_COMMENT)
DOWNLOAD_ONLY
GITHUB_REPOSITORY
GITLAB_REPOSITORY
BITBUCKET_REPOSITORY
GIT_REPOSITORY
SOURCE_DIR
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS
NO_CACHE
SYSTEM
GIT_SHALLOW
EXCLUDE_FROM_ALL
SOURCE_SUBDIR
)
set(multiValueArgs OPTIONS)
cmake_parse_arguments(PARSE_ARGV 2 CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}")
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
foreach(oneArgName ${oneValueArgs})
if(DEFINED CPM_ARGS_${oneArgName})

View File

@@ -1,4 +1,9 @@
# SPDX-License-Identifier: MIT
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
set(CPM_DOWNLOAD_VERSION 1.0.0-development-version)
set(CPM_HASH_SUM "CPM_HASH_SUM_PLACEHOLDER")
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
@@ -11,23 +16,9 @@ endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
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}
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
)
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

@@ -32,13 +32,13 @@ function(ASSERT_DEFINED KEY)
if(DEFINED ${KEY})
message(STATUS "test passed: '${KEY}' is defined")
else()
message(FATAL_ERROR "assertion failed: '${KEY}' is not defiend")
message(FATAL_ERROR "assertion failed: '${KEY}' is not defined")
endif()
endfunction()
function(ASSERT_NOT_DEFINED KEY)
if(DEFINED ${KEY})
message(FATAL_ERROR "assertion failed: '${KEY}' is defiend (${${KEY}})")
message(FATAL_ERROR "assertion failed: '${KEY}' is defined (${${KEY}})")
else()
message(STATUS "test passed: '${KEY}' is not defined")
endif()

View File

@@ -13,9 +13,10 @@ include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME Boost
VERSION 1.81.0
GITHUB_REPOSITORY "boostorg/boost"
GIT_TAG "boost-1.81.0"
VERSION 1.84.0
URL https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.xz
URL_HASH SHA256=2e64e5d79a738d0fa6fb546c6e5c2bd28f88d268a2a080546f74e5ff98f29d0e
OPTIONS "BOOST_ENABLE_CMAKE ON" "BOOST_INCLUDE_LIBRARIES container\\\;asio" # Note the escapes!
)
target_link_libraries(CPMExampleBoost PRIVATE Boost::asio)
target_link_libraries(CPMExampleBoost PRIVATE Boost::asio Boost::container)

View File

@@ -9,14 +9,22 @@
//
#include <boost/asio.hpp>
#include <boost/container/devector.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <iostream>
#include <string>
void print(const boost::system::error_code& /*e*/) { std::cout << "Hello, world!" << std::endl; }
boost::container::devector<std::string> strings;
void print(const boost::system::error_code& /*e*/) {
for (const auto& a : strings) std::cout << a;
}
int main() {
boost::asio::io_service io;
strings.push_back("Hello, world!\n");
boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
t.async_wait(&print);

View File

@@ -7,7 +7,7 @@ project(CPMExampleCatch2)
include(../../cmake/CPM.cmake)
CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage("gh:catchorg/Catch2@3.2.1")
CPMAddPackage("gh:catchorg/Catch2@3.4.0")
# ---- Create binary ----

View File

@@ -9,8 +9,7 @@ include(../../cmake/CPM.cmake)
CPMAddPackage(
NAME EnTT
VERSION 3.1.1
GITHUB_REPOSITORY skypjack/entt
# EnTT's CMakeLists screws with configuration options
GITHUB_REPOSITORY skypjack/entt # EnTT's CMakeLists screws with configuration options
DOWNLOAD_ONLY True
)

View File

@@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMExamplePatchHighway)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
# Google's highway Includes a SIMD sorting function that is faster than x86-simd-sort for larger
# arrays. See: https://github.com/google/highway/blob/master/g3doc/quick_reference.md
CPMAddPackage(
NAME highway
URL https://github.com/google/highway/archive/refs/tags/1.1.0.tar.gz
URL_HASH SHA256=354a8b4539b588e70b98ec70844273e3f2741302c4c377bcc4e81b3d1866f7c9
PATCHES "highway.patch" # This adds SYSTEM to the includes.
OPTIONS "HWY_ENABLE_EXAMPLES OFF" "HWY_ENABLE_INSTALL OFF" "HWY_ENABLE_TESTS OFF"
)
# ---- Executable ----
if(LINUX)
# This would cause a float compare error inside the highway header code if the patch is NOT
# applied.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wfloat-equal")
endif()
add_executable(CPMExamplePatchHighway "main.cpp")
target_link_libraries(CPMExamplePatchHighway hwy hwy_contrib)

View File

@@ -0,0 +1,28 @@
Common subdirectories: a/.bcr and b/.bcr
Common subdirectories: a/.github and b/.github
diff -u a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt 2024-05-21 12:50:37.738318520 -0500
+++ b/CMakeLists.txt 2024-05-21 12:49:59.914226871 -0500
@@ -350,7 +350,7 @@
target_compile_options(hwy PRIVATE ${HWY_FLAGS})
set_property(TARGET hwy PROPERTY POSITION_INDEPENDENT_CODE ON)
set_target_properties(hwy PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION})
-target_include_directories(hwy PUBLIC
+target_include_directories(hwy SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_features(hwy PUBLIC cxx_std_11)
@@ -370,7 +370,7 @@
target_compile_options(hwy_contrib PRIVATE ${HWY_FLAGS})
set_property(TARGET hwy_contrib PROPERTY POSITION_INDEPENDENT_CODE ON)
set_target_properties(hwy_contrib PROPERTIES VERSION ${LIBRARY_VERSION} SOVERSION ${LIBRARY_SOVERSION})
-target_include_directories(hwy_contrib PUBLIC
+target_include_directories(hwy_contrib SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_features(hwy_contrib PUBLIC cxx_std_11)
Common subdirectories: a/cmake and b/cmake
Common subdirectories: a/debian and b/debian
Common subdirectories: a/docs and b/docs
Common subdirectories: a/g3doc and b/g3doc
Common subdirectories: a/hwy and b/hwy

27
examples/highway/main.cpp Normal file
View File

@@ -0,0 +1,27 @@
#include <hwy/contrib/sort/vqsort.h> // hwy::VQSort() for large data sets
#include <cstdint>
#include <random>
#include <vector>
// Use hwy::VQSort to sort larger vectors
inline void sort_large(std::vector<double>& v) {
hwy::VQSort(v.data(), v.size(), hwy::SortAscending{});
}
int main(int, char**) {
std::random_device random_device;
std::default_random_engine random_engine(random_device());
std::uniform_real_distribution<double> uniform_dist(0.0, 100.0);
const std::size_t sz = 100000;
std::vector<double> v;
v.reserve(sz);
for (std::size_t i = 0; i < sz; ++i) {
v.push_back(uniform_dist(random_engine));
}
sort_large(v);
return 0;
}

View File

@@ -56,7 +56,7 @@ int main(int argc, char **argv) {
int len = atoi(line + 11);
linenoiseHistorySetMaxLen(len);
} else if (line[0] == '/') {
printf("Unreconized command: %s\n", line);
printf("Unrecognized command: %s\n", line);
}
free(line);
}

View File

@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMSIMDJSONExample)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
CPMAddPackage("gh:simdjson/simdjson@3.5.0")
# ---- Executable ----
add_executable(CPMSIMDJSONExample main.cpp)
target_compile_features(CPMSIMDJSONExample PRIVATE cxx_std_17)
target_link_libraries(CPMSIMDJSONExample simdjson::simdjson)

View File

@@ -0,0 +1,31 @@
#include <iostream>
#include "simdjson.h"
using namespace simdjson;
int main() {
ondemand::parser parser;
auto cars_json = R"( [
{ "make": "Toyota", "model": "Camry", "year": 2018, "tire_pressure": [ 40.1, 39.9, 37.7, 40.4 ] },
{ "make": "Kia", "model": "Soul", "year": 2012, "tire_pressure": [ 30.1, 31.0, 28.6, 28.7 ] },
{ "make": "Toyota", "model": "Tercel", "year": 1999, "tire_pressure": [ 29.8, 30.0, 30.2, 30.5 ] }
] )"_padded;
// Iterating through an array of objects
for (ondemand::object car : parser.iterate(cars_json)) {
// Accessing a field by name
std::cout << "Make/Model: " << std::string_view(car["make"]) << "/"
<< std::string_view(car["model"]) << std::endl;
// Casting a JSON element to an integer
uint64_t year = car["year"];
std::cout << "- This car is " << 2020 - year << " years old." << std::endl;
// Iterating through an array of floats
double total_tire_pressure = 0;
for (double tire_pressure : car["tire_pressure"]) {
total_tire_pressure += tire_pressure;
}
std::cout << "- Average tire pressure: " << (total_tire_pressure / 4) << std::endl;
}
}

View File

@@ -9,7 +9,7 @@ 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:
# can let spdlog reuse fmt from CPM.cmake like this:
#
# cmake-format: off
#

View File

@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMxxHashExample)
# ---- Dependencies ----
include(../../cmake/CPM.cmake)
CPMAddPackage(
GITHUB_REPOSITORY Cyan4973/xxHash
GIT_TAG v0.8.2
OPTIONS "XXHASH_BUILD_ENABLE_INLINE_API OFF" "XXHASH_BUILD_XXHSUM OFF"
SOURCE_SUBDIR cmake_unofficial
)
# ---- Executable ----
add_executable(CPMxxHashExample main.cpp)
target_compile_features(CPMxxHashExample PRIVATE cxx_std_17)
target_link_libraries(CPMxxHashExample xxHash::xxhash)

12
examples/xxHash/main.cpp Normal file
View File

@@ -0,0 +1,12 @@
#include <xxh3.h>
#include <iostream>
int main() {
std::string example = "Hello World!";
XXH64_hash_t hash = XXH3_64bits(example.data(), example.size());
std::cout << "Hash: " << hash << std::endl;
return 0;
}

View File

@@ -34,7 +34,7 @@ Writing tests makes use of the custom integration test framework in `lib.rb`. It
* There should be no dependency between the test scripts. Each should be executable individually and the order in which multiple ones are executed mustn't matter.
* The class should contain methods, also prefixed with `test_` which will be executed by the framework. In most cases there would be a single test method per class.
* In case there are multiple test methods, they will be executed in the order in which they are defined.
* The test methods should contain assertions which check for the expected state of things at varous points of the test's execution.
* The test methods should contain assertions which check for the expected state of things at various points of the test's execution.
### More

View File

@@ -143,7 +143,7 @@ class Project
end
class IntegrationTest < Test::Unit::TestCase
self.test_order = :defined # run tests in order of defintion (as opposed to alphabetical)
self.test_order = :defined # run tests in order of definition (as opposed to alphabetical)
def cleanup
# Clear cpm-related env vars which may have been set by the test

View File

@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(using-patch-adder)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include("%{cpm_path}")
%{packages}
add_executable(using-patch-adder using-patch-adder.cpp)
target_link_libraries(using-patch-adder adder)

View File

@@ -0,0 +1,12 @@
diff --git a/code/adder/adder.hpp b/code/adder/adder.hpp
index fdb9324..7c2fa00 100644
--- a/code/adder/adder.hpp
+++ b/code/adder/adder.hpp
@@ -1,6 +1,6 @@
#pragma once
-namespace adder
+namespace patched
{
int add(int a, int b);
}

View File

@@ -0,0 +1,12 @@
diff --git a/code/adder/adder.cpp b/code/adder/adder.cpp
index fc6e767..44b1197 100644
--- a/code/adder/adder.cpp
+++ b/code/adder/adder.cpp
@@ -1,6 +1,6 @@
#include "adder.hpp"
-namespace adder
+namespace patched
{
int add(int a, int b)
{

View File

@@ -0,0 +1,8 @@
#include <adder/adder.hpp>
#include <cstdio>
int main() {
int sum = patched::add(5, 3);
std::printf("%d\n", sum);
return 0;
}

View File

@@ -0,0 +1,25 @@
require_relative './lib'
# Tests using a multi-argumenet download command to fetch a dependency
class DownloadCommand < IntegrationTest
def test_fetch_dependency_using_download_command
prj = make_project from_template: 'using-adder'
prj.create_lists_from_default_template package: <<~PACK
set(DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/_deps/testpack-adder-src)
CPMAddPackage(
NAME testpack-adder
SOURCE_DIR ${DOWNLOAD_DIR}
DOWNLOAD_COMMAND git clone --depth 1 --branch v1.0.0 https://github.com/cpm-cmake/testpack-adder.git ${DOWNLOAD_DIR}
OPTIONS "ADDER_BUILD_TESTS OFF"
)
PACK
# configure with unpopulated cache
assert_success prj.configure
assert_success prj.build
end
end

View File

@@ -0,0 +1,27 @@
require_relative './lib'
# Tests using a multi-argumenet PATCHES command to fetch and modify a dependency
class DownloadCommand < IntegrationTest
def test_fetch_dependency_using_download_command
prj = make_project from_template: 'using-patch-adder'
prj.create_lists_from_default_template package: <<~PACK
set(DOWNLOAD_DIR ${CMAKE_BINARY_DIR}/_deps/testpack-adder-src)
CPMAddPackage(
NAME testpack-adder
DOWNLOAD_COMMAND git clone --depth 1 --branch v1.0.0 https://github.com/cpm-cmake/testpack-adder.git ${DOWNLOAD_DIR}
OPTIONS "ADDER_BUILD_TESTS OFF" "ADDER_BUILD_EXAMPLES OFF"
PATCHES
patches/001-test_patches_command.patch
patches/002-test_patches_command.patch
)
PACK
# configure with unpopulated cache
assert_success prj.configure
assert_success prj.build
end
end

View File

@@ -0,0 +1,17 @@
require_relative './lib'
class RelativeURLs < IntegrationTest
def setup
# relative URLs were introduced in CMake 3.27
@relative_urls_supported = (!ENV['CMAKE_VERSION']) || (Gem::Version.new(ENV['CMAKE_VERSION']) >= Gem::Version.new('3.27'))
end
def test_add_project_with_relative_urls
omit_if !@relative_urls_supported do
prj = make_project from_template: 'using-fibadder'
prj.create_lists_from_default_template package: 'CPMAddPackage("gh:cpm-cmake/testpack-fibadder@1.1.0-relative-urls")'
assert_success prj.configure
assert_success prj.build
end
end
end

View File

@@ -70,7 +70,7 @@ class Simple < IntegrationTest
exes = Dir[exe_dir + '/**/*'].filter {
# on multi-configuration generators (like Visual Studio) the executables will be in bin/<Config>
# also filter-out other articacts like .pdb or .dsym
# also filter-out other artifacts like .pdb or .dsym
!File.directory?(_1) && File.stat(_1).executable?
}.map {
# remove .exe extension if any (there will be one on Windows)

View File

@@ -14,7 +14,7 @@ class MyTest < IntegrationTest
end
```
Now we have our test case class, and the single test method that we will require. Let's focus on the method's contents. The integration test framework provides us with a helper class, `Project`, which can be used for this scenario. A project has an assoiciated pair of source and binary directories in the temporary directory and it provides methods to work with them.
Now we have our test case class, and the single test method that we will require. Let's focus on the method's contents. The integration test framework provides us with a helper class, `Project`, which can be used for this scenario. A project has an associated pair of source and binary directories in the temporary directory and it provides methods to work with them.
We start by creating the project:

View File

@@ -137,3 +137,19 @@ execute_process(
assert_equal(${ret} "0")
assert_not_exists("${CPM_SOURCE_CACHE_DIR}/fibonacci")
# Use custom cache directory
set(FIBONACCI_PACKAGE_ARGS
"CUSTOM_CACHE_KEY my_custom_unique_dir GIT_TAG e9ebf168ca0fffaa4ef8c6fefc6346aaa22f6ed5"
)
set(FIBONACCI_VERSION 1.1)
update_cmake_lists()
execute_process(
COMMAND ${CMAKE_COMMAND} -E env "CPM_SOURCE_CACHE=${CPM_SOURCE_CACHE_DIR}" ${CMAKE_COMMAND}
"-S${CMAKE_CURRENT_LIST_DIR}/remote_dependency" "-B${TEST_BUILD_DIR}" RESULT_VARIABLE ret
)
assert_equal(${ret} "0")
assert_exists("${CPM_SOURCE_CACHE_DIR}/fibonacci/my_custom_unique_dir")

View File

@@ -1,69 +0,0 @@
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,8 +2,6 @@ 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)