mirror of
https://github.com/cpm-cmake/CPM.cmake.git
synced 2025-11-26 06:07:26 -05:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f552da96bd | ||
|
|
ea6a8eb895 | ||
|
|
a5c22bf6e8 | ||
|
|
c5cb85b2f1 |
30
.github/workflows/examples.yml
vendored
Normal file
30
.github/workflows/examples.yml
vendored
Normal 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
|
||||||
49
.travis.yml
49
.travis.yml
@@ -1,49 +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"
|
|
||||||
- wget -O cmake.sh https://github.com/Kitware/CMake/releases/download/v3.20.3/cmake-3.20.3-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
|
|
||||||
100
cmake/CPM.cmake
100
cmake/CPM.cmake
@@ -223,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()
|
||||||
@@ -354,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)
|
||||||
@@ -544,6 +606,15 @@ function(CPMAddPackage)
|
|||||||
set(${CPM_ARGS_NAME}_BINARY_DIR ${CPM_FETCHCONTENT_BASE_DIR}/${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(DEFINED CPM_ARGS_GIT_TAG)
|
||||||
|
# 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()
|
||||||
|
|
||||||
cpm_add_subdirectory(
|
cpm_add_subdirectory(
|
||||||
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
||||||
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
||||||
@@ -587,12 +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}")
|
cpm_fetch_package("${CPM_ARGS_NAME}" populated)
|
||||||
cpm_add_subdirectory(
|
if(${populated})
|
||||||
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
cpm_add_subdirectory(
|
||||||
"${${CPM_ARGS_NAME}_SOURCE_DIR}/${CPM_ARGS_SOURCE_SUBDIR}" "${${CPM_ARGS_NAME}_BINARY_DIR}"
|
"${CPM_ARGS_NAME}" "${DOWNLOAD_ONLY}"
|
||||||
"${CPM_ARGS_EXCLUDE_FROM_ALL}" "${CPM_ARGS_OPTIONS}"
|
"${${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()
|
||||||
|
|
||||||
@@ -750,7 +823,11 @@ endfunction()
|
|||||||
|
|
||||||
# downloads a previously declared package via FetchContent and exports the variables
|
# downloads a previously declared package via FetchContent and exports the variables
|
||||||
# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope
|
# `${PACKAGE}_SOURCE_DIR` and `${PACKAGE}_BINARY_DIR` to the parent scope
|
||||||
function(cpm_fetch_package PACKAGE)
|
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()
|
||||||
@@ -758,11 +835,16 @@ function(cpm_fetch_package PACKAGE)
|
|||||||
|
|
||||||
FetchContent_GetProperties(${PACKAGE})
|
FetchContent_GetProperties(${PACKAGE})
|
||||||
|
|
||||||
|
string(TOLOWER "${PACKAGE}" lower_case_name)
|
||||||
|
|
||||||
if(NOT ${lower_case_name}_POPULATED)
|
if(NOT ${lower_case_name}_POPULATED)
|
||||||
FetchContent_Populate(${PACKAGE})
|
FetchContent_Populate(${PACKAGE})
|
||||||
|
set(${populated}
|
||||||
|
TRUE
|
||||||
|
PARENT_SCOPE
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(TOLOWER "${PACKAGE}" lower_case_name)
|
|
||||||
set(${PACKAGE}_SOURCE_DIR
|
set(${PACKAGE}_SOURCE_DIR
|
||||||
${${lower_case_name}_SOURCE_DIR}
|
${${lower_case_name}_SOURCE_DIR}
|
||||||
PARENT_SCOPE
|
PARENT_SCOPE
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
49
test/unit/dirty-cache-check.cmake
Normal file
49
test/unit/dirty-cache-check.cmake
Normal 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}")
|
||||||
38
test/unit/fetchcontent_dependency.cmake
Normal file
38
test/unit/fetchcontent_dependency.cmake
Normal 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")
|
||||||
2
test/unit/fetchcontent_dependency/.gitignore
vendored
Normal file
2
test/unit/fetchcontent_dependency/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/CMakeLists.txt
|
||||||
|
/package-lock.cmake
|
||||||
38
test/unit/fetchcontent_dependency/CMakeLists.txt.in
Normal file
38
test/unit/fetchcontent_dependency/CMakeLists.txt.in
Normal 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
|
||||||
|
)
|
||||||
15
test/unit/fetchcontent_dependency/dependency/CMakeLists.txt
Normal file
15
test/unit/fetchcontent_dependency/dependency/CMakeLists.txt
Normal 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)
|
||||||
Reference in New Issue
Block a user