diff --git a/BUCK b/BUCK index fd87a83b..4b809f69 100644 --- a/BUCK +++ b/BUCK @@ -2,8 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - -load("//:yoga_defs.bzl", "BASE_COMPILER_FLAGS", "GTEST_TARGET", "LIBRARY_COMPILER_FLAGS", "yoga_cxx_library", "yoga_cxx_test", "yoga_dep") +load("//:yoga_defs.bzl", "BASE_COMPILER_FLAGS", "GTEST_TARGET", "LIBRARY_COMPILER_FLAGS", "subdir_glob", "yoga_cxx_library", "yoga_cxx_test", "yoga_dep") GMOCK_OVERRIDE_FLAGS = [ # gmock does not mark mocked methods as override, ignore the warnings in tests diff --git a/YogaKit/BUCK b/YogaKit/BUCK index 14198edb..9675d049 100644 --- a/YogaKit/BUCK +++ b/YogaKit/BUCK @@ -2,8 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - -load("//:yoga_defs.bzl", "yoga_apple_library", "yoga_apple_test", "yoga_dep") +load("//:yoga_defs.bzl", "subdir_glob", "yoga_apple_library", "yoga_apple_test", "yoga_dep") COMPILER_FLAGS = [ "-fobjc-arc", diff --git a/benchmark/BUCK b/benchmark/BUCK index 2b30af78..82864373 100644 --- a/benchmark/BUCK +++ b/benchmark/BUCK @@ -2,8 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - -load("//:yoga_defs.bzl", "yoga_cxx_binary", "yoga_dep") +load("//:yoga_defs.bzl", "subdir_glob", "yoga_cxx_binary", "yoga_dep") yoga_cxx_binary( name = "benchmark", diff --git a/lib/fb/BUCK b/lib/fb/BUCK index e72c3cb6..cc2502ec 100644 --- a/lib/fb/BUCK +++ b/lib/fb/BUCK @@ -2,8 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - -load("//:yoga_defs.bzl", "ANDROID", "FBJNI_JAVA_TARGET", "JNI_TARGET", "YOGA_ROOTS", "yoga_cxx_library", "yoga_prebuilt_cxx_library") +load("//:yoga_defs.bzl", "ANDROID", "FBJNI_JAVA_TARGET", "JNI_TARGET", "YOGA_ROOTS", "subdir_glob", "yoga_cxx_library", "yoga_prebuilt_cxx_library") yoga_prebuilt_cxx_library( name = "ndklog", diff --git a/lib/gtest/BUCK b/lib/gtest/BUCK index 167d70eb..e489c69c 100644 --- a/lib/gtest/BUCK +++ b/lib/gtest/BUCK @@ -2,8 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - -load("//:yoga_defs.bzl", "YOGA_ROOTS", "yoga_cxx_library") +load("//:yoga_defs.bzl", "YOGA_ROOTS", "subdir_glob", "yoga_cxx_library") COMPILER_FLAGS = [ "-std=c++11", diff --git a/yoga_defs.bzl b/yoga_defs.bzl index c6d7120a..9f33a825 100644 --- a/yoga_defs.bzl +++ b/yoga_defs.bzl @@ -59,6 +59,87 @@ LIBRARY_COMPILER_FLAGS = BASE_COMPILER_FLAGS + [ "-fPIC", ] +def _paths_join(path, *others): + """Joins one or more path components.""" + result = path + + for p in others: + if p.startswith("/"): # absolute + result = p + elif not result or result.endswith("/"): + result += p + else: + result += "/" + p + + return result + +def subdir_glob(glob_specs, exclude = None, prefix = ""): + """Returns a dict of sub-directory relative paths to full paths. + + The subdir_glob() function is useful for defining header maps for C/C++ + libraries which should be relative the given sub-directory. + Given a list of tuples, the form of (relative-sub-directory, glob-pattern), + it returns a dict of sub-directory relative paths to full paths. + + Please refer to native.glob() for explanations and examples of the pattern. + + Args: + glob_specs: The array of tuples in form of + (relative-sub-directory, glob-pattern inside relative-sub-directory). + type: List[Tuple[str, str]] + exclude: A list of patterns to identify files that should be removed + from the set specified by the first argument. Defaults to []. + type: Optional[List[str]] + prefix: If is not None, prepends it to each key in the dictionary. + Defaults to None. + type: Optional[str] + + Returns: + A dict of sub-directory relative paths to full paths. + """ + if exclude == None: + exclude = [] + + results = [] + + for dirpath, glob_pattern in glob_specs: + results.append( + _single_subdir_glob(dirpath, glob_pattern, exclude, prefix), + ) + + return _merge_maps(*results) + +def _merge_maps(*file_maps): + result = {} + for file_map in file_maps: + for key in file_map: + if key in result and result[key] != file_map[key]: + fail( + "Conflicting files in file search paths. " + + "\"%s\" maps to both \"%s\" and \"%s\"." % + (key, result[key], file_map[key]), + ) + + result[key] = file_map[key] + + return result + +def _single_subdir_glob(dirpath, glob_pattern, exclude = None, prefix = None): + if exclude == None: + exclude = [] + results = {} + files = native.glob([_paths_join(dirpath, glob_pattern)], exclude = exclude) + for f in files: + if dirpath: + key = f[len(dirpath) + 1:] + else: + key = f + if prefix: + key = _paths_join(prefix, key) + results[key] = f + + return results + def yoga_dep(dep): return "//" + dep