xref: /aosp_15_r20/external/pytorch/tools/build_defs/glob_defs.bzl (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
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