xref: /aosp_15_r20/external/bazel-skylib/rules/run_binary.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1# Copyright 2019 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#    http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""
16run_binary() build rule implementation.
17
18Runs a binary as a build action. This rule does not require Bash (unlike native.genrule()).
19"""
20
21load("//lib:dicts.bzl", "dicts")
22
23def _run_binary_impl(ctx):
24    tool_as_list = [ctx.attr.tool]
25    args = [
26        # Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in args.
27        #
28        # To keep the rule simple, do not expand Make Variables (like *_binary.args usually would).
29        # (We can add this feature later if users ask for it.)
30        #
31        # Also for simple implementation and usage, do not Bash-tokenize the arguments. Without
32        # tokenization the user can write args=["a b"] to pass (a b) as one argument, but with
33        # tokenization they would have to write args=["'a b'"] or args=["a\\ b"]. There's no
34        # documented tokenization function anyway (as of 2019-05-21 ctx.tokenize exists but is
35        # undocumented, see https://github.com/bazelbuild/bazel/issues/8389).
36        ctx.expand_location(a, tool_as_list)
37        for a in ctx.attr.args
38    ]
39    envs = {
40        # Expand $(execpath ...) / $(execpaths ...) / $(location ...) / $(locations ...) in the values.
41        k: ctx.expand_location(v, tool_as_list)
42        for k, v in ctx.attr.env.items()
43    }
44    ctx.actions.run(
45        outputs = ctx.outputs.outs,
46        inputs = ctx.files.srcs,
47        tools = [ctx.executable.tool],
48        executable = ctx.executable.tool,
49        arguments = args,
50        mnemonic = "RunBinary",
51        use_default_shell_env = False,
52        env = dicts.add(ctx.configuration.default_shell_env, envs),
53    )
54    return DefaultInfo(
55        files = depset(ctx.outputs.outs),
56        runfiles = ctx.runfiles(files = ctx.outputs.outs),
57    )
58
59run_binary = rule(
60    implementation = _run_binary_impl,
61    doc = "Runs a binary as a build action.\n\nThis rule does not require Bash (unlike" +
62          " `native.genrule`).",
63    attrs = {
64        "tool": attr.label(
65            doc = "The tool to run in the action.\n\nMust be the label of a *_binary rule," +
66                  " of a rule that generates an executable file, or of a file that can be" +
67                  " executed as a subprocess (e.g. an .exe or .bat file on Windows or a binary" +
68                  " with executable permission on Linux). This label is available for" +
69                  " `$(execpath)` and `$(location)` expansion in `args` and `env`.",
70            executable = True,
71            allow_files = True,
72            mandatory = True,
73            cfg = "exec",
74        ),
75        "env": attr.string_dict(
76            doc = "Environment variables of the action.\n\nSubject to " +
77                  " [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
78                  " expansion.",
79        ),
80        "srcs": attr.label_list(
81            allow_files = True,
82            doc = "Additional inputs of the action.\n\nThese labels are available for" +
83                  " `$(execpath)` and `$(location)` expansion in `args` and `env`.",
84        ),
85        "outs": attr.output_list(
86            mandatory = True,
87            doc = "Output files generated by the action.\n\nThese labels are available for" +
88                  " `$(execpath)` and `$(location)` expansion in `args` and `env`.",
89        ),
90        "args": attr.string_list(
91            doc = "Command line arguments of the binary.\n\nSubject to" +
92                  " [`$(execpath)` and `$(location)`](https://bazel.build/reference/be/make-variables#predefined_label_variables)" +
93                  " expansion.",
94        ),
95    },
96)
97