Skip to content

Commit

Permalink
rapids_cpm_find is more invariant as one would expect (#51)
Browse files Browse the repository at this point in the history
Fixes #49

rapids_cpm_find now looks at the `GLOBAL_TARGETS` entries and will not call CPMFindPackage if any of them already exist.

This makes it safe to call `rapids_cpm_find` no matter what existing targets already exist. therefore users of rapids-cmake don't need to do manual `if(TARGET ...)` checks, resulting in missing packages in the export set.

Authors:
  - Robert Maynard (https://github.com/robertmaynard)

Approvers: None

URL: #51
  • Loading branch information
robertmaynard authored Aug 2, 2021
1 parent 95d8cbd commit f367fe6
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 14 deletions.
44 changes: 31 additions & 13 deletions rapids-cmake/cpm/find.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,6 @@ consistency. List all targets used by your project in `GLOBAL_TARGET`.
.. note::
Requires :cmake:command:`rapids_cpm_init` to be called before usage

.. note::
Adding an export set to :cmake:command:`rapids_cpm_find` has different behavior
for build and install. Build exports a respective CPM call, since
we presume other CPM packages don't generate a correct build directory
config module. While install exports a `find_dependency` call as
we expect projects to have a valid install setup.

If you need different behavior you will need to use :cmake:command:`rapids_export_package()`
or :cmake:command:`rapids_export_cpm()`.

``PackageName``
Name of the package to find.

Expand All @@ -64,6 +54,13 @@ consistency. List all targets used by your project in `GLOBAL_TARGET`.
Which targets from this package should be made global. This information
will be propagated to any associated export set.

.. versionchanged:: v21.10.00
If any targets listed in `GLOBAL_TARGET` exist when :cmake:command:`rapids_cpm_find` is called
no calls to `CPM` will be executed. This is done for the following reasons:

- Removes the need for the calling code to do the conditional checks
- Allows `BUILD_EXPORT_SET` and `INSTALL_EXPORT_SET` tracking to happen correctly when targets had already been brought it by non-CPM means.

``BUILD_EXPORT_SET``
Record that a :cmake:command:`CPMFindPackage(<PackageName> ...)` call needs to occur as part of
our build directory export set.
Expand All @@ -77,6 +74,16 @@ consistency. List all targets used by your project in `GLOBAL_TARGET`.
be passed down to :cmake:command:`CPMFindPackage`.


.. note::
Adding an export set to :cmake:command:`rapids_cpm_find` has different behavior
for build and install. Build exports a respective CPM call, since
we presume other CPM packages don't generate a correct build directory
config module. While install exports a `find_dependency` call as
we expect projects to have a valid install setup.

If you need different behavior you will need to use :cmake:command:`rapids_export_package()`
or :cmake:command:`rapids_export_cpm()`.

#]=======================================================================]
function(rapids_cpm_find name version)
list(APPEND CMAKE_MESSAGE_CONTEXT "rapids.cpm.find")
Expand All @@ -89,14 +96,25 @@ function(rapids_cpm_find name version)
message(FATAL_ERROR "rapids_cpm_find requires you to specify CPM_ARGS before any CPM arguments")
endif()

CPMFindPackage(NAME ${name} VERSION ${version} ${RAPIDS_UNPARSED_ARGUMENTS})
set(package_needs_to_be_added TRUE)
if(RAPIDS_GLOBAL_TARGETS)
include("${rapids-cmake-dir}/cmake/make_global.cmake")
rapids_cmake_make_global(RAPIDS_GLOBAL_TARGETS)
foreach(target IN LISTS RAPIDS_GLOBAL_TARGETS)
if(TARGET ${target})
set(package_needs_to_be_added FALSE)
break()
endif()
endforeach()
endif()

if(package_needs_to_be_added)
CPMFindPackage(NAME ${name} VERSION ${version} ${RAPIDS_UNPARSED_ARGUMENTS})
endif()

set(extra_info)
if(RAPIDS_GLOBAL_TARGETS)
include("${rapids-cmake-dir}/cmake/make_global.cmake")
rapids_cmake_make_global(RAPIDS_GLOBAL_TARGETS)

set(extra_info "GLOBAL_TARGETS")
list(APPEND extra_info ${RAPIDS_GLOBAL_TARGETS})
endif()
Expand Down
2 changes: 2 additions & 0 deletions testing/cpm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@
add_cmake_config_test( rapids-cpm.cmake )

add_cmake_config_test( cpm_find-existing-build-dir )
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-options-escaped )
82 changes: 82 additions & 0 deletions testing/cpm/cpm_find-existing-target-to-export-sets/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#=============================================================================
# Copyright (c) 2018-2021, 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.20)

include(${rapids-cmake-dir}/cpm/init.cmake)
include(${rapids-cmake-dir}/cpm/find.cmake)
include(${rapids-cmake-dir}/export/write_dependencies.cmake)

project(rapids-existing-target LANGUAGES CXX)

include("${rapids-cmake-testing-dir}/cpm/make_fake_project_build_dir_with_config.cmake")

make_fake_project_build_dir_with_config(RapidsTestFind 2021.01.02
RapidsTestFindConfig.cmake
RapidsTestFindConfigVersion.cmake)

rapids_cpm_init()

set(CMAKE_PREFIX_PATH
"${CMAKE_CURRENT_BINARY_DIR}/RapidsTestFind-build/"
)


add_library(RapidsTest::RapidsTest IMPORTED INTERFACE)

rapids_cpm_find(RapidsTestFind 2021.01.02
GLOBAL_TARGETS RapidsTest::RapidsTest
INSTALL_EXPORT_SET setA)

rapids_cpm_find(RapidsTestFind 2021.01.02
GLOBAL_TARGETS RapidsTest::RapidsTest
INSTALL_EXPORT_SET setB)

rapids_cpm_find(RapidsTestFind 2021.01.02
GLOBAL_TARGETS RapidsTest::RapidsTest
BUILD_EXPORT_SET setB)


function(verify_dependency_file file_name to_match)
file(STRINGS "${file_name}" text)
set(package_dependency_found FALSE)

foreach(line IN LISTS text)
if( line MATCHES ${to_match})
set(package_dependency_found TRUE)
break()
endif()
endforeach()

if(NOT package_dependency_found)
message(FATAL_ERROR "${file_name} failed to export RapidsTestFind properly")
endif()

endfunction()

set(file_path "${CMAKE_CURRENT_BINARY_DIR}/build_export_set.cmake")
file(REMOVE "${file_path}")
rapids_export_write_dependencies(build setB "${file_path}")
verify_dependency_file("${file_path}" "[=[NAME;RapidsTestFind;VERSION;2021.01.02]=]")

set(file_path "${CMAKE_CURRENT_BINARY_DIR}/install_export_setA.cmake")
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/install_export_setA.cmake")
rapids_export_write_dependencies(build setB "${file_path}")
verify_dependency_file("${file_path}" "[=[find_dependency(RapidsTestFind)]=]")

set(file_path "${CMAKE_CURRENT_BINARY_DIR}/install_export_setB.cmake")
file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/install_export_setB.cmake")
rapids_export_write_dependencies(build setB "${file_path}")
verify_dependency_file("${file_path}" "[=[find_dependency(RapidsTestFind)]=]")
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#=============================================================================
# Copyright (c) 2018-2021, 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.
#=============================================================================
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/RapidsTestFindConfigVersion.cmake")

add_library(RapidsTest::RapidsTest IMPORTED INTERFACE GLOBAL)

check_required_components(RapidsTest2)
37 changes: 37 additions & 0 deletions testing/cpm/cpm_find-existing-target/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#=============================================================================
# Copyright (c) 2018-2021, 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(${rapids-cmake-dir}/cpm/init.cmake)
include(${rapids-cmake-dir}/cpm/find.cmake)

cmake_minimum_required(VERSION 3.20)
project(rapids-existing-target LANGUAGES CXX)

include("${rapids-cmake-testing-dir}/cpm/make_fake_project_build_dir_with_config.cmake")

make_fake_project_build_dir_with_config(RapidsTestFind 2021.01.02
RapidsTestFindConfig.cmake
RapidsTestFindConfigVersion.cmake)

rapids_cpm_init()

set(CMAKE_PREFIX_PATH
"${CMAKE_CURRENT_BINARY_DIR}/RapidsTestFind-build/"
)


add_library(RapidsTest::RapidsTest IMPORTED INTERFACE)

rapids_cpm_find(RapidsTestFind 2021.01.02 GLOBAL_TARGETS RapidsTest::RapidsTest)
22 changes: 22 additions & 0 deletions testing/cpm/cpm_find-existing-target/RapidsTestFindConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#=============================================================================
# Copyright (c) 2018-2021, 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.
#=============================================================================
@PACKAGE_INIT@

include("${CMAKE_CURRENT_LIST_DIR}/RapidsTestFindConfigVersion.cmake")

add_library(RapidsTest::RapidsTest IMPORTED INTERFACE GLOBAL)

check_required_components(RapidsTest2)
1 change: 0 additions & 1 deletion testing/export/write_dependencies-duplicate-packages.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ rapids_export_write_dependencies(build test_set "${CMAKE_CURRENT_BINARY_DIR}/exp

file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/export_set.cmake" text)

set(duplicate_package )
foreach(line IN LISTS text)
# message(STATUS "1. line: ${line}")
if( line MATCHES "find_dependency\\(ExactlyDuplicate\\)" )
Expand Down

0 comments on commit f367fe6

Please sign in to comment.