1# Only used for PyTorch open source BUCK build 2 3"""Provides utility macros for working with globs.""" 4 5load("@bazel_skylib//lib:paths.bzl", "paths") 6 7def subdir_glob(glob_specs, exclude = None, prefix = ""): 8 """Returns a dict of sub-directory relative paths to full paths. 9 10 The subdir_glob() function is useful for defining header maps for C/C++ 11 libraries which should be relative the given sub-directory. 12 Given a list of tuples, the form of (relative-sub-directory, glob-pattern), 13 it returns a dict of sub-directory relative paths to full paths. 14 15 Please refer to native.glob() for explanations and examples of the pattern. 16 17 Args: 18 glob_specs: The array of tuples in form of 19 (relative-sub-directory, glob-pattern inside relative-sub-directory). 20 type: List[Tuple[str, str]] 21 exclude: A list of patterns to identify files that should be removed 22 from the set specified by the first argument. Defaults to []. 23 type: Optional[List[str]] 24 prefix: If is not None, prepends it to each key in the dictionary. 25 Defaults to None. 26 type: Optional[str] 27 28 Returns: 29 A dict of sub-directory relative paths to full paths. 30 """ 31 if exclude == None: 32 exclude = [] 33 34 results = [] 35 36 for dirpath, glob_pattern in glob_specs: 37 results.append( 38 _single_subdir_glob(dirpath, glob_pattern, exclude, prefix), 39 ) 40 41 return _merge_maps(*results) 42 43def _merge_maps(*file_maps): 44 result = {} 45 for file_map in file_maps: 46 for key in file_map: 47 if key in result and result[key] != file_map[key]: 48 fail( 49 "Conflicting files in file search paths. " + 50 "\"%s\" maps to both \"%s\" and \"%s\"." % 51 (key, result[key], file_map[key]), 52 ) 53 54 result[key] = file_map[key] 55 56 return result 57 58def _single_subdir_glob(dirpath, glob_pattern, exclude = None, prefix = None): 59 if exclude == None: 60 exclude = [] 61 results = {} 62 files = native.glob([paths.join(dirpath, glob_pattern)], exclude = exclude) 63 for f in files: 64 if dirpath: 65 key = f[len(dirpath) + 1:] 66 else: 67 key = f 68 if prefix: 69 key = paths.join(prefix, key) 70 results[key] = f 71 72 return results 73 74# Using a flat list will trigger build errors on Android. 75# cxx_library will generate an apple_library on iOS, a cxx_library on Android. 76# Those rules have different behaviors. Using a map will make the behavior consistent. 77# 78def glob_private_headers(glob_patterns, exclude = []): 79 result = {} 80 headers = native.glob(glob_patterns, exclude = exclude) 81 for header in headers: 82 result[paths.basename(header)] = header 83 return result 84 85def glob(include, exclude = (), **kwargs): 86 buildfile = native.read_config("buildfile", "name", "BUCK") 87 subpkgs = [ 88 target[:-len(buildfile)] + "**/*" 89 for target in native.glob(["*/**/" + buildfile]) 90 ] 91 return native.glob(include, exclude = list(exclude) + subpkgs, **kwargs) 92