@@ -229,12 +229,25 @@ def _glob_match(
229229 # if it isn't, it means it was not matched
230230 return p == None
231231
232- def _materialize_hdr_mapping (ctx_actions , parent_dir_name , source_hdr_file , mappings ):
232+ def _materialize_hdr_mapping (ctx_actions , parent_dir_name , source_hdr_file , mappings , existing_paths = None ):
233+ existing_paths = existing_paths if existing_paths else set ()
233234 mapped_files = []
235+
234236 for mapping in mappings :
235237 # Ensure {filename} is translated to header_file name
236238 target = mapping .replace ("{filename}" , source_hdr_file .basename )
237239
240+ # TODO: Made this behavior configurable
241+ # It might be the case, that aggregation of different header mapping, will result
242+ # in two or more files attempting to create given mapping.
243+ # For now - we are implementing "first-write-wins" strategy, where
244+ # every subsequent attempt results in warnings.
245+ if target in existing_paths :
246+ print ("[WARN][rules_cc_hdrs_map] {} attempts to overwrite mapping of {}. Refusing and continuing." .format (source_hdr_file .path , target ))
247+ continue
248+
249+ existing_paths .add (target )
250+
238251 # TODO: Hash the label name and add as prefix?
239252 mapping_path = "/" .join ([
240253 parent_dir_name ,
@@ -250,7 +263,7 @@ def _materialize_hdr_mapping(ctx_actions, parent_dir_name, source_hdr_file, mapp
250263 )
251264 mapped_files .append (mapping_file )
252265
253- return mapped_files
266+ return mapped_files , existing_paths
254267
255268def materialize_hdrs_mapping (
256269 invoker_label ,
@@ -276,33 +289,43 @@ def materialize_hdrs_mapping(
276289 materialized_include_path = None
277290 materialized_hdrs_files = []
278291
292+ # Retain paths (relative to HEADERS_MAP_DIR_NAME)
293+ # of all header files that were created during mapping phase.
294+ # This bookeeping is used for detection of scenario,
295+ # that would lead to attempt to create a duplicated file,
296+ # and would result in Bazel error.
297+ materialized_hdrs_paths_rel = set ()
298+
299+ # TODO: Refactor this nested-loop logic
279300 for header_file in hdrs .to_list ():
280301 if ".vhm" in header_file .path :
281302 # This is important! Improve the check
282303 continue
283304 if header_file .path in hdrs_map .non_glob :
284305 # This is happening before globbing to improve perf.
285- materialized_hdrs_files .extend (
286- _materialize_hdr_mapping (
287- actions ,
288- HEADERS_MAP_DIR_NAME ,
289- header_file ,
290- hdrs_map .non_glob .get (header_file .path ),
291- ),
306+ created_hdrs , created_hdrs_paths_rel = _materialize_hdr_mapping (
307+ actions ,
308+ HEADERS_MAP_DIR_NAME ,
309+ header_file ,
310+ hdrs_map .non_glob .get (header_file .path ),
311+ materialized_hdrs_paths_rel ,
292312 )
313+ materialized_hdrs_files .extend (created_hdrs )
314+ materialized_hdrs_paths_rel .update (created_hdrs_paths_rel )
293315 continue
294316
295317 for pattern , mappings in hdrs_map .glob .items ():
296318 if not _glob_match (pattern , header_file .path ):
297319 continue
298- materialized_hdrs_files .extend (
299- _materialize_hdr_mapping (
300- actions ,
301- HEADERS_MAP_DIR_NAME ,
302- header_file ,
303- mappings ,
304- ),
320+ created_hdrs , created_hdrs_paths_rel = _materialize_hdr_mapping (
321+ actions ,
322+ HEADERS_MAP_DIR_NAME ,
323+ header_file ,
324+ mappings ,
325+ materialized_hdrs_paths_rel ,
305326 )
327+ materialized_hdrs_files .extend (created_hdrs )
328+ materialized_hdrs_paths_rel .update (created_hdrs_paths_rel )
306329
307330 if materialized_hdrs_files :
308331 hdr = materialized_hdrs_files [0 ]
0 commit comments