-
Notifications
You must be signed in to change notification settings - Fork 36
/
export_exe.bzl
106 lines (89 loc) · 2.81 KB
/
export_exe.bzl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under both the MIT license found in the
# LICENSE-MIT file in the root directory of this source tree and the Apache
# License, Version 2.0 found in the LICENSE-APACHE file in the root directory
# of this source tree.
def _export_exe_impl(ctx: AnalysisContext) -> list[Provider]:
if ctx.attrs.src and ctx.attrs.exe:
fail("Must supply one of src or exe to export_exe")
src = ctx.attrs.src if ctx.attrs.src else ctx.attrs.exe
return [
DefaultInfo(),
RunInfo(
args = cmd_args(src),
),
]
_export_exe = rule(
doc = """Exports a file as an executable, for use in $(exe) macros or as a valid target for an exec_dep().
Accepts either a string `src`, which is a relative path to a file that will be directly referenced,
or an arg `exe` which should be a path to an executable relative to a $(location) macro.
The first form is a more ergonomic replacement for export_file + command_alias. Eg. Instead of
export_file(
name = "script_sh",
src = "bin/script.sh",
)
command_alias(
name = "script.sh"
exe = ":script_sh",
)
You can write
export_exe(
name = "script.sh",
src = "bin/script.sh",
)
The latter form allows executing checked in binaries with required resources (eg. runtime shared libraries)
without unnecessary indirection via another rule which allows args, like command_alias. Eg. instead of
export_file(
name = "bin"
src = "bin",
mode = "reference",
)
export_file(
name = "exec.sh",
src = "exec.sh",
)
command_alias(
name = "compiler",
exe = ":exec.sh", # Just calls exec $@
args = [
"$(location :bin)/compiler",
],
)
You can write
export_file(
name = "bin",
src = "bin",
mode = "reference",
)
export_exe(
name = "compiler",
exe = "$(location :bin)/compiler",
)
""",
impl = _export_exe_impl,
attrs = {
"exe": attrs.option(attrs.arg(), default = None, doc = "arg which should evaluate to a path to an executable binary"),
"src": attrs.option(attrs.source(), default = None, doc = "path to an executable binary relative to this package"),
},
)
def export_exe(name, exe = None, src = None, **kwargs):
# If neither `exe` nor `src` is passed, treat the target's name as the src.
#
# export_exe(
# name = "script.sh",
# )
#
# is equivalent to:
#
# export_exe(
# name = "script.sh",
# src = "script.sh",
# )
#
_export_exe(
name = name,
exe = exe,
src = src if (exe or src) else name,
**kwargs
)