1""" 2THIS IS THE EXTERNAL-ONLY VERSION OF THIS FILE. G3 HAS ITS OWN. 3 4This file contains macros which require no third-party dependencies. 5Using these where possible makes it easier for clients to use Skia 6without needing to download a bunch of unnecessary dependencies 7in their WORKSPACE.bazel file. 8""" 9 10load("@skia_user_config//:copts.bzl", "DEFAULT_COPTS", "DEFAULT_OBJC_COPTS") 11load("@skia_user_config//:linkopts.bzl", "DEFAULT_LINKOPTS") 12load("//bazel:cc_binary_with_flags.bzl", "cc_binary_with_flags") 13load( 14 "//bazel:generate_cpp_files_for_headers.bzl", 15 _generate_cpp_files_for_header_list = "generate_cpp_files_for_header_list", 16 _generate_cpp_files_for_headers = "generate_cpp_files_for_headers", 17) 18 19generate_cpp_files_for_headers = _generate_cpp_files_for_headers 20generate_cpp_files_for_header_list = _generate_cpp_files_for_header_list 21 22def select_multi(values_map): 23 """select() but allowing multiple matches of the keys. 24 25 select_multi works around a restriction in native select() that prevents multiple 26 keys from being matched unless one is a strict subset of another. For some features, 27 we allow multiple of that component to be active. For example, with codecs, we let 28 the clients mix and match anywhere from 0 built in codecs to all of them. 29 30 select_multi takes a given map and turns it into several distinct select statements 31 that have the effect of using any values associated with any active keys. 32 For example, if the following parameter is passed in: 33 values_map = { 34 ":alpha": ["apple", "apricot"], 35 ":beta": ["banana"], 36 ":gamma": ["grapefruit"], 37 } 38 it will be unrolled into the following select statements 39 [] + select({ 40 ":apple": ["apple", "apricot"], 41 "//conditions:default": [], 42 }) + select({ 43 ":beta": ["banana"], 44 "//conditions:default": [], 45 }) + select({ 46 ":gamma": ["grapefruit"], 47 "//conditions:default": [], 48 }) 49 50 Args: 51 values_map: dictionary of labels to a list of labels, just like select() 52 53 Returns: 54 A list of values that is filled in by the generated select statements. 55 """ 56 if len(values_map) == 0: 57 return [] 58 rv = [] 59 for key, value in values_map.items(): 60 rv += select({ 61 key: value, 62 "//conditions:default": [], 63 }) 64 return rv 65 66def skia_cc_binary(name, copts = DEFAULT_COPTS, linkopts = DEFAULT_LINKOPTS, **kwargs): 67 """A wrapper around cc_library for Skia C++ executables (e.g. tests). 68 69 This lets us provide compiler flags (copts) and global linker flags (linkopts) consistently 70 to Skia built executables. These executables are almost always things like unit tests and 71 dev tools. 72 73 Args: 74 name: the name of the underlying executable. 75 copts: Flags which should be passed to the C++ compiler. By default, we use DEFAULT_COPTS 76 from @skia_user_config//:copts.bzl. 77 linkopts: Global flags which should be passed to the C++ linker. By default, we use 78 DEFAULT_LINKOPTS from @skia_user_config//:linkopts.bzl. Other linker flags will be 79 passed in via deps (see deps_and_linkopts below). 80 **kwargs: All the normal arguments that cc_binary takes. 81 """ 82 native.cc_binary(name = name, copts = copts, linkopts = linkopts, **kwargs) 83 84def skia_cc_binary_with_flags( 85 name, 86 copts = DEFAULT_COPTS, 87 linkopts = DEFAULT_LINKOPTS, 88 set_flags = None, 89 **kwargs): 90 cc_binary_with_flags( 91 name = name, 92 copts = copts, 93 linkopts = linkopts, 94 set_flags = set_flags, 95 **kwargs 96 ) 97 98def skia_cc_library(name, copts = DEFAULT_COPTS, **kwargs): 99 """A wrapper around cc_library for Skia C++ libraries. 100 101 This lets us provide compiler flags (copts) consistently to the Skia build (e.g. //:skia_public) 102 and builds which depend on those targets (e.g. things in //tools or //modules). 103 104 It also lets us easily tweak these settings when being built in G3. 105 106 Third party libraries should *not* use this directly, as there are likely some flags used 107 by Skia (e.g. warnings) that we do not want to have to fix for third party code. 108 109 Args: 110 name: the name of the underlying library. 111 copts: Flags which should be passed to the C++ compiler. By default, we use DEFAULT_COPTS 112 from @skia_user_config//:copts.bzl. 113 **kwargs: All the normal arguments that cc_library takes. 114 """ 115 native.cc_library(name = name, copts = copts, **kwargs) 116 117def skia_cc_deps(name, visibility, deps = [], linkopts = [], textual_hdrs = [], testonly = False): 118 """A self-documenting wrapper around cc_library for things to pass to the top skia_cc_library. 119 120 It lets us have third_party deps, linkopts, etc be set close to where they impact, 121 and trickle up the file hierarchy to //:skia_public and //:skia_internal 122 123 Args: 124 name: the name of the underlying target. By convention, this is usually called "deps". 125 visibility: To prevent this rule from being used where it should not, we have the 126 convention of setting the visibility to just the parent package. 127 deps: A list of labels or select statements to collect third_party dependencies. 128 linkopts: A list of strings or select statements to collect linker flags. 129 textual_hdrs: A list of labels or select statements to collect files which are included, but 130 do not have a suffix of .h, like a typical C++ header does. 131 testonly: A boolean that, if true, will enforce all targets who depend on this are also 132 marked as testonly. 133 """ 134 native.cc_library( 135 name = name, 136 visibility = visibility, 137 deps = deps, 138 linkopts = linkopts, 139 textual_hdrs = textual_hdrs, 140 testonly = testonly, 141 ) 142 143def skia_defines(name, visibility, defines): 144 """A self-documenting wrapper around cc_library for defines""" 145 native.cc_library(name = name, visibility = visibility, defines = defines) 146 147def skia_filegroup(**kwargs): 148 """A wrapper around filegroup allowing us to customize visibility in G3.""" 149 native.filegroup(**kwargs) 150 151def skia_objc_library(name, copts = DEFAULT_OBJC_COPTS, **kwargs): 152 """A wrapper around cc_library for Skia Objective C libraries. 153 154 This lets us provide compiler flags (copts) consistently to the Skia build (e.g. //:skia_public) 155 and builds which depend on those targets (e.g. things in //tools or //modules). 156 157 It also lets us easily tweak these settings when being built in G3. 158 Args: 159 name: the name of the underlying target. 160 copts: Flags which should be passed to the C++ compiler. By default, we use 161 DEFAULT_OBJC_COPTS from @skia_user_config//:copts.bzl. 162 **kwargs: Normal arguments to objc_library 163 """ 164 165 # Internally, we need to combine sdk_frameworks and deps, but we can only 166 # do that if both are lists 167 # https://github.com/bazelbuild/bazel/issues/14157 168 sdks = kwargs.get("sdk_frameworks", None) 169 deps = kwargs.get("deps", []) 170 if type(sdks) != "NoneType": 171 if type(sdks) != "list" or type(deps) != "list": 172 fail("skd_frameworks and deps must both be normal lists, not selects") 173 native.objc_library(name = name, copts = copts, **kwargs) 174 175# buildifier: disable=unnamed-macro 176def exports_files_legacy(label_list = None, visibility = None): 177 """A self-annotating macro to export all files in this package for legacy G3 rules. 178 179 Args: 180 label_list: If provided, this will act like a normal exports_files rule. If not 181 provided, nothing happens. 182 visibility: Should be provided if label_list is set 183 """ 184 if label_list: 185 native.exports_files(label_list, visibility = visibility) 186 187def split_srcs_and_hdrs(name, files): 188 """Take a list of files and creates filegroups for C++ sources and headers. 189 190 The reason we make filegroups is that they are more friendly towards a file being 191 listed twice than just returning a sorted list of files. 192 193 For example, in //src/codecs, "SkEncodedInfo.cpp" is needed for some, but not all 194 the codecs. It is easier for devs to list the file for the codecs that need it 195 rather than making a complicated select statement to make sure it is only in the 196 list of files once. 197 198 Bazel is smart enough to not compile the same file twice, even if it shows up in 199 multiple filegroups. 200 201 The "_srcs" and "_hdrs" filegroups will only be created if there are a non-zero amount 202 of files of both types. Otherwise, it will fail because we do not need the macro. 203 204 Args: 205 name: The prefix of the generated filegroups. One will have the suffix "_srcs" and 206 the other "_hdrs". 207 files: List of file names, e.g. ["SkAAClip.cpp", "SkAAClip.h"] 208 """ 209 srcs = [] 210 hdrs = [] 211 for f in files: 212 if f.endswith(".cpp"): 213 srcs.append(f) 214 elif f.endswith(".mm"): 215 srcs.append(f) 216 elif f.endswith(".h"): 217 hdrs.append(f) 218 else: 219 fail("Neither .cpp, .mm, nor .h file " + f) 220 221 if len(srcs) == 0 or len(hdrs) == 0: 222 fail("The list consist of either only source or header files. No need to use this macro.") 223 224 skia_filegroup( 225 name = name + "_srcs", 226 srcs = srcs, 227 ) 228 skia_filegroup( 229 name = name + "_hdrs", 230 srcs = hdrs, 231 ) 232