# Copyright 2014 The Bazel Authors. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. GO_TOOLCHAIN = "@io_bazel_rules_go//go:toolchain" GO_TOOLCHAIN_LABEL = Label(GO_TOOLCHAIN) go_exts = [ ".go", ] asm_exts = [ ".s", ".S", ".h", # may be included by .s ] # be consistent to cc_library. hdr_exts = [ ".h", ".hh", ".hpp", ".hxx", ".inc", ] c_exts = [ ".c", ".h", ] cxx_exts = [ ".cc", ".cxx", ".cpp", ".h", ".hh", ".hpp", ".hxx", ] objc_exts = [ ".m", ".mm", ".h", ".hh", ".hpp", ".hxx", ] cgo_exts = [ ".c", ".cc", ".cpp", ".cxx", ".h", ".hh", ".hpp", ".hxx", ".inc", ".m", ".mm", ] def split_srcs(srcs): """Returns a struct of sources, divided by extension.""" sources = struct( go = [], asm = [], headers = [], c = [], cxx = [], objc = [], ) ext_pairs = ( (sources.go, go_exts), (sources.headers, hdr_exts), (sources.asm, asm_exts), (sources.c, c_exts), (sources.cxx, cxx_exts), (sources.objc, objc_exts), ) extmap = {} for outs, exts in ext_pairs: for ext in exts: ext = ext[1:] # strip the dot if ext in extmap: break extmap[ext] = outs for src in as_iterable(srcs): extouts = extmap.get(src.extension) if extouts == None: fail("Unknown source type {0}".format(src.basename)) extouts.append(src) return sources def join_srcs(source): """Combines source from a split_srcs struct into a single list.""" return source.go + source.headers + source.asm + source.c + source.cxx + source.objc def os_path(ctx, path): path = str(path) # maybe convert from path type if ctx.os.name.startswith("windows"): path = path.replace("/", "\\") return path def executable_path(ctx, path): path = os_path(ctx, path) if ctx.os.name.startswith("windows"): path += ".exe" return path def executable_extension(ctx): extension = "" if ctx.os.name.startswith("windows"): extension = ".exe" return extension def goos_to_extension(goos): if goos == "windows": return ".exe" return "" ARCHIVE_EXTENSION = ".a" SHARED_LIB_EXTENSIONS = [".dll", ".dylib", ".so"] def goos_to_shared_extension(goos): return { "windows": ".dll", "darwin": ".dylib", }.get(goos, ".so") def has_shared_lib_extension(path): """ Matches filenames of shared libraries, with or without a version number extension. """ return (has_simple_shared_lib_extension(path) or get_versioned_shared_lib_extension(path)) def has_simple_shared_lib_extension(path): """ Matches filenames of shared libraries, without a version number extension. """ return any([path.endswith(ext) for ext in SHARED_LIB_EXTENSIONS]) def get_versioned_shared_lib_extension(path): """If appears to be an versioned .so or .dylib file, return the extension; otherwise empty""" parts = path.split("/")[-1].split(".") if not parts[-1].isdigit(): return "" # only iterating to 1 because parts[0] has to be the lib name for i in range(len(parts) - 1, 0, -1): if not parts[i].isdigit(): if parts[i] == "dylib" or parts[i] == "so": return ".".join(parts[i:]) # something like foo.bar.1.2 or dylib.1.2 return "" # something like 1.2.3, or so.1.2, or dylib.1.2, or foo.1.2 return "" MINIMUM_BAZEL_VERSION = "5.4.0" def as_list(v): """Returns a list, tuple, or depset as a list.""" if type(v) == "list": return v if type(v) == "tuple": return list(v) if type(v) == "depset": return v.to_list() fail("as_list failed on {}".format(v)) def as_iterable(v): """Returns a list, tuple, or depset as something iterable.""" if type(v) == "list": return v if type(v) == "tuple": return v if type(v) == "depset": return v.to_list() fail("as_iterator failed on {}".format(v)) def as_tuple(v): """Returns a list, tuple, or depset as a tuple.""" if type(v) == "tuple": return v if type(v) == "list": return tuple(v) if type(v) == "depset": return tuple(v.to_list()) fail("as_tuple failed on {}".format(v)) def as_set(v): """Returns a list, tuple, or depset as a depset.""" if type(v) == "depset": return v if type(v) == "list": return depset(v) if type(v) == "tuple": return depset(v) fail("as_tuple failed on {}".format(v)) _STRUCT_TYPE = type(struct()) def is_struct(v): """Returns true if v is a struct.""" return type(v) == _STRUCT_TYPE def count_group_matches(v, prefix, suffix): """Counts reluctant substring matches between prefix and suffix. Equivalent to the number of regular expression matches "prefix.+?suffix" in the string v. """ count = 0 idx = 0 for i in range(0, len(v)): if idx > i: continue idx = v.find(prefix, idx) if idx == -1: break # If there is another prefix before the next suffix, the previous prefix is discarded. # This is OK; it does not affect our count. idx = v.find(suffix, idx) if idx == -1: break count = count + 1 return count # C/C++ compiler and linker options related to coverage instrumentation. COVERAGE_OPTIONS_DENYLIST = { "--coverage": None, "-ftest-coverage": None, "-fprofile-arcs": None, "-fprofile-instr-generate": None, "-fcoverage-mapping": None, } _RULES_GO_RAW_REPO_NAME = str(Label("//:unused"))[:-len("//:unused")] # When rules_go is the main repository and Bazel < 6 is used, the repo name does # not start with a "@", so we need to add it. RULES_GO_REPO_NAME = _RULES_GO_RAW_REPO_NAME if _RULES_GO_RAW_REPO_NAME.startswith("@") else "@" + _RULES_GO_RAW_REPO_NAME RULES_GO_STDLIB_PREFIX = RULES_GO_REPO_NAME + "//stdlib:"