Compare commits

...

20 Commits

Author SHA1 Message Date
Andrea Barbadoro
f552da96bd Detecting when the cache is dirty (#284)
* Check that the cache working directory is clean

* cpm_check_working_dir_is_clean for non git repo will not terminate cmake

* sileneced check for git repo, in case of error

* style(CPM.cmake): fixed indentation for ERROR_QUIET

* refactor(CPM.cmake): added logic to handle a cache folder inside a (not correlated) git repo

this is accomplished by checking if we are in the directory where .git lives

* style(CPM.cmake): stray tab to spaces

* test(dirty-cache-check): added unit test to check cpm_check_working_dir_is_clean

the test creates a file in a folder and then uses git to create a repo in that folder, to check various conditions

* Update test/unit/dirty-cache-check.cmake

added user.name and user.email to comply with test machine where git is not completely configured

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

* feat(cpm_check_working_dir_is_clean): now it takes a git tag (works with hashes too) to check for uncommitted and commited changes

* refactor(cpm_check_working_dir_is_clean): early return for the most common case of uncommited changes in a repo

* refactor(cpm_check_git_working_dir_is_clean): removed edgecase detection (a non-git folder in an unrelated git repo)

now the contract is that com_check_git_working_dir_is_clean is given the base folder of a git repo

Co-authored-by: Andrew Gribble <ag131012@renishaw.com>
Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2021-09-15 11:38:49 +02:00
Olivier Le Doeuff
ea6a8eb895 Fix CPMAddPackage when FetchContent_MakeAvailable already added package (#288)
Add fetchcontent_dependency unit test:
* This test should highlight the fact that cpm_add_subdirectory is always called, even when
  cpm_fetch_package isn't populating the dependency
* NO_CACHE YES highlight a bug introduced in 32b063eba5 where
  cpm_fetch_package was checking undefined ${lower_case_name}_POPULATED variable

https://github.com/cpm-cmake/CPM.cmake/issues/287
2021-08-29 22:02:18 +02:00
MixusMinimax
a5c22bf6e8 use quotes for CPM_FILE when creating FIND.cmake (#286) 2021-08-29 22:01:50 +02:00
Lars Melchior
c5cb85b2f1 Build examples in CI using GitHub (#283)
* build examples in CI using github

* update cxxopts style
2021-08-29 20:27:10 +02:00
pgorgon-hem
91585e3864 Added support for bitbucket repositories (#256)
* Added support for bitbucket repositories:
* added variable BITBUCKET_REPOSITORY
* added short syntax in form "bb:user/repo"
* added description of that to readme.md

* Added test for bitbucket short syntax

* Used elseif syntax in handling of git services (github, gitlab, bitbucket).

* Added HEMRND/TestingFramework example located on bitbucket.org

* Reformatted CMakeLists.txt in TestingFramework example

* Bumped version of TestingFramework. It supports older version of c++ standard.

Co-authored-by: Paweł Gorgoń <pgorgon@hem-e.com>
2021-06-08 19:15:40 +02:00
Stuart Dootson
9675d46517 Expand relative download directory to prevent unnecessary download (#267)
* Expand relative download directory to prevent unnecessary download

If `CMAKE_SOURCE_CACHE` (and thus `download_directory`) is set to a relative path, the condition `if(EXISTS ${download_directory})` will fail even if the required directory exists. Expanding the variable `download_directory` to an absolute path before the test will rectify this, preventing unnecessary downloads of the sources.

* iFixed up formatting

Co-authored-by: Stuart Dootson <stuart.dootson@rolls-royce.com>
2021-06-08 19:12:20 +02:00
Lars Melchior
7078e8286a Remove branch name references from README (#265)
As noted in #263, setting `GIT_TAG` to a branch name results in unexpected and unreproducible build behaviour, as it does not automatically update when the `HEAD` changes.
2021-06-08 15:55:03 +03:00
Lars Melchior
6a0277f16e Update CMake to 3.20 for integration tests (#264)
This allows us to use more recent projects in the examples
2021-06-08 15:27:31 +03:00
Lars Melchior
4502bf1e04 Forward exclude and subdir options when using local package override (#261)
* forward exclude and subdir options when using local package override.
fixes #260.

* run cmake format

* add SOURCE_SUBDIR parameter to cmake-format
2021-06-08 15:26:39 +03:00
Clare Macrae
dd3ba9792c Fix typo in README - omit -> emit (#258) 2021-06-02 09:36:29 +03:00
Lars Melchior
de5551e42c Update boost-cmake (#252)
* update boost-cmake

* run cmake-format
2021-05-18 16:29:52 +03:00
Paul Taylor
7644c3a40f Respect FETCHCONTENT_BASE_DIR if set by a user (#244)
* Respect `FETCHCONTENT_BASE_DIR` if set by a user

* Use a single `CPM_FETCHCONTENT_BASE_DIR` var
2021-04-16 17:27:51 +02:00
Lars Melchior
310efb9b17 Update more examples from the readme (#241)
* update examples from the readme

* add explainations to the examples
2021-03-26 18:31:35 +02:00
Lars Melchior
4fad2eac0a remove option consistency check (#240) 2021-03-25 19:24:44 +02:00
flagarde
ee08119642 Scope package options to avoid changing the local scope (#235)
* Fix #222

* Fix #222

* move policy change and local options to cpm_add_subdirectory

* change default policy as well

see https://gitlab.kitware.com/cmake/cmake/-/issues/20312

* add test

* update check to not use the NOT operator

(interestingly it works as expected locally)

* simplify test by not using options

* check options in tests

Co-authored-by: Lars Melchior <TheLartians@users.noreply.github.com>
2021-03-25 15:59:34 +01:00
Lars Melchior
259f1be8e2 update cxxopts and add reasonable options (#239) 2021-03-25 14:20:06 +02:00
Lars Melchior
32b063eba5 Fix support for source subdirectories (#238)
* add support for source subdirectories

* style fixes

* remove debug log

* grammar fix in comment
2021-03-25 10:42:51 +01:00
Lars Melchior
d64d816585 Make CPMFindPackage less prominent in the Readme (#236)
Giving `CPMFindPackage` a less prominent position, as in almost all cases, `CPMAddPackage` should be preferred.

Following a related discussion in #222.
2021-03-22 12:37:11 +01:00
Lars Melchior
8e8dcc9a8d moved test repostitory to CPM.cmake namespace (#228) 2021-03-04 11:01:01 +02:00
Lars Melchior
8afc2af4f9 update more examples to use shorthand syntax (#223)
* update more examples to use shorthand syntax

* revert google-benchmark as tests require googletest to be installed

* update comments

* always quote single-arguments

* undo accidental deletion
2021-02-25 09:53:28 +02:00
33 changed files with 553 additions and 247 deletions

View File

@@ -34,6 +34,7 @@ parse:
HTTP_USERNAME: 1 HTTP_USERNAME: 1
HTTP_PASSWORD: 1 HTTP_PASSWORD: 1
EXCLUDE_FROM_ALL: 1 EXCLUDE_FROM_ALL: 1
SOURCE_SUBDIR: 1
OPTIONS: + OPTIONS: +
cpmfindpackage: cpmfindpackage:
pargs: pargs:

30
.github/workflows/examples.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: Examples
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
gcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: build all
env:
CC: gcc
CXX: g++
run: python3 examples/build_all.py
clang:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: build all
env:
CC: clang
CXX: clang++
run: python3 examples/build_all.py

View File

@@ -1,50 +0,0 @@
language: cpp
sudo: require
dist: xenial
common_sources: &all_sources
- ubuntu-toolchain-r-test
- llvm-toolchain-trusty
python:
- 3.7
matrix:
include:
- os: linux
compiler: gcc
addons: &gcc8
apt:
sources: *all_sources
packages:
- g++-8
env:
- MATRIX_EVAL="export CC=gcc-8; export CXX=g++-8;"
- os: linux
compiler: clang
addons:
apt:
sources: *all_sources
packages:
- g++-8
- clang-6.0
env:
- MATRIX_EVAL="export CC=clang-6.0; export CXX=clang++-6.0;"
before_install:
# Update compilers
- eval "${MATRIX_EVAL}"
- echo "CC=$CC CXX=$CXX"
# Install a supported cmake version (>= 3.14)
- wget -O cmake.sh https://cmake.org/files/v3.14/cmake-3.14.0-Linux-x86_64.sh
- sudo sh cmake.sh --skip-license --exclude-subdir --prefix=/usr/local
- export PATH=/usr/local/bin:$PATH
- cmake --version
script:
# unit tests
- cmake -Htest -Bbuild/test
- cmake --build build/test --target test-verbose
# build examples
- python3 examples/build_all.py

122
README.md
View File

@@ -27,9 +27,9 @@ For everything else, the targets can be created manually after the dependency ha
## Usage ## Usage
After `CPM.cmake` has been [added](#adding-cpm) to your project, the function `CPMAddPackage` or `CPMFindPackage` can be used to fetch and configure a dependency. After `CPM.cmake` has been [added](#adding-cpm) to your project, the function `CPMAddPackage` can be used to fetch and configure a dependency.
Afterwards, any targets defined in the dependency can be used directly. Afterwards, any targets defined in the dependency can be used directly.
`CPMFindPackage` and `CPMAddPackage` take the following named parameters. `CPMAddPackage` takes the following named parameters.
```cmake ```cmake
CPMAddPackage( CPMAddPackage(
@@ -44,8 +44,7 @@ CPMAddPackage(
The origin may be specified by a `GIT_REPOSITORY`, but other sources, such as direct URLs, are [also supported](https://cmake.org/cmake/help/v3.11/module/ExternalProject.html#external-project-definition). The origin may be specified by a `GIT_REPOSITORY`, but other sources, such as direct URLs, are [also supported](https://cmake.org/cmake/help/v3.11/module/ExternalProject.html#external-project-definition).
If `GIT_TAG` hasn't been explicitly specified it defaults to `v(VERSION)`, a common convention for git projects. If `GIT_TAG` hasn't been explicitly specified it defaults to `v(VERSION)`, a common convention for git projects.
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. 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` to always download the most recent version. `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.
The optional argument `FIND_PACKAGE_ARGUMENTS` can be specified to a string of parameters that will be passed to `find_package` if enabled (see below).
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 `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.
@@ -54,13 +53,13 @@ A single-argument compact syntax is also supported:
```cmake ```cmake
# A git package from a given uri with a version # A git package from a given uri with a version
CPMAddPackage("uri@version") CPMAddPackage("uri@version")
# A git package from a given uri with a git tag or commit hash, or branch name # A git package from a given uri with a git tag or commit hash
CPMAddPackage("uri#tag") CPMAddPackage("uri#tag")
# A git package with both version and tag provided # A git package with both version and tag provided
CPMAddPackage("uri@version#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 coverted to `https://gitlab.com/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) flag.
The single-argument syntax also works for URLs: The single-argument syntax also works for URLs:
@@ -73,14 +72,15 @@ CPMAddPackage("https://example.com/my-package-1.2.3.zip#MD5=68e20f674a48be38d60e
CPMAddPackage("https://example.com/my-package.zip@1.2.3") CPMAddPackage("https://example.com/my-package.zip@1.2.3")
``` ```
After calling `CPMAddPackage` or `CPMFindPackage`, the following variables are defined in the local scope, where `<dependency>` is the name of the dependency. After calling `CPMAddPackage`, the following variables are defined in the local scope, where `<dependency>` is the name of the dependency.
- `<dependency>_SOURCE_DIR` is the path to the source of the dependency. - `<dependency>_SOURCE_DIR` is the path to the source of the dependency.
- `<dependency>_BINARY_DIR` is the path to the build directory of the dependency. - `<dependency>_BINARY_DIR` is the path to the build directory of the dependency.
- `<dependency>_ADDED` is set to `YES` if the dependency has not been added before, otherwise it is set to `NO`. - `<dependency>_ADDED` is set to `YES` if the dependency has not been added before, otherwise it is set to `NO`.
The difference between `CPMFindPackage` and `CPMAddPackage` is that `CPMFindPackage` will try to find a local dependency via CMake's `find_package` and fallback to `CPMAddPackage` if the dependency is not found. For using CPM.cmake projects with external package managers, such as conan or vcpkg, setting the variable [`CPM_USE_LOCAL_PACKAGES`](#options) will make CPM.cmake try to add a package through `find_package` first, and add it from source if it doesn't succeed.
This behaviour can be also modified globally via [CPM options](#options).
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.
## Full CMakeLists Example ## Full CMakeLists Example
@@ -156,8 +156,7 @@ CPM.cmake is a wrapper for CMake's FetchContent module and adds a number of feat
The most notable features are: The most notable features are:
- A simpler to use API - A simpler to use API
- Version checking: CPM.cmake will check the version number of any added dependency and omit a warning if another dependency requires a more recent version. - Version checking: CPM.cmake will check the version number of any added dependency and emit a warning if another dependency requires a more recent version.
- Options: any Options passed to a dependency are stored and compared on later use, so if another dependency tries to add an existing dependency with incompatible options a warning will be emitted to the user.
- Offline builds: CPM.cmake will override CMake's download and update commands, which allows new builds to be configured while offline if all dependencies [are available locally](#cpm_source_cache). - Offline builds: CPM.cmake will override CMake's download and update commands, which allows new builds to be configured while offline if all dependencies [are available locally](#cpm_source_cache).
- Automatic shallow clone: if a version tag (e.g. `v2.2.0`) is provided and `CPM_SOURCE_CACHE` is used, CPM.cmake will perform a shallow clone of the dependency, which should be significantly faster while using less storage than a full clone. - Automatic shallow clone: if a version tag (e.g. `v2.2.0`) is provided and `CPM_SOURCE_CACHE` is used, CPM.cmake will perform a shallow clone of the dependency, which should be significantly faster while using less storage than a full clone.
- Overridable: all `CPMAddPackage` can be configured to use `find_package` by setting a [CMake flag](#cpm_use_local_packages), making it easy to integrate into projects that may require local versioning through the system's package manager. - Overridable: all `CPMAddPackage` can be configured to use `find_package` by setting a [CMake flag](#cpm_use_local_packages), making it easy to integrate into projects that may require local versioning through the system's package manager.
@@ -195,6 +194,8 @@ CPM can be configured to use `find_package` to search for locally installed depe
If the option `CPM_LOCAL_PACKAGES_ONLY` is set, CPM will emit an error if the dependency is not found locally. 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. 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`.
## Local package override ## Local package override
Library developers are often in the situation where they work on a locally checked out dependency at the same time as on a consumer project. Library developers are often in the situation where they work on a locally checked out dependency at the same time as on a consumer project.
@@ -266,42 +267,48 @@ See the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/More-Snippets) for mo
### [Catch2](https://github.com/catchorg/Catch2) ### [Catch2](https://github.com/catchorg/Catch2)
```cmake ```cmake
CPMAddPackage(gh:catchorg/Catch2@2.5.0) CPMAddPackage("gh:catchorg/Catch2@2.5.0")
``` ```
### [Boost (via boost-cmake)](https://github.com/Orphis/boost-cmake) ### [Boost (via boost-cmake)](https://github.com/Orphis/boost-cmake)
```CMake ```CMake
CPMAddPackage(gh:Orphis/boost-cmake@1.67.0) # boost-cmake currently doesn't tag versions, so we use the according boost version
``` CPMAddPackage("gh:Orphis/boost-cmake#7f97a08b64bd5d2e53e932ddf80c40544cf45edf@1.71.0")
### [cxxopts](https://github.com/jarro2783/cxxopts)
```cmake
CPMAddPackage(
NAME cxxopts
GITHUB_REPOSITORY jarro2783/cxxopts
VERSION 2.2.0
OPTIONS
"CXXOPTS_BUILD_EXAMPLES Off"
"CXXOPTS_BUILD_TESTS Off"
)
``` ```
### [Yaml-cpp](https://github.com/jbeder/yaml-cpp) ### [Yaml-cpp](https://github.com/jbeder/yaml-cpp)
```CMake ```CMake
# as the tag is in an unusual format, we need to explicitly specify the version
CPMAddPackage("gh:jbeder/yaml-cpp#yaml-cpp-0.6.3@0.6.3")
```
### [Range-v3](https://github.com/ericniebler/range-v3)
```Cmake
CPMAddPackage("gh:ericniebler/range-v3#0.11.0")
```
### [nlohmann/json](https://github.com/nlohmann/json)
```cmake
CPMAddPackage( CPMAddPackage(
NAME yaml-cpp NAME nlohmann_json
GITHUB_REPOSITORY jbeder/yaml-cpp VERSION 3.9.1
# 0.6.2 uses deprecated CMake syntax
VERSION 0.6.3
# 0.6.3 is not released yet, so use a recent commit
GIT_TAG 012269756149ae99745b6dafefd415843d7420bb
OPTIONS OPTIONS
"YAML_CPP_BUILD_TESTS Off" "JSON_BuildTests OFF"
"YAML_CPP_BUILD_CONTRIB Off" )
"YAML_CPP_BUILD_TOOLS Off" ```
### [cxxopts](https://github.com/jarro2783/cxxopts)
```cmake
# the install option has to be explicitly set to allow installation
CPMAddPackage(
GITHUB_REPOSITORY jarro2783/cxxopts
VERSION 2.2.1
OPTIONS "CXXOPTS_BUILD_EXAMPLES NO" "CXXOPTS_BUILD_TESTS NO" "CXXOPTS_ENABLE_INSTALL YES"
) )
``` ```
@@ -311,48 +318,13 @@ CPMAddPackage(
CPMAddPackage( CPMAddPackage(
NAME benchmark NAME benchmark
GITHUB_REPOSITORY google/benchmark GITHUB_REPOSITORY google/benchmark
VERSION 1.4.1 VERSION 1.5.2
OPTIONS OPTIONS "BENCHMARK_ENABLE_TESTING Off"
"BENCHMARK_ENABLE_TESTING Off"
) )
if (benchmark_ADDED) if(benchmark_ADDED)
# compile with C++17 # enable c++11 to avoid compilation errors
set_target_properties(benchmark PROPERTIES CXX_STANDARD 17) set_target_properties(benchmark PROPERTIES CXX_STANDARD 11)
endif()
```
### [nlohmann/json](https://github.com/nlohmann/json)
```cmake
CPMAddPackage(
NAME nlohmann_json
VERSION 3.6.1
# the git repo is incredibly large, so we download the archived include directory
URL https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip
URL_HASH SHA256=69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf
)
if (nlohmann_json_ADDED)
add_library(nlohmann_json INTERFACE IMPORTED)
target_include_directories(nlohmann_json INTERFACE ${nlohmann_json_SOURCE_DIR})
endif()
```
### [Range-v3](https://github.com/ericniebler/range-v3)
```Cmake
CPMAddPackage(
NAME range-v3
URL https://github.com/ericniebler/range-v3/archive/0.5.0.zip
VERSION 0.5.0
# the range-v3 CMakeLists screws with configuration options
DOWNLOAD_ONLY True
)
if(range-v3_ADDED)
add_library(range-v3 INTERFACE IMPORTED)
target_include_directories(range-v3 INTERFACE "${range-v3_SOURCE_DIR}/include")
endif() endif()
``` ```

View File

@@ -132,7 +132,6 @@ if(NOT CPM_DONT_CREATE_PACKAGE_LOCK)
endif() endif()
include(FetchContent) include(FetchContent)
include(CMakeParseArguments)
# Try to infer package name from git repository uri (path or url) # Try to infer package name from git repository uri (path or url)
function(cpm_package_name_from_git_uri URI RESULT) function(cpm_package_name_from_git_uri URI RESULT)
@@ -224,7 +223,7 @@ function(cpm_create_module_file Name)
if(NOT CPM_DONT_UPDATE_MODULE_PATH) if(NOT CPM_DONT_UPDATE_MODULE_PATH)
# erase any previous modules # erase any previous modules
file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake file(WRITE ${CPM_MODULE_PATH}/Find${Name}.cmake
"include(${CPM_FILE})\n${ARGN}\nset(${Name}_FOUND TRUE)" "include(\"${CPM_FILE}\")\n${ARGN}\nset(${Name}_FOUND TRUE)"
) )
endif() endif()
endfunction() endfunction()
@@ -247,7 +246,7 @@ function(CPMFindPackage)
return() return()
endif() endif()
cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}") cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}")
if(CPM_PACKAGE_ALREADY_ADDED) if(CPM_PACKAGE_ALREADY_ADDED)
cpm_export_variables(${CPM_ARGS_NAME}) cpm_export_variables(${CPM_ARGS_NAME})
return() return()
@@ -263,7 +262,7 @@ function(CPMFindPackage)
endfunction() endfunction()
# checks if a package has been added before # checks if a package has been added before
function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION CPM_ARGS_OPTIONS) function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION)
if("${CPM_ARGS_NAME}" IN_LIST CPM_PACKAGES) if("${CPM_ARGS_NAME}" IN_LIST CPM_PACKAGES)
CPMGetPackageVersion(${CPM_ARGS_NAME} CPM_PACKAGE_VERSION) CPMGetPackageVersion(${CPM_ARGS_NAME} CPM_PACKAGE_VERSION)
if("${CPM_PACKAGE_VERSION}" VERSION_LESS "${CPM_ARGS_VERSION}") if("${CPM_PACKAGE_VERSION}" VERSION_LESS "${CPM_ARGS_VERSION}")
@@ -272,17 +271,6 @@ function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION CPM_A
"${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() endif()
if(CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
cpm_parse_option(${OPTION})
if(NOT "${${OPTION_KEY}}" STREQUAL "${OPTION_VALUE}")
message(
WARNING
"${CPM_INDENT} ignoring package option for ${CPM_ARGS_NAME}: ${OPTION_KEY} = ${OPTION_VALUE} (${${OPTION_KEY}})"
)
endif()
endforeach()
endif()
cpm_get_fetch_properties(${CPM_ARGS_NAME}) cpm_get_fetch_properties(${CPM_ARGS_NAME})
set(${CPM_ARGS_NAME}_ADDED NO) set(${CPM_ARGS_NAME}_ADDED NO)
set(CPM_PACKAGE_ALREADY_ADDED set(CPM_PACKAGE_ALREADY_ADDED
@@ -314,6 +302,9 @@ function(cpm_parse_add_package_single_arg arg outArgs)
elseif(scheme STREQUAL "gl") elseif(scheme STREQUAL "gl")
set(out "GITLAB_REPOSITORY;${uri}") set(out "GITLAB_REPOSITORY;${uri}")
set(packageType "git") set(packageType "git")
elseif(scheme STREQUAL "bb")
set(out "BITBUCKET_REPOSITORY;${uri}")
set(packageType "git")
# A CPM-specific scheme was not found. Looks like this is a generic URL so try to determine # A CPM-specific scheme was not found. Looks like this is a generic URL so try to determine
# type # type
elseif(arg MATCHES ".git/?(@|#|$)") elseif(arg MATCHES ".git/?(@|#|$)")
@@ -363,6 +354,68 @@ function(cpm_parse_add_package_single_arg arg outArgs)
) )
endfunction() endfunction()
# Check that the working directory for a git repo is clean
function(cpm_check_git_working_dir_is_clean repoPath gitTag isClean)
find_package(Git REQUIRED)
if(NOT GIT_EXECUTABLE)
# No git executable, assume directory is clean
set(${isClean}
TRUE
PARENT_SCOPE
)
return()
endif()
# check for uncommited changes
execute_process(
COMMAND ${GIT_EXECUTABLE} status --porcelain
RESULT_VARIABLE resultGitStatus
OUTPUT_VARIABLE repoStatus
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET
WORKING_DIRECTORY ${repoPath}
)
if(resultGitStatus)
# not supposed to happen, assume clean anyway
message(WARNING "Calling git status on folder ${repoPath} failed")
set(${isClean}
TRUE
PARENT_SCOPE
)
return()
endif()
if(NOT "${repoStatus}" STREQUAL "")
set(${isClean}
FALSE
PARENT_SCOPE
)
return()
endif()
# check for commited changes
execute_process(
COMMAND ${GIT_EXECUTABLE} diff -s --exit-code ${gitTag}
RESULT_VARIABLE resultGitDiff
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_QUIET
WORKING_DIRECTORY ${repoPath}
)
if(${resultGitDiff} EQUAL 0)
set(${isClean}
TRUE
PARENT_SCOPE
)
else()
set(${isClean}
FALSE
PARENT_SCOPE
)
endif()
endfunction()
# Download and add a package from source # Download and add a package from source
function(CPMAddPackage) function(CPMAddPackage)
list(LENGTH ARGN argnLength) list(LENGTH ARGN argnLength)
@@ -381,6 +434,7 @@ function(CPMAddPackage)
DOWNLOAD_ONLY DOWNLOAD_ONLY
GITHUB_REPOSITORY GITHUB_REPOSITORY
GITLAB_REPOSITORY GITLAB_REPOSITORY
BITBUCKET_REPOSITORY
GIT_REPOSITORY GIT_REPOSITORY
SOURCE_DIR SOURCE_DIR
DOWNLOAD_COMMAND DOWNLOAD_COMMAND
@@ -388,6 +442,7 @@ function(CPMAddPackage)
NO_CACHE NO_CACHE
GIT_SHALLOW GIT_SHALLOW
EXCLUDE_FROM_ALL EXCLUDE_FROM_ALL
SOURCE_SUBDIR
) )
set(multiValueArgs URL OPTIONS) set(multiValueArgs URL OPTIONS)
@@ -410,10 +465,10 @@ function(CPMAddPackage)
if(DEFINED CPM_ARGS_GITHUB_REPOSITORY) if(DEFINED CPM_ARGS_GITHUB_REPOSITORY)
set(CPM_ARGS_GIT_REPOSITORY "https://github.com/${CPM_ARGS_GITHUB_REPOSITORY}.git") set(CPM_ARGS_GIT_REPOSITORY "https://github.com/${CPM_ARGS_GITHUB_REPOSITORY}.git")
endif() elseif(DEFINED CPM_ARGS_GITLAB_REPOSITORY)
if(DEFINED CPM_ARGS_GITLAB_REPOSITORY)
set(CPM_ARGS_GIT_REPOSITORY "https://gitlab.com/${CPM_ARGS_GITLAB_REPOSITORY}.git") set(CPM_ARGS_GIT_REPOSITORY "https://gitlab.com/${CPM_ARGS_GITLAB_REPOSITORY}.git")
elseif(DEFINED CPM_ARGS_BITBUCKET_REPOSITORY)
set(CPM_ARGS_GIT_REPOSITORY "https://bitbucket.org/${CPM_ARGS_BITBUCKET_REPOSITORY}.git")
endif() endif()
if(DEFINED CPM_ARGS_GIT_REPOSITORY) if(DEFINED CPM_ARGS_GIT_REPOSITORY)
@@ -466,7 +521,7 @@ function(CPMAddPackage)
endif() endif()
# Check if package has been added before # Check if package has been added before
cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}") cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}")
if(CPM_PACKAGE_ALREADY_ADDED) if(CPM_PACKAGE_ALREADY_ADDED)
cpm_export_variables(${CPM_ARGS_NAME}) cpm_export_variables(${CPM_ARGS_NAME})
return() return()
@@ -477,10 +532,12 @@ function(CPMAddPackage)
set(PACKAGE_SOURCE ${CPM_${CPM_ARGS_NAME}_SOURCE}) set(PACKAGE_SOURCE ${CPM_${CPM_ARGS_NAME}_SOURCE})
set(CPM_${CPM_ARGS_NAME}_SOURCE "") set(CPM_${CPM_ARGS_NAME}_SOURCE "")
CPMAddPackage( CPMAddPackage(
NAME ${CPM_ARGS_NAME} NAME "${CPM_ARGS_NAME}"
SOURCE_DIR ${PACKAGE_SOURCE} SOURCE_DIR "${PACKAGE_SOURCE}"
EXCLUDE_FROM_ALL "${CPM_ARGS_EXCLUDE_FROM_ALL}"
OPTIONS "${CPM_ARGS_OPTIONS}"
SOURCE_SUBDIR "${CPM_ARGS_SOURCE_SUBDIR}"
FORCE True FORCE True
OPTIONS ${CPM_ARGS_OPTIONS}
) )
cpm_export_variables(${CPM_ARGS_NAME}) cpm_export_variables(${CPM_ARGS_NAME})
return() return()
@@ -493,7 +550,7 @@ function(CPMAddPackage)
CPMAddPackage(${declaration}) CPMAddPackage(${declaration})
cpm_export_variables(${CPM_ARGS_NAME}) cpm_export_variables(${CPM_ARGS_NAME})
# checking again to ensure version and option compatibility # checking again to ensure version and option compatibility
cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}" "${CPM_ARGS_OPTIONS}") cpm_check_if_package_already_added(${CPM_ARGS_NAME} "${CPM_ARGS_VERSION}")
return() return()
endif() endif()
@@ -515,16 +572,6 @@ function(CPMAddPackage)
CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}") CPMRegisterPackage("${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}")
if(CPM_ARGS_OPTIONS)
foreach(OPTION ${CPM_ARGS_OPTIONS})
cpm_parse_option(${OPTION})
set(${OPTION_KEY}
${OPTION_VALUE}
CACHE INTERNAL ""
)
endforeach()
endif()
if(DEFINED CPM_ARGS_GIT_TAG) if(DEFINED CPM_ARGS_GIT_TAG)
set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}") set(PACKAGE_INFO "${CPM_ARGS_GIT_TAG}")
elseif(DEFINED CPM_ARGS_SOURCE_DIR) elseif(DEFINED CPM_ARGS_SOURCE_DIR)
@@ -533,6 +580,13 @@ function(CPMAddPackage)
set(PACKAGE_INFO "${CPM_ARGS_VERSION}") set(PACKAGE_INFO "${CPM_ARGS_VERSION}")
endif() endif()
if(DEFINED FETCHCONTENT_BASE_DIR)
# respect user's FETCHCONTENT_BASE_DIR if set
set(CPM_FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR})
else()
set(CPM_FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_deps)
endif()
if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND) if(DEFINED CPM_ARGS_DOWNLOAD_COMMAND)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND}) list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS DOWNLOAD_COMMAND ${CPM_ARGS_DOWNLOAD_COMMAND})
elseif(DEFINED CPM_ARGS_SOURCE_DIR) elseif(DEFINED CPM_ARGS_SOURCE_DIR)
@@ -543,17 +597,29 @@ function(CPMAddPackage)
list(SORT origin_parameters) list(SORT origin_parameters)
string(SHA1 origin_hash "${origin_parameters}") string(SHA1 origin_hash "${origin_parameters}")
set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash}) set(download_directory ${CPM_SOURCE_CACHE}/${lower_case_name}/${origin_hash})
# Expand `download_directory` relative path. This is important because EXISTS doesn't work for
# relative paths.
get_filename_component(download_directory ${download_directory} ABSOLUTE)
list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory}) list(APPEND CPM_ARGS_UNPARSED_ARGUMENTS SOURCE_DIR ${download_directory})
if(EXISTS ${download_directory}) if(EXISTS ${download_directory})
# avoid FetchContent modules to improve performance # avoid FetchContent modules to improve performance
set(${CPM_ARGS_NAME}_BINARY_DIR ${CMAKE_BINARY_DIR}/_deps/${lower_case_name}-build) set(${CPM_ARGS_NAME}_BINARY_DIR ${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-build)
set(${CPM_ARGS_NAME}_ADDED YES) set(${CPM_ARGS_NAME}_ADDED YES)
set(${CPM_ARGS_NAME}_SOURCE_DIR ${download_directory}) set(${CPM_ARGS_NAME}_SOURCE_DIR ${download_directory})
if(NOT CPM_ARGS_DOWNLOAD_ONLY AND EXISTS ${download_directory}/CMakeLists.txt)
cpm_add_subdirectory( if(DEFINED CPM_ARGS_GIT_TAG)
${download_directory} ${${CPM_ARGS_NAME}_BINARY_DIR} "${CPM_ARGS_EXCLUDE_FROM_ALL}" # 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")
endif() 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}"
)
set(CPM_SKIP_FETCH TRUE) set(CPM_SKIP_FETCH TRUE)
set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}") set(PACKAGE_INFO "${PACKAGE_INFO} at ${download_directory}")
else() else()
@@ -567,7 +633,7 @@ function(CPMAddPackage)
endif() endif()
# remove timestamps so CMake will re-download the dependency # remove timestamps so CMake will re-download the dependency
file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/_deps/${lower_case_name}-subbuild) file(REMOVE_RECURSE ${CPM_FETCHCONTENT_BASE_DIR}/${lower_case_name}-subbuild)
set(PACKAGE_INFO "${PACKAGE_INFO} to ${download_directory}") set(PACKAGE_INFO "${PACKAGE_INFO} to ${download_directory}")
endif() endif()
endif() endif()
@@ -592,7 +658,14 @@ function(CPMAddPackage)
cpm_declare_fetch( cpm_declare_fetch(
"${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}" "${CPM_ARGS_NAME}" "${CPM_ARGS_VERSION}" "${PACKAGE_INFO}" "${CPM_ARGS_UNPARSED_ARGUMENTS}"
) )
cpm_fetch_package("${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}" "${CPM_ARGS_EXCLUDE_FROM_ALL}") cpm_fetch_package("${CPM_ARGS_NAME}" populated)
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}"
)
endif()
cpm_get_fetch_properties("${CPM_ARGS_NAME}") cpm_get_fetch_properties("${CPM_ARGS_NAME}")
endif() endif()
@@ -715,36 +788,71 @@ function(cpm_get_fetch_properties PACKAGE)
) )
endfunction() endfunction()
function(cpm_add_subdirectory SOURCE_DIR BINARY_DIR EXCLUDE) # adds a package as a subdirectory if viable, according to provided options
function(
cpm_add_subdirectory
PACKAGE
DOWNLOAD_ONLY
SOURCE_DIR
BINARY_DIR
EXCLUDE
OPTIONS
)
if(NOT DOWNLOAD_ONLY AND EXISTS ${SOURCE_DIR}/CMakeLists.txt)
if(EXCLUDE) if(EXCLUDE)
set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL) set(addSubdirectoryExtraArgs EXCLUDE_FROM_ALL)
else() else()
set(addSubdirectoryExtraArgs "") set(addSubdirectoryExtraArgs "")
endif() endif()
if(OPTIONS)
# the policy allows us to change options without caching
cmake_policy(SET CMP0077 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
foreach(OPTION ${OPTIONS})
cpm_parse_option(${OPTION})
set(${OPTION_KEY} ${OPTION_VALUE})
endforeach()
endif()
set(CPM_OLD_INDENT "${CPM_INDENT}")
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:")
add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs}) add_subdirectory(${SOURCE_DIR} ${BINARY_DIR} ${addSubdirectoryExtraArgs})
set(CPM_INDENT "${CPM_OLD_INDENT}")
endif()
endfunction() endfunction()
# downloads a previously declared package via FetchContent # downloads a previously declared package via FetchContent and exports the variables
function(cpm_fetch_package PACKAGE DOWNLOAD_ONLY EXCLUDE) # `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope
function(cpm_fetch_package PACKAGE populated)
set(${populated}
FALSE
PARENT_SCOPE
)
if(${CPM_DRY_RUN}) if(${CPM_DRY_RUN})
message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)") message(STATUS "${CPM_INDENT} package ${PACKAGE} not fetched (dry run)")
return() return()
endif() endif()
FetchContent_GetProperties(${PACKAGE}) FetchContent_GetProperties(${PACKAGE})
string(TOLOWER "${PACKAGE}" lower_case_name) string(TOLOWER "${PACKAGE}" lower_case_name)
if(NOT ${lower_case_name}_POPULATED) if(NOT ${lower_case_name}_POPULATED)
FetchContent_Populate(${PACKAGE}) FetchContent_Populate(${PACKAGE})
if(NOT DOWNLOAD_ONLY AND EXISTS ${${lower_case_name}_SOURCE_DIR}/CMakeLists.txt) set(${populated}
set(CPM_OLD_INDENT "${CPM_INDENT}") TRUE
set(CPM_INDENT "${CPM_INDENT} ${PACKAGE}:") PARENT_SCOPE
cpm_add_subdirectory(
${${lower_case_name}_SOURCE_DIR} ${${lower_case_name}_BINARY_DIR} "${EXCLUDE}"
) )
set(CPM_INDENT "${CPM_OLD_INDENT}")
endif()
endif() endif()
set(${PACKAGE}_SOURCE_DIR
${${lower_case_name}_SOURCE_DIR}
PARENT_SCOPE
)
set(${PACKAGE}_BINARY_DIR
${${lower_case_name}_BINARY_DIR}
PARENT_SCOPE
)
endfunction() endfunction()
# splits a package option # splits a package option

View File

@@ -38,7 +38,7 @@ endfunction()
function(ASSERT_NOT_DEFINED KEY) function(ASSERT_NOT_DEFINED KEY)
if(DEFINED ${KEY}) if(DEFINED ${KEY})
message(FATAL_ERROR "assertion failed: '${KEY}' is defiend") message(FATAL_ERROR "assertion failed: '${KEY}' is defiend (${${KEY}})")
else() else()
message(STATUS "test passed: '${KEY}' is not defined") message(STATUS "test passed: '${KEY}' is not defined")
endif() endif()
@@ -48,7 +48,15 @@ function(ASSERT_TRUTHY KEY)
if(${${KEY}}) if(${${KEY}})
message(STATUS "test passed: '${KEY}' is set truthy") message(STATUS "test passed: '${KEY}' is set truthy")
else() else()
message(FATAL_ERROR "assertion failed: value of '${KEY}' is not true (${${KEY}})") message(FATAL_ERROR "assertion failed: value of '${KEY}' is not truthy (${${KEY}})")
endif()
endfunction()
function(ASSERT_FALSY KEY)
if(${${KEY}})
message(FATAL_ERROR "assertion failed: value of '${KEY}' is not falsy (${${KEY}})")
else()
message(STATUS "test passed: '${KEY}' is set falsy")
endif() endif()
endfunction() endfunction()

View File

@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMTestingFrameworkExample)
include(../../cmake/CPM.cmake)
CPMAddPackage("bb:HEMRND/TestingFramework@0.4.1")
add_test_suites(TESTS SomeTest)

View File

@@ -0,0 +1,19 @@
#include <HEM/TestingFramework.hpp>
using namespace fakeit;
class ITest {
public:
virtual int getInt() = 0;
};
TEST_CASE("Testing Framework Test") {
constexpr int someIntValue = 123456;
Mock<ITest> testMock;
When(Method(testMock, getInt)).Return(someIntValue);
int readValue = testMock.get().getInt();
REQUIRE(readValue == someIntValue);
}

View File

@@ -8,12 +8,7 @@ include(../../cmake/CPM.cmake)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
CPMAddPackage( CPMAddPackage("gh:chriskohlhoff/asio#asio-1-18-1@1.18.1")
NAME asio
VERSION 1.18.1
GITHUB_REPOSITORY chriskohlhoff/asio
GIT_TAG asio-1-18-1 # asio uses non-standard version tag, we must specify GIT_TAG
)
# ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows: # ASIO doesn't use CMake, we have to configure it manually. Extra notes for using on Windows:
# #

View File

@@ -6,7 +6,7 @@ project(CPMExampleBenchmark)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage("gh:TheLartians/Fibonacci@2.0") CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage( CPMAddPackage(
NAME benchmark NAME benchmark
@@ -16,7 +16,7 @@ CPMAddPackage(
) )
if(benchmark_ADDED) if(benchmark_ADDED)
# Don't use C++14 because it doesn't work in some configurations. # enable c++11 to avoid compilation errors
set_target_properties(benchmark PROPERTIES CXX_STANDARD 11) set_target_properties(benchmark PROPERTIES CXX_STANDARD 11)
endif() endif()

View File

@@ -11,12 +11,8 @@ target_compile_features(CPMExampleBoost PRIVATE cxx_std_17)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMFindPackage( # boost-cmake currently doesn't tag versions, so we use the according boost version
NAME Boost CPMAddPackage("gh:Orphis/boost-cmake#7f97a08b64bd5d2e53e932ddf80c40544cf45edf@1.71.0")
GITHUB_REPOSITORY Orphis/boost-cmake
VERSION 1.67.0
FIND_PACKAGE_ARGUMENTS "COMPONENTS system"
)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)

View File

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

View File

@@ -6,12 +6,7 @@ project(CPMExampleCXXOpts)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage( CPMAddPackage("gh:jarro2783/cxxopts@2.2.0")
NAME cxxopts
GITHUB_REPOSITORY jarro2783/cxxopts
VERSION 2.2.0
OPTIONS "CXXOPTS_BUILD_EXAMPLES Off" "CXXOPTS_BUILD_TESTS Off"
)
# ---- Create binary ---- # ---- Create binary ----

View File

@@ -3,8 +3,14 @@
int main(int argc, char** argv) { int main(int argc, char** argv) {
cxxopts::Options options("MyProgram", "One line description of MyProgram"); cxxopts::Options options("MyProgram", "One line description of MyProgram");
options.add_options()("h,help", "Show help")("d,debug", "Enable debugging")(
"f,file", "File name", cxxopts::value<std::string>()); // clang-format off
options.add_options()
("h,help", "Show help")
("d,debug", "Enable debugging")
("f,file", "File name", cxxopts::value<std::string>()
);
// clang-format on
auto result = options.parse(argc, argv); auto result = options.parse(argc, argv);

View File

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

View File

@@ -6,7 +6,7 @@ project(CPMExampleGtest)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage("gh:TheLartians/Fibonacci@2.0") CPMAddPackage("gh:cpm-cmake/testpack-fibonacci@2.0")
CPMAddPackage( CPMAddPackage(
NAME googletest NAME googletest

View File

@@ -5,22 +5,10 @@ project(CPMJSONExample)
# ---- Dependencies ---- # ---- Dependencies ----
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage("gh:nlohmann/json@3.9.1")
CPMAddPackage(
NAME nlohmann_json
VERSION 3.9.1
# not using the repo as it takes forever to clone
URL https://github.com/nlohmann/json/releases/download/v3.9.1/include.zip
URL_HASH SHA256=6bea5877b1541d353bd77bdfbdb2696333ae5ed8f9e8cc22df657192218cad91
)
if(nlohmann_json_ADDED)
add_library(nlohmann_json INTERFACE)
target_include_directories(nlohmann_json SYSTEM INTERFACE ${nlohmann_json_SOURCE_DIR}/include)
endif()
# ---- Executable ---- # ---- Executable ----
add_executable(CPMJSONExample main.cpp) add_executable(CPMJSONExample main.cpp)
target_compile_features(CPMJSONExample PRIVATE cxx_std_17) target_compile_features(CPMJSONExample PRIVATE cxx_std_17)
target_link_libraries(CPMJSONExample nlohmann_json) target_link_libraries(CPMJSONExample nlohmann_json::nlohmann_json)

View File

@@ -6,18 +6,7 @@ project(CPMRangev3Example)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage( CPMAddPackage("gh:ericniebler/range-v3#0.11.0")
NAME range-v3
URL https://github.com/ericniebler/range-v3/archive/0.11.0.zip
VERSION 0.11.0
# the range-v3 CMakeLists screws with configuration options
DOWNLOAD_ONLY True
)
if(range-v3_ADDED)
add_library(range-v3 INTERFACE IMPORTED)
target_include_directories(range-v3 SYSTEM INTERFACE "${range-v3_SOURCE_DIR}/include")
endif()
# ---- Executable ---- # ---- Executable ----

View File

@@ -32,7 +32,7 @@ auto is_six = [](int i) { return i == 6; };
int main() { int main() {
std::vector<int> v{6, 2, 3, 4, 5, 6}; std::vector<int> v{6, 2, 3, 4, 5, 6};
cout << std::boolalpha; cout << std::boolalpha;
cout << "vector: " << ranges::view::all(v) << '\n'; cout << "vector: " << ranges::views::all(v) << '\n';
cout << "vector any_of is_six: " << ranges::any_of(v, is_six) << '\n'; cout << "vector any_of is_six: " << ranges::any_of(v, is_six) << '\n';
cout << "vector all_of is_six: " << ranges::all_of(v, is_six) << '\n'; cout << "vector all_of is_six: " << ranges::all_of(v, is_six) << '\n';

View File

@@ -6,13 +6,7 @@ project(CPMYamlExample)
include(../../cmake/CPM.cmake) include(../../cmake/CPM.cmake)
CPMAddPackage( CPMAddPackage("gh:jbeder/yaml-cpp#yaml-cpp-0.6.3@0.6.3")
NAME yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
VERSION 0.6.3
GIT_TAG yaml-cpp-0.6.3
OPTIONS "YAML_CPP_BUILD_TESTS Off" "YAML_CPP_BUILD_CONTRIB Off" "YAML_CPP_BUILD_TOOLS Off"
)
# ---- Executable ---- # ---- Executable ----

View File

@@ -0,0 +1,49 @@
include(${CPM_PATH}/CPM.cmake)
include(${CPM_PATH}/testing.cmake)
set(baseDir "${CMAKE_CURRENT_BINARY_DIR}/test_dirty_cache")
find_package(Git REQUIRED)
function(git_do dir)
execute_process(
COMMAND ${GIT_EXECUTABLE} -c user.name='User' -c user.email='user@email.org' ${ARGN}
RESULT_VARIABLE result
OUTPUT_VARIABLE status
OUTPUT_STRIP_TRAILING_WHITESPACE
WORKING_DIRECTORY "${dir}"
)
if(result)
message(FATAL_ERROR "git ${ARGN} fail: ${result} ${status}")
endif()
endfunction()
file(MAKE_DIRECTORY "${baseDir}")
file(WRITE "${baseDir}/draft.txt" "this is a test")
git_do("${baseDir}" init -b main)
git_do("${baseDir}" commit --allow-empty -m "empty repo")
message(STATUS "empty repo with file")
cpm_check_git_working_dir_is_clean(${baseDir} HEAD emptygit_test)
assert_falsy(emptygit_test)
git_do("${baseDir}" add draft.txt)
git_do("${baseDir}" commit -m "test change")
git_do("${baseDir}" tag v0.0.0)
message(STATUS "commit a change")
cpm_check_git_working_dir_is_clean(${baseDir} v0.0.0 onecommit_test)
assert_truthy(onecommit_test)
file(WRITE "${baseDir}/draft.txt" "a modification")
message(STATUS "dirty repo")
cpm_check_git_working_dir_is_clean(${baseDir} v0.0.0 nonemptygit_test)
assert_falsy(nonemptygit_test)
git_do("${baseDir}" add draft.txt)
git_do("${baseDir}" commit -m "another change")
message(STATUS "repo clean")
cpm_check_git_working_dir_is_clean(${baseDir} v0.0.0 twocommit_test)
assert_falsy(twocommit_test)
file(REMOVE_RECURSE "${baseDir}")

View File

@@ -0,0 +1,38 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
include(${CPM_PATH}/testing.cmake)
include(CMakePackageConfigHelpers)
set(CPM_SOURCE_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/CPM")
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/fetchcontent_dependency)
function(clear_cache)
message(STATUS "clearing CPM cache")
file(REMOVE_RECURSE ${CPM_SOURCE_CACHE_DIR})
assert_not_exists("${CPM_SOURCE_CACHE_DIR}")
endfunction()
function(update_cmake_lists)
configure_package_config_file(
"${CMAKE_CURRENT_LIST_DIR}/fetchcontent_dependency/CMakeLists.txt.in"
"${CMAKE_CURRENT_LIST_DIR}/fetchcontent_dependency/CMakeLists.txt"
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk
)
endfunction()
function(reset_test)
clear_cache()
file(REMOVE_RECURSE ${TEST_BUILD_DIR})
update_cmake_lists()
endfunction()
# Read CPM_SOURCE_CACHE from arguments
reset_test()
execute_process(
COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/fetchcontent_dependency"
"-B${TEST_BUILD_DIR}" "-DCPM_SOURCE_CACHE=${CPM_SOURCE_CACHE_DIR}" RESULT_VARIABLE ret
)
assert_equal(${ret} "0")

View File

@@ -0,0 +1,2 @@
/CMakeLists.txt
/package-lock.cmake

View File

@@ -0,0 +1,38 @@
# ~~~
# ┌────────────────────────┐
# │ FetchContentDependency │
# └─────┬────────────┬─────┘
# │1. │3.
# │ │
# ┌────────▼────┐ ┌───▼─────────┐
# │ Dependency ├───► Fibonacci │
# └─────────────┘2. └─────────────┘
#
# 1. Add Project with CPMAddPackage
# 2. Dependency will add Fibonacci with FetchContent
# 3. Our project add Fibonacci with CPMAddPackage
# ~~~
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMTest_FetchContentDependency)
# ---- Dependencies ----
include(@CPM_PATH@/CPM.cmake)
# 1 & 2 Dependency will add Fibonacci using FetchContent (1 & 2)
CPMAddPackage(NAME Dependency SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency)
# 3 Add again Fibonacci that have already been populated with FetchContent_MakeAvailable
#
# * This test should highlight the fact that cpm_add_subdirectory is always called, even when
# cpm_fetch_package isn't populating the dependency
# * NO_CACHE YES highlight a bug introduced in 32b063eba5c754f833725ed4b9e5f352bc3ca959 where
# cpm_fetch_package was checking undefined ${lower_case_name}_POPULATED variable
CPMAddPackage(
NAME Fibonacci
GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git
VERSION 2.0
NO_CACHE YES
)

View File

@@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMTest_Dependency)
# ---- Dependencies ----
include(FetchContent)
FetchContent_Declare(
Fibonacci
GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git
GIT_TAG v2.0
)
FetchContent_MakeAvailable(Fibonacci)

View File

@@ -0,0 +1,33 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMTest)
# ---- Options ----
option(ENABLE_TEST_COVERAGE "Enable test coverage" OFF)
# ---- Dependencies ----
include(@CPM_PATH@/CPM.cmake)
CPMAddPackage(
NAME Dependency
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency
OPTIONS "DEFINE_ALTERNATIVE_FUNCTION YES"
EXCLUDE_FROM_ALL YES
)
# ---- Dependencies ----
alternative_dependency_function()
# ---- Check parameters ----
include(@CPM_PATH@/testing.cmake)
message("DEFINE_ALTERNATIVE_FUNCTION: ${DEFINE_ALTERNATIVE_FUNCTION}")
# this option is overridden by CPM.cmake
ASSERT_NOT_DEFINED(DEFINE_ALTERNATIVE_FUNCTION)
# this option is leaked by the dependency
ASSERT_EQUAL(${LEAKED_OPTION} "OFF")

View File

@@ -0,0 +1,17 @@
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
project(CPMTest)
# ---- Dependencies ----
include(@CPM_PATH@/CPM.cmake)
CPMAddPackage(
NAME Dependency
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/dependency
SOURCE_SUBDIR inner
)
# ---- Call inner dependency method to validate correct addition of subdirectory ----
inner_dependency_function()

View File

@@ -1,3 +1,14 @@
function(dependency_function) cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
option(DEFINE_ALTERNATIVE_FUNCTION "define the alternative function" OFF)
option(LEAKED_OPTION "this option will be leaked to the outer scope" OFF)
if(NOT DEFINE_ALTERNATIVE_FUNCTION)
function(dependency_function)
message("called external method") message("called external method")
endfunction() endfunction()
else()
function(alternative_dependency_function)
message("called alternative external method")
endfunction()
endif()

View File

@@ -0,0 +1,3 @@
function(inner_dependency_function)
message("called inner method")
endfunction()

19
test/unit/options.cmake Normal file
View File

@@ -0,0 +1,19 @@
include(CMakePackageConfigHelpers)
include(${CPM_PATH}/testing.cmake)
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir)
set(TEST_DEPENDENCY_NAME Dependency)
configure_package_config_file(
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/OptionsCMakeLists.txt.in"
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt"
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk
)
execute_process(
COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/local_dependency" "-B${TEST_BUILD_DIR}"
RESULT_VARIABLE ret
)
assert_equal(${ret} "0")

View File

@@ -30,6 +30,12 @@ assert_equal("GITLAB_REPOSITORY;foo/bar" "${args}")
cpm_parse_add_package_single_arg("gl:foo/Bar" args) cpm_parse_add_package_single_arg("gl:foo/Bar" args)
assert_equal("GITLAB_REPOSITORY;foo/Bar" "${args}") assert_equal("GITLAB_REPOSITORY;foo/Bar" "${args}")
cpm_parse_add_package_single_arg("bb:foo/bar" args)
assert_equal("BITBUCKET_REPOSITORY;foo/bar" "${args}")
cpm_parse_add_package_single_arg("bb:foo/Bar" args)
assert_equal("BITBUCKET_REPOSITORY;foo/Bar" "${args}")
cpm_parse_add_package_single_arg("https://github.com/cpm-cmake/CPM.cmake.git@0.30.5" args) cpm_parse_add_package_single_arg("https://github.com/cpm-cmake/CPM.cmake.git@0.30.5" args)
assert_equal("GIT_REPOSITORY;https://github.com/cpm-cmake/CPM.cmake.git;VERSION;0.30.5" "${args}") assert_equal("GIT_REPOSITORY;https://github.com/cpm-cmake/CPM.cmake.git;VERSION;0.30.5" "${args}")

View File

@@ -12,7 +12,7 @@ include(@CPM_PATH@/CPM.cmake)
CPMAddPackage( CPMAddPackage(
NAME fibonacci NAME fibonacci
GIT_REPOSITORY https://github.com/TheLartians/Fibonacci.git GIT_REPOSITORY https://github.com/cpm-cmake/testpack-fibonacci.git
VERSION @FIBONACCI_VERSION@ VERSION @FIBONACCI_VERSION@
@FIBONACCI_PACKAGE_ARGS@ @FIBONACCI_PACKAGE_ARGS@
) )

17
test/unit/subdir.cmake Normal file
View File

@@ -0,0 +1,17 @@
include(CMakePackageConfigHelpers)
include(${CPM_PATH}/testing.cmake)
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir)
configure_package_config_file(
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/SubdirCMakeLists.txt.in"
"${CMAKE_CURRENT_LIST_DIR}/local_dependency/CMakeLists.txt"
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/junk
)
execute_process(
COMMAND ${CMAKE_COMMAND} "-H${CMAKE_CURRENT_LIST_DIR}/local_dependency" "-B${TEST_BUILD_DIR}"
RESULT_VARIABLE ret
)
assert_equal(${ret} "0")