diff --git a/cmake-format-rapids-cmake.json b/cmake-format-rapids-cmake.json index fa3bf35ba..f9095de15 100644 --- a/cmake-format-rapids-cmake.json +++ b/cmake-format-rapids-cmake.json @@ -76,10 +76,21 @@ "PATCH_COMMAND": "1" } }, - "rapids_cpm_init": { + "rapids_cpm_generate_pinned_versions": { "pargs": { "nargs": 0 }, + "kwargs": { + "OUTPUT": 1 + } + }, + "rapids_cpm_init": { + "pargs": { + "nargs": 0, + "flags": [ + "GENERATE_PINNED_VERSIONS" + ] + }, "kwargs": { "OVERRIDE": 1 } diff --git a/docs/api.rst b/docs/api.rst index 56d01e8db..96b2305de 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -33,6 +33,7 @@ tracking of these dependencies for correct export support. /command/rapids_cpm_init /command/rapids_cpm_find + /command/rapids_cpm_generate_pinned_versions /command/rapids_cpm_package_override .. _`cpm_pre-configured_packages`: diff --git a/docs/command/rapids_cpm_generate_pinned_versions.rst b/docs/command/rapids_cpm_generate_pinned_versions.rst new file mode 100644 index 000000000..8e54957fc --- /dev/null +++ b/docs/command/rapids_cpm_generate_pinned_versions.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../rapids-cmake/cpm/generate_pinned_versions.cmake diff --git a/rapids-cmake/cpm/detail/pinning_root_dir_hook.cmake b/rapids-cmake/cpm/detail/pinning_root_dir_hook.cmake new file mode 100644 index 000000000..25a1c09cc --- /dev/null +++ b/rapids-cmake/cpm/detail/pinning_root_dir_hook.cmake @@ -0,0 +1,31 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +include_guard(GLOBAL) + +# Make sure we always have CMake 3.23 policies when executing this file since we can be executing in +# directories of users of rapids-cmake which have a lower minimum cmake version and therefore +# different policies +# +cmake_policy(PUSH) +cmake_policy(VERSION 3.23) + +# Include the needed functions that write out the the pinned versions file +include("${rapids-cmake-dir}/cpm/detail/pinning_write_file.cmake") + +# Compute and write out the pinned versions file +rapids_cpm_pinning_write_file() + +cmake_policy(POP) diff --git a/rapids-cmake/cpm/detail/pinning_write_file.cmake b/rapids-cmake/cpm/detail/pinning_write_file.cmake new file mode 100644 index 000000000..8b423c0d9 --- /dev/null +++ b/rapids-cmake/cpm/detail/pinning_write_file.cmake @@ -0,0 +1,295 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +include_guard(GLOBAL) + +#[=======================================================================[.rst: +rapids_cpm_pinning_extract_source_git_info +------------------------------------------ + +.. versionadded:: v24.04.00 + +Extract the git url and git sha1 from the source directory of +the given package. + +Parameters: + +``package`` + Name of package to extract git url and git sha for + +``git_url_var`` + Holds the name of the variable to set in the calling scope with the + git url extracted from the package. + + If no git url can be found for the package, the variable won't be set. + +``git_sha_var`` + Holds the name of the variable to set in the calling scope with the + git sha1 extracted from the package. + + If no git sha1 can be found for the package, the variable won't be set. + +#]=======================================================================] +function(rapids_cpm_pinning_extract_source_git_info package git_url_var git_sha_var) + set(source_dir "${CPM_PACKAGE_${package}_SOURCE_DIR}") + set(_RAPIDS_URL) + set(_RAPIDS_SHA) + if(EXISTS "${source_dir}") + execute_process(COMMAND ${GIT_EXECUTABLE} ls-remote --get-url + WORKING_DIRECTORY ${source_dir} + ERROR_QUIET + OUTPUT_VARIABLE _RAPIDS_URL + OUTPUT_STRIP_TRAILING_WHITESPACE) + # Need to handle when we have applied N patch sets to the git repo and therefore the latest + # commit is just local + # + # Find all commits on our branch back to the common parent ( what we cloned ) + # + execute_process(COMMAND ${GIT_EXECUTABLE} show-branch --current --sha1-name + WORKING_DIRECTORY ${source_dir} + ERROR_QUIET + OUTPUT_VARIABLE _rapids_commit_stack + OUTPUT_STRIP_TRAILING_WHITESPACE) + # The last entry in the output that has "* [" is our commit + # + # Find that line and convert the `* [short-sha1] Commit Message` to a list that is ` * + # ;short-sha1;Commit Message` and extract the short sha1 + string(FIND "${_rapids_commit_stack}" "* [" position REVERSE) + if(position LESS 0) + # No changes to the repo so use the `HEAD` keyword + set(short_sha HEAD) + else() + string(SUBSTRING "${_rapids_commit_stack}" ${position} -1 _rapids_commit_stack) + string(REGEX REPLACE "(\\[|\\])" ";" _rapids_commit_stack "${_rapids_commit_stack}") + list(GET _rapids_commit_stack 1 short_sha) + endif() + + # Convert from the short sha1 ( could be keyword `HEAD` ) to a full SHA1 + execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse ${short_sha} + WORKING_DIRECTORY ${source_dir} + ERROR_QUIET + OUTPUT_VARIABLE _RAPIDS_SHA + OUTPUT_STRIP_TRAILING_WHITESPACE) + endif() + # Only set the provided variables if we extracted the information + if(_RAPIDS_URL) + set(${git_url_var} "${_RAPIDS_URL}" PARENT_SCOPE) + endif() + if(_RAPIDS_SHA) + set(${git_sha_var} "${_RAPIDS_SHA}" PARENT_SCOPE) + endif() + +endfunction() + +#[=======================================================================[.rst: +rapids_cpm_pinning_create_and_set_member +---------------------------------------- + +.. versionadded:: v24.04.00 + +Insert the given json key value pair into the provided json object variable. +If the key already exists in the json object, this will overwrite with the +new value. + +Parameters: + +``json_var`` + Variable name of the json object to both read and write too. + +``key`` + Holds the key that should be created/updated in the json object +``var`` + Holds the var that should be written to the json object + +#]=======================================================================] +function(rapids_cpm_pinning_create_and_set_member json_var key value) + + # Identify special values types that shouldn't be treated as a string + # https://gitlab.kitware.com/cmake/cmake/-/issues/25716 + if(value MATCHES "(^true$|^false$|^null$|^\\{|^\\[)") + # value is a json type that doesn't need quotes + string(JSON json_blob ERROR_VARIABLE err_var SET "${${json_var}}" ${key} ${value}) + else() + # We need to quote 'value' so that it is a valid string json element. + string(JSON json_blob ERROR_VARIABLE err_var SET "${${json_var}}" ${key} "\"${value}\"") + endif() + set(${json_var} "${json_blob}" PARENT_SCOPE) +endfunction() + +#[=======================================================================[.rst: +rapids_cpm_pinning_add_json_entry +--------------------------------- + +.. versionadded:: v24.04.00 + +Write a valid json object that represent the package with the updated +If the key already exists in the json object, this will overwrite with the +new value. + +The generated json object will have `git_shallow` as `false`, and +`always_download` as `true`. This ensures we always build from source, and +that we can safely fetch even when the SHA1 doesn't reference the tip of a named +branch/tag. + +Parameters: + +``package`` + Name of package to generate a valid json object for. + +``json_var`` + Variable name to write the generated json object to in the callers + scope. + +#]=======================================================================] +function(rapids_cpm_pinning_add_json_entry package_name json_var) + + # Make sure variables from the callers scope doesn't break us + unset(git_url) + unset(git_sha) + unset(url_string) + unset(sha_string) + rapids_cpm_pinning_extract_source_git_info(${package} git_url git_sha) + if(git_url) + string(CONFIGURE [=["git_url": "${git_url}",]=] url_string) + endif() + if(git_sha) + string(CONFIGURE [=["git_tag": "${git_sha}",]=] sha_string) + endif() + # We start with a default template, and only add members that don't exist + string(CONFIGURE [=[{ + "version": "${CPM_PACKAGE_${package_name}_VERSION}", + ${url_string} + ${sha_string} + "git_shallow": false, + "always_download": true + }]=] + pinned_json_entry) + + include("${rapids-cmake-dir}/cpm/detail/get_default_json.cmake") + include("${rapids-cmake-dir}/cpm/detail/get_override_json.cmake") + get_default_json(${package_name} json_data) + get_override_json(${package_name} override_json_data) + foreach(data IN LISTS override_json_data json_data) + if(NOT data) + # Need to handle both json_data and the override being empty + continue() + endif() + string(JSON entry_count LENGTH "${data}") + math(EXPR entry_count "${entry_count} - 1") + # cmake-lint: disable=E1120 + foreach(index RANGE ${entry_count}) + string(JSON member MEMBER "${data}" ${index}) + string(JSON existing_value ERROR_VARIABLE dont_have GET "${pinned_json_entry}" ${member}) + if(dont_have) + string(JSON value GET "${data}" ${member}) + rapids_cpm_pinning_create_and_set_member(pinned_json_entry ${member} ${value}) + endif() + endforeach() + endforeach() + set(${json_var} "\"${package_name}\": ${pinned_json_entry}" PARENT_SCOPE) +endfunction() + +#[=======================================================================[.rst: +rapids_cpm_pinning_write_file +----------------------------- + +.. versionadded:: v24.04.00 + +This function generates a rapids-cmake `versions.json` file that has +pinned versions of each project that resolved to an CPMAddPackage call for +this CMake project. + +This pinned versions.json file will be written to all output files +provided to :cmake:command:`rapids_cpm_generate_pinned_versions`. +#]=======================================================================] +function(rapids_cpm_pinning_write_file) + + find_package(Git QUIET REQUIRED) + + set(_rapids_json + [=[ +{ +"root": { +"packages": { +]=]) + + # initial pass to remove any packages that aren't checked out by source or an existing json entry. + # + # By doing this as an initial pass it makes the logic around `last_package` and trailing comma's + # significantly easier + set(packages) + set(ignored_packages) + foreach(package IN LISTS CPM_PACKAGES) + # Only add packages that have a src tree, that way we exclude packages that have been found + # locally via `CPMFindPackage` + if(NOT DEFINED CPM_PACKAGE_${package}_SOURCE_DIR) + # check to see if we have an rapids_cmake json entry, this catches all packages like nvcomp + # that don't have a source tree. + include("${rapids-cmake-dir}/cpm/detail/get_default_json.cmake") + include("${rapids-cmake-dir}/cpm/detail/get_override_json.cmake") + get_default_json(${package} json_data) + get_override_json(${package} override_json_data) + if(NOT (json_data OR override_json_data)) + list(APPEND ignored_packages ${package}) + continue() + endif() + endif() + list(APPEND packages ${package}) + endforeach() + + list(POP_BACK packages last_package) + foreach(package IN LISTS packages last_package) + # Clear variables so we don't re-use them between packages when one package doesn't have a git + # url or sha + set(git_url) + set(git_sha) + set(not_last_package TRUE) + if(package STREQUAL last_package) + set(not_last_package FALSE) + endif() + rapids_cpm_pinning_add_json_entry(${package} _rapids_entry) + if(not_last_package) + string(APPEND _rapids_entry [=[, +]=]) + else() + string(APPEND _rapids_entry [=[ +]=]) + endif() + string(APPEND _rapids_json "${_rapids_entry}") + endforeach() + + # Add closing braces + string(APPEND _rapids_json [=[}}}]=]) + + # We extract everything out of the fake `root` element so that we get a pretty JSON format from + # CMake. + string(JSON _rapids_json GET "${_rapids_json}" root) + + get_property(write_paths GLOBAL PROPERTY rapids_cpm_generate_pin_files) + foreach(path IN LISTS write_paths) + file(WRITE "${path}" "${_rapids_json}") + endforeach() + + # Setup status string to developer. + set(message_extra_info) + if(ignored_packages) + set(message_extra_info + "The following packages resolved to system installed versions: ${ignored_packages}. If you need those pinned to an explicit version please set `CPM_DOWNLOAD_ALL` and re-generate." + ) + endif() + + message(STATUS "rapids_cpm_generate_pinned_versions wrote version information. ${message_extra_info}" + ) +endfunction() diff --git a/rapids-cmake/cpm/generate_pinned_versions.cmake b/rapids-cmake/cpm/generate_pinned_versions.cmake new file mode 100644 index 000000000..ca85b2632 --- /dev/null +++ b/rapids-cmake/cpm/generate_pinned_versions.cmake @@ -0,0 +1,107 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +include_guard(GLOBAL) + +#[=======================================================================[.rst: +rapids_cpm_generate_pinned_versions +----------------------------------- + +.. versionadded:: v24.04.00 + +Generate a json file with all dependencies with pinned version values + +.. code-block:: cmake + + rapids_cpm_generate_pinned_versions( OUTPUT ) + +Generates a json file with all `CPM` dependencies with pinned version values. +This allows for subsequent reproducible builds using the exact same state. + +The rapids-cmake default `versions.json` uses branch names or git tag names +for dependencies. This is done so that projects can 'live at head' of dependencies. +By using :cmake:command:`rapids_cpm_package_override` a project can specify a custom +`versions.json` that specifies exact git SHA's so that projects have reproducible builds. + +:cmake:command:`rapids_cpm_generate_pinned_versions` can be used to transform a set of +rapids-cmake dependencies from branch names to pinned values. This can be used in subsequent +builds, e.g: + + 1. Have CI run with `versions.json` which tracks dependency by branch name + 2. Store the generated pinned `versions.json` from the CI builds + 3. If build is good, create the release branch and commit the generated pinned `versions.json` + to have reproducible builds for that release + +``OUTPUT`` +Specify a file path where the pinned versions information will be written. Can be called multiple +times and each unique path will be written to. + +The generated json file will have the following entries for each package: + +.. code-block:: json + + { + "version": "_VERSION>", + "git_url": "", + "git_tag": "", + "git_shallow": false, + "always_download": true + } + + +If the original package (or override) also had any `patches`, or `proprietary_binary` +fields those will be propagated to the generated entry. + +.. note:: + The git SHA1 computed for each package is found by finding the most recent + commit that can be cloned from the url. + + This means that for proper reproducible builds, all patches must be encapsulated + in the input json files or as CPM `PATCH_COMMAND`. + +#]=======================================================================] +function(rapids_cpm_generate_pinned_versions) + list(APPEND CMAKE_MESSAGE_CONTEXT "rapids.cpm.generate_pinned_versions") + + set(_rapids_options) + set(_rapids_one_value OUTPUT) + set(_rapids_multi_value) + cmake_parse_arguments(_RAPIDS "${_rapids_options}" "${_rapids_one_value}" + "${_rapids_multi_value}" ${ARGN}) + + if(NOT _RAPIDS_OUTPUT) + message(FATAL_ERROR "rapids_cpm_generate_pinned_versions requires an `OUTPUT` argument") + endif() + + find_package(Git QUIET) + if(NOT Git_FOUND) + message(FATAL_ERROR "rapids_cpm_generate_pinned_versions requires 'git' to exist") + endif() + + # Append the requested write path for `detail/write_pinned_versions.cmake` + set_property(GLOBAL APPEND PROPERTY rapids_cpm_generate_pin_files "${_RAPIDS_OUTPUT}") + + get_property(already_hooked GLOBAL PROPERTY rapids_cpm_generate_pin_hook SET) + if(NOT already_hooked) + # install a hook that writes out the pinned versions at the end of the root level CMakeLists.txt + # execution so we get all CPM packages added. Plus we can compute the paths once, and write out + # `N` times if needed + set(root_dir "${${CMAKE_PROJECT_NAME}_SOURCE_DIR}") + cmake_language(DEFER DIRECTORY ${root_dir} ID rapids_cpm_generate_pinned_versions CALL include + "${rapids-cmake-dir}/cpm/detail/pinning_root_dir_hook.cmake") + set_property(GLOBAL PROPERTY rapids_cpm_generate_pin_hook "ON") + endif() + +endfunction() diff --git a/rapids-cmake/cpm/init.cmake b/rapids-cmake/cpm/init.cmake index 140b31c78..d9d3a6577 100644 --- a/rapids-cmake/cpm/init.cmake +++ b/rapids-cmake/cpm/init.cmake @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -25,13 +25,21 @@ Establish the `CPM` and preset package infrastructure for the project. .. code-block:: cmake - rapids_cpm_init( [OVERRIDE ] ) + rapids_cpm_init( [OVERRIDE ] + [GENERATE_PINNED_VERSIONS] + ) The CPM module will be downloaded based on the state of :cmake:variable:`CPM_SOURCE_CACHE` and :cmake:variable:`ENV{CPM_SOURCE_CACHE}`. This allows multiple nested projects to share the same download of CPM. If those variables aren't set the file will be cached in the build tree of the calling project +.. versionadded:: v24.04.00 + As part of establishing rapids-cmake CPM the :cmake:command:`rapids_cpm_init` command + will call :cmake:command:`rapids_cpm_generate_pinned_versions` to automatically generate + `/rapids-cmake/pinned_versions.json` which will contain all the exact git SHAs + used to build cpm dependencies. + .. versionadded:: v21.10.00 ``OVERRIDE`` Override the `CPM` preset package information for the project. The user provided @@ -40,6 +48,14 @@ in the build tree of the calling project If the override file doesn't specify a value or package entry the default version will be used. +.. versionadded:: v24.04.00 + ``` + GENERATE_PINNED_VERSIONS + ``` + Generates a json file with all `CPM` dependencies with pinned version values. + This allows for reproducible builds using the exact same state. + The pinning file will be located at `/rapids-cmake/pinned_versions.json` + .. note:: Must be called before any invocation of :cmake:command:`rapids_cpm_find`. @@ -47,7 +63,7 @@ in the build tree of the calling project function(rapids_cpm_init) list(APPEND CMAKE_MESSAGE_CONTEXT "rapids.cpm.init") - set(_rapids_options) + set(_rapids_options GENERATE_PINNED_VERSIONS) set(_rapids_one_value OVERRIDE) set(_rapids_multi_value) cmake_parse_arguments(_RAPIDS "${_rapids_options}" "${_rapids_one_value}" @@ -61,6 +77,12 @@ function(rapids_cpm_init) rapids_cpm_package_override("${_RAPIDS_OVERRIDE}") endif() + if(_RAPIDS_GENERATE_PINNED_VERSIONS) + include("${rapids-cmake-dir}/cpm/generate_pinned_versions.cmake") + rapids_cpm_generate_pinned_versions( + OUTPUT "${CMAKE_BINARY_DIR}/rapids-cmake/pinned_versions.json") + endif() + include("${rapids-cmake-dir}/cpm/detail/download.cmake") rapids_cpm_download() diff --git a/rapids-cmake/cpm/patches/command_template.cmake.in b/rapids-cmake/cpm/patches/command_template.cmake.in index a164ea815..7efd2af05 100644 --- a/rapids-cmake/cpm/patches/command_template.cmake.in +++ b/rapids-cmake/cpm/patches/command_template.cmake.in @@ -49,6 +49,9 @@ function(rapids_cpm_run_git_patch file issue) ) endif() elseif(ext STREQUAL "patch") + # Setup a fake committer name/email so we execute everywhere + set(ENV{GIT_COMMITTER_NAME} "rapids-cmake" ) + set(ENV{GIT_COMMITTER_EMAIL} "rapids.cmake@rapids.ai" ) # no need to check if the git patch was already applied # `am` does that and returns a success error code for those cases execute_process( diff --git a/rapids-cmake/rapids-cpm.cmake b/rapids-cmake/rapids-cpm.cmake index 6a319700f..61a954873 100644 --- a/rapids-cmake/rapids-cpm.cmake +++ b/rapids-cmake/rapids-cpm.cmake @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -17,3 +17,4 @@ include_guard(GLOBAL) include(${CMAKE_CURRENT_LIST_DIR}/cpm/init.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cpm/find.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/cpm/generate_pinned_versions.cmake) diff --git a/testing/cpm/CMakeLists.txt b/testing/cpm/CMakeLists.txt index c06500966..73fb80785 100644 --- a/testing/cpm/CMakeLists.txt +++ b/testing/cpm/CMakeLists.txt @@ -23,10 +23,17 @@ add_cmake_config_test( cpm_find-existing-target ) add_cmake_config_test( cpm_find-existing-target-to-export-sets ) add_cmake_config_test( cpm_find-gtest-no-gmock ) add_cmake_config_test( cpm_find-options-escaped ) -add_cmake_config_test( cpm_find-patch-command ) +add_cmake_config_test( cpm_find-patch-command NO_CPM_CACHE) add_cmake_config_test( cpm_find-restore-cpm-vars ) add_cmake_config_test( cpm_find-version-explicit-install.cmake ) +add_cmake_build_test( cpm_generate_pins-format-patches NO_CPM_CACHE) +add_cmake_build_test( cpm_generate_pins-nested NO_CPM_CACHE) +add_cmake_build_test( cpm_generate_pins-override NO_CPM_CACHE) +add_cmake_build_test( cpm_generate_pins-no-src-dir ) +add_cmake_build_test( cpm_generate_pins-pure-cpm ) +add_cmake_build_test( cpm_generate_pins-simple NO_CPM_CACHE) + add_cmake_config_test( cpm_init-bad-override-path.cmake SHOULD_FAIL "rapids_cpm_package_override can't load") add_cmake_config_test( cpm_init-override-multiple.cmake ) add_cmake_config_test( cpm_init-override-simple.cmake ) diff --git a/testing/cpm/cpm_find-patch-command/CMakeLists.txt b/testing/cpm/cpm_find-patch-command/CMakeLists.txt index e5ff71191..cf443f063 100644 --- a/testing/cpm/cpm_find-patch-command/CMakeLists.txt +++ b/testing/cpm/cpm_find-patch-command/CMakeLists.txt @@ -30,8 +30,6 @@ endif() set(cccl_dir "${deps_dir}/cccl") list(APPEND CMAKE_PREFIX_PATH "${cccl_dir}") -unset(CPM_SOURCE_CACHE) -unset(CPM_SOURCE_CACHE CACHE) include(${rapids-cmake-dir}/cpm/init.cmake) include(${rapids-cmake-dir}/cpm/cccl.cmake) diff --git a/testing/cpm/cpm_generate_pins-format-patches/CMakeLists.txt b/testing/cpm/cpm_generate_pins-format-patches/CMakeLists.txt new file mode 100644 index 000000000..79bb09a07 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-format-patches/CMakeLists.txt @@ -0,0 +1,48 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +rapids_cpm_init(GENERATE_PINNED_VERSIONS) + +include(${rapids-cmake-dir}/cpm/package_override.cmake) +rapids_cpm_package_override(${CMAKE_CURRENT_SOURCE_DIR}/override.json) + +include(${rapids-cmake-dir}/cpm/rmm.cmake) +rapids_cpm_rmm(DOWNLOAD_ONLY ON) + +include(${rapids-cmake-dir}/cpm/cuco.cmake) +rapids_cpm_cuco(DOWNLOAD_ONLY ON) + +# Verify that the two files that we inserted into the RMM source tree exist +# Which proves the patches in the override are properly applied +if(NOT EXISTS "${rmm_SOURCE_DIR}/git_file_1.txt") + message(FATAL_ERROR "failed to apply rmm first patch") +endif() + +if(NOT EXISTS "${rmm_SOURCE_DIR}/git_file_2.txt") + message(FATAL_ERROR "failed to apply rmm second patch") +endif() + +# Verify that the one file that we inserted into the cuco source tree exists. +if(NOT EXISTS "${cuco_SOURCE_DIR}/git_file_1.txt") + message(FATAL_ERROR "failed to apply cucco first patch") +endif() + +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" -D"rapids-cmake-dir=${rapids-cmake-dir}" +) diff --git a/testing/cpm/cpm_generate_pins-format-patches/override.json b/testing/cpm/cpm_generate_pins-format-patches/override.json new file mode 100644 index 000000000..a352e842a --- /dev/null +++ b/testing/cpm/cpm_generate_pins-format-patches/override.json @@ -0,0 +1,33 @@ +{ + "packages": { + "cuco": { + "version": "0.0.1", + "git_shallow": false, + "git_url": "https://github.com/NVIDIA/cuCollections.git", + "git_tag": "f823d30d6b08a60383266db25821074dbdbe5822", + "patches": [ + { + "file": "${current_json_dir}/patches/0001-move-git-sha1.patch", + "issue": "Move git sha1", + "fixed_in": "" + } + ] + }, + "rmm": { + "version": "22.02", + "git_tag": "v22.02.00", + "patches": [ + { + "file": "${current_json_dir}/patches/0001-move-git-sha1.patch", + "issue": "Move git sha1", + "fixed_in": "" + }, + { + "file": "${current_json_dir}/patches/0002-move-git-sha1-a-second-time.patch", + "issue": "Move git sha1 a second time", + "fixed_in": "" + } + ] + } + } +} diff --git a/testing/cpm/cpm_generate_pins-format-patches/patches/0001-move-git-sha1.patch b/testing/cpm/cpm_generate_pins-format-patches/patches/0001-move-git-sha1.patch new file mode 100644 index 000000000..c721f9370 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-format-patches/patches/0001-move-git-sha1.patch @@ -0,0 +1,19 @@ +From deacd3fafd7fcfee954ae3044ae3ab60d36a9f3a Mon Sep 17 00:00:00 2001 +From: Robert Maynard +Date: Wed, 31 Jan 2024 15:00:47 -0500 +Subject: [PATCH 1/2] Move GIT SHA1 + +--- + git_file_1.txt | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 git_file_1.txt + +diff --git a/git_file_1.txt b/git_file_1.txt +new file mode 100644 +index 00000000..b242c360 +--- /dev/null ++++ b/git_file_1.txt +@@ -0,0 +1 @@ ++added file +-- +2.43.0 diff --git a/testing/cpm/cpm_generate_pins-format-patches/patches/0002-move-git-sha1-a-second-time.patch b/testing/cpm/cpm_generate_pins-format-patches/patches/0002-move-git-sha1-a-second-time.patch new file mode 100644 index 000000000..1986f6d51 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-format-patches/patches/0002-move-git-sha1-a-second-time.patch @@ -0,0 +1,19 @@ +From 3588e151030a30661b310a876f7cc450d6ca9201 Mon Sep 17 00:00:00 2001 +From: Robert Maynard +Date: Wed, 31 Jan 2024 15:01:21 -0500 +Subject: [PATCH 2/2] Move GIT SHA1 a second time + +--- + git_file_2.txt | 1 + + 1 file changed, 1 insertion(+) + create mode 100644 git_file_2.txt + +diff --git a/git_file_2.txt b/git_file_2.txt +new file mode 100644 +index 00000000..fa240558 +--- /dev/null ++++ b/git_file_2.txt +@@ -0,0 +1 @@ ++added another file +-- +2.43.0 diff --git a/testing/cpm/cpm_generate_pins-format-patches/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-format-patches/verify/CMakeLists.txt new file mode 100644 index 000000000..d7f8c1e8c --- /dev/null +++ b/testing/cpm/cpm_generate_pins-format-patches/verify/CMakeLists.txt @@ -0,0 +1,35 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../rapids-cmake/pinned_versions.json") + +# Verify that each git_tag is now different. +rapids_cpm_package_details(rmm rmm_version rmm_repository pin_rmm_tag rmm_shallow rmm_exclude) +rapids_cpm_package_details(cuco cuco_version cuco_repository pin_cuco_tag cuco_shallow cuco_exclude) + +if(NOT pin_rmm_tag STREQUAL "e3e32150d1bef13480ede4b2df1f0b38e43108a4") + message(FATAL_ERROR "pinned rmm tag (${pin_rmm_tag}) doesn't match pre-computed SHA1 for the 22.02 tag") +endif() +if(NOT pin_cuco_tag STREQUAL "f823d30d6b08a60383266db25821074dbdbe5822") + message(FATAL_ERROR "pinned cuco tag (${pin_cuco_tag}) doesn't match hardcoded SHA1(f823d30...)") +endif() diff --git a/testing/cpm/cpm_generate_pins-nested/CMakeLists.txt b/testing/cpm/cpm_generate_pins-nested/CMakeLists.txt new file mode 100644 index 000000000..5151d285b --- /dev/null +++ b/testing/cpm/cpm_generate_pins-nested/CMakeLists.txt @@ -0,0 +1,33 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +add_subdirectory(a) +add_subdirectory(b) + +# Turn on pin generation after cpm dependencies have been added +# to make sure it is order invariant +include(${rapids-cmake-dir}/cpm/init.cmake) +rapids_cpm_init(GENERATE_PINNED_VERSIONS) + +# don't check cuco here as it uses hashes and that breaks our verify script +set(projects-to-verify rmm fmt spdlog CCCL) +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" + -D"rapids-cmake-dir=${rapids-cmake-dir}" + -D"projects-to-verify=${projects-to-verify}" +) diff --git a/testing/cpm/cpm_generate_pins-nested/a/CMakeLists.txt b/testing/cpm/cpm_generate_pins-nested/a/CMakeLists.txt new file mode 100644 index 000000000..09aca1472 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-nested/a/CMakeLists.txt @@ -0,0 +1,23 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-a LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +rapids_cpm_init() + +include(${rapids-cmake-dir}/cpm/rmm.cmake) +rapids_cpm_rmm() diff --git a/testing/cpm/cpm_generate_pins-nested/b/CMakeLists.txt b/testing/cpm/cpm_generate_pins-nested/b/CMakeLists.txt new file mode 100644 index 000000000..cee194821 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-nested/b/CMakeLists.txt @@ -0,0 +1,28 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-b LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +rapids_cpm_init() + +include(${rapids-cmake-dir}/cpm/cccl.cmake) +include(${rapids-cmake-dir}/cpm/cuco.cmake) +include(${rapids-cmake-dir}/cpm/nvcomp.cmake) + +rapids_cpm_cccl() +rapids_cpm_cuco() +rapids_cpm_nvcomp() diff --git a/testing/cpm/cpm_generate_pins-nested/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-nested/verify/CMakeLists.txt new file mode 100644 index 000000000..918846b04 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-nested/verify/CMakeLists.txt @@ -0,0 +1,53 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() + +string(REPLACE " " ";" projects-to-verify "${projects-to-verify}") +if(NOT projects-to-verify) + message(FATAL_ERROR "Failed to pass anything in projects-to-verify") +endif() + +# Get the baseline before the override is added +foreach(proj IN LISTS projects-to-verify) + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository ${proj}_tag ${proj}_shallow ${proj}_exclude) +endforeach() + + +file(READ "${CMAKE_CURRENT_BINARY_DIR}/../rapids-cmake/pinned_versions.json" json_data) + +# Verify that the pinned_versions is valid json by using it +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../rapids-cmake/pinned_versions.json") + +foreach(proj IN LISTS projects-to-verify) + # Verify that each git_tag is now different. + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository pin_${proj}_tag pin_${proj}_shallow ${proj}_exclude) + if(pin_${proj}_tag STREQUAL ${proj}_tag) + message(FATAL_ERROR "pinned ${proj} tag (${pin_${proj}_tag}) should differ compared to baseline ${${proj}_tag}") + endif() + + # Everything should have shallow marked as false + # so that clones by SHA1 work + if(pin_${proj}_shallow) + message(FATAL_ERROR "pin_${proj}_shallow is expected to be false, but got ${pin_${proj}_shallow}") + endif() +endforeach() diff --git a/testing/cpm/cpm_generate_pins-no-src-dir/CMakeLists.txt b/testing/cpm/cpm_generate_pins-no-src-dir/CMakeLists.txt new file mode 100644 index 000000000..d84f1e3e6 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-no-src-dir/CMakeLists.txt @@ -0,0 +1,54 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/generate_pinned_versions.cmake) +include(${rapids-cmake-dir}/cpm/find.cmake) +include(${rapids-cmake-dir}/find/package.cmake) +rapids_cpm_init() +rapids_cpm_generate_pinned_versions(OUTPUT "${CMAKE_BINARY_DIR}/output_pinned_versions.json") + +set(PKG_VERSION 0.6.2) +set(PKG_REPOSITORY https://github.com/nmslib/hnswlib.git) +rapids_cpm_find( + hnswlib ${PKG_VERSION} + GLOBAL_TARGETS hnswlib::hnswlib + CPM_ARGS + GIT_REPOSITORY ${PKG_REPOSITORY} + GIT_TAG v${PKG_VERSION} + GIT_SHALLOW TRUE + DOWNLOAD_ONLY ON + EXCLUDE_FROM_ALL ON + ) + +# rapids_find_package should never be in CPM packages, but lets double check +rapids_find_package(Threads REQUIRED) + +# rapids_cpm_find for found system installed packages will be in CPM package +# So we need to verify that we don't generate a pinned versions entry +# for this package +rapids_cpm_find(ZLIB 1.0 REQUIRED) + +set(projects-to-verify hnswlib) +set(projects-not-in-list ZLIB Threads) +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" + -D"rapids-cmake-dir=${rapids-cmake-dir}" + -D"projects-to-verify=${projects-to-verify}" + -D"projects-not-in-list=${projects-not-in-list}" +) diff --git a/testing/cpm/cpm_generate_pins-no-src-dir/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-no-src-dir/verify/CMakeLists.txt new file mode 100644 index 000000000..7b4ccb404 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-no-src-dir/verify/CMakeLists.txt @@ -0,0 +1,64 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() + +string(REPLACE " " ";" projects-to-verify "${projects-to-verify}") +string(REPLACE " " ";" projects-not-in-list "${projects-not-in-list}") +if(NOT projects-to-verify) + message(FATAL_ERROR "Failed to pass anything in projects-to-verify") +endif() +if(NOT projects-not-in-list) + message(FATAL_ERROR "Failed to pass anything in projects-not-in-list") +endif() + +# Get the baseline before the override is added +foreach(proj IN LISTS projects-to-verify) + message(STATUS "${proj}") + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository ${proj}_tag ${proj}_shallow ${proj}_exclude) +endforeach() + +# Verify that the pinned_versions is valid json by using it +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../output_pinned_versions.json") + +foreach(proj IN LISTS projects-to-verify) + # Verify that each git_tag is now different. + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository pin_${proj}_tag ${proj}_shallow ${proj}_exclude) + if(pin_${proj}_tag STREQUAL ${proj}_tag) + message(FATAL_ERROR "pinned ${proj} tag (${pin_${proj}_tag}) should differ compared to baseline ${${proj}_tag}") + endif() + + # Everything should have shallow marked as false + # so that clones by SHA1 work + if(${proj}_shallow) + message(FATAL_ERROR "${proj}_shallow} is expected to be false, but got ${${proj}_shallow}") + endif() +endforeach() + +foreach(proj IN LISTS projects-not-in-list) + # Verify that we don't have entries for these + rapids_cpm_package_details(${proj} pin_${proj}_version ${proj}_repository pin_${proj}_tag ${proj}_shallow ${proj}_exclude) + if(pin_${proj}_version) + message(FATAL_ERROR "${proj} shouldn't in override, it was a system installed package") + endif() +endforeach() diff --git a/testing/cpm/cpm_generate_pins-override/CMakeLists.txt b/testing/cpm/cpm_generate_pins-override/CMakeLists.txt new file mode 100644 index 000000000..674e105be --- /dev/null +++ b/testing/cpm/cpm_generate_pins-override/CMakeLists.txt @@ -0,0 +1,42 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +rapids_cpm_init(GENERATE_PINNED_VERSIONS) + +# Need to write out an override file +file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/override.json + [=[ +{ + "packages" : { + "rmm" : { + "version" : "22.02", + "git_tag" : "v22.02.00" + } + } +} + ]=]) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +rapids_cpm_package_override(${CMAKE_CURRENT_BINARY_DIR}/override.json) + +include(${rapids-cmake-dir}/cpm/rmm.cmake) +rapids_cpm_rmm(DOWNLOAD_ONLY ON) + +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" -D"rapids-cmake-dir=${rapids-cmake-dir}" +) diff --git a/testing/cpm/cpm_generate_pins-override/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-override/verify/CMakeLists.txt new file mode 100644 index 000000000..fc330408a --- /dev/null +++ b/testing/cpm/cpm_generate_pins-override/verify/CMakeLists.txt @@ -0,0 +1,31 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../rapids-cmake/pinned_versions.json") + +# Verify that each git_tag is now different. +rapids_cpm_package_details(rmm rmm_version rmm_repository pin_rmm_tag rmm_shallow rmm_exclude) + +if(NOT pin_rmm_tag STREQUAL "e3e32150d1bef13480ede4b2df1f0b38e43108a4") + message(FATAL_ERROR "pinned rmm tag (${pin_rmm_tag}) doesn't match pre-computed SHA1 for the 22.02 tag") +endif() diff --git a/testing/cpm/cpm_generate_pins-pure-cpm/CMakeLists.txt b/testing/cpm/cpm_generate_pins-pure-cpm/CMakeLists.txt new file mode 100644 index 000000000..09cfff740 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-pure-cpm/CMakeLists.txt @@ -0,0 +1,43 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/generate_pinned_versions.cmake) +include(${rapids-cmake-dir}/cpm/find.cmake) +rapids_cpm_init() +rapids_cpm_generate_pinned_versions(OUTPUT "${CMAKE_BINARY_DIR}/output_pinned_versions.json") + +set(PKG_VERSION 0.6.2) +set(PKG_REPOSITORY https://github.com/nmslib/hnswlib.git) +rapids_cpm_find( + hnswlib ${PKG_VERSION} + GLOBAL_TARGETS hnswlib::hnswlib + CPM_ARGS + GIT_REPOSITORY ${PKG_REPOSITORY} + GIT_TAG v${PKG_VERSION} + GIT_SHALLOW TRUE + DOWNLOAD_ONLY ON + EXCLUDE_FROM_ALL ON + ) + +set(projects-to-verify hnswlib) +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" + -D"rapids-cmake-dir=${rapids-cmake-dir}" + -D"projects-to-verify=${projects-to-verify}" +) diff --git a/testing/cpm/cpm_generate_pins-pure-cpm/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-pure-cpm/verify/CMakeLists.txt new file mode 100644 index 000000000..e00af42d4 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-pure-cpm/verify/CMakeLists.txt @@ -0,0 +1,51 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() + +string(REPLACE " " ";" projects-to-verify "${projects-to-verify}") +if(NOT projects-to-verify) + message(FATAL_ERROR "Failed to pass anything in projects-to-verify") +endif() + +# Get the baseline before the override is added +foreach(proj IN LISTS projects-to-verify) + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository ${proj}_tag ${proj}_shallow ${proj}_exclude) +endforeach() + +# Verify that the pinned_versions is valid json by using it +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../output_pinned_versions.json") + +foreach(proj IN LISTS projects-to-verify) + # Verify that each git_tag is now different. + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository pin_${proj}_tag ${proj}_shallow ${proj}_exclude) + if(pin_${proj}_tag STREQUAL ${proj}_tag) + message(FATAL_ERROR "pinned ${proj} tag (${pin_${proj}_tag}) should differ compared to baseline ${${proj}_tag}") + endif() + + # Everything should have shallow marked as false + # so that clones by SHA1 work + if(${proj}_shallow) + message(FATAL_ERROR "${proj}_shallow} is expected to be false, but got ${${proj}_shallow}") + endif() +endforeach() diff --git a/testing/cpm/cpm_generate_pins-simple/CMakeLists.txt b/testing/cpm/cpm_generate_pins-simple/CMakeLists.txt new file mode 100644 index 000000000..6be743856 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-simple/CMakeLists.txt @@ -0,0 +1,30 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/rmm.cmake) + +rapids_cpm_init(GENERATE_PINNED_VERSIONS) +rapids_cpm_rmm() +set(projects-to-verify rmm fmt spdlog CCCL) +add_custom_target(verify_generated_pins ALL + COMMAND ${CMAKE_COMMAND} -S="${CMAKE_SOURCE_DIR}/verify/" -B"${CMAKE_BINARY_DIR}/verify_build" + -D"rapids-cmake-dir=${rapids-cmake-dir}" + -D"projects-to-verify=${projects-to-verify}" +) diff --git a/testing/cpm/cpm_generate_pins-simple/verify/CMakeLists.txt b/testing/cpm/cpm_generate_pins-simple/verify/CMakeLists.txt new file mode 100644 index 000000000..736662b74 --- /dev/null +++ b/testing/cpm/cpm_generate_pins-simple/verify/CMakeLists.txt @@ -0,0 +1,50 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= +cmake_minimum_required(VERSION 3.23.1) +project(rapids-test-project LANGUAGES CXX) + +include(${rapids-cmake-dir}/cpm/init.cmake) +include(${rapids-cmake-dir}/cpm/package_override.cmake) +include(${rapids-cmake-dir}/cpm/detail/package_details.cmake) + +rapids_cpm_init() + +string(REPLACE " " ";" projects-to-verify "${projects-to-verify}") +if(NOT projects-to-verify) + message(FATAL_ERROR "Failed to pass anything in projects-to-verify") +endif() + +# Get the baseline before the override is added +foreach(proj IN LISTS projects-to-verify) + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository ${proj}_tag ${proj}_shallow ${proj}_exclude) +endforeach() + +# Verify that the pinned_versions is valid json by using it +rapids_cpm_package_override("${CMAKE_CURRENT_BINARY_DIR}/../rapids-cmake/pinned_versions.json") + +foreach(proj IN LISTS projects-to-verify) + # Verify that each git_tag is now different. + rapids_cpm_package_details(${proj} ${proj}_version ${proj}_repository pin_${proj}_tag pin_${proj}_shallow ${proj}_exclude) + if(pin_${proj}_tag STREQUAL ${proj}_tag) + message(FATAL_ERROR "pinned ${proj} tag (${pin_${proj}_tag}) should differ compared to baseline ${${proj}_tag}") + endif() + + # Everything should have shallow marked as false + # so that clones by SHA1 work + if(pin_${proj}_shallow) + message(FATAL_ERROR "pin_${proj}_shallow is expected to be false, but got ${pin_${proj}_shallow}") + endif() +endforeach() diff --git a/testing/export/write_language-multiple-nested-enables/CMakeLists.txt b/testing/export/write_language-multiple-nested-enables/CMakeLists.txt index 8698a4b98..b9122d3a6 100644 --- a/testing/export/write_language-multiple-nested-enables/CMakeLists.txt +++ b/testing/export/write_language-multiple-nested-enables/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,11 +23,11 @@ project(write_language-multiple-nested-enable LANGUAGES NONE) # only installs one hook in `A` and `CMAKE_SOURCE_DIR` add_subdirectory(A) -#Verify number of hooks is equal to 2 +# Verify number of hooks is equal to 3 (2 langs, 1 rapids init hook) cmake_language(DEFER GET_CALL_IDS all_ids) list(LENGTH all_ids list_len) -if(NOT list_len EQUAL 2) - message(FATAL_ERROR "incorrect number of language hooks detected") +if(NOT list_len EQUAL 3) + message(FATAL_ERROR "incorrect number of language hooks detected ${all_ids}") endif() add_executable(write_language-multiple-nested-enable main.cpp) diff --git a/testing/other/CMakeLists.txt b/testing/other/CMakeLists.txt index 9e135d995..398181de6 100644 --- a/testing/other/CMakeLists.txt +++ b/testing/other/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,8 @@ # See the License for the specific language governing permissions and # limitations under the License. #============================================================================= -add_cmake_config_test( rapids_cmake-multiple-cpm ) -add_cmake_config_test( rapids_cmake-multiple-simple ) +add_cmake_config_test( rapids_cmake-multiple-cpm NO_RAPIDS_CMAKE_HOOKS) +add_cmake_config_test( rapids_cmake-multiple-simple NO_RAPIDS_CMAKE_HOOKS) -add_cmake_config_test( FetchContent-legacy ) -add_cmake_config_test( FetchContent-hostile-legacy ) +add_cmake_config_test( FetchContent-legacy NO_RAPIDS_CMAKE_HOOKS) +add_cmake_config_test( FetchContent-hostile-legacy NO_RAPIDS_CMAKE_HOOKS) diff --git a/testing/utils/cmake_test.cmake b/testing/utils/cmake_test.cmake index 61c875675..1b0b77c72 100644 --- a/testing/utils/cmake_test.cmake +++ b/testing/utils/cmake_test.cmake @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021-2023, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -35,6 +35,8 @@ adds a test for each generator: add_cmake_build_test( (config|build|test|install) [SERIAL] + [NO_CPM_CACHE] + [NO_RAPIDS_CMAKE_HOOKS] [SHOULD_FAIL ] ) @@ -58,7 +60,7 @@ adds a test for each generator: #]=======================================================================] function(add_cmake_test mode source_or_dir) - set(options SERIAL) + set(options SERIAL NO_CPM_CACHE NO_RAPIDS_CMAKE_HOOKS) set(one_value SHOULD_FAIL) set(multi_value) cmake_parse_arguments(RAPIDS_TEST "${options}" "${one_value}" "${multi_value}" ${ARGN}) @@ -81,8 +83,10 @@ function(add_cmake_test mode source_or_dir) message(FATAL_ERROR "Unable to find a file or directory named: ${source_or_dir}") endif() - set(extra_configure_flags) - if(DEFINED CPM_SOURCE_CACHE) + if(NOT RAPIDS_TEST_NO_RAPIDS_CMAKE_HOOKS) + set(extra_configure_flags "-DCMAKE_PROJECT_INCLUDE_BEFORE=${PROJECT_SOURCE_DIR}/utils/emulate_fetching_rapids_cmake.cmake") + endif() + if(DEFINED CPM_SOURCE_CACHE AND NOT RAPIDS_TEST_NO_CPM_CACHE) list(APPEND extra_configure_flags "-DCPM_SOURCE_CACHE=${CPM_SOURCE_CACHE}") endif() diff --git a/testing/utils/emulate_fetching_rapids_cmake.cmake b/testing/utils/emulate_fetching_rapids_cmake.cmake new file mode 100644 index 000000000..54491a5d6 --- /dev/null +++ b/testing/utils/emulate_fetching_rapids_cmake.cmake @@ -0,0 +1,50 @@ +#============================================================================= +# Copyright (c) 2024, NVIDIA CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +# Emulate the variables and properties that FetchContent would set so +# tests that themselves download rapids-cmake will use the version we have +# symlinked. +include(FetchContent) + +set(prefix "_FetchContent_rapids-cmake") +get_property(_rapids_already_hooked GLOBAL PROPERTY ${prefix}_populated DEFINED) +if(NOT _rapids_already_hooked) + set(local-rapids-cmake-root "${rapids-cmake-dir}/..") + cmake_path(NORMAL_PATH local-rapids-cmake-root) + + set(scratch_dir "${CMAKE_CURRENT_BINARY_DIR}/_deps") + + set(rapids-cmake_SOURCE_DIR "${scratch_dir}/rapids-cmake-src") + set(rapids-cmake_BINARY_DIR "${scratch_dir}/rapids-cmake-build") + set(rapids-cmake_POPULATED TRUE) + set_property(GLOBAL PROPERTY ${prefix}_sourceDir "${rapids-cmake_SOURCE_DIR}") + set_property(GLOBAL PROPERTY ${prefix}_binaryDir "${rapids-cmake_BINARY_DIR}") + define_property(GLOBAL PROPERTY ${prefix}_populated) + + # construct a symlink from the source to the build dir + # so we get the latest local changes without issue + execute_process( + COMMAND ${CMAKE_COMMAND} -E make_directory "${scratch_dir}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E create_symlink "${local-rapids-cmake-root}" "${rapids-cmake_SOURCE_DIR}" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + ECHO_OUTPUT_VARIABLE + ECHO_ERROR_VARIABLE) + unset(scratch_dir) + + message(STATUS "${local-rapids-cmake-root} -> ${rapids-cmake_SOURCE_DIR}") + add_subdirectory(${rapids-cmake_SOURCE_DIR} ${rapids-cmake_BINARY_DIR}) +endif() diff --git a/testing/utils/fill_cache/CMakeLists.txt b/testing/utils/fill_cache/CMakeLists.txt index 15cdf72ef..a0dcb751a 100644 --- a/testing/utils/fill_cache/CMakeLists.txt +++ b/testing/utils/fill_cache/CMakeLists.txt @@ -1,5 +1,5 @@ #============================================================================= -# Copyright (c) 2021-2023, NVIDIA CORPORATION. +# Copyright (c) 2021-2024, NVIDIA CORPORATION. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,7 +31,7 @@ include(${rapids-cmake-dir}/cpm/spdlog.cmake) include(${rapids-cmake-dir}/cpm/fmt.cmake) include(${rapids-cmake-dir}/cpm/thrust.cmake) -rapids_cpm_init() +rapids_cpm_init(GENERATE_PINNED_VERSIONS) set(CPM_SOURCE_CACHE "${CMAKE_BINARY_DIR}") diff --git a/testing/utils/project_template.cmake.in b/testing/utils/project_template.cmake.in index 7e33b42b4..24cdfd88e 100644 --- a/testing/utils/project_template.cmake.in +++ b/testing/utils/project_template.cmake.in @@ -15,38 +15,6 @@ #============================================================================= cmake_minimum_required(VERSION 3.23.1) -include(FetchContent) - -set(local-rapids-cmake-root "${rapids-cmake-dir}/..") -cmake_path(NORMAL_PATH local-rapids-cmake-root) - -set(scratch_dir "${CMAKE_CURRENT_BINARY_DIR}/_deps") - -# emulate the variables and properties that FetchContent would set so -# tests that themselves download rapids-cmake will use the version we have -# symlinked. -set(rapids-cmake_SOURCE_DIR "${scratch_dir}/rapids-cmake-src") -set(rapids-cmake_BINARY_DIR "${scratch_dir}/rapids-cmake-build") -set(rapids-cmake_POPULATED TRUE) -set(prefix "_FetchContent_rapids-cmake") -set_property(GLOBAL PROPERTY ${prefix}_sourceDir "${rapids-cmake_SOURCE_DIR}") -set_property(GLOBAL PROPERTY ${prefix}_binaryDir "${rapids-cmake_BINARY_DIR}") -define_property(GLOBAL PROPERTY ${prefix}_populated) - - -# construct a symlink from the source to the build dir -# so we get the latest local changes without issue -execute_process( - COMMAND ${CMAKE_COMMAND} -E make_directory "${scratch_dir}") -execute_process( - COMMAND ${CMAKE_COMMAND} -E create_symlink "${local-rapids-cmake-root}" "${rapids-cmake_SOURCE_DIR}" - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" - ECHO_OUTPUT_VARIABLE - ECHO_ERROR_VARIABLE) -unset(scratch_dir) - -add_subdirectory(${rapids-cmake_SOURCE_DIR} ${rapids-cmake_BINARY_DIR}) - # We need to enable at least one language so that we get properly # generated system search paths. project(@test_name_stem@ LANGUAGES CXX)