Skip to content

Commit 007006a

Browse files
committed
Redirect find_package to FetchContent
Reuse the exemplar infrastructure for find_package integration.
1 parent eec9177 commit 007006a

File tree

5 files changed

+188
-16
lines changed

5 files changed

+188
-16
lines changed

CMakeLists.txt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,6 @@ option(
1818
${PROJECT_IS_TOP_LEVEL}
1919
)
2020

21-
# Build the tests if enabled via the option OPTIONAL_ENABLE_TESTING
22-
if(OPTIONAL_ENABLE_TESTING)
23-
# Fetch GoogleTest
24-
FetchContent_Declare(
25-
googletest
26-
EXCLUDE_FROM_ALL
27-
GIT_REPOSITORY https://github.com/google/googletest.git
28-
GIT_TAG
29-
e39786088138f2749d64e9e90e0f9902daa77c40 # release-1.15.0
30-
)
31-
FetchContent_MakeAvailable(googletest)
32-
endif()
33-
3421
set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ON)
3522

3623
# Create the library target and named header set for beman_optional

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ define run_cmake =
4545
-DCMAKE_CONFIGURATION_TYPES=$(_configuration_types) \
4646
-DCMAKE_INSTALL_PREFIX=$(abspath $(INSTALL_PREFIX)) \
4747
-DCMAKE_EXPORT_COMPILE_COMMANDS=1 \
48+
-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="./cmake/use-fetch-content.cmake" \
4849
$(_cmake_args) \
4950
$(CURDIR)
5051
endef

cmake/use-fetch-content.cmake

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
cmake_minimum_required(VERSION 3.24)
2+
3+
if(NOT BEMAN_OPTIONAL_LOCKFILE)
4+
set(BEMAN_OPTIONAL_LOCKFILE
5+
"lockfile.json"
6+
CACHE FILEPATH
7+
"Path to the dependency lockfile for the Beman Optional."
8+
)
9+
endif()
10+
11+
set(BemanOptional_projectDir "${CMAKE_CURRENT_LIST_DIR}/..")
12+
message(TRACE "BemanOptional_projectDir=\"${BemanOptional_projectDir}\"")
13+
14+
message(TRACE "BEMAN_OPTIONAL_LOCKFILE=\"${BEMAN_OPTIONAL_LOCKFILE}\"")
15+
file(
16+
REAL_PATH
17+
"${BEMAN_OPTIONAL_LOCKFILE}"
18+
BemanOptional_lockfile
19+
BASE_DIRECTORY "${BemanOptional_projectDir}"
20+
EXPAND_TILDE
21+
)
22+
message(DEBUG "Using lockfile: \"${BemanOptional_lockfile}\"")
23+
24+
# Force CMake to reconfigure the project if the lockfile changes
25+
set_property(
26+
DIRECTORY "${BemanOptional_projectDir}"
27+
APPEND
28+
PROPERTY CMAKE_CONFIGURE_DEPENDS "${BemanOptional_lockfile}"
29+
)
30+
31+
# For more on the protocol for this function, see:
32+
# https://cmake.org/cmake/help/latest/command/cmake_language.html#provider-commands
33+
function(BemanOptional_provideDependency method package_name)
34+
# Read the lockfile
35+
file(READ "${BemanOptional_lockfile}" BemanOptional_rootObj)
36+
37+
# Get the "dependencies" field and store it in BemanOptional_dependenciesObj
38+
string(
39+
JSON
40+
BemanOptional_dependenciesObj
41+
ERROR_VARIABLE BemanOptional_error
42+
GET "${BemanOptional_rootObj}"
43+
"dependencies"
44+
)
45+
if(BemanOptional_error)
46+
message(FATAL_ERROR "${BemanOptional_lockfile}: ${BemanOptional_error}")
47+
endif()
48+
49+
# Get the length of the libraries array and store it in BemanOptional_dependenciesObj
50+
string(
51+
JSON
52+
BemanOptional_numDependencies
53+
ERROR_VARIABLE BemanOptional_error
54+
LENGTH "${BemanOptional_dependenciesObj}"
55+
)
56+
if(BemanOptional_error)
57+
message(FATAL_ERROR "${BemanOptional_lockfile}: ${BemanOptional_error}")
58+
endif()
59+
60+
# Loop over each dependency object
61+
math(EXPR BemanOptional_maxIndex "${BemanOptional_numDependencies} - 1")
62+
foreach(BemanOptional_index RANGE "${BemanOptional_maxIndex}")
63+
set(BemanOptional_errorPrefix
64+
"${BemanOptional_lockfile}, dependency ${BemanOptional_index}"
65+
)
66+
67+
# Get the dependency object at BemanOptional_index
68+
# and store it in BemanOptional_depObj
69+
string(
70+
JSON
71+
BemanOptional_depObj
72+
ERROR_VARIABLE BemanOptional_error
73+
GET "${BemanOptional_dependenciesObj}"
74+
"${BemanOptional_index}"
75+
)
76+
if(BemanOptional_error)
77+
message(
78+
FATAL_ERROR
79+
"${BemanOptional_errorPrefix}: ${BemanOptional_error}"
80+
)
81+
endif()
82+
83+
# Get the "name" field and store it in BemanOptional_name
84+
string(
85+
JSON
86+
BemanOptional_name
87+
ERROR_VARIABLE BemanOptional_error
88+
GET "${BemanOptional_depObj}"
89+
"name"
90+
)
91+
if(BemanOptional_error)
92+
message(
93+
FATAL_ERROR
94+
"${BemanOptional_errorPrefix}: ${BemanOptional_error}"
95+
)
96+
endif()
97+
98+
# Get the "package_name" field and store it in BemanOptional_pkgName
99+
string(
100+
JSON
101+
BemanOptional_pkgName
102+
ERROR_VARIABLE BemanOptional_error
103+
GET "${BemanOptional_depObj}"
104+
"package_name"
105+
)
106+
if(BemanOptional_error)
107+
message(
108+
FATAL_ERROR
109+
"${BemanOptional_errorPrefix}: ${BemanOptional_error}"
110+
)
111+
endif()
112+
113+
# Get the "git_repository" field and store it in BemanOptional_repo
114+
string(
115+
JSON
116+
BemanOptional_repo
117+
ERROR_VARIABLE BemanOptional_error
118+
GET "${BemanOptional_depObj}"
119+
"git_repository"
120+
)
121+
if(BemanOptional_error)
122+
message(
123+
FATAL_ERROR
124+
"${BemanOptional_errorPrefix}: ${BemanOptional_error}"
125+
)
126+
endif()
127+
128+
# Get the "git_tag" field and store it in BemanOptional_tag
129+
string(
130+
JSON
131+
BemanOptional_tag
132+
ERROR_VARIABLE BemanOptional_error
133+
GET "${BemanOptional_depObj}"
134+
"git_tag"
135+
)
136+
if(BemanOptional_error)
137+
message(
138+
FATAL_ERROR
139+
"${BemanOptional_errorPrefix}: ${BemanOptional_error}"
140+
)
141+
endif()
142+
143+
if(method STREQUAL "FIND_PACKAGE")
144+
if(package_name STREQUAL BemanOptional_pkgName)
145+
string(
146+
APPEND
147+
BemanOptional_debug
148+
"Redirecting find_package calls for ${BemanOptional_pkgName} "
149+
"to FetchContent logic fetching ${BemanOptional_repo} at "
150+
"${BemanOptional_tag} according to ${BemanOptional_lockfile}."
151+
)
152+
message(DEBUG "${BemanOptional_debug}")
153+
FetchContent_Declare(
154+
"${BemanOptional_name}"
155+
GIT_REPOSITORY "${BemanOptional_repo}"
156+
GIT_TAG "${BemanOptional_tag}"
157+
EXCLUDE_FROM_ALL
158+
)
159+
set(INSTALL_GTEST OFF) # Disable GoogleTest installation
160+
FetchContent_MakeAvailable("${BemanOptional_name}")
161+
162+
# Important! <PackageName>_FOUND tells CMake that `find_package` is
163+
# not needed for this package anymore
164+
set("${BemanOptional_pkgName}_FOUND" TRUE PARENT_SCOPE)
165+
endif()
166+
endif()
167+
endforeach()
168+
169+
set(GTest_FOUND TRUE PARENT_SCOPE)
170+
endfunction()
171+
172+
cmake_language(
173+
SET_DEPENDENCY_PROVIDER BemanOptional_provideDependency
174+
SUPPORTED_METHODS FIND_PACKAGE
175+
)

lockfile.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"dependencies": [
3+
{
4+
"name": "googletest",
5+
"package_name": "GTest",
6+
"git_repository": "https://github.com/google/googletest.git",
7+
"git_tag": "e39786088138f2749d64e9e90e0f9902daa77c40"
8+
}
9+
]
10+
}

tests/beman/optional/CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,9 @@
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
# cmake-format: on
55

6-
include(GoogleTest)
6+
find_package(GTest REQUIRED)
77

88
# Tests
9-
# add_executable(beman_optional_test)
10-
119
target_sources(
1210
beman_optional_test
1311
PRIVATE
@@ -37,6 +35,7 @@ target_link_libraries(
3735
# Note: clang-19 + gtest_discover_tests + Asan setup causes errors on some
3836
# platforms. Temporary switch to gtest_add_tests and skip some Asan checks.
3937
# Change also applied for CI flows.
38+
include(GoogleTest)
4039
gtest_add_tests(TARGET beman_optional_test "" AUTO)
4140

4241
add_library(constructor_fails test_constructor_fail.cpp)

0 commit comments

Comments
 (0)