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 15""" 16This file contains rule and transition for building rust toolchain for device 17""" 18 19# Flags common to builds of the standard library. 20_EXTRA_FLAGS_FOR_STDLIB_BUILDS = [ 21 # Even though --cap-lints=allow is set at the toolchain level (b/301466790), 22 # setting it again here is needed to disble linting in all upstream deps 23 "--cap-lints=allow", 24] 25 26_TRANSITION_OUTPUTS = [ 27 "//command_line_option:compilation_mode", 28 "//build/bazel/toolchains/rust/bootstrap:enable_base_toolchain", 29 "@rules_rust//:extra_rustc_flags", 30 "@rules_rust//:extra_exec_rustc_flags", 31 "@rules_rust//rust/settings:use_real_import_macro", 32 "@rules_rust//rust/settings:pipelined_compilation", 33 "//command_line_option:cpu", 34] 35 36def _base_transition_impl(_, __): 37 return { 38 "//build/bazel/toolchains/rust/bootstrap:enable_base_toolchain": True, 39 "//command_line_option:compilation_mode": "opt", 40 "//command_line_option:cpu": "k8", 41 "@rules_rust//:extra_rustc_flags": _EXTRA_FLAGS_FOR_STDLIB_BUILDS, 42 "@rules_rust//:extra_exec_rustc_flags": _EXTRA_FLAGS_FOR_STDLIB_BUILDS, 43 "@rules_rust//rust/settings:use_real_import_macro": False, 44 "@rules_rust//rust/settings:pipelined_compilation": True, 45 } 46 47_base_transition = transition( 48 inputs = [], 49 outputs = _TRANSITION_OUTPUTS, 50 implementation = _base_transition_impl, 51) 52 53# Re-exports libs passed in `srcs` attribute. Used together with 54# transitions to build stdlibs at various stages. 55def _with_base_transition_impl(ctx): 56 return [DefaultInfo(files = depset(ctx.files.srcs))] 57 58# For each os + arch configuration, there is a pair of 59# 1. `<os_arch>_base_rust_toolchain` 60# 2. `<os_arch>_rust_toolchain` 61# registered in WORKSPACE. The base toolchains are only enabled when 62# `base_toolchain_enabled` `config_setting` is enabled. 63# Because `base_toolchain_enabled` is False by default, only <os_arch>_rust_toolchain 64# is enabled for a particular os + arch configuration and hence is resolved to build 65# a normal downstream rust target. 66# 67# with_base_transition attachs an incoming transition to `enable_base_toolchain` 68# which enable the base toolchains. When building for a particular configuration, 69# 1. `<os_arch>_base_rust_toolchain` 70# 2. `<os_arch>_rust_toolchain` 71# are enabled. 72# Because the base toolchain is registered before the non-base one, Bazel resolves 73# to the base toolchain. This mechanism allows building rust stdlibs using the base toolchain 74with_base_transition = rule( 75 implementation = _with_base_transition_impl, 76 attrs = { 77 "srcs": attr.label_list( 78 allow_files = True, 79 ), 80 "_allowlist_function_transition": attr.label( 81 default = Label("@bazel_tools//tools/allowlists/function_transition_allowlist"), 82 ), 83 }, 84 cfg = _base_transition, 85) 86 87def _toolchain_sysroot_impl(ctx): 88 sysroot = ctx.attr.dirname 89 outputs = [] 90 91 rustlibdir = "{}/lib/rustlib/{}/lib".format(sysroot, ctx.attr.target_triple) 92 rustbindir = "{}/bin".format(sysroot) 93 94 for inp in ctx.files.srcs: 95 if inp.short_path in ctx.attr.tools: 96 out = ctx.actions.declare_file(rustbindir + "/" + ctx.attr.tools[inp.short_path]) 97 else: 98 out = ctx.actions.declare_file(rustlibdir + "/" + inp.basename) 99 100 outputs.append(out) 101 ctx.actions.symlink(output = out, target_file = inp) 102 103 return [DefaultInfo( 104 files = depset(outputs), 105 runfiles = ctx.runfiles(files = outputs), 106 )] 107 108toolchain_sysroot = rule( 109 implementation = _toolchain_sysroot_impl, 110 doc = """Creates a directory tree with copies of the passed Rust libraries 111 and tools, suitable to use in a rust_stdlib_filegroup. 112 113 The `srcs` attribute should enumerate the libraries and tools. Tools are 114 distinguished from libraries via the `tools` attribute, which should 115 contain an entry from the tool short_path to its final name under 116 dirname/bin/ 117 118 The libraries are processed by creating symlinks to them in a local 119 directory rooted at `dirname`, e.g., 120 dirname/lib/rustlib/x86_64-unknown-linux-gnu/lib/ 121 122 The output under `dirname` is intended to constitute a valid sysroot, per 123 https://rustc-dev-guide.rust-lang.org/building/bootstrapping.html#what-is-a-sysroot 124 """, 125 attrs = { 126 "dirname": attr.string( 127 mandatory = True, 128 ), 129 "target_triple": attr.string( 130 doc = "The target triple for the rlibs.", 131 default = "x86_64-unknown-linux-gnu", 132 ), 133 "srcs": attr.label_list( 134 allow_files = True, 135 ), 136 "tools": attr.string_dict( 137 doc = "A map from tool's short_path to its final name under bin/", 138 ), 139 }, 140) 141