1*7887bec8SAndroid Build Coastguard Worker"""Rule to support Bazel in copying its output files to the dist dir outside of 2*7887bec8SAndroid Build Coastguard Workerthe standard Bazel output user root. 3*7887bec8SAndroid Build Coastguard Worker""" 4*7887bec8SAndroid Build Coastguard Worker 5*7887bec8SAndroid Build Coastguard Workerload("@bazel_skylib//rules:copy_file.bzl", "copy_file") 6*7887bec8SAndroid Build Coastguard Workerload("//build/bazel_common_rules/exec/impl:embedded_exec.bzl", "embedded_exec") 7*7887bec8SAndroid Build Coastguard Worker 8*7887bec8SAndroid Build Coastguard Workerdef _label_list_to_manifest(lst): 9*7887bec8SAndroid Build Coastguard Worker """Convert the outputs of a label list to manifest content.""" 10*7887bec8SAndroid Build Coastguard Worker all_dist_files = [] 11*7887bec8SAndroid Build Coastguard Worker for f in lst: 12*7887bec8SAndroid Build Coastguard Worker all_dist_files += f[DefaultInfo].files.to_list() 13*7887bec8SAndroid Build Coastguard Worker return all_dist_files, "\n".join([dist_file.short_path for dist_file in all_dist_files]) 14*7887bec8SAndroid Build Coastguard Worker 15*7887bec8SAndroid Build Coastguard Workerdef _generate_dist_manifest_impl(ctx): 16*7887bec8SAndroid Build Coastguard Worker if ctx.attr.archives: 17*7887bec8SAndroid Build Coastguard Worker # buildifier: disable=print 18*7887bec8SAndroid Build Coastguard Worker print("archives is deprecated. Please file a bug if you are using it.") 19*7887bec8SAndroid Build Coastguard Worker 20*7887bec8SAndroid Build Coastguard Worker # Create a manifest of dist files to differentiate them from other runfiles. 21*7887bec8SAndroid Build Coastguard Worker dist_manifest = ctx.actions.declare_file(ctx.attr.name + "_dist_manifest.txt") 22*7887bec8SAndroid Build Coastguard Worker all_dist_files, dist_manifest_content = _label_list_to_manifest(ctx.attr.data) 23*7887bec8SAndroid Build Coastguard Worker ctx.actions.write( 24*7887bec8SAndroid Build Coastguard Worker output = dist_manifest, 25*7887bec8SAndroid Build Coastguard Worker content = dist_manifest_content, 26*7887bec8SAndroid Build Coastguard Worker ) 27*7887bec8SAndroid Build Coastguard Worker 28*7887bec8SAndroid Build Coastguard Worker dist_archives_manifest = ctx.actions.declare_file(ctx.attr.name + "_dist_archives_manifest.txt") 29*7887bec8SAndroid Build Coastguard Worker all_dist_archives, dist_archives_manifest_content = _label_list_to_manifest(ctx.attr.archives) 30*7887bec8SAndroid Build Coastguard Worker ctx.actions.write( 31*7887bec8SAndroid Build Coastguard Worker output = dist_archives_manifest, 32*7887bec8SAndroid Build Coastguard Worker content = dist_archives_manifest_content, 33*7887bec8SAndroid Build Coastguard Worker ) 34*7887bec8SAndroid Build Coastguard Worker 35*7887bec8SAndroid Build Coastguard Worker # Create the runfiles object. 36*7887bec8SAndroid Build Coastguard Worker runfiles = ctx.runfiles(files = all_dist_files + all_dist_archives + [ 37*7887bec8SAndroid Build Coastguard Worker dist_manifest, 38*7887bec8SAndroid Build Coastguard Worker dist_archives_manifest, 39*7887bec8SAndroid Build Coastguard Worker ]) 40*7887bec8SAndroid Build Coastguard Worker 41*7887bec8SAndroid Build Coastguard Worker return [DefaultInfo(runfiles = runfiles)] 42*7887bec8SAndroid Build Coastguard Worker 43*7887bec8SAndroid Build Coastguard Worker_generate_dist_manifest = rule( 44*7887bec8SAndroid Build Coastguard Worker implementation = _generate_dist_manifest_impl, 45*7887bec8SAndroid Build Coastguard Worker doc = """Generate a manifest of files to be dist to a directory.""", 46*7887bec8SAndroid Build Coastguard Worker attrs = { 47*7887bec8SAndroid Build Coastguard Worker "data": attr.label_list( 48*7887bec8SAndroid Build Coastguard Worker allow_files = True, 49*7887bec8SAndroid Build Coastguard Worker doc = """Files or targets to copy to the dist dir. 50*7887bec8SAndroid Build Coastguard Worker 51*7887bec8SAndroid Build Coastguard WorkerIn the case of targets, the rule copies the list of `files` from the target's DefaultInfo provider. 52*7887bec8SAndroid Build Coastguard Worker""", 53*7887bec8SAndroid Build Coastguard Worker ), 54*7887bec8SAndroid Build Coastguard Worker "archives": attr.label_list( 55*7887bec8SAndroid Build Coastguard Worker allow_files = [".tar.gz", ".tar"], 56*7887bec8SAndroid Build Coastguard Worker doc = """Files or targets to be extracted to the dist dir. 57*7887bec8SAndroid Build Coastguard Worker 58*7887bec8SAndroid Build Coastguard WorkerIn the case of targets, the rule copies the list of `files` from the target's DefaultInfo provider. 59*7887bec8SAndroid Build Coastguard Worker""", 60*7887bec8SAndroid Build Coastguard Worker ), 61*7887bec8SAndroid Build Coastguard Worker }, 62*7887bec8SAndroid Build Coastguard Worker) 63*7887bec8SAndroid Build Coastguard Worker 64*7887bec8SAndroid Build Coastguard Workerdef copy_to_dist_dir( 65*7887bec8SAndroid Build Coastguard Worker name, 66*7887bec8SAndroid Build Coastguard Worker data = None, 67*7887bec8SAndroid Build Coastguard Worker archives = None, 68*7887bec8SAndroid Build Coastguard Worker flat = None, 69*7887bec8SAndroid Build Coastguard Worker prefix = None, 70*7887bec8SAndroid Build Coastguard Worker strip_components = 0, 71*7887bec8SAndroid Build Coastguard Worker archive_prefix = None, 72*7887bec8SAndroid Build Coastguard Worker dist_dir = None, 73*7887bec8SAndroid Build Coastguard Worker wipe_dist_dir = None, 74*7887bec8SAndroid Build Coastguard Worker allow_duplicate_filenames = None, 75*7887bec8SAndroid Build Coastguard Worker mode_overrides = None, 76*7887bec8SAndroid Build Coastguard Worker log = None, 77*7887bec8SAndroid Build Coastguard Worker testonly = False, 78*7887bec8SAndroid Build Coastguard Worker **kwargs): 79*7887bec8SAndroid Build Coastguard Worker """A dist rule to copy files out of Bazel's output directory into a custom location. 80*7887bec8SAndroid Build Coastguard Worker 81*7887bec8SAndroid Build Coastguard Worker Example: 82*7887bec8SAndroid Build Coastguard Worker ``` 83*7887bec8SAndroid Build Coastguard Worker bazel run //path/to/my:dist_target -- --dist_dir=/tmp/dist 84*7887bec8SAndroid Build Coastguard Worker ``` 85*7887bec8SAndroid Build Coastguard Worker 86*7887bec8SAndroid Build Coastguard Worker Run `bazel run //path/to/my:dist_target -- --help` for explanations of 87*7887bec8SAndroid Build Coastguard Worker options. 88*7887bec8SAndroid Build Coastguard Worker 89*7887bec8SAndroid Build Coastguard Worker Args: 90*7887bec8SAndroid Build Coastguard Worker name: name of this rule 91*7887bec8SAndroid Build Coastguard Worker data: A list of labels, whose outputs are copied to `--dist_dir`. 92*7887bec8SAndroid Build Coastguard Worker archives: **DEPRECATED**. A list of labels, whose outputs are treated as tarballs and 93*7887bec8SAndroid Build Coastguard Worker extracted to `--dist_dir`. 94*7887bec8SAndroid Build Coastguard Worker 95*7887bec8SAndroid Build Coastguard Worker Deprecated: 96*7887bec8SAndroid Build Coastguard Worker 97*7887bec8SAndroid Build Coastguard Worker This is deprecated due to inactive usage. If you are using it, please file 98*7887bec8SAndroid Build Coastguard Worker a bug. 99*7887bec8SAndroid Build Coastguard Worker flat: If true, `--flat` is provided to the script by default. Flatten the distribution 100*7887bec8SAndroid Build Coastguard Worker directory. 101*7887bec8SAndroid Build Coastguard Worker strip_components: If specified, `--strip_components <prefix>` is provided to the script. Strip 102*7887bec8SAndroid Build Coastguard Worker leading components from the existing copied file paths before applying --prefix 103*7887bec8SAndroid Build Coastguard Worker (if specified). 104*7887bec8SAndroid Build Coastguard Worker prefix: If specified, `--prefix <prefix>` is provided to the script by default. Path prefix 105*7887bec8SAndroid Build Coastguard Worker to apply within dist_dir for copied files. 106*7887bec8SAndroid Build Coastguard Worker archive_prefix: **DEPRECATED**. If specified, `--archive_prefix <prefix>` is provided to the script by 107*7887bec8SAndroid Build Coastguard Worker default. Path prefix to apply within dist_dir for extracted archives. 108*7887bec8SAndroid Build Coastguard Worker 109*7887bec8SAndroid Build Coastguard Worker Deprecated: 110*7887bec8SAndroid Build Coastguard Worker 111*7887bec8SAndroid Build Coastguard Worker This is deprecated due to inactive usage. If you are using it, please file 112*7887bec8SAndroid Build Coastguard Worker a bug. 113*7887bec8SAndroid Build Coastguard Worker dist_dir: If specified, `--dist_dir <dist_dir>` is provided to the script by default. 114*7887bec8SAndroid Build Coastguard Worker 115*7887bec8SAndroid Build Coastguard Worker In particular, if this is a relative path, it is interpreted as a relative path 116*7887bec8SAndroid Build Coastguard Worker under workspace root when the target is executed with `bazel run`. 117*7887bec8SAndroid Build Coastguard Worker 118*7887bec8SAndroid Build Coastguard Worker By default, the script will overwrite any files of the same name in `dist_dir`, but preserve 119*7887bec8SAndroid Build Coastguard Worker any other contents there. This can be overridden with `wipe_dist_dir`. 120*7887bec8SAndroid Build Coastguard Worker 121*7887bec8SAndroid Build Coastguard Worker See details by running the target with `--help`. 122*7887bec8SAndroid Build Coastguard Worker wipe_dist_dir: If true, and `dist_dir` already exists, `dist_dir` will be removed prior to 123*7887bec8SAndroid Build Coastguard Worker copying. 124*7887bec8SAndroid Build Coastguard Worker allow_duplicate_filenames: If true, duplicate filenames from different sources will be allowed to 125*7887bec8SAndroid Build Coastguard Worker be copied to the same `dist_dir` (with subsequent sources overwriting previous sources). 126*7887bec8SAndroid Build Coastguard Worker 127*7887bec8SAndroid Build Coastguard Worker With this option enabled, order matters. The final source of the file listed in `data` will be the 128*7887bec8SAndroid Build Coastguard Worker final version copied. 129*7887bec8SAndroid Build Coastguard Worker 130*7887bec8SAndroid Build Coastguard Worker Use of this option is discouraged. Preferably, the input `data` targets would not include labels 131*7887bec8SAndroid Build Coastguard Worker which produce a duplicate filename. This option is available as a last resort. 132*7887bec8SAndroid Build Coastguard Worker mode_overrides: Map of glob patterns to octal permissions. If the file path being copied matches the 133*7887bec8SAndroid Build Coastguard Worker glob pattern, the corresponding permissions will be set in `dist_dir`. Full file paths are used for 134*7887bec8SAndroid Build Coastguard Worker matching even if `flat = True`. Paths are relative to the workspace root. 135*7887bec8SAndroid Build Coastguard Worker 136*7887bec8SAndroid Build Coastguard Worker Order matters; the overrides will be stepped through in the order given for each file. To prevent 137*7887bec8SAndroid Build Coastguard Worker buildifier from sorting the list, use the `# do not sort` magic line. For example: 138*7887bec8SAndroid Build Coastguard Worker ``` 139*7887bec8SAndroid Build Coastguard Worker mode_overrides = { 140*7887bec8SAndroid Build Coastguard Worker # do not sort 141*7887bec8SAndroid Build Coastguard Worker "**/*.sh": 755, 142*7887bec8SAndroid Build Coastguard Worker "**/hello_world": 755, 143*7887bec8SAndroid Build Coastguard Worker "restricted_dir/**": 600, 144*7887bec8SAndroid Build Coastguard Worker "common/kernel_aarch64/vmlinux": 755, 145*7887bec8SAndroid Build Coastguard Worker "**/*": 644, 146*7887bec8SAndroid Build Coastguard Worker }, 147*7887bec8SAndroid Build Coastguard Worker ``` 148*7887bec8SAndroid Build Coastguard Worker 149*7887bec8SAndroid Build Coastguard Worker If no `mode_overrides` are provided, the default Bazel output permissions are preserved. 150*7887bec8SAndroid Build Coastguard Worker log: If specified, `--log <log>` is provided to the script by default. This sets the 151*7887bec8SAndroid Build Coastguard Worker default log level of the script. 152*7887bec8SAndroid Build Coastguard Worker 153*7887bec8SAndroid Build Coastguard Worker testonly: If enabled, testonly will also be set on the internal targets 154*7887bec8SAndroid Build Coastguard Worker for Bazel analysis to succeed due to the nature of testonly enforcement 155*7887bec8SAndroid Build Coastguard Worker on reverse dependencies. 156*7887bec8SAndroid Build Coastguard Worker 157*7887bec8SAndroid Build Coastguard Worker See `dist.py` for allowed values and the default value. 158*7887bec8SAndroid Build Coastguard Worker **kwargs: Additional attributes to the internal rule, e.g. 159*7887bec8SAndroid Build Coastguard Worker [`visibility`](https://docs.bazel.build/versions/main/visibility.html). 160*7887bec8SAndroid Build Coastguard Worker 161*7887bec8SAndroid Build Coastguard Worker These additional attributes are only passed to the underlying embedded_exec rule. 162*7887bec8SAndroid Build Coastguard Worker """ 163*7887bec8SAndroid Build Coastguard Worker 164*7887bec8SAndroid Build Coastguard Worker unhandled_attrs = [] 165*7887bec8SAndroid Build Coastguard Worker unsupported_attrs = [] 166*7887bec8SAndroid Build Coastguard Worker 167*7887bec8SAndroid Build Coastguard Worker default_args = [] 168*7887bec8SAndroid Build Coastguard Worker if flat: 169*7887bec8SAndroid Build Coastguard Worker default_args.append("--flat") 170*7887bec8SAndroid Build Coastguard Worker if strip_components != None: 171*7887bec8SAndroid Build Coastguard Worker if strip_components < 0: 172*7887bec8SAndroid Build Coastguard Worker fail("strip_components must greater than 0, but is %s" % strip_components) 173*7887bec8SAndroid Build Coastguard Worker default_args += ["--strip_components", str(strip_components)] 174*7887bec8SAndroid Build Coastguard Worker if strip_components: 175*7887bec8SAndroid Build Coastguard Worker unhandled_attrs.append("strip_components") 176*7887bec8SAndroid Build Coastguard Worker if prefix != None: 177*7887bec8SAndroid Build Coastguard Worker default_args += ["--prefix", prefix] 178*7887bec8SAndroid Build Coastguard Worker unhandled_attrs.append("archive_prefix") 179*7887bec8SAndroid Build Coastguard Worker if archive_prefix != None: 180*7887bec8SAndroid Build Coastguard Worker default_args += ["--archive_prefix", archive_prefix] 181*7887bec8SAndroid Build Coastguard Worker unsupported_attrs.append("archive_prefix") 182*7887bec8SAndroid Build Coastguard Worker if dist_dir != None: 183*7887bec8SAndroid Build Coastguard Worker default_args += ["--dist_dir", dist_dir] 184*7887bec8SAndroid Build Coastguard Worker if wipe_dist_dir: 185*7887bec8SAndroid Build Coastguard Worker default_args.append("--wipe_dist_dir") 186*7887bec8SAndroid Build Coastguard Worker unsupported_attrs.append("wipe_dist_dir") 187*7887bec8SAndroid Build Coastguard Worker if allow_duplicate_filenames: 188*7887bec8SAndroid Build Coastguard Worker default_args.append("--allow_duplicate_filenames") 189*7887bec8SAndroid Build Coastguard Worker unsupported_attrs.append("allow_duplicate_filenames") 190*7887bec8SAndroid Build Coastguard Worker if mode_overrides != None: 191*7887bec8SAndroid Build Coastguard Worker for (pattern, mode) in mode_overrides.items(): 192*7887bec8SAndroid Build Coastguard Worker default_args += ["--mode_override", pattern, str(mode)] 193*7887bec8SAndroid Build Coastguard Worker unhandled_attrs.append("mode_overrides") 194*7887bec8SAndroid Build Coastguard Worker if log != None: 195*7887bec8SAndroid Build Coastguard Worker default_args += ["--log", log] 196*7887bec8SAndroid Build Coastguard Worker 197*7887bec8SAndroid Build Coastguard Worker # Separate flags from BUILD with flags from command line 198*7887bec8SAndroid Build Coastguard Worker default_args.append("CMDLINE_FLAGS_SENTINEL") 199*7887bec8SAndroid Build Coastguard Worker 200*7887bec8SAndroid Build Coastguard Worker _generate_dist_manifest( 201*7887bec8SAndroid Build Coastguard Worker name = name + "_dist_manifest", 202*7887bec8SAndroid Build Coastguard Worker data = data, 203*7887bec8SAndroid Build Coastguard Worker archives = archives, 204*7887bec8SAndroid Build Coastguard Worker testonly = testonly, 205*7887bec8SAndroid Build Coastguard Worker ) 206*7887bec8SAndroid Build Coastguard Worker 207*7887bec8SAndroid Build Coastguard Worker copy_file( 208*7887bec8SAndroid Build Coastguard Worker name = name + "_dist_tool", 209*7887bec8SAndroid Build Coastguard Worker src = "//build/bazel_common_rules/dist:dist.py", 210*7887bec8SAndroid Build Coastguard Worker out = name + "_dist.py", 211*7887bec8SAndroid Build Coastguard Worker ) 212*7887bec8SAndroid Build Coastguard Worker 213*7887bec8SAndroid Build Coastguard Worker # The dist py_binary tool must be colocated in the same package as the 214*7887bec8SAndroid Build Coastguard Worker # dist_manifest so that the runfiles directory is the same, and that the 215*7887bec8SAndroid Build Coastguard Worker # dist_manifest is in the data runfiles of the dist tool. 216*7887bec8SAndroid Build Coastguard Worker native.py_binary( 217*7887bec8SAndroid Build Coastguard Worker name = name + "_internal", 218*7887bec8SAndroid Build Coastguard Worker main = name + "_dist.py", 219*7887bec8SAndroid Build Coastguard Worker srcs = [name + "_dist.py"], 220*7887bec8SAndroid Build Coastguard Worker python_version = "PY3", 221*7887bec8SAndroid Build Coastguard Worker visibility = ["//visibility:public"], 222*7887bec8SAndroid Build Coastguard Worker data = [name + "_dist_manifest"], 223*7887bec8SAndroid Build Coastguard Worker testonly = testonly, 224*7887bec8SAndroid Build Coastguard Worker args = default_args, 225*7887bec8SAndroid Build Coastguard Worker ) 226*7887bec8SAndroid Build Coastguard Worker 227*7887bec8SAndroid Build Coastguard Worker kwargs.setdefault("deprecation", """copy_to_dist_dir() is deprecated. Use pkg_install() instead. 228*7887bec8SAndroid Build Coastguard Worker 229*7887bec8SAndroid Build Coastguard WorkerSuggested edit: 230*7887bec8SAndroid Build Coastguard Worker 231*7887bec8SAndroid Build Coastguard Workerload("@rules_pkg//pkg:install.bzl", "pkg_install") 232*7887bec8SAndroid Build Coastguard Workerload("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") 233*7887bec8SAndroid Build Coastguard Workerpkg_files( 234*7887bec8SAndroid Build Coastguard Worker name = {name_files}, 235*7887bec8SAndroid Build Coastguard Worker srcs = {data}, 236*7887bec8SAndroid Build Coastguard Worker strip_prefix = {strip_prefix}, 237*7887bec8SAndroid Build Coastguard Worker visibility = ["//visibility:private"], 238*7887bec8SAndroid Build Coastguard Worker) 239*7887bec8SAndroid Build Coastguard Workerpkg_install( 240*7887bec8SAndroid Build Coastguard Worker name = {name}, 241*7887bec8SAndroid Build Coastguard Worker srcs = [{colon_name_files}], 242*7887bec8SAndroid Build Coastguard Worker destdir = {dist_dir}, 243*7887bec8SAndroid Build Coastguard Worker){unhandled_attrs}{unsupported_attrs}""".format( 244*7887bec8SAndroid Build Coastguard Worker name = repr(name), 245*7887bec8SAndroid Build Coastguard Worker name_files = repr(name + "_files"), 246*7887bec8SAndroid Build Coastguard Worker colon_name_files = repr(":" + name + "_files"), 247*7887bec8SAndroid Build Coastguard Worker dist_dir = repr(dist_dir), 248*7887bec8SAndroid Build Coastguard Worker strip_prefix = "strip_prefix.files_only()" if flat else "None", 249*7887bec8SAndroid Build Coastguard Worker data = repr(data), 250*7887bec8SAndroid Build Coastguard Worker unhandled_attrs = "" if not unhandled_attrs else "\nThe following attributes are not converted; read the API reference of rules_pkg " + 251*7887bec8SAndroid Build Coastguard Worker "for an alternative: {}".format(repr(unhandled_attrs)), 252*7887bec8SAndroid Build Coastguard Worker unsupported_attrs = "" if not unsupported_attrs else "\nThe following attributes may not be supported by rules_pkg: {}".format(repr(unsupported_attrs)), 253*7887bec8SAndroid Build Coastguard Worker )) 254*7887bec8SAndroid Build Coastguard Worker 255*7887bec8SAndroid Build Coastguard Worker embedded_exec( 256*7887bec8SAndroid Build Coastguard Worker name = name, 257*7887bec8SAndroid Build Coastguard Worker actual = name + "_internal", 258*7887bec8SAndroid Build Coastguard Worker testonly = testonly, 259*7887bec8SAndroid Build Coastguard Worker **kwargs 260*7887bec8SAndroid Build Coastguard Worker ) 261