blob: bc154cea15ce19d8c53e6de165399a6a9b732453 [file] [log] [blame] [edit]
# Copyright (C) 2023 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Helper to resolve toolchain for a single platform."""
load("@bazel_skylib//lib:paths.bzl", "paths")
load(
"@bazel_tools//tools/build_defs/cc:action_names.bzl",
"CPP_LINK_EXECUTABLE_ACTION_NAME",
"C_COMPILE_ACTION_NAME",
)
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain")
load(":common_providers.bzl", "KernelPlatformToolchainInfo")
load(":debug.bzl", "debug")
visibility("//build/kernel/kleaf/...")
def _kernel_platform_toolchain_transition_impl(_settings, attrs):
if attrs.override_platform:
return {"//command_line_option:platforms": str(attrs.override_platform)}
return {}
_kernel_platform_toolchain_transition = transition(
implementation = _kernel_platform_toolchain_transition_impl,
inputs = [],
outputs = ["//command_line_option:platforms"],
)
def _kernel_platform_toolchain_impl(ctx):
should_print_platforms = debug.print_platforms(ctx)
cc_info = cc_common.merge_cc_infos(
cc_infos = [src[CcInfo] for src in ctx.attr.deps],
)
cc_toolchain = find_cpp_toolchain(ctx, mandatory = False)
if not cc_toolchain:
# Intentionally not put any keys so kernel_toolchains emit a hard error
return KernelPlatformToolchainInfo()
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features + [
"kleaf-lld-compiler-rt",
],
unsupported_features = [
# -no-canonical-prefixes is added to work around
# https://github.com/bazelbuild/bazel/issues/4605
# "cxx_builtin_include_directory doesn't work with non-absolute path"
# Disable it.
"kleaf-no-canonical-prefixes",
# Disable flags for C++. These only applies to cc_* rules with
# C++ code.
"kleaf-host-cc",
],
)
compile_variables = cc_common.create_compile_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
user_compile_flags = [], # copts
include_directories = cc_info.compilation_context.includes,
quote_include_directories = cc_info.compilation_context.quote_includes,
system_include_directories = cc_info.compilation_context.system_includes,
)
compile_command_line = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
variables = compile_variables,
)
# Handle "//prebuilts/kernel-build-tools:linux_x86_imported_libs",
user_link_flags = []
additional_libs = []
library_search_directories = []
for dep in ctx.attr.deps:
if dep[CcInfo].linking_context:
for linker_input in dep[CcInfo].linking_context.linker_inputs.to_list():
for lib in linker_input.libraries:
if lib.dynamic_library:
additional_libs.append(lib.dynamic_library)
library_search_directories.append(lib.dynamic_library.dirname)
link_variables = cc_common.create_link_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
user_link_flags = user_link_flags, # linkopts
library_search_directories = depset(library_search_directories),
)
link_command_line = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
# Use CPP_LINK_EXECUTABLE_ACTION_NAME to get rid of "-shared"
action_name = CPP_LINK_EXECUTABLE_ACTION_NAME,
variables = link_variables,
)
# See kernel_toolchains.bzl on how RUNPATH_EXECROOT is interpreted.
# Because Bazel isolates each .so in its own directory, $ORIGIN in these .so files no longer
# works. So we have to rely on the source tree directly, instead of the generated
# library_search_directories.
ldexpr = "' '".join([
'"-Wl,-rpath,${{RUNPATH_EXECROOT}}/{}"'.format(runpath.path)
for runpath in ctx.files.runpaths
])
all_files = depset(transitive = [
depset(cc_info.compilation_context.direct_headers),
cc_info.compilation_context.headers,
cc_toolchain.all_files,
depset(additional_libs),
])
# All executables are in the same place, so just use the compiler executable
# to locate PATH.
compiler_executable = cc_common.get_tool_for_action(
feature_configuration = feature_configuration,
action_name = C_COMPILE_ACTION_NAME,
)
bin_path = paths.dirname(compiler_executable)
if should_print_platforms:
# buildifier: disable=print
print("{}: {}".format(ctx.label, cc_toolchain.toolchain_id))
return KernelPlatformToolchainInfo(
compiler_version = cc_toolchain.compiler,
toolchain_id = cc_toolchain.toolchain_id,
all_files = all_files,
cflags = compile_command_line,
ldflags = link_command_line,
ldexpr = ldexpr,
bin_path = bin_path,
runpaths = [runpath.path for runpath in ctx.files.runpaths],
sysroot = cc_toolchain.sysroot,
libc = _get_libc(ctx),
)
def _get_libc(ctx):
if ctx.target_platform_has_constraint(ctx.attr._glibc[platform_common.ConstraintValueInfo]):
return "glibc"
if ctx.target_platform_has_constraint(ctx.attr._musl[platform_common.ConstraintValueInfo]):
return "musl"
fail("{}: Cannot determine platform.".format(ctx.label))
kernel_platform_toolchain = rule(
doc = """Helper to resolve toolchain for a single platform.""",
implementation = _kernel_platform_toolchain_impl,
attrs = {
"deps": attr.label_list(providers = [CcInfo]),
"runpaths": attr.label_list(allow_files = True),
"_musl": attr.label(default = "//build/kernel/kleaf/platforms/libc:musl"),
"_glibc": attr.label(default = "//build/kernel/kleaf/platforms/libc:glibc"),
# For using mandatory = False
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:optional_current_cc_toolchain"),
"override_platform": attr.label(
doc = "If set, force this target to use the given platform.",
),
},
toolchains = use_cpp_toolchain(mandatory = False),
fragments = ["cpp"],
subrules = [debug.print_platforms],
cfg = _kernel_platform_toolchain_transition,
)