1*9bb1b549SSpandan Das# Copyright 2014 The Bazel Authors. All rights reserved. 2*9bb1b549SSpandan Das# 3*9bb1b549SSpandan Das# Licensed under the Apache License, Version 2.0 (the "License"); 4*9bb1b549SSpandan Das# you may not use this file except in compliance with the License. 5*9bb1b549SSpandan Das# You may obtain a copy of the License at 6*9bb1b549SSpandan Das# 7*9bb1b549SSpandan Das# http://www.apache.org/licenses/LICENSE-2.0 8*9bb1b549SSpandan Das# 9*9bb1b549SSpandan Das# Unless required by applicable law or agreed to in writing, software 10*9bb1b549SSpandan Das# distributed under the License is distributed on an "AS IS" BASIS, 11*9bb1b549SSpandan Das# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9bb1b549SSpandan Das# See the License for the specific language governing permissions and 13*9bb1b549SSpandan Das# limitations under the License. 14*9bb1b549SSpandan Das 15*9bb1b549SSpandan Dasgo_exts = [ 16*9bb1b549SSpandan Das ".go", 17*9bb1b549SSpandan Das] 18*9bb1b549SSpandan Das 19*9bb1b549SSpandan Dasasm_exts = [ 20*9bb1b549SSpandan Das ".s", 21*9bb1b549SSpandan Das ".S", 22*9bb1b549SSpandan Das ".h", # may be included by .s 23*9bb1b549SSpandan Das] 24*9bb1b549SSpandan Das 25*9bb1b549SSpandan Das# be consistent to cc_library. 26*9bb1b549SSpandan Dashdr_exts = [ 27*9bb1b549SSpandan Das ".h", 28*9bb1b549SSpandan Das ".hh", 29*9bb1b549SSpandan Das ".hpp", 30*9bb1b549SSpandan Das ".hxx", 31*9bb1b549SSpandan Das ".inc", 32*9bb1b549SSpandan Das] 33*9bb1b549SSpandan Das 34*9bb1b549SSpandan Dasc_exts = [ 35*9bb1b549SSpandan Das ".c", 36*9bb1b549SSpandan Das ".h", 37*9bb1b549SSpandan Das] 38*9bb1b549SSpandan Das 39*9bb1b549SSpandan Dascxx_exts = [ 40*9bb1b549SSpandan Das ".cc", 41*9bb1b549SSpandan Das ".cxx", 42*9bb1b549SSpandan Das ".cpp", 43*9bb1b549SSpandan Das ".h", 44*9bb1b549SSpandan Das ".hh", 45*9bb1b549SSpandan Das ".hpp", 46*9bb1b549SSpandan Das ".hxx", 47*9bb1b549SSpandan Das] 48*9bb1b549SSpandan Das 49*9bb1b549SSpandan Dasobjc_exts = [ 50*9bb1b549SSpandan Das ".m", 51*9bb1b549SSpandan Das ".mm", 52*9bb1b549SSpandan Das ".h", 53*9bb1b549SSpandan Das ".hh", 54*9bb1b549SSpandan Das ".hpp", 55*9bb1b549SSpandan Das ".hxx", 56*9bb1b549SSpandan Das] 57*9bb1b549SSpandan Das 58*9bb1b549SSpandan Dascgo_exts = [ 59*9bb1b549SSpandan Das ".c", 60*9bb1b549SSpandan Das ".cc", 61*9bb1b549SSpandan Das ".cpp", 62*9bb1b549SSpandan Das ".cxx", 63*9bb1b549SSpandan Das ".h", 64*9bb1b549SSpandan Das ".hh", 65*9bb1b549SSpandan Das ".hpp", 66*9bb1b549SSpandan Das ".hxx", 67*9bb1b549SSpandan Das ".inc", 68*9bb1b549SSpandan Das ".m", 69*9bb1b549SSpandan Das ".mm", 70*9bb1b549SSpandan Das] 71*9bb1b549SSpandan Das 72*9bb1b549SSpandan Dasdef split_srcs(srcs): 73*9bb1b549SSpandan Das """Returns a struct of sources, divided by extension.""" 74*9bb1b549SSpandan Das sources = struct( 75*9bb1b549SSpandan Das go = [], 76*9bb1b549SSpandan Das asm = [], 77*9bb1b549SSpandan Das headers = [], 78*9bb1b549SSpandan Das c = [], 79*9bb1b549SSpandan Das cxx = [], 80*9bb1b549SSpandan Das objc = [], 81*9bb1b549SSpandan Das ) 82*9bb1b549SSpandan Das ext_pairs = ( 83*9bb1b549SSpandan Das (sources.go, go_exts), 84*9bb1b549SSpandan Das (sources.headers, hdr_exts), 85*9bb1b549SSpandan Das (sources.asm, asm_exts), 86*9bb1b549SSpandan Das (sources.c, c_exts), 87*9bb1b549SSpandan Das (sources.cxx, cxx_exts), 88*9bb1b549SSpandan Das (sources.objc, objc_exts), 89*9bb1b549SSpandan Das ) 90*9bb1b549SSpandan Das extmap = {} 91*9bb1b549SSpandan Das for outs, exts in ext_pairs: 92*9bb1b549SSpandan Das for ext in exts: 93*9bb1b549SSpandan Das ext = ext[1:] # strip the dot 94*9bb1b549SSpandan Das if ext in extmap: 95*9bb1b549SSpandan Das break 96*9bb1b549SSpandan Das extmap[ext] = outs 97*9bb1b549SSpandan Das for src in as_iterable(srcs): 98*9bb1b549SSpandan Das extouts = extmap.get(src.extension) 99*9bb1b549SSpandan Das if extouts == None: 100*9bb1b549SSpandan Das fail("Unknown source type {0}".format(src.basename)) 101*9bb1b549SSpandan Das extouts.append(src) 102*9bb1b549SSpandan Das return sources 103*9bb1b549SSpandan Das 104*9bb1b549SSpandan Dasdef join_srcs(source): 105*9bb1b549SSpandan Das """Combines source from a split_srcs struct into a single list.""" 106*9bb1b549SSpandan Das return source.go + source.headers + source.asm + source.c + source.cxx + source.objc 107*9bb1b549SSpandan Das 108*9bb1b549SSpandan Dasdef os_path(ctx, path): 109*9bb1b549SSpandan Das path = str(path) # maybe convert from path type 110*9bb1b549SSpandan Das if ctx.os.name.startswith("windows"): 111*9bb1b549SSpandan Das path = path.replace("/", "\\") 112*9bb1b549SSpandan Das return path 113*9bb1b549SSpandan Das 114*9bb1b549SSpandan Dasdef executable_path(ctx, path): 115*9bb1b549SSpandan Das path = os_path(ctx, path) 116*9bb1b549SSpandan Das if ctx.os.name.startswith("windows"): 117*9bb1b549SSpandan Das path += ".exe" 118*9bb1b549SSpandan Das return path 119*9bb1b549SSpandan Das 120*9bb1b549SSpandan Dasdef executable_extension(ctx): 121*9bb1b549SSpandan Das extension = "" 122*9bb1b549SSpandan Das if ctx.os.name.startswith("windows"): 123*9bb1b549SSpandan Das extension = ".exe" 124*9bb1b549SSpandan Das return extension 125*9bb1b549SSpandan Das 126*9bb1b549SSpandan Dasdef goos_to_extension(goos): 127*9bb1b549SSpandan Das if goos == "windows": 128*9bb1b549SSpandan Das return ".exe" 129*9bb1b549SSpandan Das return "" 130*9bb1b549SSpandan Das 131*9bb1b549SSpandan DasARCHIVE_EXTENSION = ".a" 132*9bb1b549SSpandan Das 133*9bb1b549SSpandan DasSHARED_LIB_EXTENSIONS = [".dll", ".dylib", ".so"] 134*9bb1b549SSpandan Das 135*9bb1b549SSpandan Dasdef goos_to_shared_extension(goos): 136*9bb1b549SSpandan Das return { 137*9bb1b549SSpandan Das "windows": ".dll", 138*9bb1b549SSpandan Das "darwin": ".dylib", 139*9bb1b549SSpandan Das }.get(goos, ".so") 140*9bb1b549SSpandan Das 141*9bb1b549SSpandan Dasdef has_shared_lib_extension(path): 142*9bb1b549SSpandan Das """ 143*9bb1b549SSpandan Das Matches filenames of shared libraries, with or without a version number extension. 144*9bb1b549SSpandan Das """ 145*9bb1b549SSpandan Das return (has_simple_shared_lib_extension(path) or 146*9bb1b549SSpandan Das get_versioned_shared_lib_extension(path)) 147*9bb1b549SSpandan Das 148*9bb1b549SSpandan Dasdef has_simple_shared_lib_extension(path): 149*9bb1b549SSpandan Das """ 150*9bb1b549SSpandan Das Matches filenames of shared libraries, without a version number extension. 151*9bb1b549SSpandan Das """ 152*9bb1b549SSpandan Das return any([path.endswith(ext) for ext in SHARED_LIB_EXTENSIONS]) 153*9bb1b549SSpandan Das 154*9bb1b549SSpandan Dasdef get_versioned_shared_lib_extension(path): 155*9bb1b549SSpandan Das """If appears to be an versioned .so or .dylib file, return the extension; otherwise empty""" 156*9bb1b549SSpandan Das parts = path.split("/")[-1].split(".") 157*9bb1b549SSpandan Das if not parts[-1].isdigit(): 158*9bb1b549SSpandan Das return "" 159*9bb1b549SSpandan Das 160*9bb1b549SSpandan Das # only iterating to 1 because parts[0] has to be the lib name 161*9bb1b549SSpandan Das for i in range(len(parts) - 1, 0, -1): 162*9bb1b549SSpandan Das if not parts[i].isdigit(): 163*9bb1b549SSpandan Das if parts[i] == "dylib" or parts[i] == "so": 164*9bb1b549SSpandan Das return ".".join(parts[i:]) 165*9bb1b549SSpandan Das 166*9bb1b549SSpandan Das # something like foo.bar.1.2 or dylib.1.2 167*9bb1b549SSpandan Das return "" 168*9bb1b549SSpandan Das 169*9bb1b549SSpandan Das # something like 1.2.3, or so.1.2, or dylib.1.2, or foo.1.2 170*9bb1b549SSpandan Das return "" 171*9bb1b549SSpandan Das 172*9bb1b549SSpandan DasMINIMUM_BAZEL_VERSION = "5.4.0" 173*9bb1b549SSpandan Das 174*9bb1b549SSpandan Dasdef as_list(v): 175*9bb1b549SSpandan Das """Returns a list, tuple, or depset as a list.""" 176*9bb1b549SSpandan Das if type(v) == "list": 177*9bb1b549SSpandan Das return v 178*9bb1b549SSpandan Das if type(v) == "tuple": 179*9bb1b549SSpandan Das return list(v) 180*9bb1b549SSpandan Das if type(v) == "depset": 181*9bb1b549SSpandan Das return v.to_list() 182*9bb1b549SSpandan Das fail("as_list failed on {}".format(v)) 183*9bb1b549SSpandan Das 184*9bb1b549SSpandan Dasdef as_iterable(v): 185*9bb1b549SSpandan Das """Returns a list, tuple, or depset as something iterable.""" 186*9bb1b549SSpandan Das if type(v) == "list": 187*9bb1b549SSpandan Das return v 188*9bb1b549SSpandan Das if type(v) == "tuple": 189*9bb1b549SSpandan Das return v 190*9bb1b549SSpandan Das if type(v) == "depset": 191*9bb1b549SSpandan Das return v.to_list() 192*9bb1b549SSpandan Das fail("as_iterator failed on {}".format(v)) 193*9bb1b549SSpandan Das 194*9bb1b549SSpandan Dasdef as_tuple(v): 195*9bb1b549SSpandan Das """Returns a list, tuple, or depset as a tuple.""" 196*9bb1b549SSpandan Das if type(v) == "tuple": 197*9bb1b549SSpandan Das return v 198*9bb1b549SSpandan Das if type(v) == "list": 199*9bb1b549SSpandan Das return tuple(v) 200*9bb1b549SSpandan Das if type(v) == "depset": 201*9bb1b549SSpandan Das return tuple(v.to_list()) 202*9bb1b549SSpandan Das fail("as_tuple failed on {}".format(v)) 203*9bb1b549SSpandan Das 204*9bb1b549SSpandan Dasdef as_set(v): 205*9bb1b549SSpandan Das """Returns a list, tuple, or depset as a depset.""" 206*9bb1b549SSpandan Das if type(v) == "depset": 207*9bb1b549SSpandan Das return v 208*9bb1b549SSpandan Das if type(v) == "list": 209*9bb1b549SSpandan Das return depset(v) 210*9bb1b549SSpandan Das if type(v) == "tuple": 211*9bb1b549SSpandan Das return depset(v) 212*9bb1b549SSpandan Das fail("as_tuple failed on {}".format(v)) 213*9bb1b549SSpandan Das 214*9bb1b549SSpandan Das_STRUCT_TYPE = type(struct()) 215*9bb1b549SSpandan Das 216*9bb1b549SSpandan Dasdef is_struct(v): 217*9bb1b549SSpandan Das """Returns true if v is a struct.""" 218*9bb1b549SSpandan Das return type(v) == _STRUCT_TYPE 219*9bb1b549SSpandan Das 220*9bb1b549SSpandan Dasdef count_group_matches(v, prefix, suffix): 221*9bb1b549SSpandan Das """Counts reluctant substring matches between prefix and suffix. 222*9bb1b549SSpandan Das 223*9bb1b549SSpandan Das Equivalent to the number of regular expression matches "prefix.+?suffix" 224*9bb1b549SSpandan Das in the string v. 225*9bb1b549SSpandan Das """ 226*9bb1b549SSpandan Das 227*9bb1b549SSpandan Das count = 0 228*9bb1b549SSpandan Das idx = 0 229*9bb1b549SSpandan Das for i in range(0, len(v)): 230*9bb1b549SSpandan Das if idx > i: 231*9bb1b549SSpandan Das continue 232*9bb1b549SSpandan Das 233*9bb1b549SSpandan Das idx = v.find(prefix, idx) 234*9bb1b549SSpandan Das if idx == -1: 235*9bb1b549SSpandan Das break 236*9bb1b549SSpandan Das 237*9bb1b549SSpandan Das # If there is another prefix before the next suffix, the previous prefix is discarded. 238*9bb1b549SSpandan Das # This is OK; it does not affect our count. 239*9bb1b549SSpandan Das idx = v.find(suffix, idx) 240*9bb1b549SSpandan Das if idx == -1: 241*9bb1b549SSpandan Das break 242*9bb1b549SSpandan Das 243*9bb1b549SSpandan Das count = count + 1 244*9bb1b549SSpandan Das 245*9bb1b549SSpandan Das return count 246*9bb1b549SSpandan Das 247*9bb1b549SSpandan Das# C/C++ compiler and linker options related to coverage instrumentation. 248*9bb1b549SSpandan DasCOVERAGE_OPTIONS_DENYLIST = { 249*9bb1b549SSpandan Das "--coverage": None, 250*9bb1b549SSpandan Das "-ftest-coverage": None, 251*9bb1b549SSpandan Das "-fprofile-arcs": None, 252*9bb1b549SSpandan Das "-fprofile-instr-generate": None, 253*9bb1b549SSpandan Das "-fcoverage-mapping": None, 254*9bb1b549SSpandan Das} 255