Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 35 additions & 11 deletions rapids-cmake/cpm/detail/generate_patch_command.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2022-2025, NVIDIA CORPORATION.
# SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
Expand All @@ -19,7 +19,7 @@ Applies any relevant patches to the provided CPM package
rapids_cpm_generate_patch_command(<pkg> <version> patch_command build_patch_only)

#]=======================================================================]
# cmake-lint: disable=R0915,E1120
# cmake-lint: disable=R0912,R0915,E1120
function(rapids_cpm_generate_patch_command package_name version patch_command build_patch_only)
list(APPEND CMAKE_MESSAGE_CONTEXT "rapids.cpm.generate_patch_command")

Expand All @@ -28,16 +28,16 @@ function(rapids_cpm_generate_patch_command package_name version patch_command bu

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)
get_default_json(${package_name} full_default_json)
get_override_json(${package_name} full_override_json)

string(TOLOWER "${package_name}" normalized_pkg_name)
get_property(json_path GLOBAL PROPERTY rapids_cpm_${normalized_pkg_name}_json_file)
get_property(override_json_path GLOBAL
PROPERTY rapids_cpm_${normalized_pkg_name}_override_json_file)

string(JSON json_data ERROR_VARIABLE no_default_patch GET "${json_data}" patches)
string(JSON override_json_data ERROR_VARIABLE no_override_patch GET "${override_json_data}"
string(JSON json_data ERROR_VARIABLE no_default_patch GET "${full_default_json}" patches)
string(JSON override_json_data ERROR_VARIABLE no_override_patch GET "${full_override_json}"
patches)
if(no_default_patch AND no_override_patch)
return() # no patches
Expand All @@ -59,11 +59,35 @@ function(rapids_cpm_generate_patch_command package_name version patch_command bu
endif()
endfunction()

# Need Git to apply the patches
find_package(Git REQUIRED)
if(NOT GIT_EXECUTABLE)
message(WARNING "Unable to apply git patches to ${package_name}, git not found")
return()
# Determine if the package uses git or URL (tarball) mode to select the patch tool. An override
# that specifies git fields switches the package to git mode; an override that specifies url
# fields switches it to url mode. Otherwise fall back to the default JSON.
set(use_git_patch TRUE)
if(full_override_json)
string(JSON _v ERROR_VARIABLE no_url GET "${full_override_json}" url)
string(JSON _v ERROR_VARIABLE no_git_url GET "${full_override_json}" git_url)
if(no_url AND no_git_url)
string(JSON _v ERROR_VARIABLE no_url GET "${full_default_json}" url)
endif()
else()
string(JSON _v ERROR_VARIABLE no_url GET "${full_default_json}" url)
endif()
if(NOT no_url)
set(use_git_patch FALSE)
endif()
Comment thread
robertmaynard marked this conversation as resolved.

if(use_git_patch)
find_package(Git REQUIRED)
if(NOT GIT_EXECUTABLE)
message(WARNING "Unable to apply git patches to ${package_name}, git not found")
return()
endif()
else()
find_package(Patch REQUIRED)
if(NOT Patch_EXECUTABLE)
message(WARNING "Unable to apply patches to ${package_name}, patch not found")
return()
endif()
endif()
# For each project cache the subset of the json
set(patch_files_to_run)
Expand Down
26 changes: 16 additions & 10 deletions rapids-cmake/cpm/detail/pinning_write_file.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -272,20 +272,26 @@ function(rapids_cpm_pinning_add_json_entry package_name json_var)
get_default_json(${package_name} json_data)
get_override_json(${package_name} override_json_data)

# Determine if this package uses URL mode (url + url_hash) or git mode (git_url + git_tag) Check
# override first, then default
# Determine if this package uses URL mode (url + url_hash) or git mode (git_url + git_tag). The
# override can switch modes: if the override provides git fields, use git mode regardless of the
# default. If the override provides url fields, use url mode. Only fall back to the default if the
# override doesn't specify either mode.
set(is_url_mode FALSE)
string(JSON url_value ERROR_VARIABLE no_url_override GET "${override_json_data}" url)
string(JSON url_hash_value ERROR_VARIABLE no_url_hash_override GET "${override_json_data}"
url_hash)
if(NOT no_url_override AND NOT no_url_hash_override)
set(is_url_mode TRUE)
if(override_json_data)
string(JSON value ERROR_VARIABLE no_git_url GET "${override_json_data}" git_url)
string(JSON value ERROR_VARIABLE no_git_tag GET "${override_json_data}" git_tag)
string(JSON url_value ERROR_VARIABLE no_url GET "${override_json_data}" url)
string(JSON url_hash_value ERROR_VARIABLE no_url_hash GET "${override_json_data}" url_hash)
if(no_url AND no_url_hash AND no_git_url AND no_git_tag)
string(JSON url_value ERROR_VARIABLE no_url GET "${json_data}" url)
string(JSON url_hash_value ERROR_VARIABLE no_url_hash GET "${json_data}" url_hash)
endif()
else()
string(JSON url_value ERROR_VARIABLE no_url GET "${json_data}" url)
string(JSON url_hash_value ERROR_VARIABLE no_url_hash GET "${json_data}" url_hash)
if(NOT no_url AND NOT no_url_hash)
set(is_url_mode TRUE)
endif()
endif()
if(NOT no_url AND NOT no_url_hash)
set(is_url_mode TRUE)
endif()

rapids_cpm_pinning_extract_source_subdir(${package} source_subdir)
Expand Down
50 changes: 49 additions & 1 deletion rapids-cmake/cpm/patches/command_template.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

set(msg_state)
set(error_state)
set(use_git_patch @use_git_patch@)

function(rapids_cpm_run_git_patch file issue require)
set(git_command @GIT_EXECUTABLE@)
cmake_path(GET file FILENAME file_name)
Expand Down Expand Up @@ -67,6 +69,48 @@ function(rapids_cpm_run_git_patch file issue require)
set(error_state ${error_state} PARENT_SCOPE)
endfunction()

function(rapids_cpm_run_patch file issue require)
set(patch_command @Patch_EXECUTABLE@)
cmake_path(GET file FILENAME file_name)
cmake_path(GET file_name EXTENSION LAST_ONLY ext)
string(SUBSTRING "${ext}" 1 -1 ext)

if(NOT (ext STREQUAL "diff" OR ext STREQUAL "patch") )
list(APPEND msg_state "rapids-cmake: Unable to apply ${file} as ${ext} is unsupported. Only .diff and .patch are supported")
set(msg_state ${msg_state} PARENT_SCOPE)
return()
endif()

set(result 1)
execute_process(
COMMAND ${patch_command} -p1 -i ${file}
RESULT_VARIABLE result
ERROR_VARIABLE repo_error_info
)
if(NOT result EQUAL 0)
# See if the patch was previously applied
execute_process(
COMMAND ${patch_command} -p1 --reverse --dry-run -i ${file}
RESULT_VARIABLE result
)
endif()

# Setup where we log error message too
set(error_msg_var msg_state)
if(require)
set(error_msg_var error_state)
endif()

if(result EQUAL 0)
list(APPEND msg_state "rapids-cmake [@package_name@]: applied ${ext} ${file_name} to fix issue: '${issue}'\n")
else()
list(APPEND ${error_msg_var} "rapids-cmake [@package_name@]: failed to apply ${ext} ${file_name}\n")
list(APPEND ${error_msg_var} "rapids-cmake [@package_name@]: patch output: ${repo_error_info}\n")
endif()
set(msg_state ${msg_state} PARENT_SCOPE)
set(error_state ${error_state} PARENT_SCOPE)
endfunction()

# We want to ensure that any patched files have a timestamp
# that is at least 1 second newer compared to the git checkout
# This ensures that all of CMake up-to-date install logic
Expand All @@ -83,7 +127,11 @@ set(required "@patch_required_to_apply@")
set(output_file "@log_file@")
set(error_file "@err_file@")
foreach(file issue require IN ZIP_LISTS files issues required)
rapids_cpm_run_git_patch(${file} ${issue} ${require})
if(use_git_patch)
rapids_cpm_run_git_patch(${file} ${issue} ${require})
else()
rapids_cpm_run_patch(${file} ${issue} ${require})
endif()
endforeach()
if(msg_state)
file(WRITE "${output_file}" ${msg_state})
Expand Down
15 changes: 11 additions & 4 deletions testing/cpm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,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 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
add_cmake_config_test(cpm_find-patch-command-git NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-tarball NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-diff-git NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-diff-tarball NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-embedded-git NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-embedded-tarball NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-required-git NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-required-tarball NO_CPM_CACHE)
add_cmake_config_test(cpm_find-patch-command-required-fails-git NO_CPM_CACHE SHOULD_FAIL
"rapids-cmake [GTest]: failed to apply patch")
add_cmake_config_test(cpm_find-patch-command-required-fails-tarball NO_CPM_CACHE SHOULD_FAIL
"rapids-cmake [GTest]: failed to apply patch")
add_cmake_config_test(cpm_find-restore-cpm-vars)
add_cmake_config_test(cpm_find-version-explicit-install.cmake)
Expand Down
41 changes: 41 additions & 0 deletions testing/cpm/cpm_find-patch-command-diff-git/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 3.30.4)
project(rapids-cpm_find-patch-command-project LANGUAGES CXX)

include(${rapids-cmake-dir}/cpm/init.cmake)
rapids_cpm_init()

include(${rapids-cmake-dir}/cpm/package_override.cmake)
rapids_cpm_package_override(${CMAKE_CURRENT_SOURCE_DIR}/override.json)

include("${rapids-cmake-dir}/cpm/detail/package_details.cmake")
rapids_cpm_package_details_internal(GTest version repository tag src_subdir shallow exclude)

set(deps_dir "${CMAKE_CURRENT_BINARY_DIR}/_gtest_dep")
if(NOT EXISTS "${deps_dir}")
file(MAKE_DIRECTORY "${deps_dir}")
find_package(Git)
execute_process(COMMAND ${GIT_EXECUTABLE} clone --depth 1 --branch "${tag}" "${repository}"
WORKING_DIRECTORY "${deps_dir}")
endif()

set(gtest_dir "${deps_dir}/googletest")
list(APPEND CMAKE_PREFIX_PATH "${gtest_dir}")

include(${rapids-cmake-dir}/cpm/gtest.cmake)
rapids_cpm_gtest()

if(NOT "${GTest_ADDED}")
message(FATAL_ERROR "The found repo was used rather than downloading and patching a new version")
endif()

# Verify that the file inserted by the .diff patch exists, proving that git apply (in git mode)
# correctly applied a .diff file.
if(NOT EXISTS "${GTest_SOURCE_DIR}/git_file_1.txt")
message(FATAL_ERROR "failed to apply GTest diff patch")
endif()
15 changes: 15 additions & 0 deletions testing/cpm/cpm_find-patch-command-diff-git/override.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"packages": {
"GTest": {
"git_url": "https://github.com/google/googletest.git",
"git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5",
"patches": [
{
"file": "${current_json_dir}/patches/0001-add-file.diff",
"issue": "Add file via diff",
"fixed_in": ""
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
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
42 changes: 42 additions & 0 deletions testing/cpm/cpm_find-patch-command-diff-tarball/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 3.30.4)
project(rapids-cpm_find-patch-command-project LANGUAGES CXX)

include(${rapids-cmake-dir}/cpm/init.cmake)
rapids_cpm_init()

include(${rapids-cmake-dir}/cpm/package_override.cmake)
rapids_cpm_package_override(${CMAKE_CURRENT_SOURCE_DIR}/override.json)

include("${rapids-cmake-dir}/cpm/detail/package_details.cmake")
rapids_cpm_package_details_internal(GTest version repository tag src_subdir shallow exclude)

set(deps_dir "${CMAKE_CURRENT_BINARY_DIR}/_gtest_dep")
if(NOT EXISTS "${deps_dir}")
file(MAKE_DIRECTORY "${deps_dir}")
file(DOWNLOAD "${repository}" "${deps_dir}/gtest.tar.gz")
file(ARCHIVE_EXTRACT INPUT "${deps_dir}/gtest.tar.gz" DESTINATION "${deps_dir}")
file(GLOB extracted_dir "${deps_dir}/googletest-*")
file(RENAME "${extracted_dir}" "${deps_dir}/googletest")
endif()

set(gtest_dir "${deps_dir}/googletest")
list(APPEND CMAKE_PREFIX_PATH "${gtest_dir}")

include(${rapids-cmake-dir}/cpm/gtest.cmake)
rapids_cpm_gtest()

if(NOT "${GTest_ADDED}")
message(FATAL_ERROR "The found repo was used rather than downloading and patching a new version")
endif()

# Verify that the file inserted by the .diff patch exists, proving that patch -p1 (in tarball mode)
# correctly applied a .diff file.
if(NOT EXISTS "${GTest_SOURCE_DIR}/git_file_1.txt")
message(FATAL_ERROR "failed to apply GTest diff patch")
endif()
15 changes: 15 additions & 0 deletions testing/cpm/cpm_find-patch-command-diff-tarball/override.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"packages": {
"GTest": {
"url": "https://github.com/google/googletest/archive/6910c9d9165801d8827d628cb72eb7ea9dd538c5.tar.gz",
"url_hash": "SHA256=bde221be7f3841fcbc3971665d77d717116394a42155d988ee6407dfc39f1f09",
"patches": [
{
"file": "${current_json_dir}/patches/0001-add-file.diff",
"issue": "Add file via diff",
"fixed_in": ""
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
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
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
# =============================================================================
# cmake-format: off
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION.
# SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION.
# SPDX-License-Identifier: Apache-2.0
# cmake-format: on
# =============================================================================
cmake_minimum_required(VERSION 3.26.4)
project(rapids-cpm_find-patch-command-project LANGUAGES CXX)

include(${rapids-cmake-dir}/cpm/init.cmake)
rapids_cpm_init()

include(${rapids-cmake-dir}/cpm/package_override.cmake)
rapids_cpm_package_override(${CMAKE_CURRENT_SOURCE_DIR}/override.json)

include("${rapids-cmake-dir}/cpm/detail/package_details.cmake")
rapids_cpm_package_details_internal(GTest version repository tag src_subdir shallow exclude)

Expand All @@ -21,12 +27,6 @@ endif()
set(gtest_dir "${deps_dir}/googletest")
list(APPEND CMAKE_PREFIX_PATH "${gtest_dir}")

include(${rapids-cmake-dir}/cpm/init.cmake)
rapids_cpm_init()

include(${rapids-cmake-dir}/cpm/package_override.cmake)
rapids_cpm_package_override(${CMAKE_CURRENT_SOURCE_DIR}/override.json)

include(${rapids-cmake-dir}/cpm/gtest.cmake)
rapids_cpm_gtest()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"packages": {
"GTest": {
"git_url": "https://github.com/google/googletest.git",
"git_tag": "6910c9d9165801d8827d628cb72eb7ea9dd538c5",
"patches": [
{
"inline_patch": {
Expand Down
Loading
Loading