Skip to content

Commit 548d132

Browse files
authored
[libc][NFC] Refactor FLAGS expansion using cmake_language(CALL ...). (#80156)
1 parent 4739a97 commit 548d132

File tree

4 files changed

+184
-402
lines changed

4 files changed

+184
-402
lines changed

libc/cmake/modules/LLVMLibCFlagRules.cmake

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,135 @@ function(get_fq_dep_list_without_flag output_list flag)
129129
set(${output_list} ${fq_dep_no_flag_list} PARENT_SCOPE)
130130
endfunction(get_fq_dep_list_without_flag)
131131

132+
# Check if a `flag` is set
133+
function(check_flag result flag_name)
134+
list(FIND ARGN ${flag_name}_FLAG has_flag)
135+
if(${has_flag} LESS 0)
136+
list(FIND ARGN "${flag_name}_FLAG__ONLY" has_flag)
137+
endif()
138+
if(${has_flag} GREATER -1)
139+
set(${result} TRUE PARENT_SCOPE)
140+
else()
141+
set(${result} FALSE PARENT_SCOPE)
142+
endif()
143+
endfunction(check_flag)
144+
145+
# Generate all flags' combinations and call the corresponding function provided
146+
# by `CREATE_TARGET` to create a target for each combination.
147+
function(expand_flags_for_target target_name flags)
148+
cmake_parse_arguments(
149+
"EXPAND_FLAGS"
150+
"" # Optional arguments
151+
"CREATE_TARGET" # Single-value arguments
152+
"DEPENDS;FLAGS" # Multi-value arguments
153+
${ARGN}
154+
)
155+
156+
list(LENGTH flags nflags)
157+
if(NOT ${nflags})
158+
cmake_language(CALL ${EXPAND_FLAGS_CREATE_TARGET}
159+
${target_name}
160+
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
161+
DEPENDS ${EXPAND_FLAGS_DEPENDS}
162+
FLAGS ${EXPAND_FLAGS_FLAGS}
163+
)
164+
return()
165+
endif()
166+
167+
list(GET flags 0 flag)
168+
list(REMOVE_AT flags 0)
169+
extract_flag_modifier(${flag} real_flag modifier)
170+
171+
if(NOT "${modifier}" STREQUAL "NO")
172+
expand_flags_for_target(
173+
${target_name}
174+
"${flags}"
175+
DEPENDS ${EXPAND_FLAGS_DEPENDS}
176+
FLAGS ${EXPAND_FLAGS_FLAGS}
177+
CREATE_TARGET ${EXPAND_FLAGS_CREATE_TARGET}
178+
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
179+
)
180+
endif()
181+
182+
if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY")
183+
return()
184+
endif()
185+
186+
set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS})
187+
list(REMOVE_ITEM NEW_FLAGS ${flag})
188+
get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS})
189+
190+
# Only target with `flag` has `.__NO_flag` target, `flag__NO` and
191+
# `flag__ONLY` do not.
192+
if("${modifier}" STREQUAL "")
193+
set(TARGET_NAME "${target_name}.__NO_${flag}")
194+
else()
195+
set(TARGET_NAME "${target_name}")
196+
endif()
197+
198+
expand_flags_for_target(
199+
${TARGET_NAME}
200+
"${flags}"
201+
DEPENDS ${NEW_DEPS}
202+
FLAGS ${NEW_FLAGS}
203+
CREATE_TARGET ${EXPAND_FLAGS_CREATE_TARGET}
204+
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
205+
)
206+
endfunction(expand_flags_for_target)
207+
208+
# Collect all flags from a target's dependency, and then forward to
209+
# `expand_flags_for_target to generate all flags' combinations and call
210+
# the corresponding function provided by `CREATE_TARGET` to create a target for
211+
# each combination.
212+
function(add_target_with_flags target_name)
213+
cmake_parse_arguments(
214+
"ADD_TO_EXPAND"
215+
"" # Optional arguments
216+
"CREATE_TARGET;" # Single value arguments
217+
"DEPENDS;FLAGS;ADD_FLAGS" # Multi-value arguments
218+
${ARGN}
219+
)
220+
221+
if(NOT target_name)
222+
message(FATAL_ERROR "Bad target name")
223+
endif()
224+
225+
if(NOT ADD_TO_EXPAND_CREATE_TARGET)
226+
message(FATAL_ERROR "Missing function to create targets. Please specify "
227+
"`CREATE_TARGET <function>`")
228+
endif()
229+
230+
get_fq_target_name(${target_name} fq_target_name)
231+
232+
if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS"))
233+
message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}")
234+
endif()
235+
236+
get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS})
237+
get_flags_from_dep_list(deps_flag_list ${fq_deps_list})
238+
239+
# Appending ADD_FLAGS before flags from dependency.
240+
if(ADD_TO_EXPAND_ADD_FLAGS)
241+
list(APPEND ADD_TO_EXPAND_FLAGS ${ADD_TO_EXPAND_ADD_FLAGS})
242+
endif()
243+
list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list})
244+
remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags)
245+
list(SORT flags)
246+
247+
if(SHOW_INTERMEDIATE_OBJECTS AND flags)
248+
message(STATUS "Target ${fq_target_name} has FLAGS: ${flags}")
249+
endif()
250+
251+
expand_flags_for_target(
252+
${fq_target_name}
253+
"${flags}"
254+
DEPENDS "${fq_deps_list}"
255+
FLAGS "${flags}"
256+
CREATE_TARGET ${ADD_TO_EXPAND_CREATE_TARGET}
257+
${ADD_TO_EXPAND_UNPARSED_ARGUMENTS}
258+
)
259+
endfunction(add_target_with_flags)
260+
132261
# Special flags
133262
set(FMA_OPT_FLAG "FMA_OPT")
134263
set(ROUND_OPT_FLAG "ROUND_OPT")

libc/cmake/modules/LLVMLibCLibraryRules.cmake

Lines changed: 3 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -207,97 +207,10 @@ endfunction(create_header_library)
207207
# FLAGS <list of flags>
208208
# )
209209

210-
# Internal function, used by `add_header_library`.
211-
function(expand_flags_for_header_library target_name flags)
212-
cmake_parse_arguments(
213-
"EXPAND_FLAGS"
214-
"IGNORE_MARKER" # Optional arguments
215-
"" # Single-value arguments
216-
"DEPENDS;FLAGS" # Multi-value arguments
217-
${ARGN}
218-
)
219-
220-
list(LENGTH flags nflags)
221-
if(NOT ${nflags})
222-
create_header_library(
223-
${target_name}
224-
DEPENDS ${EXPAND_FLAGS_DEPENDS}
225-
FLAGS ${EXPAND_FLAGS_FLAGS}
226-
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
227-
)
228-
return()
229-
endif()
230-
231-
list(GET flags 0 flag)
232-
list(REMOVE_AT flags 0)
233-
extract_flag_modifier(${flag} real_flag modifier)
234-
235-
if(NOT "${modifier}" STREQUAL "NO")
236-
expand_flags_for_header_library(
237-
${target_name}
238-
"${flags}"
239-
DEPENDS ${EXPAND_FLAGS_DEPENDS} IGNORE_MARKER
240-
FLAGS ${EXPAND_FLAGS_FLAGS} IGNORE_MARKER
241-
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
242-
)
243-
endif()
244-
245-
if("${real_flag}" STREQUAL "" OR "${modifier}" STREQUAL "ONLY")
246-
return()
247-
endif()
248-
249-
set(NEW_FLAGS ${EXPAND_FLAGS_FLAGS})
250-
list(REMOVE_ITEM NEW_FLAGS ${flag})
251-
get_fq_dep_list_without_flag(NEW_DEPS ${real_flag} ${EXPAND_FLAGS_DEPENDS})
252-
253-
# Only target with `flag` has `.__NO_flag` target, `flag__NO` and
254-
# `flag__ONLY` do not.
255-
if("${modifier}" STREQUAL "")
256-
set(TARGET_NAME "${target_name}.__NO_${flag}")
257-
else()
258-
set(TARGET_NAME "${target_name}")
259-
endif()
260-
261-
expand_flags_for_header_library(
262-
${TARGET_NAME}
263-
"${flags}"
264-
DEPENDS ${NEW_DEPS} IGNORE_MARKER
265-
FLAGS ${NEW_FLAGS} IGNORE_MARKER
266-
${EXPAND_FLAGS_UNPARSED_ARGUMENTS}
267-
)
268-
endfunction(expand_flags_for_header_library)
269-
270210
function(add_header_library target_name)
271-
cmake_parse_arguments(
272-
"ADD_TO_EXPAND"
273-
"" # Optional arguments
274-
"" # Single value arguments
275-
"DEPENDS;FLAGS" # Multi-value arguments
211+
add_target_with_flags(
212+
${target_name}
213+
CREATE_TARGET create_header_library
276214
${ARGN}
277215
)
278-
279-
get_fq_target_name(${target_name} fq_target_name)
280-
281-
if(ADD_TO_EXPAND_DEPENDS AND ("${SHOW_INTERMEDIATE_OBJECTS}" STREQUAL "DEPS"))
282-
message(STATUS "Gathering FLAGS from dependencies for ${fq_target_name}")
283-
endif()
284-
285-
get_fq_deps_list(fq_deps_list ${ADD_TO_EXPAND_DEPENDS})
286-
get_flags_from_dep_list(deps_flag_list ${fq_deps_list})
287-
288-
list(APPEND ADD_TO_EXPAND_FLAGS ${deps_flag_list})
289-
remove_duplicated_flags("${ADD_TO_EXPAND_FLAGS}" flags)
290-
list(SORT flags)
291-
292-
if(SHOW_INTERMEDIATE_OBJECTS AND flags)
293-
message(STATUS "Header library ${fq_target_name} has FLAGS: ${flags}")
294-
endif()
295-
296-
expand_flags_for_header_library(
297-
${fq_target_name}
298-
"${flags}"
299-
DEPENDS ${fq_deps_list} IGNORE_MARKER
300-
FLAGS ${flags} IGNORE_MARKER
301-
${ADD_TO_EXPAND_UNPARSED_ARGUMENTS}
302-
)
303216
endfunction(add_header_library)

0 commit comments

Comments
 (0)