blob: 405be8d52252b8bf230e86e6a01ef59328d39983 [file] [log] [blame]
Tim Windelschmidt98000a52025-03-06 14:22:15 +01001load("@rules_foreign_cc//toolchains/native_tools:native_tools_toolchain.bzl", "native_tool_toolchain")
2
Tim Windelschmidt03dadba2025-07-09 06:58:03 +02003SUPPORTED_TARGETS = [
4 struct(
5 tuple = "linux_x86_64",
6 triple = "x86_64-unknown-linux-musl",
7 constrain = ["@platforms//os:linux", "@platforms//cpu:x86_64"],
8 ),
9 struct(
10 tuple = "linux_aarch64",
11 triple = "aarch64-unknown-linux-musl",
12 constrain = ["@platforms//os:linux", "@platforms//cpu:aarch64"],
13 ),
14]
15
Tim Windelschmidt98000a52025-03-06 14:22:15 +010016# Copied from bazel-contrib/rules_foreign_cc licensed under Apache-2.0
17def _current_toolchain_impl(ctx):
18 toolchain = ctx.toolchains[ctx.attr._toolchain]
19
20 if toolchain.data.target:
21 return [
22 toolchain,
23 platform_common.TemplateVariableInfo(toolchain.data.env),
24 DefaultInfo(
25 files = toolchain.data.target.files,
26 runfiles = toolchain.data.target.default_runfiles,
27 ),
28 ]
29 return [
30 toolchain,
31 platform_common.TemplateVariableInfo(toolchain.data.env),
32 DefaultInfo(),
33 ]
34
35def current_toolchain(name):
36 return rule(
37 implementation = _current_toolchain_impl,
38 attrs = {
39 "_toolchain": attr.string(default = "//build/toolchain/toolchain-bundle:%s_toolchain" % name),
40 },
41 toolchains = [
42 "//build/toolchain/toolchain-bundle:%s_toolchain" % name,
43 ],
44 )
45
46def toolchain_for(name, config):
47 native.toolchain_type(
48 name = "%s_toolchain" % name,
49 )
50
51 config.current_toolchain_func(
52 name = name,
53 )
54
Tim Windelschmidt03dadba2025-07-09 06:58:03 +020055 for target in SUPPORTED_TARGETS:
56 native.toolchain(
57 name = "%s_%s_toolchain" % (name, target.tuple),
58 exec_compatible_with = target.constrain,
59 toolchain = ":%s_%s" % (name, target.tuple),
60 toolchain_type = ":%s_toolchain" % name,
61 )
Tim Windelschmidt98000a52025-03-06 14:22:15 +010062
Tim Windelschmidt03dadba2025-07-09 06:58:03 +020063 native_tool_toolchain(
64 name = "%s_%s" % (name, target.tuple),
65 env = {
66 name.upper(): "$(execpath @toolchain-bundle-%s//:%s)" % (target.triple, config.target),
67 },
68 target = "@toolchain-bundle-%s//:%s" % (target.triple, config.target),
69 )
Tim Windelschmidt98000a52025-03-06 14:22:15 +010070
71current_qemu_img_toolchain = current_toolchain("qemu-img")
72current_qemu_kvm_toolchain = current_toolchain("qemu-kvm")
73current_make_toolchain = current_toolchain("make")
74current_strace_toolchain = current_toolchain("strace")
75current_nasm_toolchain = current_toolchain("nasm")
76current_bison_toolchain = current_toolchain("bison")
77current_flex_toolchain = current_toolchain("flex")
78current_m4_toolchain = current_toolchain("m4")
79current_bc_toolchain = current_toolchain("bc")
80current_busybox_toolchain = current_toolchain("busybox")
81current_diff_toolchain = current_toolchain("diff")
82current_perl_toolchain = current_toolchain("perl")
83current_iasl_toolchain = current_toolchain("iasl")
84current_lz4_toolchain = current_toolchain("lz4")
85
86TOOLCHAINS = {
87 "qemu-img": struct(
88 target = "bin/qemu-img",
89 current_toolchain_func = current_qemu_img_toolchain,
90 ),
91 "qemu-kvm": struct(
92 target = "qemu-kvm",
93 current_toolchain_func = current_qemu_kvm_toolchain,
94 ),
95 "make": struct(
96 target = "bin/make",
97 current_toolchain_func = current_make_toolchain,
98 ),
99 "strace": struct(
100 target = "bin/strace",
101 current_toolchain_func = current_strace_toolchain,
102 ),
103 "nasm": struct(
104 target = "bin/nasm",
105 current_toolchain_func = current_nasm_toolchain,
106 ),
107 "bison": struct(
108 target = "bison",
109 current_toolchain_func = current_bison_toolchain,
110 ),
111 "flex": struct(
112 target = "bin/flex",
113 current_toolchain_func = current_flex_toolchain,
114 ),
115 "m4": struct(
116 target = "bin/m4",
117 current_toolchain_func = current_m4_toolchain,
118 ),
119 "bc": struct(
120 target = "bin/bc",
121 current_toolchain_func = current_bc_toolchain,
122 ),
123 "diff": struct(
124 target = "bin/diff",
125 current_toolchain_func = current_diff_toolchain,
126 ),
127 "iasl": struct(
128 target = "bin/iasl",
129 current_toolchain_func = current_iasl_toolchain,
130 ),
131 "busybox": struct(
132 target = "busybox",
133 current_toolchain_func = current_busybox_toolchain,
134 ),
135 "perl": struct(
136 target = "perl",
137 current_toolchain_func = current_perl_toolchain,
138 ),
139 "lz4": struct(
140 target = "bin/lz4",
141 current_toolchain_func = current_lz4_toolchain,
142 ),
143}
144
145def build_toolchain_env(ctx, toolchains):
146 toolchain_info = [ctx.toolchains[t] for t in toolchains]
147 env = dict([(k, v) for t in toolchain_info for k, v in t.data.env.items()])
148 env = env | {"TOOL_PATH": ":".join([t.data.target.files.to_list()[0].path.rsplit("/", 1)[0] for t in toolchain_info])}
149
150 inputs = depset(transitive = [
151 depset(transitive = [t.data.target.files, t.data.target.default_runfiles.files])
152 for t in toolchain_info
153 ])
154
155 return env, inputs
156
157TOOLCHAIN_ENV_SETUP = """
158set -e
159
160# Iterate over all environment variables and expand paths that are
161# either external or bazel-out.
162for name in $(env | cut -d= -f1); do
163 val="${!name}"
164 [[ "$val" != *external/* && "$val" != *bazel-out/* ]] && continue # Quick skip
165
166 sep=' '; [[ $name == "TOOL_PATH" ]] && sep=':' # Set separator: : for PATH, space otherwise
167 IFS=$sep read -r -a items <<< "$val" # Split value into array using correct separator
168
169 for i in "${!items[@]}"; do
170 key="${items[i]%%=*}"; v="${items[i]#*=}" # Handle 'key=val' and standalone paths
171 if [[ ( $v == external/* || $v == bazel-out/* ) && -e "$v" ]]; then
172 [ "$key" = "$v" ] && items[i]=$(realpath -s "$v") || items[i]="$key=$(realpath -s "$v")"
173 fi
174 done
175 export "$name=$(IFS=$sep; echo "${items[*]}")" # Re-export with correct separator
176done
177
178# Add our now expanded TOOL_PATH to PATH
179PATH="$PATH:$TOOL_PATH"
180
181"""