-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Single-argument shorthand syntax for CPMAddPackage (#207)
* Added quotes in equality checks so lists can be compared * Function to parse argument of CPMAddPackage in case a single one was provided * Error on URL type in CPMAddPackage single-arg * Fixed format * Support single argument syntax of CPMAddPackage * Documenting and showcasing the new shorthand syntax of CPMAddPackage * Auto EXCLUDE_FROM_ALL for the shorthand syntax * Fixed accidental paste of TOLOWER * Document why some test cases are commented out Co-authored-by: Lars Melchior <[email protected]> * Update README.md Co-authored-by: Lars Melchior <[email protected]> * Removed GitHub as the default package shorthand provider Co-authored-by: Lars Melchior <[email protected]>
- Loading branch information
1 parent
4aadac1
commit 3f6cbe7
Showing
4 changed files
with
159 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,19 @@ On the other hand, if `VERSION` hasn't been explicitly specified, CPM can automa | |
`GIT_TAG` can also be set to a specific commit or a branch name such as `master` to always download the most recent version. | ||
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). | ||
|
||
A single-argument compact syntax is also supported: | ||
|
||
```cmake | ||
# A git package from a given uri with a version | ||
CPMAddPackage("uri@version") | ||
# A git package from a given uri with a git tag or commit hash, or branch name | ||
CPMAddPackage("uri#tag") | ||
# A git package with both version and tag provided | ||
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. | ||
|
||
After calling `CPMAddPackage` or `CPMFindPackage`, 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. | ||
|
@@ -70,10 +83,7 @@ add_executable(tests tests.cpp) | |
# add dependencies | ||
include(cmake/CPM.cmake) | ||
CPMAddPackage( | ||
GITHUB_REPOSITORY catchorg/Catch2 | ||
VERSION 2.5.0 | ||
) | ||
CPMAddPackage(gh:catchorg/[email protected]) | ||
# link dependencies | ||
target_link_libraries(tests Catch2) | ||
|
@@ -244,21 +254,13 @@ See the [wiki](https://github.com/cpm-cmake/CPM.cmake/wiki/More-Snippets) for mo | |
### [Catch2](https://github.com/catchorg/Catch2) | ||
|
||
```cmake | ||
CPMAddPackage( | ||
NAME Catch2 | ||
GITHUB_REPOSITORY catchorg/Catch2 | ||
VERSION 2.5.0 | ||
) | ||
CPMAddPackage(gh:catchorg/[email protected]) | ||
``` | ||
|
||
### [Boost (via boost-cmake)](https://github.com/Orphis/boost-cmake) | ||
|
||
```CMake | ||
CPMAddPackage( | ||
NAME boost-cmake | ||
GITHUB_REPOSITORY Orphis/boost-cmake | ||
VERSION 1.67.0 | ||
) | ||
CPMAddPackage(gh:Orphis/[email protected]) | ||
``` | ||
|
||
### [cxxopts](https://github.com/jarro2783/cxxopts) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -252,8 +252,85 @@ function(cpm_check_if_package_already_added CPM_ARGS_NAME CPM_ARGS_VERSION CPM_A | |
endif() | ||
endfunction() | ||
|
||
# Parse the argument of CPMAddPackage in case a single one was provided and convert it to a list of | ||
# arguments which can then be parsed idiomatically. For example gh:foo/[email protected] will be converted | ||
# to: GITHUB_REPOSITORY;foo/bar;VERSION;1.2.3 | ||
function(cpm_parse_add_package_single_arg arg outArgs) | ||
# Look for a scheme | ||
if("${arg}" MATCHES "^([a-zA-Z]+):(.+)$") | ||
string(TOLOWER "${CMAKE_MATCH_1}" scheme) | ||
set(uri "${CMAKE_MATCH_2}") | ||
|
||
# Check for CPM-specific schemes | ||
if(scheme STREQUAL "gh") | ||
set(out "GITHUB_REPOSITORY;${uri}") | ||
set(packageType "git") | ||
elseif(scheme STREQUAL "gl") | ||
set(out "GITLAB_REPOSITORY;${uri}") | ||
set(packageType "git") | ||
# A CPM-specific scheme was not found. Looks like this is a generic URL so try to determine | ||
# type | ||
elseif(arg MATCHES ".git/?(@|#|$)") | ||
set(out "GIT_REPOSITORY;${arg}") | ||
set(packageType "git") | ||
else() | ||
# This error here is temporary. We can't provide URLs from here until we support inferring the | ||
# package name from an url. When this is supported, remove this error as well as commented out | ||
# tests in test/unit/parse_add_package_single_arg.cmake | ||
message(FATAL_ERROR "CPM: Unsupported package type of '${arg}'") | ||
|
||
# Fall back to a URL | ||
set(out "URL;${arg}") | ||
set(packageType "archive") | ||
|
||
# We could also check for SVN since FetchContent supports it, but SVN is so rare these days. | ||
# We just won't bother with the additional complexity it will induce in this function. SVN is | ||
# done by multi-arg | ||
endif() | ||
else() | ||
if(arg MATCHES ".git/?(@|#|$)") | ||
set(out "GIT_REPOSITORY;${arg}") | ||
set(packageType "git") | ||
else() | ||
# Give up | ||
message(FATAL_ERROR "CPM: Can't determine package type of '${arg}'") | ||
endif() | ||
endif() | ||
|
||
# For all packages we interpret @... as version. Only replace the last occurence. Thus URIs | ||
# containing '@' can be used | ||
string(REGEX REPLACE "@([^@]+)$" ";VERSION;\\1" out "${out}") | ||
|
||
# Parse the rest according to package type | ||
if(packageType STREQUAL "git") | ||
# For git repos we interpret #... as a tag or branch or commit hash | ||
string(REGEX REPLACE "#([^#]+)$" ";GIT_TAG;\\1" out "${out}") | ||
elseif(packageType STREQUAL "archive") | ||
# For archives we interpret #... as a URL hash. | ||
string(REGEX REPLACE "#([^#]+)$" ";URL_HASH;\\1" out "${out}") | ||
# 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. | ||
message(FATAL_ERROR "CPM: Unsupported package type '${packageType}' of '${arg}'") | ||
endif() | ||
|
||
set(${outArgs} | ||
${out} | ||
PARENT_SCOPE | ||
) | ||
endfunction() | ||
|
||
# Download and add a package from source | ||
function(CPMAddPackage) | ||
list(LENGTH ARGN argnLength) | ||
if(argnLength EQUAL 1) | ||
cpm_parse_add_package_single_arg("${ARGN}" ARGN) | ||
|
||
# The shorthand syntax implies EXCLUDE_FROM_ALL | ||
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES") | ||
endif() | ||
|
||
set(oneValueArgs | ||
NAME | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR) | ||
|
||
include(${CPM_PATH}/CPM.cmake) | ||
include(${CPM_PATH}/testing.cmake) | ||
|
||
cpm_parse_add_package_single_arg("gh:cpm-cmake/CPM.cmake" args) | ||
assert_equal("GITHUB_REPOSITORY;cpm-cmake/CPM.cmake" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:cpm-cmake/[email protected]" args) | ||
assert_equal("GITHUB_REPOSITORY;cpm-cmake/CPM.cmake;VERSION;1.2.3" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:cpm-cmake/CPM.cmake#master" args) | ||
assert_equal("GITHUB_REPOSITORY;cpm-cmake/CPM.cmake;GIT_TAG;master" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:cpm-cmake/[email protected]#asdf" args) | ||
assert_equal("GITHUB_REPOSITORY;cpm-cmake/CPM.cmake;VERSION;0.20.3;GIT_TAG;asdf" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:a/b#c@d" args) | ||
assert_equal("GITHUB_REPOSITORY;a/b;GIT_TAG;c;VERSION;d" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:foo#c@d" args) | ||
assert_equal("GITHUB_REPOSITORY;foo;GIT_TAG;c;VERSION;d" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gh:Foo@5" args) | ||
assert_equal("GITHUB_REPOSITORY;Foo;VERSION;5" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gl:foo/bar" args) | ||
assert_equal("GITLAB_REPOSITORY;foo/bar" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("gl:foo/Bar" args) | ||
assert_equal("GITLAB_REPOSITORY;foo/Bar" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("https://github.com/cpm-cmake/[email protected]" args) | ||
assert_equal("GIT_REPOSITORY;https://github.com/cpm-cmake/CPM.cmake.git;VERSION;0.30.5" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("[email protected]:user/[email protected]" args) | ||
assert_equal("GIT_REPOSITORY;[email protected]:user/pkg.git;VERSION;0.1.2" "${args}") | ||
|
||
cpm_parse_add_package_single_arg("[email protected]:user/[email protected]#rc" args) | ||
assert_equal("GIT_REPOSITORY;[email protected]:user/pkg.git;VERSION;0.1.2;GIT_TAG;rc" "${args}") | ||
|
||
cpm_parse_add_package_single_arg( | ||
"ssh://[email protected]:123/path/to/pkg.git#[email protected]#branch" args | ||
) | ||
assert_equal( | ||
"GIT_REPOSITORY;ssh://[email protected]:123/path/to/pkg.git#fragment;VERSION;1.2.3;GIT_TAG;branch" | ||
"${args}" | ||
) | ||
|
||
# The following test cases are to be used in the future, once single-argument archives are supported | ||
|
||
# cpm_parse_add_package_single_arg("https://example.org/foo.tar.gz" args) | ||
|
||
# assert_equal("URL;https://example.org/foo.tar.gz" "${args}") | ||
|
||
# cpm_parse_add_package_single_arg("https://example.org/foo.tar.gz#[email protected]" args) | ||
|
||
# assert_equal("URL;https://example.org/foo.tar.gz;URL_HASH;baadf00d;VERSION;1.2.0" "${args}") | ||
|
||
# cpm_parse_add_package_single_arg("ftp://user:password@server/pathname.zip#fragment#0ddb411@0" | ||
# args) | ||
|
||
# assert_equal("URL;ftp://user:password@server/pathname.zip#fragment;URL_HASH;0ddb411;VERSION;0" | ||
# "${args}") |