-
Notifications
You must be signed in to change notification settings - Fork 248
/
native_tools_toolchain.bzl
93 lines (84 loc) · 3.86 KB
/
native_tools_toolchain.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
"""Rules for building native build tools such as ninja, make or cmake"""
# buildifier: disable=module-docstring
ToolInfo = provider(
doc = "Information about the native tool",
fields = {
"env": "Environment variables to set when using this tool e.g. M4",
"path": (
"Absolute path to the tool in case the tool is preinstalled on the machine. " +
"Relative path to the tool in case the tool is built as part of a build; the path should be relative " +
"to the bazel-genfiles, i.e. it should start with the name of the top directory of the built tree " +
"artifact. (Please see the example `//examples:built_cmake_toolchain`)"
),
"target": (
"If the tool is preinstalled, must be None. " +
"If the tool is built as part of the build, the corresponding build target, which should produce " +
"the tree artifact with the binary to call."
),
},
)
def _resolve_tool_path(ctx, path, target):
"""
Resolve the path to a tool.
Note that ctx.resolve_command is used instead of ctx.expand_location as the
latter cannot be used with py_binary and sh_binary targets as they both produce multiple files in some contexts, meaning
that the plural make variables must be used, e.g. $(execpaths) must be used. See https://github.com/bazelbuild/bazel/issues/11820.
The usage of ctx.resolve_command facilitates the usage of the singular make variables, e.g $(execpath), with py_binary and sh_binary targets
"""
_, resolved_bash_command, _ = ctx.resolve_command(
command = path,
expand_locations = True,
tools = [target],
)
return resolved_bash_command[-1]
def _native_tool_toolchain_impl(ctx):
if not ctx.attr.path and not ctx.attr.target:
fail("Either path or target (and path) should be defined for the tool.")
path = None
env = {}
if ctx.attr.target:
path = _resolve_tool_path(ctx, ctx.attr.path, ctx.attr.target)
for k, v in ctx.attr.env.items():
env[k] = _resolve_tool_path(ctx, v, ctx.attr.target)
else:
path = ctx.expand_location(ctx.attr.path)
env = {k: ctx.expand_location(v) for (k, v) in ctx.attr.env.items()}
return platform_common.ToolchainInfo(data = ToolInfo(
env = env,
path = path,
target = ctx.attr.target,
))
native_tool_toolchain = rule(
doc = (
"Rule for defining the toolchain data of the native tools (cmake, ninja), " +
"to be used by rules_foreign_cc with toolchain types " +
"`@rules_foreign_cc//toolchains:cmake_toolchain` and " +
"`@rules_foreign_cc//toolchains:ninja_toolchain`."
),
implementation = _native_tool_toolchain_impl,
attrs = {
"env": attr.string_dict(
doc = "Environment variables to be set when using this tool e.g. M4",
),
"path": attr.string(
mandatory = False,
doc = (
"Absolute path to the tool in case the tool is preinstalled on the machine. " +
"Relative path to the tool in case the tool is built as part of a build; the path should be " +
"relative to the bazel-genfiles, i.e. it should start with the name of the top directory " +
"of the built tree artifact. (Please see the example `//examples:built_cmake_toolchain`)"
),
),
"target": attr.label(
mandatory = False,
cfg = "exec",
doc = (
"If the tool is preinstalled, must be None. " +
"If the tool is built as part of the build, the corresponding build target, " +
"which should produce the tree artifact with the binary to call."
),
allow_files = True,
),
},
incompatible_use_toolchain_transition = True,
)