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"""Configure CC toolchain for Android kernel."""
16
17load(
18    "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
19    "feature",
20    "flag_group",
21    "flag_set",
22)
23load(
24    "@rules_cc//cc:action_names.bzl",
25    "ACTION_NAMES",
26)
27load(":android.bzl", "android")
28load(":common.bzl", "common")
29load(":linux.bzl", "linux")
30
31def _impl(ctx):
32    if ctx.attr.target_os == "linux":
33        features = linux.features(ctx)
34    elif ctx.attr.target_os == "android":
35        features = android.features(ctx)
36    else:
37        fail("target_os == {} is not supported yet".format(ctx.attr.target_os))
38
39    features += common.features(ctx)
40    if ctx.attr.extra_features:
41        features.append(feature(
42            name = "kleaf-extra-features",
43            enabled = True,
44            implies = ctx.attr.extra_features,
45        ))
46    if ctx.attr.static_link_cpp_runtimes:
47        # Add custom static_link_cpp_runtimes and always set it to true. This
48        # allows static_runtime_lib/dynamic_runtime_lib to be used.
49        features.append(feature(
50            name = "static_link_cpp_runtimes",
51            enabled = True,
52        ))
53
54        # If the binary has linkstatic=True (the default), always -static to make
55        # it fully static.
56        features.append(feature(
57            name = "static_linking_mode",
58            enabled = False,
59            implies = [
60                "fully_static_link",
61            ],
62        ))
63
64        # Overrides the builtin static_libgcc feature so it does not add -static-libgcc
65        # when static_link_cpp_runtimes is enabled
66        features.append(feature(
67            name = "static_libgcc",
68            enabled = False,
69        ))
70
71        # Hack to get rid of EXEC_ORIGIN. This fixes running cc_test.
72        # https://github.com/bazelbuild/bazel/issues/3592
73        features.append(feature(
74            name = "runtime_library_search_directories",
75            flag_sets = [flag_set(
76                actions = [
77                    ACTION_NAMES.cpp_link_executable,
78                    ACTION_NAMES.cpp_link_dynamic_library,
79                    ACTION_NAMES.cpp_link_nodeps_dynamic_library,
80                ],
81                flag_groups = [flag_group(
82                    expand_if_available = "runtime_library_search_directories",
83                    iterate_over = "runtime_library_search_directories",
84                    flag_groups = [flag_group(
85                        flags = ["-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}"],
86                    )],
87                )],
88            )],
89        ))
90
91    sysroot_path = "/dev/null"
92    if ctx.file.sysroot_dir:
93        sysroot_path = ctx.file.sysroot_dir.path
94
95    return cc_common.create_cc_toolchain_config_info(
96        ctx = ctx,
97        toolchain_identifier = ctx.attr.toolchain_identifier,
98        target_cpu = ctx.attr.target_cpu,
99        action_configs = common.action_configs(ctx),
100        features = features,
101        builtin_sysroot = sysroot_path,
102
103        # The attributes below are required by the constructor, but don't
104        # affect actions at all.
105        host_system_name = "__toolchain_host_system_name__",
106        target_system_name = "__toolchain_target_system_name__",
107        target_libc = "__toolchain_target_libc__",
108        compiler = ctx.attr.clang_version,
109        abi_version = "__toolchain_abi_version__",
110        abi_libc_version = "__toolchain_abi_libc_version__",
111    )
112
113clang_config = rule(
114    implementation = _impl,
115    attrs = {
116        "target_cpu": attr.string(mandatory = True, values = [
117            "arm",
118            "arm64",
119            "i386",
120            "riscv64",
121            "x86_64",
122        ]),
123        "target_os": attr.string(mandatory = True, values = [
124            "android",
125            "linux",
126        ]),
127        "sysroot_dir": attr.label(allow_single_file = True),
128        "bin_dirs": attr.label_list(),
129        "lib_dirs": attr.label_list(),
130        "target": attr.string(),
131        "toolchain_identifier": attr.string(),
132        "clang_version": attr.string(),
133        "extra_features": attr.string_list(),
134        "static_link_cpp_runtimes": attr.bool(),
135    } | common.tool_attrs(),
136    provides = [CcToolchainConfigInfo],
137)
138