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