-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeUtils.cmake
More file actions
276 lines (212 loc) · 7.32 KB
/
CMakeUtils.cmake
File metadata and controls
276 lines (212 loc) · 7.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# Enables ADD_GIT_DEPENDENCY functionality
option(ENABLE_GIT_DEPENDENCIES "Enables automatic cloning of dependencies that do not already exit" ON)
find_package(Git QUIET)
#
# Adds a new dependency and automatically clones it if the target does not already exist.
#
# @param depPath Where to clone the repo into, must be an absolute path!
# @param depTarget Name of the target, this is used to check if the dependency already exists
# @param depRepo Path or URL to clone the repo from
# @param branchName? Name of the branch to clone, defaults to HEAD
#
function(ADD_GIT_DEPENDENCY_FN depPath depTarget depRepo)
# Ignore if target already exists
if (NOT TARGET ${depTarget})
# Add the cloned repo as a subdir if it has CMake support
if (EXISTS "${depPath}/CMakeLists.txt")
add_subdirectory("${depPath}")
# Check that dependency target is now defined
if (NOT TARGET ${depTarget})
message(FATAL_ERROR "Cloned dependency has a CMakeLists but the dependency target was not defined!")
endif()
# Only preform branch if git dependencies are allowed
else (ENABLE_GIT_DEPENDENCIES)
#
# Add the dependecy directory if it exists, or clone it from the github repo url if not
#
if (EXISTS "${depPath}/CMakeLists.txt")
# Add subdirectory
add_subdirectory("${depPath}")
# Check that dependency target is now defined
if (NOT TARGET ${depTarget})
message(FATAL_ERROR "Cloned dependency has a CMakeLists but the dependency target was not defined!")
endif()
else()
set(gitResult )
# Use branch optional parameter if it was provided
if (ARGC GREATER 3)
execute_process(COMMAND
${GIT_EXECUTABLE} clone -b "${ARGV3}" ${depRepo} ${depPath}
RESULTS_VARIABLE gitResult)
else()
execute_process(COMMAND
${GIT_EXECUTABLE} clone ${depRepo} ${depPath}
RESULTS_VARIABLE gitResult)
endif()
# Check result
if ("${gitResult}" EQUAL "0")
# TODO: Add notification of cloned repo
else()
message(FATAL_ERROR "bad")
endif()
# Add the cloned repo as a subdir if it has CMake support
if (EXISTS "${depPath}/CMakeLists.txt")
add_subdirectory("${depPath}")
# Check that dependency target is now defined
if (NOT TARGET ${depTarget})
message(FATAL_ERROR "Cloned dependency has a CMakeLists but the dependency target was not defined!")
endif()
endif()
endif()
endif()
endif()
endfunction()
#
# Adds a new dependency and automatically clones it if the target does not already exist.
#
# @param depPath Relative path to clone the repo into
# @param depTarget Name of the target, this is used to check if the dependency already exists
# @param depRepo Path or URL to clone the repo from
# @param branchName? Name of the branch to clone, defaults to HEAD
#
macro(ADD_GIT_DEPENDENCY depPath depTarget depRepo)
# Make file path absolute
set(__addgitdepedency_realpath ${depPath})
# Determine invocation syntax
if (${ARGC} GREATER 3)
# Invoke with branchName parameter
ADD_GIT_DEPENDENCY_FN(${__addgitdepedency_realpath} ${depTarget} ${depRepo} ${ARGV3})
else()
# Invoke without branchName parameter
ADD_GIT_DEPENDENCY_FN(${__addgitdepedency_realpath} ${depTarget} ${depRepo})
endif()
endmacro()
#
# Adds a list of sources to a target, sourceList should be a list variable
#
macro(ADD_SOURCES_LIST targetName sourceList)
list(TRANSFORM ${sourceList} PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
set(lfefiles )
foreach(lfe IN LISTS ${sourceList})
set(lfefiles ${lfefiles} ${lfe})
endforeach()
target_sources(${targetName} PRIVATE ${lfefiles})
endmacro(ADD_SOURCES_LIST)
#
# Returns the child DIRECTORY paths of a given directory
#
macro(SUBDIRLIST result curdir)
file(GLOB children RELATIVE ${curdir} ${curdir}/*)
set(dirlist "")
foreach(child ${children})
if(IS_DIRECTORY ${curdir}/${child})
list(APPEND dirlist ${child})
endif()
endforeach()
set(${result} ${dirlist})
endmacro()
#
# Returns the child paths of a given directory
#
# @param out_Result Output variable, a list of paths will be written into it
# @param in_DirectoryPath Directory to get children of
#
macro(GET_DIRECTORY_CONTENTS out_Result in_DirectoryPath)
# The evaluated absolute file path
set(__get_directory_contents_Path ${in_DirectoryPath})
# Holds all child paths
set(__get_directory_contents_Children )
file(GLOB __get_directory_contents_Children
RELATIVE ${__get_directory_contents_Path} "${__get_directory_contents_Path}/*")
# Write results to output variable
set(${out_Result} ${__get_directory_contents_Children})
endmacro()
#
# Adds a list of subdirectories to the project, pathList should be a list variable
#
macro(ADD_SUBDIRS_LIST pathList)
foreach(lfe IN LISTS ${pathList})
add_subdirectory(${lfe})
endforeach()
endmacro(ADD_SUBDIRS_LIST)
#
# Includes all subdirectories from the current source path
#
macro(ADD_SUBDIRS_HERE)
set(dirlist )
SUBDIRLIST(dirlist ${CMAKE_CURRENT_SOURCE_DIR})
foreach(lfe IN LISTS dirlist)
set(lfename )
get_filename_component(lfename ${lfe} NAME)
add_subdirectory(${lfename})
endforeach()
endmacro()
#
# Includes all paths listed that contain CMake lists
#
# @param rootDir Root directory path
#
function(ADD_CMAKE_SUBDIRS_FN rootDir)
# Get subdirectories
set(subdirList )
SUBDIRLIST(subdirList ${rootDir})
# Include each subdir if it has a cmake lists
foreach(subd IN LISTS subdirList)
if (EXISTS "${rootDir}/${subd}/CMakeLists.txt")
add_subdirectory("${rootDir}/${subd}")
endif()
endforeach()
endfunction()
#
# Includes all subdirectories containing CMake lists from the current source dir
#
macro(ADD_CMAKE_SUBDIRS_HERE)
ADD_CMAKE_SUBDIRS_FN("${CMAKE_CURRENT_SOURCE_DIR}")
endmacro()
#
# Adds the sources in the current directory matching a pattern to a target
#
macro(ADD_SOURCES_HERE in_Target in_MatchPattern)
# Check that a valid target was given
if(NOT TARGET ${in_Target})
message(FATAL_ERROR "Cannot add sources to invalid target ${in_Target}")
endif()
# Root path to get source files from
set(__add_sources_here_Path "${CMAKE_CURRENT_SOURCE_DIR}")
# Get directory contents
set(__add_sources_here_Contents )
GET_DIRECTORY_CONTENTS(__add_sources_here_Contents "${__add_sources_here_Path}")
# Get list of paths that pass the given match pattern
set(__add_sources_here_SourceList )
foreach(lfe IN LISTS __add_sources_here_Contents)
if ("${lfe}" MATCHES "${in_MatchPattern}")
list(APPEND __add_sources_here_SourceList "${lfe}")
endif()
endforeach()
# Add sources to project
ADD_SOURCES_LIST(${in_Target} __add_sources_here_SourceList)
endmacro()
#
# Adds the C++ sources in the current directory to a target
#
macro(ADD_CPP_SOURCES_HERE in_Target)
# Match expression
set(__add_cpp_sources_here_Pattern "\.[ch]|\.[ch]pp$")
ADD_SOURCES_HERE(${in_Target} ${__add_cpp_sources_here_Pattern})
endmacro()
#
# Gets the contents of a directory that match a given filter
#
# @param out_Result Output variable
# @param in_RootPath Directory to search in
# @param in_Pattern Regex pattern used to filter which child paths are returned
#
macro(MATCH_DIRECTORY_CONTENTS out_Result in_RootPath in_Pattern)
set(__match_directory_contents_Raw )
GET_DIRECTORY_CONTENTS(__match_directory_contents_Raw "${in_RootPath}")
foreach (lfe IN LISTS __match_directory_contents_Raw)
if ("${lfe}" MATCHES "${in_Pattern}")
list(APPEND ${out_Result} "${lfe}")
endif()
endforeach()
endmacro()