xref: /aosp_15_r20/external/bazel-skylib/rules/native_binary.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifan# Copyright 2019 The Bazel Authors. All rights reserved.
2*bcb5dc79SHONG Yifan#
3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License");
4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License.
5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at
6*bcb5dc79SHONG Yifan#
7*bcb5dc79SHONG Yifan#    http://www.apache.org/licenses/LICENSE-2.0
8*bcb5dc79SHONG Yifan#
9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software
10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS,
11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and
13*bcb5dc79SHONG Yifan# limitations under the License.
14*bcb5dc79SHONG Yifan
15*bcb5dc79SHONG Yifan"""native_binary() and native_test() rule implementations.
16*bcb5dc79SHONG Yifan
17*bcb5dc79SHONG YifanThese rules let you wrap a pre-built binary or script in a conventional binary
18*bcb5dc79SHONG Yifanand test rule respectively. They fulfill the same goal as sh_binary and sh_test
19*bcb5dc79SHONG Yifando, but they run the wrapped binary directly, instead of through Bash, so they
20*bcb5dc79SHONG Yifandon't depend on Bash and work with --shell_executable="".
21*bcb5dc79SHONG Yifan"""
22*bcb5dc79SHONG Yifan
23*bcb5dc79SHONG Yifandef _impl_rule(ctx):
24*bcb5dc79SHONG Yifan    out = ctx.actions.declare_file(ctx.attr.out if (ctx.attr.out != "") else ctx.attr.name + ".exe")
25*bcb5dc79SHONG Yifan    ctx.actions.symlink(
26*bcb5dc79SHONG Yifan        target_file = ctx.executable.src,
27*bcb5dc79SHONG Yifan        output = out,
28*bcb5dc79SHONG Yifan        is_executable = True,
29*bcb5dc79SHONG Yifan    )
30*bcb5dc79SHONG Yifan    runfiles = ctx.runfiles(files = ctx.files.data)
31*bcb5dc79SHONG Yifan
32*bcb5dc79SHONG Yifan    # Bazel 4.x LTS does not support `merge_all`.
33*bcb5dc79SHONG Yifan    # TODO: remove `merge` branch once we drop support for Bazel 4.x.
34*bcb5dc79SHONG Yifan    if hasattr(runfiles, "merge_all"):
35*bcb5dc79SHONG Yifan        runfiles = runfiles.merge_all([
36*bcb5dc79SHONG Yifan            d[DefaultInfo].default_runfiles
37*bcb5dc79SHONG Yifan            for d in ctx.attr.data + [ctx.attr.src]
38*bcb5dc79SHONG Yifan        ])
39*bcb5dc79SHONG Yifan    else:
40*bcb5dc79SHONG Yifan        for d in ctx.attr.data:
41*bcb5dc79SHONG Yifan            runfiles = runfiles.merge(d[DefaultInfo].default_runfiles)
42*bcb5dc79SHONG Yifan        runfiles = runfiles.merge(ctx.attr.src[DefaultInfo].default_runfiles)
43*bcb5dc79SHONG Yifan
44*bcb5dc79SHONG Yifan    return DefaultInfo(
45*bcb5dc79SHONG Yifan        executable = out,
46*bcb5dc79SHONG Yifan        files = depset([out]),
47*bcb5dc79SHONG Yifan        runfiles = runfiles,
48*bcb5dc79SHONG Yifan    )
49*bcb5dc79SHONG Yifan
50*bcb5dc79SHONG Yifan_ATTRS = {
51*bcb5dc79SHONG Yifan    "src": attr.label(
52*bcb5dc79SHONG Yifan        executable = True,
53*bcb5dc79SHONG Yifan        # This must be used instead of `allow_single_file` because otherwise a
54*bcb5dc79SHONG Yifan        # target with multiple default outputs (e.g. py_binary) would not be
55*bcb5dc79SHONG Yifan        # allowed.
56*bcb5dc79SHONG Yifan        allow_files = True,
57*bcb5dc79SHONG Yifan        mandatory = True,
58*bcb5dc79SHONG Yifan        cfg = "target",
59*bcb5dc79SHONG Yifan        doc = "path of the pre-built executable",
60*bcb5dc79SHONG Yifan    ),
61*bcb5dc79SHONG Yifan    "data": attr.label_list(
62*bcb5dc79SHONG Yifan        allow_files = True,
63*bcb5dc79SHONG Yifan        doc = "data dependencies. See" +
64*bcb5dc79SHONG Yifan              " https://bazel.build/reference/be/common-definitions#typical.data",
65*bcb5dc79SHONG Yifan    ),
66*bcb5dc79SHONG Yifan    # "out" is attr.string instead of attr.output, so that it is select()'able.
67*bcb5dc79SHONG Yifan    "out": attr.string(
68*bcb5dc79SHONG Yifan        default = "",
69*bcb5dc79SHONG Yifan        doc = "An output name for the copy of the binary. Defaults to " +
70*bcb5dc79SHONG Yifan              "name.exe. (We add .exe to the name by default because it's " +
71*bcb5dc79SHONG Yifan              "required on Windows and tolerated on other platforms.)",
72*bcb5dc79SHONG Yifan    ),
73*bcb5dc79SHONG Yifan}
74*bcb5dc79SHONG Yifan
75*bcb5dc79SHONG Yifannative_binary = rule(
76*bcb5dc79SHONG Yifan    implementation = _impl_rule,
77*bcb5dc79SHONG Yifan    attrs = _ATTRS,
78*bcb5dc79SHONG Yifan    executable = True,
79*bcb5dc79SHONG Yifan    doc = """
80*bcb5dc79SHONG YifanWraps a pre-built binary or script with a binary rule.
81*bcb5dc79SHONG Yifan
82*bcb5dc79SHONG YifanYou can "bazel run" this rule like any other binary rule, and use it as a tool
83*bcb5dc79SHONG Yifanin genrule.tools for example. You can also augment the binary with runfiles.
84*bcb5dc79SHONG Yifan""",
85*bcb5dc79SHONG Yifan)
86*bcb5dc79SHONG Yifan
87*bcb5dc79SHONG Yifannative_test = rule(
88*bcb5dc79SHONG Yifan    implementation = _impl_rule,
89*bcb5dc79SHONG Yifan    attrs = _ATTRS,
90*bcb5dc79SHONG Yifan    test = True,
91*bcb5dc79SHONG Yifan    doc = """
92*bcb5dc79SHONG YifanWraps a pre-built binary or script with a test rule.
93*bcb5dc79SHONG Yifan
94*bcb5dc79SHONG YifanYou can "bazel test" this rule like any other test rule. You can also augment
95*bcb5dc79SHONG Yifanthe binary with runfiles.
96*bcb5dc79SHONG Yifan""",
97*bcb5dc79SHONG Yifan)
98