-
Notifications
You must be signed in to change notification settings - Fork 2
/
CMakeBBLM.cmake
295 lines (283 loc) · 11.9 KB
/
CMakeBBLM.cmake
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
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# CMakeBBLM. See https://github.com/sakra/CMakeBBLM
#
# This script generates a BBEdit codeless language module for CMake from cmake.plist.in
# See https://www.barebones.com/support/develop/clm.html
#
# Copyright (c) 2016-2024 Sascha Kratky
#
# Distributed under the MIT License. See accompanying license file.
function(resolve_templates _propNames)
set (${_propNames} "")
set (_languages "C" "CXX" "Fortran" "ASM")
if (NOT CMAKE_VERSION VERSION_LESS "3.8.0")
list (APPEND _languages "CSharp" "CUDA")
endif()
if (NOT CMAKE_VERSION VERSION_LESS "3.16.0")
list (APPEND _languages "OBJC" "OBJCXX")
endif()
if (NOT CMAKE_VERSION VERSION_LESS "3.19.0")
list (APPEND _languages "ISPC")
endif()
if (NOT CMAKE_VERSION VERSION_LESS "3.21.0")
list (APPEND _languages "HIP")
endif()
# Predefined configuration names
set (_configurations "None" "Debug" "MinSizeRel" "Release" "RelWithDebInfo")
# Predefined link group features
set (_linkGroupFeatures "RESCAN")
# Predefined linker types
set (_linkerTypes "DEFAULT" "SYSTEM" "LLD" "BFD" "GOLD" "MOLD" "SOLD" "APPLE_CLASSIC" "MSVC")
# Predefined Xcode embed build phases
set (_xcodeBuildPhases "FRAMEWORKS" "APP_EXTENSIONS" "EXTENSIONKIT_EXTENSIONS" "PLUGINS" "RESOURCES" "XPC_SERVICES")
# resolve known templates, e.g., <CONFIG>, <LANG>, <FEATURE>, ...
set (_resolvedPropNames "")
foreach (_unresolvedPropName IN LISTS ARGN)
if (_unresolvedPropName MATCHES "<CONFIG>" AND _unresolvedPropName MATCHES "<LANG>")
foreach (_config ${_configurations})
foreach (_lang ${_languages})
if (NOT _config STREQUAL "None")
string (TOUPPER "${_config}" _config)
string (REPLACE "<CONFIG>" "${_config}" _propName "${_unresolvedPropName}")
string (REPLACE "<LANG>" "${_lang}" _propName "${_propName}")
list (APPEND _resolvedPropNames ${_propName})
endif()
endforeach()
endforeach()
elseif (_unresolvedPropName MATCHES "<FEATURE>" AND _unresolvedPropName MATCHES "<LANG>")
foreach (_feature ${_linkGroupFeatures})
foreach (_lang ${_languages})
if (NOT _config STREQUAL "None")
string (TOUPPER "${_feature}" _feature)
string (REPLACE "<FEATURE>" "${_feature}" _propName "${_unresolvedPropName}")
string (REPLACE "<LANG>" "${_lang}" _propName "${_propName}")
list (APPEND _resolvedPropNames ${_propName})
endif()
endforeach()
endforeach()
elseif (_unresolvedPropName MATCHES "LINKER_<TYPE>" AND _unresolvedPropName MATCHES "<LANG>")
foreach (_linkerType ${_linkerTypes})
foreach (_lang ${_languages})
if (NOT _config STREQUAL "None")
string (TOUPPER "${_linkerType}" _linkerType)
string (REPLACE "<TYPE>" "${_linkerType}" _propName "${_unresolvedPropName}")
string (REPLACE "<LANG>" "${_lang}" _propName "${_propName}")
list (APPEND _resolvedPropNames ${_propName})
endif()
endforeach()
endforeach()
elseif (_unresolvedPropName MATCHES "<CONFIG>")
foreach (_config ${_configurations})
if (_config STREQUAL "None")
# handle special build type "None" which requires unqualified property name
string (REGEX REPLACE "_?<CONFIG>_?" "" _propName "${_unresolvedPropName}")
else()
string (TOUPPER "${_config}" _config)
string (REPLACE "<CONFIG>" "${_config}" _propName "${_unresolvedPropName}")
endif()
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "<FEATURE>")
foreach (_feature ${_linkGroupFeatures})
string (TOUPPER "${_feature}" _feature)
string (REPLACE "<FEATURE>" "${_feature}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "LINKER_<TYPE>")
foreach (_linkerType ${_linkerTypes})
string (TOUPPER "${_linkerType}" _linkerType)
string (REPLACE "<TYPE>" "${_linkerType}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "XCODE_EMBED_<type>")
foreach (_buildPhase ${_xcodeBuildPhases})
string (TOUPPER "${_buildPhase}" _buildPhase)
string (REPLACE "<type>" "${_buildPhase}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "GNU<LANG>")
foreach (_lang "CC" "CXX" "G77")
string (REPLACE "<LANG>" "${_lang}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "ASM<DIALECT>")
foreach (_lang "ASM" "ASM_NASM" "ASM_MASM" "ASM-ATT" "ASM_MARMASM")
string (REPLACE "ASM<DIALECT>" "${_lang}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "<LANG>")
foreach (_lang ${_languages})
string (REPLACE "<LANG>" "${_lang}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "CMP<NNNN>")
execute_process(
COMMAND ${CMAKE_COMMAND} --help-policies
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
foreach (_line IN LISTS _output)
if (_line MATCHES "^ *CMP([0-9]+) *$")
list (APPEND _policies "${CMAKE_MATCH_1}")
endif()
endforeach()
foreach (_policy IN LISTS _policies)
string (REPLACE "<NNNN>" "${_policy}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "\\(([0-9]+)..([0-9]+)\\)")
# handle properties with trailing number, e.g., CMAKE_MATCH_(0..9)
foreach (_index RANGE ${CMAKE_MATCH_1} ${CMAKE_MATCH_2})
string (REPLACE "${CMAKE_MATCH_0}" "${_index}" _propName "${_unresolvedPropName}")
list (APPEND _resolvedPropNames ${_propName})
endforeach()
elseif (_unresolvedPropName MATCHES "<[a-zA-Z0-9_-]+>")
message(STATUS "Skipping ${_unresolvedPropName}")
else()
list (APPEND _resolvedPropNames ${_unresolvedPropName})
endif()
endforeach()
# skip properties containing unknown unresolved templates
list (REMOVE_DUPLICATES _resolvedPropNames)
set (${_propNames} "")
foreach (_resolvedPropName IN LISTS _resolvedPropNames)
if (_resolvedPropName MATCHES "<[a-zA-Z0-9_-]+>")
message(STATUS "Skipping ${_resolvedPropName}")
else()
list (APPEND ${_propNames} ${_resolvedPropName})
endif()
endforeach()
set (${_propNames} ${${_propNames}} PARENT_SCOPE)
endfunction()
execute_process(
COMMAND ${CMAKE_COMMAND} --help-command-list
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
foreach (_line IN LISTS _output)
if (_line MATCHES "^([a-z_]+) *$")
list (APPEND _commandList "${CMAKE_MATCH_1}")
else()
message(STATUS "Skipping line \"${_line}\"")
endif()
endforeach()
#message (STATUS "${_commandList}")
if (CMAKE_VERSION VERSION_LESS "3.0.0")
execute_process(
COMMAND ${CMAKE_COMMAND} --help-compatcommands
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
foreach (_line IN LISTS _output)
if (_line MATCHES "^ ([a-z_]+) *$")
list (APPEND _deprecatedCommandList "${CMAKE_MATCH_1}")
endif()
endforeach()
#message (STATUS "${_deprecatedCommandList}")
endif()
# generate keyword list without deprecated commands
set (BBLMKeywordList ${_commandList})
if (_deprecatedCommandList)
list (REMOVE_ITEM BBLMKeywordList ${_deprecatedCommandList})
endif()
list (SORT BBLMKeywordList)
list (REMOVE_DUPLICATES BBLMKeywordList)
string (
REGEX REPLACE "[A-Za-z0-9_-]+" "\t\t<string>\\0</string>"
BBLMKeywordList "${BBLMKeywordList}")
string (REPLACE ";" "\n" BBLMKeywordList "${BBLMKeywordList}")
#message (STATUS "${BBLMKeywordList}")
execute_process(
COMMAND ${CMAKE_COMMAND} --help-property-list
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
foreach (_line IN LISTS _output)
if (_line MATCHES "^([A-Za-z0-9_<>-]+) *$")
list (APPEND _propertyList "${CMAKE_MATCH_1}")
else()
message(STATUS "Skipping line \"${_line}\"")
endif()
endforeach()
resolve_templates(_propertyList ${_propertyList})
#message (STATUS "${_propertyList}")
# cmake variables
execute_process(
COMMAND ${CMAKE_COMMAND} --help-variable-list
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
foreach (_line IN LISTS _output)
if (_line MATCHES "^([A-Za-z0-9_<>-]+) *$")
list (APPEND _variableList "${CMAKE_MATCH_1}")
else()
message(STATUS "Skipping line \"${_line}\"")
endif()
endforeach()
# cmake environment variables
if (NOT CMAKE_VERSION VERSION_LESS "3.0.0")
execute_process(
COMMAND ${CMAKE_COMMAND} --help-manual cmake-env-variables
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REPLACE "\n" ";" _output "${_output}")
set (_variable "")
foreach (_line IN LISTS _output)
if(_line MATCHES "^-+ *$")
if (_variable)
list (APPEND _variableList "${_variable}")
set (_variable "")
endif()
elseif (_line MATCHES "^([A-Za-z0-9_<>-]+) *$")
set (_variable "${_line}")
endif()
endforeach()
endif()
# explicitly add variables missed by command parser
list(APPEND _variableList "CMAKE_ARGV(0..9)" "CMAKE_MATCH_(0..9)")
# add undocumented, but useful CMake variables
list(APPEND _variableList "CMAKE_SKIP_ASSEMBLY_SOURCE_RULES" "CMAKE_SKIP_PREPROCESSED_SOURCE_RULES" "CMAKE_SKIP_RULE_DEPENDENCY")
list(APPEND _variableList "CMAKE_DISABLE_SOURCE_CHANGES" "CMAKE_DISABLE_IN_SOURCE_BUILD")
list(APPEND _variableList "CMAKE_LINK_DEPENDS_DEBUG_MODE")
list(APPEND _variableList "CMAKE_NINJA_FORCE_RESPONSE_FILE")
list(APPEND _variableList "CMAKE_ADD_CUSTOM_COMMAND_DEPENDS_EXPLICIT_ONLY")
list(APPEND _variableList "CMAKE_SUPPRESS_DEVELOPER_ERRORS" "CMAKE_SUPPRESS_DEVELOPER_WARNINGS")
list(APPEND _variableList "CMAKE_SYSTEM_ARCH" "CMAKE_REQUIRED_LIBRARIES")
resolve_templates(_variableList ${_variableList})
#message (STATUS "${_variableList}")
# parse keywords from command help
foreach (_command IN LISTS _commandList)
execute_process(
COMMAND ${CMAKE_COMMAND} --help-command ${_command}
OUTPUT_VARIABLE _output
OUTPUT_STRIP_TRAILING_WHITESPACE)
string (REGEX MATCHALL "${_command}\\([^)]*\\)" _signatures "${_output}")
#message (STATUS "${_signatures}")
foreach (_singnature IN LISTS _signatures)
string (REGEX MATCHALL "[A-Z@][A-Z0-9_]+(<[A-Z0-9_]+>)?" _keywords "${_singnature}")
list (APPEND _keywordList ${_keywords})
endforeach()
endforeach()
# remove false positives, e.g.:
# mark_as_advanced([CLEAR|FORCE] VAR VAR2 VAR...)
# add_definitions(-DFOO -DBAR ...)
list (REMOVE_ITEM _keywordList "FOO" "BAR" "DFOO" "DBAR" "VAR" "VAR2")
# explicitly add keywords missed by command parser
list (APPEND _keywordList "ARGV(0..9)" "ARGC" "ARGV" "ARGN")
list (APPEND _keywordList "STATUS" "WARNING" "AUTHOR_WARNING" "SEND_ERROR" "FATAL_ERROR" "DEPRECATION")
list (APPEND _keywordList "DIRECTORY" "NAME" "EXT" "NAME_WE" "PATH" "ABSOLUTE" "REALPATH")
resolve_templates(_keywordList ${_keywordList})
#message (STATUS "${_keywordList}")
set (BBLMPredefinedNameList ${_propertyList} ${_variableList} ${_keywordList})
list (SORT BBLMPredefinedNameList)
list (REMOVE_DUPLICATES BBLMPredefinedNameList)
string (
REGEX REPLACE "[@A-Za-z0-9_<>-]+" "\t\t<string>\\0</string>"
BBLMPredefinedNameList "${BBLMPredefinedNameList}")
string (REPLACE ";" "\n" BBLMPredefinedNameList "${BBLMPredefinedNameList}")
#message (STATUS "${BBLMPredefinedNameList}")
if (CMAKE_VERSION VERSION_LESS "3.0.0")
set (BBLMReferenceSearchURLTemplate "https://www.cmake.org/cmake/help/v${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}/cmake.html#__SYMBOLNAME__")
else()
set (BBLMReferenceSearchURLTemplate "https://www.cmake.org/cmake/help/v${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}/search.html?q=__SYMBOLNAME__&check_keywords=yes&area=default")
endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/cmake.plist.in" "${CMAKE_CURRENT_LIST_DIR}/cmake.plist")