chore: import upstream snapshot with attribution
cffconvert / validate (push) Has been skipped
License Check / license-check (push) Failing after 2s

This commit is contained in:
wehub-resource-sync
2026-07-13 12:14:16 +08:00
commit 8a852e4b4e
36502 changed files with 9277225 additions and 0 deletions
@@ -0,0 +1,21 @@
# AARCH64 toolchain
Toolchain for performing TensorFlow AARCH64 builds such as used in Github
Actions ARM_CI and ARM_CD.
Maintainer: @elfringham (Linaro LDCG)
********************************************************************************
This repository contains a toolchain for use with the specially constructed
Docker containers that match those created by SIG Build for x86 architecture
builds, but modified for AARCH64 builds.
These Docker containers have been constructed to perform builds of TensorFlow
that are compatible with manylinux2014 requirements but in an environment that
has the C++11 Dual ABI enabled.
The Docker containers are available from
[Docker Hub](https://hub.docker.com/r/linaro/tensorflow-arm64-build/tags) The
source Dockerfiles are available from
[Linaro git](https://git.linaro.org/ci/dockerfiles.git/tree/tensorflow-arm64-build)
@@ -0,0 +1,317 @@
"""Repository rule for aarch64 docker container
"""
load(
"//third_party/remote_config:common.bzl",
"err_out",
"get_host_environ",
"raw_exec",
"which",
)
_GCC_HOST_COMPILER_PATH = "GCC_HOST_COMPILER_PATH"
_GCC_HOST_COMPILER_PREFIX = "GCC_HOST_COMPILER_PREFIX"
_TF_SYSROOT = "TF_SYSROOT"
def to_list_of_strings(elements):
"""Convert the list of ["a", "b", "c"] into '"a", "b", "c"'.
This is to be used to put a list of strings into the bzl file templates
so it gets interpreted as list of strings in Starlark.
Args:
elements: list of string elements
Returns:
single string of elements wrapped in quotes separated by a comma."""
quoted_strings = ["\"" + element + "\"" for element in elements]
return ", ".join(quoted_strings)
def verify_build_defines(params):
"""Verify all variables that crosstool/BUILD.tpl expects are substituted.
Args:
params: dict of variables that will be passed to the BUILD.tpl template.
"""
missing = []
for param in [
"cxx_builtin_include_directories",
"extra_no_canonical_prefixes_flags",
"host_compiler_path",
"host_compiler_prefix",
"host_compiler_warnings",
"linker_bin_path",
"compiler_deps",
"unfiltered_compile_flags",
]:
if ("%{" + param + "}") not in params:
missing.append(param)
if missing:
auto_configure_fail(
"BUILD.tpl template is missing these variables: " +
str(missing) +
".\nWe only got: " +
str(params) +
".",
)
# TODO(dzc): Once these functions have been factored out of Bazel's
# cc_configure.bzl, load them from @bazel_tools instead.
# BEGIN cc_configure common functions.
def find_cc(repository_ctx):
"""Find the C++ compiler."""
if _use_clang(repository_ctx):
target_cc_name = "clang"
cc_path_envvar = "CLANG_COMPILER_PATH"
else:
target_cc_name = "gcc"
cc_path_envvar = _GCC_HOST_COMPILER_PATH
cc_name = target_cc_name
cc_name_from_env = get_host_environ(repository_ctx, cc_path_envvar)
if cc_name_from_env:
cc_name = cc_name_from_env
if cc_name.startswith("/"):
# Absolute path, maybe we should make this supported by our which function.
return cc_name
cc = which(repository_ctx, cc_name)
if cc == None:
fail(("Cannot find {}, either correct your path or set the {}" +
" environment variable").format(target_cc_name, cc_path_envvar))
return cc
_INC_DIR_MARKER_BEGIN = "#include <...>"
def _normalize_include_path(repository_ctx, path):
"""Normalizes include paths before writing them to the crosstool.
If path points inside the 'crosstool' folder of the repository, a relative
path is returned.
If path points outside the 'crosstool' folder, an absolute path is returned.
"""
path = str(repository_ctx.path(path))
crosstool_folder = str(repository_ctx.path(".").get_child("crosstool"))
if path.startswith(crosstool_folder):
# We drop the path to "$REPO/crosstool" and a trailing path separator.
return path[len(crosstool_folder) + 1:]
return path
def _get_cxx_inc_directories_impl(repository_ctx, cc, lang_is_cpp, tf_sysroot):
"""Compute the list of default C or C++ include directories."""
if lang_is_cpp:
lang = "c++"
else:
lang = "c"
sysroot = []
if tf_sysroot:
sysroot += ["--sysroot", tf_sysroot]
result = raw_exec(repository_ctx, [cc, "-E", "-x" + lang, "-", "-v"] +
sysroot)
stderr = err_out(result)
index1 = stderr.find(_INC_DIR_MARKER_BEGIN)
if index1 == -1:
return []
index1 = stderr.find("\n", index1)
if index1 == -1:
return []
index2 = stderr.rfind("\n ")
if index2 == -1 or index2 < index1:
return []
index2 = stderr.find("\n", index2 + 1)
if index2 == -1:
inc_dirs = stderr[index1 + 1:]
else:
inc_dirs = stderr[index1 + 1:index2].strip()
return [
_normalize_include_path(repository_ctx, p.strip())
for p in inc_dirs.split("\n")
]
def get_cxx_inc_directories(repository_ctx, cc, tf_sysroot):
"""Compute the list of default C and C++ include directories."""
# For some reason `clang -xc` sometimes returns include paths that are
# different from the ones from `clang -xc++`. (Symlink and a dir)
# So we run the compiler with both `-xc` and `-xc++` and merge resulting lists
includes_cpp = _get_cxx_inc_directories_impl(
repository_ctx,
cc,
True,
tf_sysroot,
)
includes_c = _get_cxx_inc_directories_impl(
repository_ctx,
cc,
False,
tf_sysroot,
)
return includes_cpp + [
inc
for inc in includes_c
if inc not in includes_cpp
]
def auto_configure_fail(msg):
"""Output failure message when aarch64 gcc configuration fails."""
red = "\033[0;31m"
no_color = "\033[0m"
fail("\n%sAARCH64 gcc Configuration Error:%s %s\n" % (red, no_color, msg))
# END cc_configure common functions (see TODO above).
def _use_clang(repository_ctx):
return get_host_environ(repository_ctx, "CC_TOOLCHAIN_NAME") == "linux_llvm_aarch64"
def _tf_sysroot(repository_ctx):
return get_host_environ(repository_ctx, _TF_SYSROOT, "")
def _tpl_path(repository_ctx, filename):
return repository_ctx.path(Label("//tensorflow/tools/toolchains/cpus/aarch64/%s.tpl" % filename))
def _create_local_aarch64_repository(repository_ctx):
"""Creates the repository containing files set up to build with gcc."""
# Resolve all labels before doing any real work. Resolving causes the
# function to be restarted with all previous state being lost. This
# can easily lead to a O(n^2) runtime in the number of labels.
# See https://github.com/tensorflow/tensorflow/commit/62bd3534525a036f07d9851b3199d68212904778
tpl_paths = {filename: _tpl_path(repository_ctx, filename) for filename in [
"crosstool:BUILD",
"crosstool:cc_toolchain_config.bzl",
]}
tf_sysroot = _tf_sysroot(repository_ctx)
cc = find_cc(repository_ctx)
cc_fullpath = cc
host_compiler_includes = get_cxx_inc_directories(
repository_ctx,
cc_fullpath,
tf_sysroot,
)
aarch64_defines = {}
aarch64_defines["%{builtin_sysroot}"] = tf_sysroot
aarch64_defines["%{compiler}"] = "gcc"
host_compiler_prefix = get_host_environ(repository_ctx, _GCC_HOST_COMPILER_PREFIX)
if not host_compiler_prefix:
host_compiler_prefix = "/usr/bin"
aarch64_defines["%{host_compiler_prefix}"] = host_compiler_prefix
aarch64_defines["%{linker_bin_path}"] = host_compiler_prefix
aarch64_defines["%{host_compiler_path}"] = str(cc)
aarch64_defines["%{host_compiler_warnings}"] = ""
aarch64_defines["%{cxx_builtin_include_directories}"] = to_list_of_strings(host_compiler_includes)
aarch64_defines["%{compiler_deps}"] = ":aarch64_gcc_pieces"
aarch64_defines["%{extra_no_canonical_prefixes_flags}"] = "\"-fno-canonical-system-headers\""
aarch64_defines["%{unfiltered_compile_flags}"] = ""
verify_build_defines(aarch64_defines)
# Only expand template variables in the BUILD file
repository_ctx.template(
"crosstool/BUILD",
tpl_paths["crosstool:BUILD"],
aarch64_defines,
)
# No templating of cc_toolchain_config - use attributes and templatize the
# BUILD file.
repository_ctx.template(
"crosstool/cc_toolchain_config.bzl",
tpl_paths["crosstool:cc_toolchain_config.bzl"],
{},
)
def _create_local_aarch64_clang_repository(repository_ctx):
"""Creates the repository containing files set up to build with clang."""
# Resolve all labels before doing any real work. Resolving causes the
# function to be restarted with all previous state being lost. This
# can easily lead to a O(n^2) runtime in the number of labels.
# See https://github.com/tensorflow/tensorflow/commit/62bd3534525a036f07d9851b3199d68212904778
tpl_paths = {filename: _tpl_path(repository_ctx, filename) for filename in [
"crosstool:BUILD",
"crosstool:cc_toolchain_config.bzl",
]}
tf_sysroot = _tf_sysroot(repository_ctx)
cc = find_cc(repository_ctx)
cc_fullpath = cc
host_compiler_includes = get_cxx_inc_directories(
repository_ctx,
cc_fullpath,
tf_sysroot,
)
aarch64_clang_defines = {}
aarch64_clang_defines["%{builtin_sysroot}"] = tf_sysroot
aarch64_clang_defines["%{compiler}"] = "clang"
host_compiler_prefix = get_host_environ(repository_ctx, _GCC_HOST_COMPILER_PREFIX)
if not host_compiler_prefix:
host_compiler_prefix = "/usr/bin"
aarch64_clang_defines["%{host_compiler_prefix}"] = host_compiler_prefix
aarch64_clang_defines["%{linker_bin_path}"] = host_compiler_prefix
aarch64_clang_defines["%{host_compiler_path}"] = str(cc)
aarch64_clang_defines["%{host_compiler_warnings}"] = """
# Some parts of the codebase set -Werror and hit this warning, so
# switch it off for now.
"-Wno-invalid-partial-specialization"
"""
aarch64_clang_defines["%{cxx_builtin_include_directories}"] = to_list_of_strings(host_compiler_includes)
aarch64_clang_defines["%{compiler_deps}"] = ":empty"
aarch64_clang_defines["%{extra_no_canonical_prefixes_flags}"] = ""
aarch64_clang_defines["%{unfiltered_compile_flags}"] = ""
verify_build_defines(aarch64_clang_defines)
# Only expand template variables in the BUILD file
repository_ctx.template(
"crosstool/BUILD",
tpl_paths["crosstool:BUILD"],
aarch64_clang_defines,
)
# No templating of cc_toolchain_config - use attributes and templatize the
# BUILD file.
repository_ctx.template(
"crosstool/cc_toolchain_config.bzl",
tpl_paths["crosstool:cc_toolchain_config.bzl"],
{},
)
def _clang_autoconf_impl(repository_ctx):
if _use_clang(repository_ctx):
_create_local_aarch64_clang_repository(repository_ctx)
else:
_create_local_aarch64_repository(repository_ctx)
_ENVIRONS = [
"CC_TOOLCHAIN_NAME",
"CLANG_COMPILER_PATH",
_GCC_HOST_COMPILER_PATH,
_GCC_HOST_COMPILER_PREFIX,
"TMP",
"TMPDIR",
]
remote_aarch64_configure = repository_rule(
implementation = _clang_autoconf_impl,
environ = _ENVIRONS,
remotable = True,
attrs = {
"environ": attr.string_dict(),
},
)
@@ -0,0 +1,76 @@
"""Configurations of AARCH64 builds used with Docker container."""
load("//third_party/remote_config:remote_platform_configure.bzl", "remote_platform_configure")
load("//tools/toolchains:cpus/aarch64/aarch64.bzl", "remote_aarch64_configure")
def ml2014_tf_aarch64_configs(name_container_map, env):
for name, container in name_container_map.items():
exec_properties = {
"container-image": container,
"Pool": "default",
}
remote_aarch64_configure(
name = "%s_config_aarch64" % name,
environ = env,
exec_properties = exec_properties,
)
remote_platform_configure(
name = "%s_config_aarch64_platform" % name,
platform = "linux",
platform_exec_properties = exec_properties,
)
def aarch64_compiler_configure():
ml2014_tf_aarch64_configs(
name_container_map = {
"ml2014_aarch64": "docker://localhost/tensorflow-build-aarch64",
"ml2014_aarch64-python3.10": "docker://localhost/tensorflow-build-aarch64:latest-python3.10",
"ml2014_aarch64-python3.11": "docker://localhost/tensorflow-build-aarch64:latest-python3.11",
},
env = {
"ABI_LIBC_VERSION": "glibc_2.17",
"ABI_VERSION": "gcc",
"BAZEL_COMPILER": "/dt10/usr/bin/gcc",
"BAZEL_HOST_SYSTEM": "aarch64-unknown-linux-gnu",
"BAZEL_TARGET_CPU": "generic",
"BAZEL_TARGET_LIBC": "glibc_2.17",
"BAZEL_TARGET_SYSTEM": "aarch64-unknown-linux-gnu",
"CC": "/dt10/usr/bin/gcc",
"CC_TOOLCHAIN_NAME": "linux_gnu_aarch64",
"CLEAR_CACHE": "1",
"GCC_HOST_COMPILER_PATH": "/dt10/usr/bin/gcc",
"GCC_HOST_COMPILER_PREFIX": "/usr/bin",
"HOST_CXX_COMPILER": "/dt10/usr/bin/gcc",
"HOST_C_COMPILER": "/dt10/usr/bin/gcc",
"TF_ENABLE_XLA": "1",
"TF_SYSROOT": "/dt10",
},
)
ml2014_tf_aarch64_configs(
name_container_map = {
"ml2014_clang_aarch64": "docker://localhost/tensorflow-build-aarch64",
"ml2014_clang_aarch64-python3.10": "docker://localhost/tensorflow-build-aarch64:latest-python3.10",
"ml2014_clang_aarch64-python3.11": "docker://localhost/tensorflow-build-aarch64:latest-python3.11",
"ml2014_clang_aarch64-python3.12": "docker://localhost/tensorflow-build-aarch64:latest-python3.12",
},
env = {
"ABI_LIBC_VERSION": "glibc_2.17",
"ABI_VERSION": "gcc",
"BAZEL_COMPILER": "/usr/lib/llvm-18/bin/clang",
"BAZEL_HOST_SYSTEM": "aarch64-unknown-linux-gnu",
"BAZEL_TARGET_CPU": "generic",
"BAZEL_TARGET_LIBC": "glibc_2.17",
"BAZEL_TARGET_SYSTEM": "aarch64-unknown-linux-gnu",
"CC": "/usr/lib/llvm-18/bin/clang",
"CC_TOOLCHAIN_NAME": "linux_llvm_aarch64",
"CLEAR_CACHE": "1",
"CLANG_COMPILER_PATH": "/usr/lib/llvm-18/bin/clang",
"HOST_CXX_COMPILER": "/usr/lib/llvm-18/bin/clang",
"HOST_C_COMPILER": "/usr/lib/llvm-18/bin/clang",
"TF_ENABLE_XLA": "1",
"TF_SYSROOT": "/dt10",
},
)
@@ -0,0 +1 @@
# copybara:uncomment package(default_applicable_licenses = ["//tensorflow:license"])
@@ -0,0 +1,78 @@
# This file is expanded from a template by aarch64_configure.bzl
# Update aarch64_configure.bzl#verify_build_defines when adding new variables.
load(":cc_toolchain_config.bzl", "cc_toolchain_config")
licenses(["restricted"])
package(default_visibility = ["//visibility:public"])
toolchain(
name = "toolchain-linux-aarch64",
exec_compatible_with = [
"@bazel_tools//platforms:linux",
"@bazel_tools//platforms:aarch64",
],
target_compatible_with = [
"@bazel_tools//platforms:linux",
"@bazel_tools//platforms:aarch64",
],
toolchain = ":cc-compiler-local-aarch64",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
cc_toolchain_suite(
name = "toolchain",
toolchains = {
"local|compiler": ":cc-compiler-local-aarch64",
"aarch64": ":cc-compiler-local-aarch64",
},
)
cc_toolchain(
name = "cc-compiler-local-aarch64",
all_files = "%{compiler_deps}",
compiler_files = "%{compiler_deps}",
ar_files = "%{compiler_deps}",
as_files = "%{compiler_deps}",
dwp_files = ":empty",
linker_files = "%{compiler_deps}",
objcopy_files = ":empty",
strip_files = ":empty",
# To support linker flags that need to go to the start of command line
# we need the toolchain to support parameter files. Parameter files are
# last on the command line and contain all shared libraries to link, so all
# regular options will be left of them.
supports_param_files = 1,
toolchain_identifier = "local_linux_aarch64",
toolchain_config = ":cc-compiler-local-aarch64-config",
)
cc_toolchain_config(
name = "cc-compiler-local-aarch64-config",
cpu = "local",
builtin_include_directories = [%{cxx_builtin_include_directories}],
extra_no_canonical_prefixes_flags = [%{extra_no_canonical_prefixes_flags}],
host_compiler_path = "%{host_compiler_path}",
host_compiler_prefix = "%{host_compiler_prefix}",
host_compiler_warnings = [%{host_compiler_warnings}],
host_unfiltered_compile_flags = [%{unfiltered_compile_flags}],
linker_bin_path = "%{linker_bin_path}",
builtin_sysroot = "%{builtin_sysroot}",
compiler = "%{compiler}",
)
filegroup(
name = "empty",
srcs = [],
)
filegroup(
name = "aarch64_gcc_pieces",
srcs = glob([
"usr/aarch64-linux-gnu/**",
"usr/libexec/**",
"usr/lib/gcc/aarch64-unknown-linux-gnu/**",
"usr/include/**",
]),
)
@@ -0,0 +1,639 @@
"""cc_toolchain_config rule for configuring AARCH64 toolchains on Linux."""
load(
"@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl",
"action_config",
"artifact_name_pattern",
"env_entry",
"env_set",
"feature",
"feature_set",
"flag_group",
"flag_set",
"tool",
"tool_path",
"variable_with_value",
"with_feature_set",
)
load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES")
def all_assembly_actions():
return [
ACTION_NAMES.assemble,
ACTION_NAMES.preprocess_assemble,
]
def all_compile_actions():
return [
ACTION_NAMES.assemble,
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_codegen,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.preprocess_assemble,
]
def all_c_compile_actions():
return [
ACTION_NAMES.c_compile,
]
def all_cpp_compile_actions():
return [
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_codegen,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.linkstamp_compile,
]
def all_preprocessed_actions():
return [
ACTION_NAMES.c_compile,
ACTION_NAMES.cpp_compile,
ACTION_NAMES.cpp_header_parsing,
ACTION_NAMES.cpp_module_codegen,
ACTION_NAMES.cpp_module_compile,
ACTION_NAMES.linkstamp_compile,
ACTION_NAMES.preprocess_assemble,
]
def all_link_actions():
return [
ACTION_NAMES.cpp_link_executable,
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
]
def all_executable_link_actions():
return [
ACTION_NAMES.cpp_link_executable,
]
def all_shared_library_link_actions():
return [
ACTION_NAMES.cpp_link_dynamic_library,
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
]
def all_archive_actions():
return [ACTION_NAMES.cpp_link_static_library]
def all_strip_actions():
return [ACTION_NAMES.strip]
def _library_to_link(flag_prefix, value, iterate = None):
return flag_group(
flags = [
"{}%{{libraries_to_link.{}}}".format(
flag_prefix,
iterate if iterate else "name",
),
],
iterate_over = ("libraries_to_link." + iterate if iterate else None),
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = value,
),
)
def _surround_static_library(prefix, suffix):
return [
flag_group(
flags = [prefix, "%{libraries_to_link.name}", suffix],
expand_if_true = "libraries_to_link.is_whole_archive",
),
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_false = "libraries_to_link.is_whole_archive",
),
]
def _prefix_static_library(prefix):
return [
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_false = "libraries_to_link.is_whole_archive",
),
flag_group(
flags = [prefix + "%{libraries_to_link.name}"],
expand_if_true = "libraries_to_link.is_whole_archive",
),
]
def _static_library_to_link(alwayslink_prefix, alwayslink_suffix = None):
if alwayslink_suffix:
flag_groups = _surround_static_library(alwayslink_prefix, alwayslink_suffix)
else:
flag_groups = _prefix_static_library(alwayslink_prefix)
return flag_group(
flag_groups = flag_groups,
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "static_library",
),
)
def _iterate_flag_group(iterate_over, flags = [], flag_groups = []):
return flag_group(
iterate_over = iterate_over,
expand_if_available = iterate_over,
flag_groups = flag_groups,
flags = flags,
)
def _libraries_to_link_group(flavour):
if flavour == "linux":
return _iterate_flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
flag_group(
flags = ["-Wl,--start-lib"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
_library_to_link("", "object_file_group", "object_files"),
flag_group(
flags = ["-Wl,--end-lib"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
_library_to_link("", "object_file"),
_library_to_link("", "interface_library"),
_static_library_to_link("-Wl,-whole-archive", "-Wl,-no-whole-archive"),
_library_to_link("-l", "dynamic_library"),
_library_to_link("-l:", "versioned_dynamic_library"),
],
)
elif flavour == "darwin":
return _iterate_flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
_library_to_link("", "object_file_group", "object_files"),
_library_to_link("", "object_file"),
_library_to_link("", "interface_library"),
_static_library_to_link("-Wl,-force_load,"),
_library_to_link("-l", "dynamic_library"),
_library_to_link("-l:", "versioned_dynamic_library"),
],
)
elif flavour == "msvc":
return _iterate_flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
_library_to_link("", "object_file_group", "object_files"),
_library_to_link("", "object_file"),
_library_to_link("", "interface_library"),
_static_library_to_link("/WHOLEARCHIVE:"),
],
)
def _action_configs_with_tool(path, actions):
return [
action_config(
action_name = name,
enabled = True,
tools = [tool(path = path)],
)
for name in actions
]
def _action_configs(assembly_path, c_compiler_path, cc_compiler_path, archiver_path, linker_path, strip_path):
return _action_configs_with_tool(
assembly_path,
all_assembly_actions(),
) + _action_configs_with_tool(
c_compiler_path,
all_c_compile_actions(),
) + _action_configs_with_tool(
cc_compiler_path,
all_cpp_compile_actions(),
) + _action_configs_with_tool(
archiver_path,
all_archive_actions(),
) + _action_configs_with_tool(
linker_path,
all_link_actions(),
) + _action_configs_with_tool(
strip_path,
all_strip_actions(),
)
def _tool_paths(cpu, ctx):
if cpu in ["local", "darwin"]:
return [
tool_path(name = "gcc", path = ctx.attr.host_compiler_path),
tool_path(name = "ar", path = ctx.attr.host_compiler_prefix + (
"/ar" if cpu == "local" else "/libtool"
)),
tool_path(name = "compat-ld", path = ctx.attr.host_compiler_prefix + "/ld"),
tool_path(name = "cpp", path = ctx.attr.host_compiler_prefix + "/cpp"),
tool_path(name = "dwp", path = ctx.attr.host_compiler_prefix + "/dwp"),
tool_path(name = "gcov", path = ctx.attr.host_compiler_prefix + "/gcov"),
tool_path(name = "ld", path = ctx.attr.host_compiler_prefix + "/ld"),
tool_path(name = "nm", path = ctx.attr.host_compiler_prefix + "/nm"),
tool_path(name = "objcopy", path = ctx.attr.host_compiler_prefix + "/objcopy"),
tool_path(name = "objdump", path = ctx.attr.host_compiler_prefix + "/objdump"),
tool_path(name = "strip", path = ctx.attr.host_compiler_prefix + "/strip"),
]
else:
fail("Unreachable")
def _sysroot_group():
return flag_group(
flags = ["--sysroot=%{sysroot}"],
expand_if_available = "sysroot",
)
def _no_canonical_prefixes_group(extra_flags):
return flag_group(
flags = [
"-no-canonical-prefixes",
] + extra_flags,
)
def _nologo():
return flag_group(flags = ["/nologo"])
def _features(cpu, compiler, ctx):
if cpu in ["local", "darwin"]:
return [
feature(name = "no_legacy_features"),
feature(
name = "all_compile_flags",
enabled = True,
flag_sets = [
flag_set(
actions = all_compile_actions(),
flag_groups = [
flag_group(
flags = ["-MD", "-MF", "%{dependency_file}"],
expand_if_available = "dependency_file",
),
flag_group(
flags = ["-gsplit-dwarf"],
expand_if_available = "per_object_debug_info_file",
),
],
),
flag_set(
actions = all_preprocessed_actions(),
flag_groups = [
flag_group(
flags = ["-frandom-seed=%{output_file}"],
expand_if_available = "output_file",
),
_iterate_flag_group(
flags = ["-D%{preprocessor_defines}"],
iterate_over = "preprocessor_defines",
),
_iterate_flag_group(
flags = ["-include", "%{includes}"],
iterate_over = "includes",
),
_iterate_flag_group(
flags = ["-iquote", "%{quote_include_paths}"],
iterate_over = "quote_include_paths",
),
_iterate_flag_group(
flags = ["-I%{include_paths}"],
iterate_over = "include_paths",
),
_iterate_flag_group(
flags = ["-isystem", "%{system_include_paths}"],
iterate_over = "system_include_paths",
),
_iterate_flag_group(
flags = ["-F", "%{framework_include_paths}"],
iterate_over = "framework_include_paths",
),
],
),
flag_set(
actions = all_cpp_compile_actions(),
flag_groups = [
flag_group(flags = [
"-fmerge-all-constants",
]),
] if compiler == "clang" else [],
),
flag_set(
actions = all_compile_actions(),
flag_groups = [
flag_group(
flags = [
"-Wno-builtin-macro-redefined",
"-D__DATE__=\"redacted\"",
"-D__TIMESTAMP__=\"redacted\"",
"-D__TIME__=\"redacted\"",
],
),
flag_group(
flags = ["-fPIC"],
expand_if_available = "pic",
),
flag_group(
flags = ["-fPIE"],
expand_if_not_available = "pic",
),
flag_group(
flags = [
"-U_FORTIFY_SOURCE",
"-D_FORTIFY_SOURCE=1",
"-fstack-protector",
"-Wall",
] + ctx.attr.host_compiler_warnings + [
"-fno-omit-frame-pointer",
],
),
_no_canonical_prefixes_group(
ctx.attr.extra_no_canonical_prefixes_flags,
),
],
),
flag_set(
actions = all_compile_actions(),
flag_groups = [flag_group(flags = ["-DNDEBUG"])],
with_features = [with_feature_set(features = ["disable-assertions"])],
),
flag_set(
actions = all_compile_actions(),
flag_groups = [
flag_group(
flags = [
"-g0",
"-O2",
"-ffunction-sections",
"-fdata-sections",
],
),
],
with_features = [with_feature_set(features = ["opt"])],
),
flag_set(
actions = all_compile_actions(),
flag_groups = [flag_group(flags = ["-g"])],
with_features = [with_feature_set(features = ["dbg"])],
),
] + [
flag_set(
actions = all_compile_actions(),
flag_groups = [
_iterate_flag_group(
flags = ["%{user_compile_flags}"],
iterate_over = "user_compile_flags",
),
_sysroot_group(),
flag_group(
expand_if_available = "source_file",
flags = ["-c", "%{source_file}"],
),
flag_group(
expand_if_available = "output_assembly_file",
flags = ["-S"],
),
flag_group(
expand_if_available = "output_preprocess_file",
flags = ["-E"],
),
flag_group(
expand_if_available = "output_file",
flags = ["-o", "%{output_file}"],
),
],
),
],
),
feature(
name = "all_archive_flags",
enabled = True,
flag_sets = [
flag_set(
actions = all_archive_actions(),
flag_groups = [
flag_group(
expand_if_available = "linker_param_file",
flags = ["@%{linker_param_file}"],
),
flag_group(flags = ["rcsD"]),
flag_group(
flags = ["%{output_execpath}"],
expand_if_available = "output_execpath",
),
flag_group(
iterate_over = "libraries_to_link",
flag_groups = [
flag_group(
flags = ["%{libraries_to_link.name}"],
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file",
),
),
flag_group(
flags = ["%{libraries_to_link.object_files}"],
iterate_over = "libraries_to_link.object_files",
expand_if_equal = variable_with_value(
name = "libraries_to_link.type",
value = "object_file_group",
),
),
],
expand_if_available = "libraries_to_link",
),
],
),
],
),
feature(
name = "all_link_flags",
enabled = True,
flag_sets = [
flag_set(
actions = all_shared_library_link_actions(),
flag_groups = [flag_group(flags = ["-shared"])],
),
flag_set(
actions = all_link_actions(),
flag_groups = ([
flag_group(flags = ["-Wl,-no-as-needed"])
] if cpu == "local" else []) + ([
flag_group(flags = ["-B" + ctx.attr.linker_bin_path])
] if ctx.attr.linker_bin_path else []) + [
flag_group(
flags = ["@%{linker_param_file}"],
expand_if_available = "linker_param_file",
),
_iterate_flag_group(
flags = ["%{linkstamp_paths}"],
iterate_over = "linkstamp_paths",
),
flag_group(
flags = ["-o", "%{output_execpath}"],
expand_if_available = "output_execpath",
),
_iterate_flag_group(
flags = ["-L%{library_search_directories}"],
iterate_over = "library_search_directories",
),
_iterate_flag_group(
iterate_over = "runtime_library_search_directories",
flags = [
"-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
] if cpu == "local" else [
"-Wl,-rpath,@loader_path/%{runtime_library_search_directories}",
],
),
_libraries_to_link_group("darwin" if cpu == "darwin" else "linux"),
_iterate_flag_group(
flags = ["%{user_link_flags}"],
iterate_over = "user_link_flags",
),
flag_group(
flags = ["-Wl,--gdb-index"],
expand_if_available = "is_using_fission",
),
flag_group(
flags = ["-Wl,-S"],
expand_if_available = "strip_debug_symbols",
),
flag_group(flags = ["-lc++" if cpu == "darwin" else "-lstdc++"]),
_no_canonical_prefixes_group(
ctx.attr.extra_no_canonical_prefixes_flags,
),
],
),
flag_set(
actions = all_executable_link_actions(),
flag_groups = [flag_group(flags = ["-pie"])],
),
] + ([
flag_set(
actions = all_link_actions(),
flag_groups = [flag_group(flags = [
"-Wl,-z,relro,-z,now",
])],
),
] if cpu == "local" else []) + ([
flag_set(
actions = all_link_actions(),
flag_groups = [
flag_group(flags = ["-Wl,--gc-sections"]),
flag_group(
flags = ["-Wl,--build-id=md5", "-Wl,--hash-style=gnu"],
),
],
),
] if cpu == "local" else []) + ([
flag_set(
actions = all_link_actions(),
flag_groups = [flag_group(flags = ["-undefined", "dynamic_lookup"])],
),
] if cpu == "darwin" else []) + [
flag_set(
actions = all_link_actions(),
flag_groups = [
_sysroot_group(),
],
),
],
),
feature(name = "disable-assertions"),
feature(
name = "opt",
implies = ["disable-assertions"],
),
feature(name = "fastbuild"),
feature(name = "dbg"),
feature(name = "supports_dynamic_linker", enabled = True),
feature(name = "pic", enabled = True),
feature(name = "supports_pic", enabled = True),
feature(name = "has_configured_linker_path", enabled = True),
]
else:
fail("Unreachable")
def _impl(ctx):
cpu = ctx.attr.cpu
compiler = ctx.attr.compiler
if (cpu == "darwin"):
toolchain_identifier = "local_darwin"
target_cpu = "darwin"
target_libc = "macosx"
compiler = "compiler"
action_configs = _action_configs(
assembly_path = ctx.attr.host_compiler_path,
c_compiler_path = ctx.attr.host_compiler_path,
cc_compiler_path = ctx.attr.host_compiler_path,
archiver_path = ctx.attr.host_compiler_prefix + "/libtool",
linker_path = ctx.attr.host_compiler_path,
strip_path = ctx.attr.host_compiler_prefix + "/strip",
)
artifact_name_patterns = []
elif (cpu == "local"):
toolchain_identifier = "local_linux"
target_cpu = "local"
target_libc = "local"
action_configs = _action_configs(
assembly_path = ctx.attr.host_compiler_path,
c_compiler_path = ctx.attr.host_compiler_path,
cc_compiler_path = ctx.attr.host_compiler_path,
archiver_path = ctx.attr.host_compiler_prefix + "/ar",
linker_path = ctx.attr.host_compiler_path,
strip_path = ctx.attr.host_compiler_prefix + "/strip",
)
artifact_name_patterns = []
else:
fail("Unreachable")
out = ctx.actions.declare_file(ctx.label.name)
ctx.actions.write(out, "Fake executable")
return [
cc_common.create_cc_toolchain_config_info(
ctx = ctx,
features = _features(cpu, compiler, ctx),
action_configs = action_configs,
artifact_name_patterns = artifact_name_patterns,
cxx_builtin_include_directories = ctx.attr.builtin_include_directories,
toolchain_identifier = toolchain_identifier,
host_system_name = "local",
target_system_name = "local",
target_cpu = target_cpu,
target_libc = target_libc,
compiler = compiler,
abi_version = "local",
abi_libc_version = "local",
tool_paths = _tool_paths(cpu, ctx),
make_variables = [],
builtin_sysroot = ctx.attr.builtin_sysroot,
cc_target_os = None,
),
DefaultInfo(
executable = out,
),
]
cc_toolchain_config = rule(
implementation = _impl,
attrs = {
"cpu": attr.string(mandatory = True, values = ["darwin", "local"]),
"compiler": attr.string(values = ["clang", "gcc", "unknown"], default = "gcc"),
"builtin_include_directories": attr.string_list(),
"extra_no_canonical_prefixes_flags": attr.string_list(),
"host_compiler_path": attr.string(),
"host_compiler_prefix": attr.string(),
"host_compiler_warnings": attr.string_list(),
"host_unfiltered_compile_flags": attr.string_list(),
"linker_bin_path": attr.string(),
"builtin_sysroot": attr.string(),
},
provides = [CcToolchainConfigInfo],
executable = True,
)