| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- # Exceptions. See /LICENSE for license information.
- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- """Starlark cc_toolchain configuration rules for using the Carbon toolchain"""
- load(
- "@carbon_toolchain_config//:carbon_detected_variables.bzl",
- "clang_include_dirs",
- "clang_sysroot",
- )
- load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
- load(
- "@rules_cc//cc:cc_toolchain_config_lib.bzl",
- "action_config",
- "flag_group",
- "flag_set",
- "tool",
- )
- load(
- "@rules_cc//cc:defs.bzl",
- "CcToolchainConfigInfo",
- "cc_toolchain",
- )
- load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
- load("//bazel:runtimes_build_vars.bzl", "llvm_version_major")
- load(
- ":cc_toolchain_actions.bzl",
- "all_c_compile_actions",
- "all_cpp_compile_actions",
- "all_link_actions",
- )
- load(":cc_toolchain_features.bzl", "clang_cc_toolchain_features")
- load(
- ":cc_toolchain_tools.bzl",
- "llvm_tool_paths",
- )
- def _make_action_configs(runtimes_path = None):
- runtimes_flag = "--no-build-runtimes"
- if runtimes_path:
- runtimes_flag = "--prebuilt-runtimes={0}".format(runtimes_path)
- return [
- action_config(
- action_name = name,
- enabled = True,
- tools = [tool(path = "llvm/bin/clang")],
- )
- for name in all_c_compile_actions
- ] + [
- action_config(
- action_name = name,
- enabled = True,
- tools = [tool(path = "llvm/bin/clang++")],
- )
- for name in all_cpp_compile_actions
- ] + [
- action_config(
- action_name = name,
- enabled = True,
- tools = [tool(path = "carbon-busybox")],
- flag_sets = [flag_set(flag_groups = [flag_group(flags = [
- runtimes_flag,
- "link",
- # We want to allow Bazel to intermingle linked object files and
- # Clang-spelled link flags. The first `--` starts the list of
- # initial object files by ending flags to the `link` subcommand,
- # and the second `--` switches to Clang-spelled flags.
- "--",
- "--",
- ])])],
- )
- for name in all_link_actions
- ] + [
- action_config(
- action_name = name,
- enabled = True,
- tools = [tool(path = "llvm/bin/llvm-ar")],
- )
- for name in [ACTION_NAMES.cpp_link_static_library]
- ] + [
- action_config(
- action_name = name,
- enabled = True,
- tools = [tool(path = "llvm/bin/llvm-strip")],
- )
- for name in [ACTION_NAMES.strip]
- ]
- def _carbon_cc_toolchain_config_impl(ctx):
- # Hard code the the repository-relative path of the LLVM (and Clang)
- # binaries as it is a fixed aspect of the install structure.
- llvm_bindir = "llvm/bin"
- # Only use a sysroot if a non-trivial one is set in Carbon's config.
- builtin_sysroot = None
- if clang_sysroot != "None" and clang_sysroot != "/":
- builtin_sysroot = clang_sysroot
- runtimes_path = None
- if ctx.attr.runtimes:
- for f in ctx.files.runtimes:
- if f.basename == "runtimes_root":
- runtimes_path = f.dirname
- break
- if not runtimes_path:
- fail("Unable to compute the runtimes path for: {0}".format(
- ctx.attr.runtimes,
- ))
- identifier = "carbon-toolchain-{0}-{1}".format(
- ctx.attr.target_cpu,
- ctx.attr.target_os,
- )
- return cc_common.create_cc_toolchain_config_info(
- ctx = ctx,
- features = clang_cc_toolchain_features(
- target_os = ctx.attr.target_os,
- target_cpu = ctx.attr.target_cpu,
- ),
- action_configs = _make_action_configs(runtimes_path),
- cxx_builtin_include_directories = clang_include_dirs,
- builtin_sysroot = builtin_sysroot,
- # This configuration only supports local non-cross builds so derive
- # everything from the target CPU selected.
- toolchain_identifier = identifier,
- # This is used to expose a "flag" that `config_setting` rules can use to
- # determine if the compiler is Clang.
- compiler = "clang",
- # We do have to pass in our tool paths.
- tool_paths = llvm_tool_paths(llvm_bindir),
- )
- carbon_cc_toolchain_config = rule(
- implementation = _carbon_cc_toolchain_config_impl,
- attrs = {
- "runtimes": attr.label(mandatory = False),
- "target_cpu": attr.string(mandatory = True),
- "target_os": attr.string(mandatory = True),
- },
- provides = [CcToolchainConfigInfo],
- )
- def _runtimes_transition_impl(_, attr):
- # Adjust the platform to the runtimes platform across the transition.
- return {"//command_line_option:platforms": [str(attr.runtimes_platform)]}
- runtimes_transition = transition(
- inputs = [],
- outputs = ["//command_line_option:platforms"],
- implementation = _runtimes_transition_impl,
- )
- def _runtimes_filegroup_impl(ctx):
- return [DefaultInfo(files = depset(ctx.files.srcs))]
- runtimes_filegroup = rule(
- implementation = _runtimes_filegroup_impl,
- attrs = {
- # The platform to use when building the runtimes.
- "runtimes_platform": attr.label(mandatory = True),
- # Mark that our dependencies are built through a transition.
- "srcs": attr.label_list(mandatory = True, cfg = runtimes_transition),
- # Enable transitions in this rule.
- "_allowlist_function_transition": attr.label(
- default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
- ),
- },
- )
- def carbon_cc_toolchain_suite(name, platforms):
- """Create a toolchain suite that uses the local Clang/LLVM install.
- Args:
- name: The name of the toolchain suite to produce.
- platforms: An array of (os, cpu) pairs to support in the toolchain.
- """
- # Our base filegroup for the toolchain just includes the busybox and the
- # LLVM symlinks. Importantly, this _doesn't_ include the install digest that
- # would cause cache misses as-if every file in the toolchain were an input
- # to every action.
- native.filegroup(
- name = name + "_base_files",
- srcs = ["carbon-busybox", "carbon_install.txt"] + native.glob([
- "llvm/bin/*",
- ]),
- )
- # We also need a compile-specific filegroup for use when _building_
- # runtimes. This needs to include the dedicated Clang headers, but we
- # require the runtimes themselves to provide the relevant headers and
- # dependencies.
- native.filegroup(
- name = name + "_runtimes_compile_files",
- srcs = [
- ":" + name + "_base_files",
- "//llvm/lib/clang/{0}:clang_hdrs".format(llvm_version_major),
- ],
- )
- # We can build a single common compile filegroup regardless of CPU and OS.
- # This needs to include all the headers of the runtimes, but those are
- # architecture independent.
- native.filegroup(
- name = name + "_compile_files",
- srcs = [
- ":" + name + "_runtimes_compile_files",
- "//runtimes:libunwind_hdrs",
- "//runtimes:libcxx_hdrs",
- ],
- )
- # Create the actual toolchains for each OS and CPU.
- for (os, cpu) in platforms:
- platform_name = "{0}_{1}_{2}".format(name, os, cpu)
- platform_constraints = [
- "@platforms//os:" + os,
- "@platforms//cpu:" + cpu,
- ]
- # First, configure a platform and toolchain for building runtimes. This
- # toolchain will only have the Clang headers and no runtime libraries
- # included.
- native.platform(
- name = platform_name + "_runtimes_platform",
- constraint_values = [":is_runtimes_build"] + platform_constraints,
- )
- carbon_cc_toolchain_config(
- name = platform_name + "_runtimes_toolchain_config",
- target_cpu = cpu,
- target_os = os,
- )
- cc_toolchain(
- name = platform_name + "_runtimes_cc_toolchain",
- all_files = ":" + name + "_runtimes_compile_files",
- ar_files = ":" + name + "_base_files",
- as_files = ":" + name + "_runtimes_compile_files",
- compiler_files = ":" + name + "_runtimes_compile_files",
- dwp_files = ":" + name + "_base_files",
- linker_files = ":" + name + "_base_files",
- objcopy_files = ":" + name + "_base_files",
- strip_files = ":" + name + "_base_files",
- toolchain_config = ":" + platform_name + "_runtimes_toolchain_config",
- toolchain_identifier = platform_name + "_runtimes",
- )
- native.toolchain(
- name = platform_name + "_runtimes_toolchain",
- exec_compatible_with = platform_constraints,
- target_compatible_with = [":is_runtimes_build"] + platform_constraints,
- toolchain = platform_name + "_runtimes_cc_toolchain",
- toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
- )
- # Now we can use the runtimes platform to build the runtimes on-demand.
- runtimes_filegroup(
- name = platform_name + "_runtimes",
- srcs = ["//runtimes:carbon_runtimes"],
- runtimes_platform = ":" + platform_name + "_runtimes_platform",
- )
- # Finally, we can build the main platform and toolchain.
- native.platform(
- name = platform_name + "_platform",
- constraint_values = platform_constraints,
- )
- # Build the main config with runtimes passed in. This allows the
- # configuration to use these built runtimes where needed.
- carbon_cc_toolchain_config(
- name = platform_name + "_toolchain_config",
- target_cpu = cpu,
- target_os = os,
- runtimes = ":" + platform_name + "_runtimes",
- )
- # We also include the runtimes in the linker files. We have to do this
- # in addition to the config parameter as the config can't carry the
- # actual dependency.
- native.filegroup(
- name = platform_name + "_linker_files",
- srcs = [
- ":" + name + "_base_files",
- ":" + platform_name + "_runtimes",
- ],
- )
- native.filegroup(
- name = platform_name + "_all_files",
- srcs = [
- ":" + name + "_compile_files",
- ":" + platform_name + "_linker_files",
- ],
- )
- cc_toolchain(
- name = platform_name + "_cc_toolchain",
- all_files = ":" + platform_name + "_all_files",
- ar_files = ":" + name + "_base_files",
- as_files = ":" + name + "_compile_files",
- compiler_files = ":" + name + "_compile_files",
- dwp_files = ":" + platform_name + "_linker_files",
- linker_files = ":" + platform_name + "_linker_files",
- objcopy_files = ":" + name + "_base_files",
- strip_files = ":" + name + "_base_files",
- toolchain_config = ":" + platform_name + "_toolchain_config",
- toolchain_identifier = platform_name,
- )
- native.toolchain(
- name = platform_name + "_toolchain",
- exec_compatible_with = platform_constraints,
- target_compatible_with = platform_constraints,
- toolchain = platform_name + "_cc_toolchain",
- toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
- )
|