• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2023 The Android Open Source Project
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
15load("@bazel_skylib//rules:common_settings.bzl", "bool_setting")
16load(
17    "@gbl_llvm_prebuilts//:info.bzl",
18    "LINUX_SYSROOT_INCLUDES",
19    "LLVM_PREBUILTS_CPP_INCLUDE",
20    "LLVM_PREBUILTS_C_INCLUDE",
21    "gbl_llvm_tool_path",
22)
23load("@rules_rust//bindgen:defs.bzl", "rust_bindgen_toolchain")
24load(
25    "@rules_rust//rust:toolchain.bzl",
26    "rust_stdlib_filegroup",
27    "rust_toolchain",
28    "rustfmt_toolchain",
29)
30load(
31    ":gbl_toolchain.bzl",
32    "build_with_no_rust_sysroot",
33    "gbl_clang_cc_toolchain",
34    "prebuilt_binary",
35)
36
37package(
38    default_visibility = ["//visibility:public"],
39)
40
41# The following constraint/settings will be used in our newly defined
42# toolchains, so that they only get selected by bazel when we configure
43# to build GBL.
44constraint_setting(name = "firmware_image_type")
45
46constraint_value(
47    name = "uefi",
48    constraint_setting = ":firmware_image_type",
49)
50
51constraint_value(
52    name = "elf",
53    constraint_setting = ":firmware_image_type",
54)
55
56host_x86_64_constraint_values = [
57    "@platforms//os:linux",
58    "@platforms//cpu:x86_64",
59]
60
61uefi_x86_64_constraint_values = [
62    ":uefi",
63    "@platforms//os:none",
64    "@platforms//cpu:x86_64",
65]
66
67uefi_x86_32_constraint_values = [
68    ":uefi",
69    "@platforms//os:none",
70    "@platforms//cpu:x86_32",
71]
72
73uefi_aarch64_constraint_values = [
74    ":uefi",
75    "@platforms//os:none",
76    "@platforms//cpu:aarch64",
77]
78
79elf_riscv64_constraint_values = [
80    ":elf",
81    "@platforms//os:none",
82    "@platforms//cpu:riscv64",
83]
84
85config_setting(
86    name = "gbl_rust_host_x86_64",
87    constraint_values = host_x86_64_constraint_values,
88)
89
90config_setting(
91    name = "gbl_rust_uefi_x86_64",
92    constraint_values = uefi_x86_64_constraint_values,
93)
94
95config_setting(
96    name = "gbl_rust_uefi_x86_32",
97    constraint_values = uefi_x86_32_constraint_values,
98)
99
100config_setting(
101    name = "gbl_rust_uefi_aarch64",
102    constraint_values = uefi_aarch64_constraint_values,
103)
104
105config_setting(
106    name = "gbl_rust_elf_riscv64",
107    constraint_values = elf_riscv64_constraint_values,
108)
109
110# The following will be passed to "bazel build --platform=<>" argument to
111# configure building for specific architecture and image type.
112platform(
113    name = "gbl_uefi_x86_64",
114    constraint_values = uefi_x86_64_constraint_values,
115)
116
117platform(
118    name = "gbl_uefi_x86_32",
119    constraint_values = uefi_x86_32_constraint_values,
120)
121
122platform(
123    name = "gbl_uefi_aarch64",
124    constraint_values = uefi_aarch64_constraint_values,
125)
126
127platform(
128    name = "gbl_elf_riscv64",
129    constraint_values = elf_riscv64_constraint_values,
130)
131
132bool_setting(
133    name = "rust_no_sysroot",
134    build_setting_default = False,
135    visibility = ["//visibility:public"],
136)
137
138config_setting(
139    name = "rust_no_sysroot_true",
140    flag_values = {":rust_no_sysroot": "True"},
141)
142
143# Linux host LLVM toolchain.
144# The toolchain is mainly used for building/linking host tools, i.e. bindgen pre-processing
145gbl_clang_cc_toolchain(
146    name = "x86_64-unknown-linux-gnu",
147    # Host LLVM toolchain has additional C++ stdlib.
148    builtin_includes = [
149        LLVM_PREBUILTS_CPP_INCLUDE,  # C++ headers must come first.
150        LLVM_PREBUILTS_C_INCLUDE,
151    ] + LINUX_SYSROOT_INCLUDES,
152    ld_flags = [
153        "-stdlib=libc++",
154        "-static-libstdc++",
155    ],
156    target_cpu = "x86_64",
157    target_system_triple = "x86_64-unknown-linux-gnu",
158)
159
160toolchain(
161    name = "x86_64-unknown-linux-gnu_toolchain",
162    exec_compatible_with = ["@platforms//os:linux"],
163    target_compatible_with = [
164        "@platforms//os:linux",
165        "@platforms//cpu:x86_64",
166    ],
167    toolchain = ":x86_64-unknown-linux-gnu",
168    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
169)
170
171# The following defines LLVM C++ toolchains for UEFI/ELF targets. They are mostly used for the
172# final step of linking Rust executables, but may also be used for compiling mixed C/C++ code.
173
174cc_flags_common = [
175    "-ffreestanding",
176    "-fno-common",
177    "-fno-exceptions",
178    "-fno-rtti",
179    # Enable optimization otherwise software AVB hash will be too slow.
180    "-O3",
181]
182
183# x86_64 UEFI targets
184gbl_clang_cc_toolchain(
185    name = "x86_64_uefi_clang_cc_toolchain",
186    cc_flags = cc_flags_common + [
187        # Adding this prevents the compiler from generating mmx, sse instructions such as
188        # "movsd (%esp),%xmm0" which likely isn't enabled during the bootloader stage and causes
189        # crash as a result.
190        "-mgeneral-regs-only",
191    ],
192    target_cpu = "x86_64",
193    target_system_triple = "x86_64-unknown-windows-msvc",
194)
195
196toolchain(
197    name = "x86_64_uefi_clang",
198    exec_compatible_with = ["@platforms//os:linux"],
199    target_compatible_with = uefi_x86_64_constraint_values,
200    toolchain = ":x86_64_uefi_clang_cc_toolchain",
201    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
202)
203
204# x86_32 UEFI targets
205gbl_clang_cc_toolchain(
206    name = "x86_32_uefi_clang_cc_toolchain",
207    cc_flags = cc_flags_common + [
208        "-m32",
209        # Adding this prevents the compiler from generating mmx, sse instructions such as
210        # "movsd (%esp),%xmm0" which likely isn't enabled during the bootloader stage and causes
211        # crash as a result.
212        "-march=i686",
213    ],
214    # Safe Exception Handlers is not applicable to EFI systems.
215    ld_flags = ["/SAFESEH:no"],
216    target_cpu = "x86_32",
217    target_system_triple = "i686-unknown-windows-gnu",
218)
219
220toolchain(
221    name = "x86_32_uefi_clang",
222    exec_compatible_with = ["@platforms//os:linux"],
223    target_compatible_with = uefi_x86_32_constraint_values,
224    toolchain = ":x86_32_uefi_clang_cc_toolchain",
225    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
226)
227
228# aarch64 UEFI targets
229gbl_clang_cc_toolchain(
230    name = "aarch64_uefi_clang_cc_toolchain",
231    cc_flags = cc_flags_common,
232    target_cpu = "aarch64",
233    target_system_triple = "aarch64-windows-msvc",
234)
235
236toolchain(
237    name = "aarch64_uefi_clang",
238    exec_compatible_with = ["@platforms//os:linux"],
239    target_compatible_with = uefi_aarch64_constraint_values,
240    toolchain = ":aarch64_uefi_clang_cc_toolchain",
241    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
242)
243
244# riscv64 ELF targets
245gbl_clang_cc_toolchain(
246    name = "riscv64_elf_clang_cc_toolchain",
247    cc_flags = cc_flags_common + ["-fpie"],
248    target_cpu = "riscv64",
249    target_system_triple = "riscv64-unknown-linux",
250)
251
252toolchain(
253    name = "riscv64_elf_clang",
254    exec_compatible_with = ["@platforms//os:linux"],
255    target_compatible_with = elf_riscv64_constraint_values,
256    toolchain = ":riscv64_elf_clang_cc_toolchain",
257    toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
258)
259
260# Rust toolchains
261
262# An empty rust std file group used as placeholder when building rust sysroot.
263rust_stdlib_filegroup(
264    name = "rust_stdlib_empty",
265    srcs = [],
266)
267
268# A rule for building sysroot from source.
269build_with_no_rust_sysroot(
270    name = "rust_sysroot_source_build",
271    deps = [
272        "@rust_prebuilts//:liballoc",
273        "@rust_prebuilts//:libcompiler_builtins",
274        "@rust_prebuilts//:libcore",
275    ],
276)
277
278rust_stdlib_filegroup(
279    name = "rust_std_source_build",
280    srcs = [":rust_sysroot_source_build"],
281)
282
283common_lint_opts = [
284    "-A",
285    "deprecated",
286    # external/rust/crates/spin doesn't pass this lint check and there is not a way to make an
287    # exemption. Disable it until upstream is fixed or we figure out a workaround.
288    #"-D",
289    #"unsafe_op_in_unsafe_fn",
290    "-D",
291    "warnings",
292    "-D",
293    "clippy::undocumented_unsafe_blocks",
294    "-D",
295    "clippy::too-many-arguments",
296]
297
298# Linux x86_64 Host toolchain
299rust_toolchain(
300    name = "x86_64_unknown_linux_gnu",
301    allocator_library = None,
302    binary_ext = "",
303    default_edition = "2021",
304    dylib_ext = ".so",
305    exec_triple = "x86_64-unknown-linux-gnu",
306    global_allocator_library = None,
307    rust_doc = "@rust_prebuilts//:bin/rustdoc",
308    rust_std = "@rust_prebuilts//:prebuilt_stdlibs",
309    rustc = "@rust_prebuilts//:bin/rustc",
310    staticlib_ext = ".a",
311    stdlib_linkflags = [],
312    target_triple = "x86_64-unknown-linux-gnu",
313)
314
315toolchain(
316    name = "x86_64_unknown_linux_gnu_toolchain",
317    exec_compatible_with = ["@platforms//os:linux"],
318    target_settings = [":gbl_rust_host_x86_64"],
319    toolchain = ":x86_64_unknown_linux_gnu",
320    toolchain_type = "@rules_rust//rust:toolchain",
321)
322
323# x86_64 UEFI toolchain
324rust_toolchain(
325    name = "x86_64-unknown-uefi",
326    allocator_library = None,
327    binary_ext = ".efi",
328    default_edition = "2021",
329    dylib_ext = ".so",
330    exec_triple = "x86_64-unknown-linux-gnu",
331    extra_rustc_flags = common_lint_opts + [
332        # The linker options generated by rustc assumes `lld` as the linker. For windows platforms,
333        # the lld args style is different than that of clang++, i.e. for library search path, lld
334        # uses "/L<path>" while clang++ uses "-L<path>". Thus we need to use lld directly instead
335        # of `clang++`.
336        "--codegen=linker={}".format(gbl_llvm_tool_path("lld")),
337        # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below.
338        "--sysroot",
339        "/dev/null",
340    ],
341    global_allocator_library = None,
342    rust_doc = "@rust_prebuilts//:bin/rustdoc",
343    rust_std = "@rust_prebuilts//:x86_64-unknown-uefi_prebuilt_stdlibs",
344    rustc = "@rust_prebuilts//:bin/rustc",
345    staticlib_ext = ".a",
346    stdlib_linkflags = [],
347    target_triple = "x86_64-unknown-uefi",
348)
349
350toolchain(
351    name = "x86_64-unknown-uefi_toolchain",
352    exec_compatible_with = ["@platforms//os:linux"],
353    target_settings = [":gbl_rust_uefi_x86_64"],
354    toolchain = ":x86_64-unknown-uefi",
355    toolchain_type = "@rules_rust//rust:toolchain",
356)
357
358# i686 UEFI toolchain
359rust_toolchain(
360    name = "i686-unknown-uefi",
361    allocator_library = None,
362    binary_ext = ".efi",
363    default_edition = "2021",
364    dylib_ext = ".so",
365    exec_triple = "x86_64-unknown-linux-gnu",
366    extra_rustc_flags = common_lint_opts + [
367        "--codegen=linker={}".format(gbl_llvm_tool_path("lld")),
368        # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below.
369        "--sysroot",
370        "/dev/null",
371    ],
372    global_allocator_library = None,
373    rust_doc = "@rust_prebuilts//:bin/rustdoc",
374    # Need to use our own sysroot because we have a custom patch that needs to be applied for std
375    # in order to enable compiler builtin for chkstk(), alloca(). Once the fix is upstreamed, we
376    # can use the prebuilt.
377    rust_std = select({
378        ":rust_no_sysroot_true": ":rust_stdlib_empty",
379        "//conditions:default": ":rust_std_source_build",
380    }),
381    #rust_std = "@rust_prebuilts//:i686-unknown-uefi_prebuilt_stdlibs",
382    rustc = "@rust_prebuilts//:bin/rustc",
383    staticlib_ext = ".a",
384    stdlib_linkflags = [],
385    target_triple = "i686-unknown-uefi",
386)
387
388toolchain(
389    name = "i686-unknown-uefi_toolchain",
390    exec_compatible_with = ["@platforms//os:linux"],
391    target_settings = [":gbl_rust_uefi_x86_32"],
392    toolchain = ":i686-unknown-uefi",
393    toolchain_type = "@rules_rust//rust:toolchain",
394)
395
396# aarch64 UEFI toolchain
397rust_toolchain(
398    name = "aarch64-unknown-uefi",
399    allocator_library = None,
400    binary_ext = ".efi",
401    default_edition = "2021",
402    dylib_ext = ".so",
403    exec_triple = "x86_64-unknown-linux-gnu",
404    extra_rustc_flags = common_lint_opts + [
405        "--codegen=linker={}".format(gbl_llvm_tool_path("lld")),
406        # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below.
407        "--sysroot",
408        "/dev/null",
409    ],
410    global_allocator_library = None,
411    rust_doc = "@rust_prebuilts//:bin/rustdoc",
412    rust_std = "@rust_prebuilts//:aarch64-unknown-uefi_prebuilt_stdlibs",
413    rustc = "@rust_prebuilts//:bin/rustc",
414    staticlib_ext = ".a",
415    stdlib_linkflags = [],
416    target_triple = "aarch64-unknown-uefi",
417)
418
419toolchain(
420    name = "aarch64-unknown-uefi_toolchain",
421    exec_compatible_with = ["@platforms//os:linux"],
422    target_settings = [":gbl_rust_uefi_aarch64"],
423    toolchain = ":aarch64-unknown-uefi",
424    toolchain_type = "@rules_rust//rust:toolchain",
425)
426
427# riscv64 PIE ELF toolchain
428rust_toolchain(
429    name = "riscv64gc-unknown-none-pie_elf",
430    allocator_library = None,
431    binary_ext = "",
432    default_edition = "2021",
433    dylib_ext = ".so",
434    exec_triple = "x86_64-unknown-linux-gnu",
435    extra_rustc_flags = common_lint_opts + [
436        "--codegen=linker={}".format(gbl_llvm_tool_path("lld")),
437        # Disable default sysroot. We'll pass sysroot explicitly via the `rust_std` field below.
438        "--sysroot",
439        "/dev/null",
440    ],
441    global_allocator_library = None,
442    rust_doc = "@rust_prebuilts//:bin/rustdoc",
443    # Need to use our own built sysroot because we are using a custom spec below.
444    rust_std = select({
445        ":rust_no_sysroot_true": ":rust_stdlib_empty",
446        "//conditions:default": ":rust_std_source_build",
447    }),
448    rustc = "@rust_prebuilts//:bin/rustc",
449    staticlib_ext = ".a",
450    stdlib_linkflags = [],
451    # The custom spec is based on builtin target "riscv64gc-unknown-none-elf" but with the
452    # following changes for enabling PIE:
453    #
454    #   1. "relocation-model" config entry changed from "static" to "pic".
455    #   2. Added "position-independent-executables": true.
456    #
457    # The original spec can be obtained by:
458    #
459    #   rustc +nightly -Z unstable-options --print target-spec-json \
460    #     --target riscv64gc-unknown-none-elf
461    target_json = """
462                {
463                    "arch": "riscv64",
464                    "code-model": "medium",
465                    "cpu": "generic-rv64",
466                    "data-layout": "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128",
467                    "eh-frame-header": false,
468                    "emit-debug-gdb-scripts": false,
469                    "features": "+m,+a,+f,+d,+c",
470                    "is-builtin": false,
471                    "linker": "rust-lld",
472                    "linker-flavor": "ld.lld",
473                    "llvm-abiname": "lp64d",
474                    "llvm-target": "riscv64-unknown-linux",
475                    "max-atomic-width": 64,
476                    "os": "none",
477                    "panic-strategy": "abort",
478                    "relocation-model": "pic",
479                    "position-independent-executables": true,
480                    "supported-sanitizers": [
481                        "kernel-address"
482                    ],
483                    "target-pointer-width": "64"
484                }
485""",
486)
487
488toolchain(
489    name = "riscv64gc-unknown-none-pie_elf_toolchain",
490    exec_compatible_with = ["@platforms//os:linux"],
491    target_settings = ["@gbl//toolchain:gbl_rust_elf_riscv64"],
492    toolchain = ":riscv64gc-unknown-none-pie_elf",
493    toolchain_type = "@rules_rust//rust:toolchain",
494)
495
496# rustfmt toolchain
497rustfmt_toolchain(
498    name = "rustfmt",
499    rustfmt = "@rust_prebuilts//:bin/rustfmt",
500)
501
502toolchain(
503    name = "rustfmt_toolchain",
504    exec_compatible_with = ["@platforms//os:linux"],
505    toolchain = ":rustfmt",
506    toolchain_type = "@rules_rust//rust/rustfmt:toolchain_type",
507)
508
509# Rust bindgen toolchain
510
511prebuilt_binary(
512    name = "bindgen_prebuilt",
513    bin = "@bindgen//:bindgen",
514)
515
516rust_bindgen_toolchain(
517    name = "bindgen_toolchain_impl",
518    bindgen = ":bindgen_prebuilt",
519    clang = "@gbl_llvm_prebuilts//:clang-bin",
520    libclang = "@gbl_llvm_prebuilts//:libclang",
521    libstdcxx = "@gbl_llvm_prebuilts//:libc++",
522)
523
524toolchain(
525    name = "bindgen_toolchain",
526    toolchain = "bindgen_toolchain_impl",
527    toolchain_type = "@rules_rust//bindgen:toolchain_type",
528)
529