@@ -129,6 +129,135 @@ function(get_fq_dep_list_without_flag output_list flag)
129
129
set (${output_list} ${fq_dep_no_flag_list} PARENT_SCOPE )
130
130
endfunction (get_fq_dep_list_without_flag )
131
131
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
+
132
261
# Special flags
133
262
set (FMA_OPT_FLAG "FMA_OPT" )
134
263
set (ROUND_OPT_FLAG "ROUND_OPT" )
0 commit comments