Compare commits

..

7 Commits

Author SHA1 Message Date
Lars Melchior
6b5cd6f190 add removed test cases 2023-04-13 17:59:08 +02:00
Lars Melchior
a49358ef34 refactor empty argument passing to not require eval 2023-04-13 17:49:13 +02:00
Craig Hutchinson
f4fd660d09 Maintain key-value CMake formatting 2023-03-23 20:55:19 +00:00
Craig Hutchinson
5c1ce67e3b Fix docs typo 2023-03-23 20:55:19 +00:00
Craig Hutchinson
b847af65c0 Support EVAL CODE on CMake <3.18 2023-03-23 20:55:18 +00:00
Craig Hutchinson
cbe5144f79 Preserving forwarding of empty string arguments
Also:
- Support cmake-format on Windows by using auto lione-ending
2023-03-23 20:55:18 +00:00
Craig Hutchinson
b70460aca4 Test forwarding of arguments to FetchCOntent_Declare 2023-03-23 20:55:18 +00:00
10 changed files with 246 additions and 135 deletions

View File

@@ -1,5 +1,75 @@
include: ["cmake/.cmake-format-additional_commands-cpm"]
format: format:
tab_size: 2 tab_size: 2
line_width: 100 line_width: 100
line_ending: auto
dangle_parens: true 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,9 +15,8 @@ jobs:
- name: Set CPM version by tag - name: Set CPM version by tag
run: | run: |
mkdir dist mkdir dist
sed -e "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/CPM.cmake > dist/CPM.cmake
sed -e "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" \ sed "s/1.0.0-development-version/${GITHUB_REF/refs\/tags\/v}/g" cmake/get_cpm.cmake > dist/get_cpm.cmake
-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 - name: Upload CPM.cmake to release
uses: svenstaro/upload-release-action@v1-release uses: svenstaro/upload-release-action@v1-release

View File

@@ -12,7 +12,7 @@ It's built as a thin wrapper around CMake's [FetchContent](https://cmake.org/cma
## Manage everything ## Manage everything
Any downloadable project or resource can be added as a version-controlled dependency through CPM, it is not necessary to modify or package anything. Any downloadable project or resource can be added as a version-controlled dependency though CPM, it is not necessary to modify or package anything.
Projects using modern CMake are automatically configured and their targets can be used immediately. 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). For everything else, the targets can be created manually after the dependency has been downloaded (see the [snippets](#snippets) below for examples).
@@ -324,22 +324,8 @@ 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> <p align="center"><b>JNGL - easy to use cross-platform 2D game library</b></p>
</a> </a>
</td> </td>
<td> <td/>
<a href="https://github.com/sillydan1/aaltitoad"> <td/>
<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>
</table> </table>

View File

@@ -1,69 +0,0 @@
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

@@ -5,7 +5,7 @@
# MIT License # MIT License
# ----------- # -----------
#[[ #[[
Copyright (c) 2019-2023 Lars Melchior and contributors Copyright (c) 2019-2022 Lars Melchior and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
@@ -505,6 +505,60 @@ function(cpm_override_fetchcontent contentName)
set_property(GLOBAL PROPERTY ${propertyName} TRUE) set_property(GLOBAL PROPERTY ${propertyName} TRUE)
endfunction() 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 # Download and add a package from source
function(CPMAddPackage) function(CPMAddPackage)
cpm_set_policies() cpm_set_policies()
@@ -512,7 +566,6 @@ function(CPMAddPackage)
list(LENGTH ARGN argnLength) list(LENGTH ARGN argnLength)
if(argnLength EQUAL 1) if(argnLength EQUAL 1)
cpm_parse_add_package_single_arg("${ARGN}" ARGN) cpm_parse_add_package_single_arg("${ARGN}" ARGN)
# The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM # The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM
set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;") set(ARGN "${ARGN};EXCLUDE_FROM_ALL;YES;SYSTEM;YES;")
endif() endif()
@@ -528,6 +581,7 @@ function(CPMAddPackage)
BITBUCKET_REPOSITORY BITBUCKET_REPOSITORY
GIT_REPOSITORY GIT_REPOSITORY
SOURCE_DIR SOURCE_DIR
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS FIND_PACKAGE_ARGUMENTS
NO_CACHE NO_CACHE
SYSTEM SYSTEM
@@ -536,12 +590,28 @@ function(CPMAddPackage)
SOURCE_SUBDIR SOURCE_SUBDIR
) )
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND) set(multiValueArgs URL OPTIONS)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${ARGN}") # Encode arguments for `cmake_parse_arguments`
cpm_encode_empty_arguments("${ARGN}" "PARSE_ARGS")
# Parse arguments
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" "${PARSE_ARGS}")
# Decode arguments
foreach(ARG IN LISTS oneValueArgs)
if(DEFINED CPM_ARGS_${ARG})
cpm_decode_empty_argument("${CPM_ARGS_${ARG}}" CPM_ARGS_${ARG})
endif()
endforeach()
foreach(ARG IN LISTS multiValueArgs)
if(DEFINED CPM_ARGS_${ARG})
cpm_decode_empty_arguments("${CPM_ARGS_${ARG}}" CPM_ARGS_${ARG})
endif()
endforeach()
cpm_decode_empty_arguments("${CPM_ARGS_UNPARSED_ARGUMENTS}" CPM_ARGS_UNPARSED_ARGUMENTS)
# Set default values for arguments # Set default values for arguments
if(NOT DEFINED CPM_ARGS_VERSION) if(NOT DEFINED CPM_ARGS_VERSION)
if(DEFINED CPM_ARGS_GIT_TAG) if(DEFINED CPM_ARGS_GIT_TAG)
cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION) cpm_get_version_from_git_tag("${CPM_ARGS_GIT_TAG}" CPM_ARGS_VERSION)
@@ -796,7 +866,7 @@ function(CPMAddPackage)
"${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}" populated) cpm_fetch_package("${CPM_ARGS_NAME}" populated)
if(CPM_SOURCE_CACHE AND download_directory) if(CPM_CACHE_SOURCE AND download_directory)
file(LOCK ${download_directory}/../cmake.lock RELEASE) file(LOCK ${download_directory}/../cmake.lock RELEASE)
endif() endif()
if(${populated}) if(${populated})
@@ -915,8 +985,7 @@ function(cpm_declare_fetch PACKAGE VERSION INFO)
cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)") cpm_message(STATUS "${CPM_INDENT} Package not declared (dry run)")
return() return()
endif() endif()
FetchContent_Declare(${PACKAGE} "${ARGN}")
FetchContent_Declare(${PACKAGE} ${ARGN})
endfunction() endfunction()
# returns properties for a package previously defined by cpm_declare_fetch # returns properties for a package previously defined by cpm_declare_fetch
@@ -1097,13 +1166,14 @@ function(cpm_prettify_package_arguments OUT_VAR IS_IN_COMMENT)
GITLAB_REPOSITORY GITLAB_REPOSITORY
GIT_REPOSITORY GIT_REPOSITORY
SOURCE_DIR SOURCE_DIR
DOWNLOAD_COMMAND
FIND_PACKAGE_ARGUMENTS FIND_PACKAGE_ARGUMENTS
NO_CACHE NO_CACHE
SYSTEM SYSTEM
GIT_SHALLOW GIT_SHALLOW
) )
set(multiValueArgs URL OPTIONS DOWNLOAD_COMMAND) set(multiValueArgs OPTIONS)
cmake_parse_arguments(CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_parse_arguments(PARSE_ARGV 2 CPM_ARGS "" "${oneValueArgs}" "${multiValueArgs}")
foreach(oneArgName ${oneValueArgs}) foreach(oneArgName ${oneValueArgs})
if(DEFINED CPM_ARGS_${oneArgName}) if(DEFINED CPM_ARGS_${oneArgName})

View File

@@ -1,9 +1,4 @@
# 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_DOWNLOAD_VERSION 1.0.0-development-version)
set(CPM_HASH_SUM "CPM_HASH_SUM_PLACEHOLDER")
if(CPM_SOURCE_CACHE) if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
@@ -16,9 +11,23 @@ endif()
# Expand relative path. This is important if the provided path contains a tilde (~) # Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE) get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
file(DOWNLOAD function(download_cpm)
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM} file(DOWNLOAD
) https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION}
)
endfunction()
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
download_cpm()
else()
# resume download if it previously failed
file(READ ${CPM_DOWNLOAD_LOCATION} check)
if("${check}" STREQUAL "")
download_cpm()
endif()
unset(check)
endif()
include(${CPM_DOWNLOAD_LOCATION}) include(${CPM_DOWNLOAD_LOCATION})

View File

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

View File

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

View File

@@ -2,6 +2,8 @@ include(CMakePackageConfigHelpers)
include(${CPM_PATH}/testing.cmake) include(${CPM_PATH}/testing.cmake)
set(TEST_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/source_dir) 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) set(TEST_DEPENDENCY_NAME Dependency)