Skip to content

Commit fcd9b33

Browse files
committed
cmake: Add layered dependency resolution for offline builds
Add a layered dependency resolution system inspired by abseil-cpp's ABSL_USE_EXTERNAL_GOOGLETEST / ABSL_FIND_GOOGLETEST / ABSL_LOCAL_* pattern. Each dependency now supports three resolution strategies: 1. TCMALLOC_USE_EXTERNAL_<DEP> (ON/OFF): Assume targets already provided by parent project, or use find_package() to locate them. 2. TCMALLOC_LOCAL_<DEP>_DIR (path): Point to a local source checkout which is added via add_subdirectory(). 3. Default: Fall back to FetchContent from GitHub (existing behavior). Dependencies covered: - abseil-cpp: TCMALLOC_USE_EXTERNAL_ABSEIL, TCMALLOC_LOCAL_ABSEIL_DIR - GoogleTest: TCMALLOC_USE_EXTERNAL_GOOGLETEST, TCMALLOC_LOCAL_GOOGLETEST_DIR - Protobuf: TCMALLOC_USE_EXTERNAL_PROTOBUF, TCMALLOC_LOCAL_PROTOBUF_DIR - Benchmark: TCMALLOC_USE_EXTERNAL_BENCHMARK, TCMALLOC_LOCAL_BENCHMARK_DIR - FuzzTest: TCMALLOC_USE_EXTERNAL_FUZZTEST, TCMALLOC_LOCAL_FUZZTEST_DIR This enables fully offline/hermetic builds by pointing all dependencies to pre-fetched local directories or system-installed packages.
1 parent 631c31e commit fcd9b33

1 file changed

Lines changed: 136 additions & 39 deletions

File tree

CMakeLists.txt

Lines changed: 136 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -53,48 +53,145 @@ set(ABSL_FIND_GOOGLETEST OFF CACHE BOOL "" FORCE)
5353

5454
include(FetchContent)
5555

56-
# -- abseil-cpp (always required) --
57-
FetchContent_Declare(
58-
abseil-cpp
59-
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
60-
GIT_TAG master
61-
FIND_PACKAGE_ARGS NAMES absl
62-
)
63-
FetchContent_MakeAvailable(abseil-cpp)
56+
##
57+
## Dependency resolution options
58+
##
59+
## Each dependency supports a layered resolution strategy inspired by
60+
## abseil-cpp's ABSL_USE_EXTERNAL_GOOGLETEST / ABSL_FIND_GOOGLETEST
61+
## pattern. For offline or hermetic builds, set the appropriate
62+
## TCMALLOC_USE_EXTERNAL_* or TCMALLOC_LOCAL_*_DIR options so that
63+
## no network fetch is required.
64+
##
65+
66+
# -- abseil-cpp --
67+
option(TCMALLOC_USE_EXTERNAL_ABSEIL
68+
"If ON, assume abseil-cpp targets (absl::*) are already provided by the parent project." OFF)
69+
set(TCMALLOC_LOCAL_ABSEIL_DIR "" CACHE PATH
70+
"Path to a local abseil-cpp source directory. Used when TCMALLOC_USE_EXTERNAL_ABSEIL is OFF.")
71+
72+
if(TCMALLOC_USE_EXTERNAL_ABSEIL)
73+
if(NOT TARGET absl::base)
74+
find_package(absl REQUIRED)
75+
endif()
76+
else()
77+
if(TCMALLOC_LOCAL_ABSEIL_DIR)
78+
add_subdirectory("${TCMALLOC_LOCAL_ABSEIL_DIR}" abseil-cpp EXCLUDE_FROM_ALL)
79+
else()
80+
FetchContent_Declare(
81+
abseil-cpp
82+
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
83+
GIT_TAG master
84+
FIND_PACKAGE_ARGS NAMES absl
85+
)
86+
FetchContent_MakeAvailable(abseil-cpp)
87+
endif()
88+
endif()
6489

6590
# -- Test-only dependencies --
6691
if((BUILD_TESTING AND TCMALLOC_BUILD_TESTING) OR TCMALLOC_BUILD_TEST_HELPERS)
67-
FetchContent_Declare(
68-
googletest
69-
GIT_REPOSITORY https://github.com/google/googletest.git
70-
GIT_TAG main
71-
FIND_PACKAGE_ARGS NAMES GTest
72-
)
73-
FetchContent_MakeAvailable(googletest)
74-
75-
FetchContent_Declare(
76-
protobuf
77-
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
78-
GIT_TAG main
79-
FIND_PACKAGE_ARGS NAMES Protobuf
80-
)
81-
FetchContent_MakeAvailable(protobuf)
82-
83-
FetchContent_Declare(
84-
benchmark
85-
GIT_REPOSITORY https://github.com/google/benchmark.git
86-
GIT_TAG main
87-
FIND_PACKAGE_ARGS NAMES benchmark
88-
)
89-
FetchContent_MakeAvailable(benchmark)
90-
91-
FetchContent_Declare(
92-
fuzztest
93-
GIT_REPOSITORY https://github.com/google/fuzztest.git
94-
GIT_TAG main
95-
FIND_PACKAGE_ARGS NAMES fuzztest
96-
)
97-
FetchContent_MakeAvailable(fuzztest)
92+
93+
# GoogleTest
94+
option(TCMALLOC_USE_EXTERNAL_GOOGLETEST
95+
"If ON, assume GoogleTest targets (GTest::*) are already provided." OFF)
96+
set(TCMALLOC_LOCAL_GOOGLETEST_DIR "" CACHE PATH
97+
"Path to a local GoogleTest source directory.")
98+
99+
if(TCMALLOC_USE_EXTERNAL_GOOGLETEST)
100+
if(NOT TARGET GTest::gtest)
101+
find_package(GTest REQUIRED)
102+
endif()
103+
else()
104+
if(TCMALLOC_LOCAL_GOOGLETEST_DIR)
105+
add_subdirectory("${TCMALLOC_LOCAL_GOOGLETEST_DIR}" googletest EXCLUDE_FROM_ALL)
106+
if(TARGET gtest AND NOT TARGET GTest::gtest)
107+
add_library(GTest::gtest ALIAS gtest)
108+
add_library(GTest::gtest_main ALIAS gtest_main)
109+
add_library(GTest::gmock ALIAS gmock)
110+
add_library(GTest::gmock_main ALIAS gmock_main)
111+
endif()
112+
else()
113+
FetchContent_Declare(
114+
googletest
115+
GIT_REPOSITORY https://github.com/google/googletest.git
116+
GIT_TAG main
117+
FIND_PACKAGE_ARGS NAMES GTest
118+
)
119+
FetchContent_MakeAvailable(googletest)
120+
endif()
121+
endif()
122+
123+
# Protobuf
124+
option(TCMALLOC_USE_EXTERNAL_PROTOBUF
125+
"If ON, assume Protobuf targets are already provided." OFF)
126+
set(TCMALLOC_LOCAL_PROTOBUF_DIR "" CACHE PATH
127+
"Path to a local protobuf source directory.")
128+
129+
if(TCMALLOC_USE_EXTERNAL_PROTOBUF)
130+
if(NOT TARGET protobuf::libprotobuf)
131+
find_package(Protobuf REQUIRED)
132+
endif()
133+
else()
134+
if(TCMALLOC_LOCAL_PROTOBUF_DIR)
135+
add_subdirectory("${TCMALLOC_LOCAL_PROTOBUF_DIR}" protobuf EXCLUDE_FROM_ALL)
136+
else()
137+
FetchContent_Declare(
138+
protobuf
139+
GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
140+
GIT_TAG main
141+
FIND_PACKAGE_ARGS NAMES Protobuf
142+
)
143+
FetchContent_MakeAvailable(protobuf)
144+
endif()
145+
endif()
146+
147+
# Google Benchmark
148+
option(TCMALLOC_USE_EXTERNAL_BENCHMARK
149+
"If ON, assume Google Benchmark targets are already provided." OFF)
150+
set(TCMALLOC_LOCAL_BENCHMARK_DIR "" CACHE PATH
151+
"Path to a local Google Benchmark source directory.")
152+
153+
if(TCMALLOC_USE_EXTERNAL_BENCHMARK)
154+
if(NOT TARGET benchmark::benchmark)
155+
find_package(benchmark REQUIRED)
156+
endif()
157+
else()
158+
if(TCMALLOC_LOCAL_BENCHMARK_DIR)
159+
add_subdirectory("${TCMALLOC_LOCAL_BENCHMARK_DIR}" benchmark EXCLUDE_FROM_ALL)
160+
else()
161+
FetchContent_Declare(
162+
benchmark
163+
GIT_REPOSITORY https://github.com/google/benchmark.git
164+
GIT_TAG main
165+
FIND_PACKAGE_ARGS NAMES benchmark
166+
)
167+
FetchContent_MakeAvailable(benchmark)
168+
endif()
169+
endif()
170+
171+
# FuzzTest
172+
option(TCMALLOC_USE_EXTERNAL_FUZZTEST
173+
"If ON, assume FuzzTest targets are already provided." OFF)
174+
set(TCMALLOC_LOCAL_FUZZTEST_DIR "" CACHE PATH
175+
"Path to a local FuzzTest source directory.")
176+
177+
if(TCMALLOC_USE_EXTERNAL_FUZZTEST)
178+
if(NOT TARGET fuzztest::fuzztest)
179+
find_package(fuzztest REQUIRED)
180+
endif()
181+
else()
182+
if(TCMALLOC_LOCAL_FUZZTEST_DIR)
183+
add_subdirectory("${TCMALLOC_LOCAL_FUZZTEST_DIR}" fuzztest EXCLUDE_FROM_ALL)
184+
else()
185+
FetchContent_Declare(
186+
fuzztest
187+
GIT_REPOSITORY https://github.com/google/fuzztest.git
188+
GIT_TAG main
189+
FIND_PACKAGE_ARGS NAMES fuzztest
190+
)
191+
FetchContent_MakeAvailable(fuzztest)
192+
endif()
193+
endif()
194+
98195
endif()
99196

100197
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/CMake)

0 commit comments

Comments
 (0)