Skip to content

Commit

Permalink
Merge pull request #752 from rapidsai/branch-25.02
Browse files Browse the repository at this point in the history
Forward-merge branch-25.02 into branch-25.04
  • Loading branch information
GPUtester authored Jan 27, 2025
2 parents a773334 + 36939de commit 6f6bb6f
Show file tree
Hide file tree
Showing 12 changed files with 415 additions and 23 deletions.
25 changes: 19 additions & 6 deletions docs/cpm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -197,19 +197,32 @@ as needed.

The existence of a patch entry in the package definition being used will cause the `always_download` value always to be true.

.. literalinclude:: /packages/patches.json
:language: json

Each dictionary in the array of patches contains the following fields:

``file``
A required string representing the git diff ( .diff ) or patch ( .patch ) to apply.
Absolute and relative paths are supported. Relative paths are
evaluated in relation to the ``rapids-cmake/cpm/patches`` directory.

.. literalinclude:: /packages/patches.json
:language: json

Mutually exclusive string field with `inline_patch`. Only one of these fields may be provided.

Absolute or relative path to the git diff ( .diff ) or patch ( .patch ) to apply.
Relative paths are evaluated in relation to the ``rapids-cmake/cpm/patches`` directory.

Supports the following placeholders:
- ``${current_json_dir}`` will be evaluated to the absolute path to the directory holding the current json file

``inline_patch``

.. literalinclude:: /packages/patches_inline.json
:language: json

Mutually exclusive dictionary field with `file`. Only one of these fields may be provided.

Required keys for `inline_patch` are:
* `type` the format of the patch, either `diff` ( git diff ) or `patch` ( git format-patch ).
* `content` the lines of the patch file represented as an array of strings ( each element is a line ).

``issue``
A required string that explains the need for the patch. Preference is for the
string to also contain the URL to the upstream issue or PR that
Expand Down
33 changes: 33 additions & 0 deletions docs/packages/patches_inline.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"patches": [
{
"inline_patch": {
"type": "patch",
"content": [
"From deacd3fafd7fcfee954ae3044ae3ab60d36a9f3a Mon Sep 17 00:00:00 2001",
"From: Robert Maynard <rmaynard@nvidia.com>",
"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",
""
]
},
"issue": "Example of an inline patch",
"fixed_in": ""
}
]
}
96 changes: 96 additions & 0 deletions rapids-cmake/cpm/detail/convert_patch_json.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#=============================================================================
# Copyright (c) 2024-2025, 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_convert_patch_json
-------------------------------
.. versionadded:: v25.02.00
.. code-block:: cmake
rapids_cpm_convert_patch_json( (FROM_JSON_TO_FILE|FROM_FILE_TO_JSON)
<json_var>
FILE_VAR <path>
<PACKAGE_NAME package_name INDEX index> # required for FROM_JSON_TO_FILE
)
#]=======================================================================]
function(rapids_cpm_convert_patch_json)
list(APPEND CMAKE_MESSAGE_CONTEXT "rapids.cpm.conver_path_json")

set(options)
set(one_value FROM_JSON_TO_FILE FROM_FILE_TO_JSON FILE_VAR PACKAGE_NAME INDEX)
set(multi_value)
cmake_parse_arguments(_RAPIDS "${options}" "${one_value}" "${multi_value}" ${ARGN})

if(NOT _RAPIDS_FILE_VAR)
message(FATAL_ERROR "rapids_cpm_convert_patch_json required field of `FILE_VAR` is missing")
endif()

if(_RAPIDS_FROM_JSON_TO_FILE)
set(json "${${_RAPIDS_FROM_JSON_TO_FILE}}")

string(JSON type GET "${json}" "type")
string(JSON json_content GET "${json}" "content")

# Figure out the file path
set(file
"${CMAKE_BINARY_DIR}/rapids-cmake/patches/${_RAPIDS_PACKAGE_NAME}/embedded_patch_${_RAPIDS_INDEX}.${type}"
)

# Transform from a list of strings to a single file
string(JSON content_length LENGTH "${json_content}")
math(EXPR content_length "${content_length} - 1")
unset(file_content)
# cmake-lint: disable=E1120
foreach(index RANGE ${content_length})
string(JSON line GET "${json_content}" ${index})
string(APPEND file_content "${line}\n")
endforeach()
file(WRITE "${file}" "${file_content}")

set(${_RAPIDS_FILE_VAR} "${file}" PARENT_SCOPE)
elseif(_RAPIDS_FROM_FILE_TO_JSON)
# extract contents from `file`
file(STRINGS "${${_RAPIDS_FILE_VAR}}" file_content)
list(LENGTH file_content content_length)

# Get the file extension
cmake_path(GET ${_RAPIDS_FILE_VAR} EXTENSION LAST_ONLY patch_ext)
string(SUBSTRING "${patch_ext}" 1 -1 patch_ext)

# add each line as a json array element
set(inline_patch [=[ [ ] ]=])
foreach(line IN LISTS file_content)
string(JSON inline_patch SET "${inline_patch}" ${content_length} "\"${line}\"")
endforeach()

set(json_content
[=[{
"type" : "",
"content" : []
}]=])
string(JSON json_content SET "${json_content}" "type" "\"${patch_ext}\"")
string(JSON json_content SET "${json_content}" "content" "${inline_patch}")
set(${_RAPIDS_FROM_FILE_TO_JSON} "${json_content}" PARENT_SCOPE)
else()
message(FATAL_ERROR "rapids_cpm_convert_patch_json unsupported mode: ${mode}")
endif()

endfunction()
12 changes: 11 additions & 1 deletion rapids-cmake/cpm/detail/generate_patch_command.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#=============================================================================
# Copyright (c) 2022-2024, NVIDIA CORPORATION.
# Copyright (c) 2022-2025, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -88,7 +88,16 @@ function(rapids_cpm_generate_patch_command package_name version patch_command)
rapids_cpm_json_get_value(${patch_data} fixed_in)
if(NOT fixed_in OR version VERSION_LESS fixed_in)
rapids_cpm_json_get_value(${patch_data} file)
rapids_cpm_json_get_value(${patch_data} inline_patch)
rapids_cpm_json_get_value(${patch_data} issue)

# Convert any embedded patch to a file.
if(inline_patch)
include("${rapids-cmake-dir}/cpm/detail/convert_patch_json.cmake")
rapids_cpm_convert_patch_json(FROM_JSON_TO_FILE inline_patch FILE_VAR file PACKAGE_NAME
${package_name} INDEX ${index})
endif()

if(file AND issue)
cmake_language(EVAL CODE "set(file ${file})")
cmake_path(IS_RELATIVE file is_relative)
Expand All @@ -103,6 +112,7 @@ function(rapids_cpm_generate_patch_command package_name version patch_command)
list(APPEND patch_required_to_apply "${required}")
endif()
unset(file)
unset(inline_patch)
unset(issue)
endif()
endforeach()
Expand Down
8 changes: 4 additions & 4 deletions rapids-cmake/cpm/detail/load_preset_versions.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#=============================================================================
# Copyright (c) 2021-2024, NVIDIA CORPORATION.
# Copyright (c) 2021-2025, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -49,7 +49,7 @@ function(rapids_cpm_load_preset_versions)
endif()

if(NOT EXISTS "${_rapids_preset_version_file}")
message(FATAL_ERROR "rapids_cpm can't load '${filepath}' to find package version information, verify it exists"
message(FATAL_ERROR "rapids_cpm can't load '${_rapids_preset_version_file}' to find package version information, verify it exists"
)
endif()

Expand Down Expand Up @@ -85,8 +85,8 @@ function(rapids_cpm_load_preset_versions)
)
else()
set_property(GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_json "${data}")
set_property(GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_json_file "${filepath}")

set_property(GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_json_file
"${_rapids_preset_version_file}")
set_property(GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_proper_name "${package_name}")
endif()
endforeach()
Expand Down
89 changes: 84 additions & 5 deletions rapids-cmake/cpm/detail/pinning_write_file.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#=============================================================================
# Copyright (c) 2024, NVIDIA CORPORATION.
# Copyright (c) 2024-2025, NVIDIA CORPORATION.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -93,6 +93,65 @@ function(rapids_cpm_pinning_extract_source_git_info package git_url_var git_sha_

endfunction()

#[=======================================================================[.rst:
rapids_cpm_pinning_transform_patches
------------------------------------
.. versionadded:: v25.02.00
Transform the `patches` value json string to not reference any files
on disk but instead embed the patches contents directly in the json
Parameters:
``value_var``
Variable name of the json object of the patch content to transform
#]=======================================================================]
function(rapids_cpm_pinning_transform_patches package_name patches_array_var output_var)

include("${rapids-cmake-dir}/cpm/detail/convert_patch_json.cmake")

# We need to get the `files` key and transform it
set(json_data "${${patches_array_var}}")
string(JSON patch_count LENGTH "${json_data}")
if(patch_count GREATER_EQUAL 1)

# Setup state so that we can eval `current_json_dir` placeholder
string(TOLOWER "${package_name}" normalized_pkg_name)
get_property(json_path GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_override_json_file)
if(NOT json_path)
get_property(json_path GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_json_file)
endif()
cmake_path(GET json_path PARENT_PATH current_json_dir)

math(EXPR patch_count "${patch_count} - 1")
# cmake-lint: disable=E1120
foreach(index RANGE ${patch_count})
string(JSON patch_data GET "${json_data}" ${index})
string(JSON file_path ERROR_VARIABLE have_error GET "${patch_data}" file)
cmake_language(EVAL CODE "set(file_path ${file_path})")
if(file_path)
# Eval the file to transform `current_json_dir`
cmake_path(IS_RELATIVE file_path is_relative)
if(is_relative)
string(PREPEND file_path "${rapids-cmake-dir}/cpm/patches/")
endif()

# Read the file and transform to string
rapids_cpm_convert_patch_json(FROM_FILE_TO_JSON as_json FILE_VAR file_path)
# Remove the the file entry and replace it with the correct inline json format
string(JSON patch_data ERROR_VARIABLE have_error REMOVE "${patch_data}" file)
set(json_key "inline_patch")
string(JSON patch_data ERROR_VARIABLE have_error SET "${patch_data}" "${json_key}"
"${as_json}")
string(JSON json_data SET "${json_data}" ${index} "${patch_data}")
endif()
endforeach()
endif()
set(${output_var} "${json_data}" PARENT_SCOPE)
endfunction()

#[=======================================================================[.rst:
rapids_cpm_pinning_create_and_set_member
----------------------------------------
Expand All @@ -105,6 +164,9 @@ new value.
Parameters:
``package_name``
Name of the project that this json object is associated to.
``json_var``
Variable name of the json object to both read and write too.
Expand All @@ -114,8 +176,12 @@ Parameters:
Holds the var that should be written to the json object
#]=======================================================================]
function(rapids_cpm_pinning_create_and_set_member json_var key value)
function(rapids_cpm_pinning_create_and_set_member package_name json_var key value)

if(key MATCHES "patches")
# Transform inplace the value to only have inline patches
rapids_cpm_pinning_transform_patches(${package_name} value value)
endif()
# 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$|^\\{|^\\[)")
Expand Down Expand Up @@ -181,7 +247,19 @@ function(rapids_cpm_pinning_add_json_entry package_name json_var)
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)

set(override_exclusion_list "")
set(json_exclusion_list "")
# patch and proprietary_binary can't propagate if an override exists
if(override_json_data)
list(APPEND json_exclusion_list "patch" "proprietary_binary")
endif()

set(data_list override_json_data json_data)
set(exclusion_list override_exclusion_list json_exclusion_list)
foreach(data_var exclusion_var IN ZIP_LISTS data_list exclusion_list)
set(data "${${data_var}}")
set(exclusions "${${exclusion_var}}")
if(NOT data)
# Need to handle both json_data and the override being empty
continue()
Expand All @@ -192,9 +270,10 @@ function(rapids_cpm_pinning_add_json_entry package_name json_var)
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)
if(dont_have AND (NOT member IN_LIST exclusions))
string(JSON value GET "${data}" ${member})
rapids_cpm_pinning_create_and_set_member(pinned_json_entry ${member} ${value})
rapids_cpm_pinning_create_and_set_member(${package_name} pinned_json_entry ${member}
${value})
endif()
endforeach()
endforeach()
Expand Down
1 change: 1 addition & 0 deletions testing/cpm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ 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 NO_CPM_CACHE )
add_cmake_config_test( cpm_find-patch-command-embedded NO_CPM_CACHE )
add_cmake_config_test( cpm_find-patch-command-required NO_CPM_CACHE )
add_cmake_config_test( cpm_find-patch-command-required-fails NO_CPM_CACHE SHOULD_FAIL "rapids-cmake [fmt]: failed to apply patch")
add_cmake_config_test( cpm_find-restore-cpm-vars )
Expand Down
Loading

0 comments on commit 6f6bb6f

Please sign in to comment.