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 rules and logic for setting up GBL workspace dependencies in the AOSP
17u-boot-mainline branch.
18"""
19
20load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
21load("@gbl//toolchain:gbl_workspace_util.bzl", "android_rust_prebuilts", "gbl_llvm_prebuilts")
22load("@kernel_toolchain_info//:dict.bzl", "CLANG_VERSION")
23
24def rust_crate_build_file(name, crate_name = "", deps = [], features = [], rustc_flags = []):
25    """Generate BUILD file content for a rust crate
26
27    This helper is suitable for crates that have straightforward build rules. Specifically, the
28    crate contains a single `rust_library` targets that includes all source files under the repo.
29    There is not any need of preprocessing, patching or source generation.
30
31    Args:
32        name (String): name of the rust_library target.
33        crate_name (String): name of the rust_library crate, same as name by default.
34        deps (List of strings): The `deps` field.
35        features (List of strings): The `features` field.
36        rustc_flags (List of strings): The `rustc_flags` field.
37
38    Returns:
39        A string for the BUILD file content.
40    """
41    crate_name = name if len(crate_name) == 0 else crate_name
42    deps = "[{}]".format(",".join(["\"{}\"".format(ele) for ele in deps]))
43    features = "[{}]".format(",".join(["\"{}\"".format(ele) for ele in features]))
44    rustc_flags = "[{}]".format(",".join(["\"{}\"".format(ele) for ele in rustc_flags]))
45    return """
46load("@rules_rust//rust:defs.bzl", "rust_library")
47
48rust_library(
49    name = \"{}\",
50    crate_name = \"{}\",
51    srcs = glob(["**/*.rs"]),
52    crate_features = {},
53    edition = "2021",
54    rustc_flags ={},
55    visibility = ["//visibility:public"],
56    deps = {},
57)
58""".format(name, crate_name, features, rustc_flags, deps)
59
60def define_gbl_workspace(name = None):
61    """Set up worksapce dependencies for GBL
62
63    Dependencies are checked out during "repo init". The rule simply maps them to the correct repo
64    names.
65
66    Args:
67        name (String): Placeholder for buildifier check.
68    """
69    maybe(
70        repo_rule = native.local_repository,
71        name = "rules_rust",
72        path = "external/bazelbuild-rules_rust",
73    )
74
75    maybe(
76        repo_rule = native.local_repository,
77        name = "rules_license",
78        path = "external/bazelbuild-rules_license",
79    )
80
81    native.new_local_repository(
82        name = "rules_rust_tinyjson",
83        path = "external/rust/crates/tinyjson",
84        build_file = "@rules_rust//util/process_wrapper:BUILD.tinyjson.bazel",
85    )
86
87    native.new_local_repository(
88        name = "llvm_linux_x86_64_prebuilts",
89        path = "prebuilts/clang/host/linux-x86/clang-{}".format(CLANG_VERSION),
90        build_file_content = "",
91    )
92
93    native.new_local_repository(
94        name = "linux_x86_64_sysroot",
95        path = "build/kernel/build-tools",
96        build_file_content = """exports_files(glob(["**/*"]))
97cc_library(
98    name = "linux_x86_64_sysroot_include",
99    hdrs = glob(["sysroot/usr/include/**/*.h"]),
100    includes = [ "sysroot/usr/include" ],
101    visibility = ["//visibility:public"],
102)
103""",
104    )
105
106    android_rust_prebuilts(
107        name = "rust_prebuilts",
108        path = "prebuilts/rust/",
109        build_file = "@gbl//toolchain:BUILD.android_rust_prebuilts.bazel",
110    )
111
112    native.new_local_repository(
113        name = "bindgen",
114        path = "prebuilts/clang-tools/linux-x86/bin",
115        build_file_content = """exports_files(["bindgen"])""",
116    )
117
118    native.new_local_repository(
119        name = "elfutils",
120        path = "external/elfutils",
121        build_file_content = """
122cc_library(
123    name = "elf_type_header",
124    hdrs = ["libelf/elf.h"],
125    visibility = ["//visibility:public"],
126)
127""",
128    )
129
130    native.new_local_repository(
131        name = "mkbootimg",
132        path = "tools/mkbootimg",
133        build_file_content = """exports_files(glob(["**/*"]))""",
134    )
135
136    native.new_local_repository(
137        name = "libfdt_c",
138        path = "external/dtc/libfdt",
139        build_file = "@gbl//libfdt:BUILD.libfdt_c.bazel",
140    )
141
142    native.new_local_repository(
143        name = "arm_trusted_firmware",
144        path = "external/arm-trusted-firmware",
145        build_file = "@gbl//libboot/aarch64_cache_helper:BUILD.arm_trusted_firmware.bazel",
146    )
147
148    native.new_local_repository(
149        name = "avb",
150        path = "external/avb",
151        build_file = "@gbl//libavb:BUILD.avb.bazel",
152    )
153
154    native.new_local_repository(
155        name = "uuid",
156        path = "external/rust/crates/uuid",
157        build_file_content = rust_crate_build_file("uuid"),
158    )
159
160    native.new_local_repository(
161        name = "cstr",
162        path = "packages/modules/Virtualization/libs/cstr",
163        build_file_content = rust_crate_build_file("cstr"),
164    )
165
166    native.new_local_repository(
167        name = "spin",
168        path = "external/rust/crates/spin",
169        build_file_content = rust_crate_build_file(
170            "spin",
171            features = [
172                "mutex",
173                "spin_mutex",
174            ],
175            rustc_flags = [
176                "-A",
177                "unused_imports",
178            ],
179        ),
180    )
181
182    native.new_local_repository(
183        name = "static_assertions",
184        path = "external/rust/crates/static_assertions",
185        build_file_content = rust_crate_build_file("static_assertions"),
186    )
187
188    native.new_local_repository(
189        name = "managed",
190        path = "external/rust/crates/managed",
191        build_file_content = rust_crate_build_file(
192            "managed",
193            features = ["map"],
194            rustc_flags = [
195                "-A",
196                "unused_macros",
197                "-A",
198                "redundant_semicolons",
199            ],
200        ),
201    )
202
203    native.new_local_repository(
204        name = "itertools",
205        path = "external/rust/crates/itertools",
206        build_file_content = rust_crate_build_file(
207            "itertools",
208            deps = ["@either"],
209            features = ["default", "use_std", "use_alloc"],
210            rustc_flags = ["-A", "dead_code"],
211        ),
212    )
213
214    native.new_local_repository(
215        name = "itertools_noalloc",
216        path = "external/rust/crates/itertools",
217        build_file_content = rust_crate_build_file(
218            "itertools_noalloc",
219            crate_name = "itertools",
220            features = [],
221            deps = ["@either_noalloc"],
222            rustc_flags = ["-A", "dead_code"],
223        ),
224    )
225
226    native.new_local_repository(
227        name = "either",
228        path = "external/rust/crates/either",
229        build_file_content = rust_crate_build_file(
230            "either",
231            features = ["default", "use_std"],
232        ),
233    )
234
235    native.new_local_repository(
236        name = "either_noalloc",
237        path = "external/rust/crates/either",
238        build_file_content = rust_crate_build_file(
239            "either_noalloc",
240            crate_name = "either",
241            features = [],
242        ),
243    )
244
245    native.new_local_repository(
246        name = "smoltcp",
247        path = "external/rust/crates/smoltcp",
248        build_file = "@gbl//smoltcp:BUILD.smoltcp.bazel",
249    )
250
251    # Following are third party rust crates dependencies.
252
253    THIRD_PARTY_CRATES = [
254        "bitflags",
255        "byteorder",
256        "cfg-if",
257        "crc32fast",
258        "hex",
259        "proc-macro2",
260        "quote",
261        "syn",
262        "unicode-ident",
263        "zerocopy",
264        "zerocopy-derive",
265    ]
266
267    for crate in THIRD_PARTY_CRATES:
268        native.new_local_repository(
269            name = crate,
270            path = "external/rust/crates/{}".format(crate),
271            build_file = "//external/rust/crates/{}:BUILD".format(crate),
272        )
273
274    # Set up a repo to export LLVM tool/library/header/sysroot paths
275    gbl_llvm_prebuilts(name = "gbl_llvm_prebuilts")
276
277    # We don't register GBL toolchains here because they will be masked by toolchains from
278    # `build/kleaf//:` as they are registered earlier. Instead, we will pass GBL toolchains via
279    # bazel commandline argument "--extra_toolchains=@gbl//toolchain:all" when building GBL
280    # targets, which allows them to be evaluated first during toolchain resolution.
281