|
|
@@ -7,18 +7,53 @@
|
|
|
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
|
|
|
load(
|
|
|
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
|
|
|
- "action_config",
|
|
|
"feature",
|
|
|
"feature_set",
|
|
|
"flag_group",
|
|
|
"flag_set",
|
|
|
- "tool",
|
|
|
- "tool_path",
|
|
|
- "variable_with_value",
|
|
|
"with_feature_set",
|
|
|
)
|
|
|
load("@rules_cc//cc:defs.bzl", "cc_toolchain")
|
|
|
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
|
|
|
+load(
|
|
|
+ ":cc_toolchain_actions.bzl",
|
|
|
+ "all_compile_actions",
|
|
|
+ "all_cpp_compile_actions",
|
|
|
+ "all_link_actions",
|
|
|
+ "codegen_compile_actions",
|
|
|
+ "preprocessor_compile_actions",
|
|
|
+)
|
|
|
+load(
|
|
|
+ ":cc_toolchain_base_features.bzl",
|
|
|
+ "base_features",
|
|
|
+ "output_flags_feature",
|
|
|
+ "user_flags_feature",
|
|
|
+)
|
|
|
+load(":cc_toolchain_debugging.bzl", "debugging_features")
|
|
|
+load(
|
|
|
+ ":cc_toolchain_linking.bzl",
|
|
|
+ "default_link_libraries_feature",
|
|
|
+ "linking_features",
|
|
|
+ "macos_link_libraries_feature",
|
|
|
+)
|
|
|
+load(":cc_toolchain_modules.bzl", "modules_features")
|
|
|
+load(
|
|
|
+ ":cc_toolchain_optimization.bzl",
|
|
|
+ "aarch64_cpu_flags",
|
|
|
+ "optimization_features",
|
|
|
+ "x86_64_cpu_flags",
|
|
|
+)
|
|
|
+load(
|
|
|
+ ":cc_toolchain_sanitizer_features.bzl",
|
|
|
+ "macos_asan_workarounds",
|
|
|
+ "sanitizer_features",
|
|
|
+ "sanitizer_static_lib_flags",
|
|
|
+)
|
|
|
+load(
|
|
|
+ ":cc_toolchain_tools.bzl",
|
|
|
+ "llvm_action_configs",
|
|
|
+ "llvm_tool_paths",
|
|
|
+)
|
|
|
load(
|
|
|
":clang_detected_variables.bzl",
|
|
|
"clang_bindir",
|
|
|
@@ -30,97 +65,7 @@ load(
|
|
|
"sysroot_dir",
|
|
|
)
|
|
|
|
|
|
-all_c_compile_actions = [
|
|
|
- ACTION_NAMES.c_compile,
|
|
|
- ACTION_NAMES.assemble,
|
|
|
- ACTION_NAMES.preprocess_assemble,
|
|
|
-]
|
|
|
-
|
|
|
-all_cpp_compile_actions = [
|
|
|
- ACTION_NAMES.cpp_compile,
|
|
|
- ACTION_NAMES.linkstamp_compile,
|
|
|
- ACTION_NAMES.cpp_header_parsing,
|
|
|
- ACTION_NAMES.cpp_module_compile,
|
|
|
- ACTION_NAMES.cpp_module_codegen,
|
|
|
-]
|
|
|
-
|
|
|
-all_compile_actions = all_c_compile_actions + all_cpp_compile_actions
|
|
|
-
|
|
|
-preprocessor_compile_actions = [
|
|
|
- ACTION_NAMES.c_compile,
|
|
|
- ACTION_NAMES.cpp_compile,
|
|
|
- ACTION_NAMES.linkstamp_compile,
|
|
|
- ACTION_NAMES.preprocess_assemble,
|
|
|
- ACTION_NAMES.cpp_header_parsing,
|
|
|
- ACTION_NAMES.cpp_module_compile,
|
|
|
-]
|
|
|
-
|
|
|
-codegen_compile_actions = [
|
|
|
- ACTION_NAMES.c_compile,
|
|
|
- ACTION_NAMES.cpp_compile,
|
|
|
- ACTION_NAMES.linkstamp_compile,
|
|
|
- ACTION_NAMES.assemble,
|
|
|
- ACTION_NAMES.preprocess_assemble,
|
|
|
- ACTION_NAMES.cpp_module_codegen,
|
|
|
-]
|
|
|
-
|
|
|
-all_link_actions = [
|
|
|
- ACTION_NAMES.cpp_link_executable,
|
|
|
- ACTION_NAMES.cpp_link_dynamic_library,
|
|
|
- ACTION_NAMES.cpp_link_nodeps_dynamic_library,
|
|
|
-]
|
|
|
-
|
|
|
-def _impl(ctx):
|
|
|
- tool_paths = [
|
|
|
- tool_path(name = "ar", path = llvm_bindir + "/llvm-ar"),
|
|
|
- tool_path(name = "ld", path = clang_bindir + "/ld.lld"),
|
|
|
- tool_path(name = "cpp", path = clang_bindir + "/clang-cpp"),
|
|
|
- tool_path(name = "gcc", path = clang_bindir + "/clang++"),
|
|
|
- tool_path(name = "dwp", path = llvm_bindir + "/llvm-dwp"),
|
|
|
- tool_path(name = "gcov", path = llvm_bindir + "/llvm-cov"),
|
|
|
- tool_path(name = "nm", path = llvm_bindir + "/llvm-nm"),
|
|
|
- tool_path(name = "objcopy", path = llvm_bindir + "/llvm-objcopy"),
|
|
|
- tool_path(name = "objdump", path = llvm_bindir + "/llvm-objdump"),
|
|
|
- tool_path(name = "strip", path = llvm_bindir + "/llvm-strip"),
|
|
|
- ]
|
|
|
-
|
|
|
- action_configs = [
|
|
|
- action_config(
|
|
|
- action_name = name,
|
|
|
- enabled = True,
|
|
|
- tools = [tool(path = clang_bindir + "/clang")],
|
|
|
- )
|
|
|
- for name in all_c_compile_actions
|
|
|
- ] + [
|
|
|
- action_config(
|
|
|
- action_name = name,
|
|
|
- enabled = True,
|
|
|
- tools = [tool(path = clang_bindir + "/clang++")],
|
|
|
- )
|
|
|
- for name in all_cpp_compile_actions
|
|
|
- ] + [
|
|
|
- action_config(
|
|
|
- action_name = name,
|
|
|
- enabled = True,
|
|
|
- tools = [tool(path = clang_bindir + "/clang++")],
|
|
|
- )
|
|
|
- for name in all_link_actions
|
|
|
- ] + [
|
|
|
- action_config(
|
|
|
- action_name = name,
|
|
|
- enabled = True,
|
|
|
- tools = [tool(path = llvm_bindir + "/llvm-ar")],
|
|
|
- )
|
|
|
- for name in [ACTION_NAMES.cpp_link_static_library]
|
|
|
- ] + [
|
|
|
- action_config(
|
|
|
- action_name = name,
|
|
|
- enabled = True,
|
|
|
- tools = [tool(path = llvm_bindir + "/llvm-strip")],
|
|
|
- )
|
|
|
- for name in [ACTION_NAMES.strip]
|
|
|
- ]
|
|
|
-
|
|
|
+def _build_features(ctx):
|
|
|
std_compile_flags = ["-std=c++20"]
|
|
|
|
|
|
# libc++ is only used on non-Windows platforms.
|
|
|
@@ -137,16 +82,23 @@ def _impl(ctx):
|
|
|
else:
|
|
|
missing_field_init_flags = []
|
|
|
|
|
|
+ # TODO: Refactor this into a reusable form in its own file.
|
|
|
default_flags_feature = feature(
|
|
|
name = "default_flags",
|
|
|
enabled = True,
|
|
|
flag_sets = [
|
|
|
flag_set(
|
|
|
actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-no-canonical-prefixes",
|
|
|
- "-fcolor-diagnostics",
|
|
|
- ])],
|
|
|
+ flag_groups = [
|
|
|
+ flag_group(flags = [
|
|
|
+ "-no-canonical-prefixes",
|
|
|
+ "-fcolor-diagnostics",
|
|
|
+ ]),
|
|
|
+ flag_group(
|
|
|
+ expand_if_available = "sysroot",
|
|
|
+ flags = ["--sysroot=%{sysroot}"],
|
|
|
+ ),
|
|
|
+ ],
|
|
|
),
|
|
|
flag_set(
|
|
|
actions = all_compile_actions,
|
|
|
@@ -293,295 +245,6 @@ def _impl(ctx):
|
|
|
],
|
|
|
)
|
|
|
|
|
|
- # Handle different levels of optimization with individual features so that
|
|
|
- # they can be ordered and the defaults can override the minimal settings if
|
|
|
- # both are enabled.
|
|
|
- minimal_optimization_flags = feature(
|
|
|
- name = "minimal_optimization_flags",
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-O1"])],
|
|
|
- )],
|
|
|
- )
|
|
|
- default_optimization_flags = feature(
|
|
|
- name = "default_optimization_flags",
|
|
|
- enabled = True,
|
|
|
- requires = [feature_set(["opt"])],
|
|
|
- flag_sets = [
|
|
|
- flag_set(
|
|
|
- actions = all_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-DNDEBUG"])],
|
|
|
- ),
|
|
|
- flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-O3"])],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
-
|
|
|
- x86_64_cpu_flags = feature(
|
|
|
- name = "x86_64_cpu_flags",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-march=x86-64-v2"])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- aarch64_cpu_flags = feature(
|
|
|
- name = "aarch64_cpu_flags",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-march=armv8.2-a"])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- # Handle different levels and forms of debug info emission with individual
|
|
|
- # features so that they can be ordered and the defaults can override the
|
|
|
- # minimal settings if both are enabled.
|
|
|
- minimal_debug_info_flags = feature(
|
|
|
- name = "minimal_debug_info_flags",
|
|
|
- implies = ["debug_info_compression_flags"],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-gmlt"])],
|
|
|
- )],
|
|
|
- )
|
|
|
- debug_info_flags = feature(
|
|
|
- name = "debug_info_flags",
|
|
|
- implies = ["debug_info_compression_flags"],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [
|
|
|
- flag_group(flags = ["-g"]),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "per_object_debug_info_file",
|
|
|
- flags = ["-gsplit-dwarf"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )],
|
|
|
- )
|
|
|
- debug_info_compression_flags = feature(
|
|
|
- name = "debug_info_compression_flags",
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-gz"])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- # Define a set of mutually exclusive debugger flags.
|
|
|
- debugger_flags = feature(name = "debugger_flags")
|
|
|
- lldb_flags = feature(
|
|
|
- # Use a convenient name for users to select if needed.
|
|
|
- name = "lldb_flags",
|
|
|
- # Default enable LLDB-optimized flags whenever debugging.
|
|
|
- enabled = True,
|
|
|
- requires = [feature_set(features = ["debug_info_flags"])],
|
|
|
- provides = ["debugger_flags"],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-glldb",
|
|
|
- "-gpubnames",
|
|
|
- "-gsimple-template-names",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
- gdb_flags = feature(
|
|
|
- # Use a convenient name for users to select if needed.
|
|
|
- name = "gdb_flags",
|
|
|
- requires = [feature_set(features = ["debug_info_flags"])],
|
|
|
- provides = ["debugger_flags"],
|
|
|
- flag_sets = [
|
|
|
- flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-ggdb",
|
|
|
- "-ggnu-pubnames",
|
|
|
- ])],
|
|
|
- ),
|
|
|
- flag_set(
|
|
|
- actions = all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-Wl,--gdb-index"])],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
-
|
|
|
- # An enabled feature that requires the `dbg` compilation mode. This is used
|
|
|
- # to toggle on more general features to use by default, while allowing those
|
|
|
- # general features to be explicitly enabled where needed.
|
|
|
- enable_in_dbg = feature(
|
|
|
- name = "enable_in_dbg",
|
|
|
- enabled = True,
|
|
|
- requires = [feature_set(["dbg"])],
|
|
|
- implies = ["debug_info_flags"],
|
|
|
- )
|
|
|
-
|
|
|
- # This feature can be enabled in conjunction with any optimizations to
|
|
|
- # ensure accurate call stacks and backtraces for profilers or errors.
|
|
|
- preserve_call_stacks = feature(
|
|
|
- name = "preserve_call_stacks",
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = codegen_compile_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- # Ensure good backtraces by preserving frame pointers and
|
|
|
- # disabling tail call elimination.
|
|
|
- "-fno-omit-frame-pointer",
|
|
|
- "-mno-omit-leaf-frame-pointer",
|
|
|
- "-fno-optimize-sibling-calls",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- sysroot_feature = feature(
|
|
|
- name = "sysroot",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(
|
|
|
- expand_if_available = "sysroot",
|
|
|
- flags = ["--sysroot=%{sysroot}"],
|
|
|
- )],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- use_module_maps = feature(
|
|
|
- name = "use_module_maps",
|
|
|
- requires = [feature_set(features = ["module_maps"])],
|
|
|
- flag_sets = [
|
|
|
- flag_set(
|
|
|
- actions = [
|
|
|
- ACTION_NAMES.c_compile,
|
|
|
- ACTION_NAMES.cpp_compile,
|
|
|
- ACTION_NAMES.cpp_header_parsing,
|
|
|
- ACTION_NAMES.cpp_module_compile,
|
|
|
- ],
|
|
|
- flag_groups = [
|
|
|
- # These flag groups are separate so they do not expand to
|
|
|
- # the cross product of the variables.
|
|
|
- flag_group(flags = ["-fmodule-name=%{module_name}"]),
|
|
|
- flag_group(
|
|
|
- flags = ["-fmodule-map-file=%{module_map_file}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
-
|
|
|
- # Tell bazel we support module maps in general, so they will be generated
|
|
|
- # for all c/c++ rules.
|
|
|
- # Note: not all C++ rules support module maps; thus, do not imply this
|
|
|
- # feature from other features - instead, require it.
|
|
|
- module_maps = feature(
|
|
|
- name = "module_maps",
|
|
|
- enabled = True,
|
|
|
- implies = [
|
|
|
- # "module_map_home_cwd",
|
|
|
- # "module_map_without_extern_module",
|
|
|
- # "generate_submodules",
|
|
|
- ],
|
|
|
- )
|
|
|
-
|
|
|
- layering_check = feature(
|
|
|
- name = "layering_check",
|
|
|
- implies = ["use_module_maps"],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = [
|
|
|
- ACTION_NAMES.c_compile,
|
|
|
- ACTION_NAMES.cpp_compile,
|
|
|
- ACTION_NAMES.cpp_header_parsing,
|
|
|
- ACTION_NAMES.cpp_module_compile,
|
|
|
- ],
|
|
|
- flag_groups = [
|
|
|
- flag_group(flags = [
|
|
|
- "-fmodules-strict-decluse",
|
|
|
- "-Wprivate-header",
|
|
|
- ]),
|
|
|
- flag_group(
|
|
|
- iterate_over = "dependent_module_map_files",
|
|
|
- flags = ["-fmodule-map-file=%{dependent_module_map_files}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- sanitizer_common_flags = feature(
|
|
|
- name = "sanitizer_common_flags",
|
|
|
- implies = ["minimal_debug_info_flags", "preserve_call_stacks"],
|
|
|
- )
|
|
|
-
|
|
|
- # Separated from the feature above so it can only be included on platforms
|
|
|
- # where it is supported. There is no negative flag in Clang so we can't just
|
|
|
- # override it later.
|
|
|
- sanitizer_static_lib_flags = feature(
|
|
|
- name = "sanitizer_static_lib_flags",
|
|
|
- enabled = True,
|
|
|
- requires = [feature_set(["sanitizer_common_flags"])],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = ["-static-libsan"])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- asan = feature(
|
|
|
- name = "asan",
|
|
|
- implies = ["sanitizer_common_flags"],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-fsanitize=address,undefined,nullability",
|
|
|
- "-fsanitize-address-use-after-scope",
|
|
|
- # Outlining is almost always the right tradeoff for our
|
|
|
- # sanitizer usage where we're more pressured on generated code
|
|
|
- # size than runtime performance.
|
|
|
- "-fsanitize-address-outline-instrumentation",
|
|
|
- # We don't need the recovery behavior of UBSan as we expect
|
|
|
- # builds to be clean. Not recovering is a bit cheaper.
|
|
|
- "-fno-sanitize-recover=undefined,nullability",
|
|
|
- # Don't embed the full path name for files. This limits the size
|
|
|
- # and combined with line numbers is unlikely to result in many
|
|
|
- # ambiguities.
|
|
|
- "-fsanitize-undefined-strip-path-components=-1",
|
|
|
- # Needed due to clang AST issues, such as in
|
|
|
- # clang/AST/Redeclarable.h line 199.
|
|
|
- "-fno-sanitize=vptr",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- # A feature that further reduces the generated code size of our the ASan
|
|
|
- # feature, but at the cost of lower quality diagnostics. This is enabled
|
|
|
- # along with ASan in our fastbuild configuration, but can be disabled
|
|
|
- # explicitly to get better error messages.
|
|
|
- asan_min_size = feature(
|
|
|
- name = "asan_min_size",
|
|
|
- requires = [feature_set(["asan"])],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- # Force two UBSan checks that have especially large code size
|
|
|
- # cost to use the minimal branch to a trapping instruction model
|
|
|
- # instead of the full diagnostic.
|
|
|
- "-fsanitize-trap=alignment,null",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- # Likely due to being unable to use the static-linked and up-to-date
|
|
|
- # sanitizer runtimes, we have to disable a number of sanitizers on macOS.
|
|
|
- macos_asan_workarounds = feature(
|
|
|
- name = "macos_sanitizer_workarounds",
|
|
|
- enabled = True,
|
|
|
- requires = [feature_set(["asan"])],
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-fno-sanitize=function",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
# An enabled feature that requires the `fastbuild` compilation. This is used
|
|
|
# to toggle general features on by default, while allowing them to be
|
|
|
# directly enabled and disabled more generally as desired.
|
|
|
@@ -597,16 +260,6 @@ def _impl(ctx):
|
|
|
],
|
|
|
)
|
|
|
|
|
|
- fuzzer = feature(
|
|
|
- name = "fuzzer",
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_compile_actions + all_link_actions,
|
|
|
- flag_groups = [flag_group(flags = [
|
|
|
- "-fsanitize=fuzzer-no-link",
|
|
|
- ])],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
# Clang HARDENING_MODE has 4 possible values:
|
|
|
# https://libcxx.llvm.org/Hardening.html#notes-for-users
|
|
|
#
|
|
|
@@ -621,6 +274,7 @@ def _impl(ctx):
|
|
|
"-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST",
|
|
|
]
|
|
|
|
|
|
+ # TODO: Refactor this into a reusable form in its own file.
|
|
|
linux_flags_feature = feature(
|
|
|
name = "linux_flags",
|
|
|
enabled = True,
|
|
|
@@ -677,6 +331,7 @@ def _impl(ctx):
|
|
|
],
|
|
|
)
|
|
|
|
|
|
+ # TODO: Refactor this into a reusable form in its own file.
|
|
|
macos_flags_feature = feature(
|
|
|
name = "macos_flags",
|
|
|
enabled = True,
|
|
|
@@ -691,6 +346,7 @@ def _impl(ctx):
|
|
|
],
|
|
|
)
|
|
|
|
|
|
+ # TODO: Refactor this into a reusable form in its own file.
|
|
|
freebsd_flags_feature = feature(
|
|
|
name = "freebsd_flags",
|
|
|
enabled = True,
|
|
|
@@ -714,367 +370,26 @@ def _impl(ctx):
|
|
|
],
|
|
|
)
|
|
|
|
|
|
- default_link_libraries_feature = feature(
|
|
|
- name = "default_link_libraries",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_link_actions,
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_available = "linkstamp_paths",
|
|
|
- flags = ["%{linkstamp_paths}"],
|
|
|
- iterate_over = "linkstamp_paths",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "libraries_to_link",
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["-Wl,--start-lib"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-whole-archive"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.object_files}"],
|
|
|
- iterate_over = "libraries_to_link.object_files",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "interface_library",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "static_library",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "dynamic_library",
|
|
|
- ),
|
|
|
- flags = ["-l%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "versioned_dynamic_library",
|
|
|
- ),
|
|
|
- flags = ["-l:%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-no-whole-archive"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["-Wl,--end-lib"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- iterate_over = "libraries_to_link",
|
|
|
- ),
|
|
|
- # Note that the params file comes at the end, after the
|
|
|
- # libraries to link above.
|
|
|
- flag_group(
|
|
|
- expand_if_available = "linker_param_file",
|
|
|
- flags = ["@%{linker_param_file}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- macos_link_libraries_feature = feature(
|
|
|
- name = "macos_link_libraries",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = all_link_actions,
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_available = "linkstamp_paths",
|
|
|
- flags = ["%{linkstamp_paths}"],
|
|
|
- iterate_over = "linkstamp_paths",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "libraries_to_link",
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["-Wl,--start-lib"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_false = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["%{libraries_to_link.object_files}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-force_load,%{libraries_to_link.object_files}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- iterate_over = "libraries_to_link.object_files",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file",
|
|
|
- ),
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_false = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-force_load,%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "interface_library",
|
|
|
- ),
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_false = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-force_load,%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "static_library",
|
|
|
- ),
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_false = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flags = ["-Wl,-force_load,%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "dynamic_library",
|
|
|
- ),
|
|
|
- flags = ["-l%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "versioned_dynamic_library",
|
|
|
- ),
|
|
|
- flags = ["-l:%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_true = "libraries_to_link.is_whole_archive",
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_false = "macos_flags",
|
|
|
- flags = ["-Wl,-no-whole-archive"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["-Wl,--end-lib"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- iterate_over = "libraries_to_link",
|
|
|
- ),
|
|
|
- # Note that the params file comes at the end, after the
|
|
|
- # libraries to link above.
|
|
|
- flag_group(
|
|
|
- expand_if_available = "linker_param_file",
|
|
|
- flags = ["@%{linker_param_file}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )],
|
|
|
- )
|
|
|
-
|
|
|
- # Place user provided compile flags after all the features so that these
|
|
|
- # flags can override or customize behavior. The only thing user flags
|
|
|
- # cannot override is the output file as Bazel depends on that.
|
|
|
- #
|
|
|
- # Finally, place the source file (if present) and output file last to make
|
|
|
- # reading the compile command lines easier for humans.
|
|
|
- final_flags_feature = feature(
|
|
|
- name = "final_flags",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [
|
|
|
- flag_set(
|
|
|
- actions = all_compile_actions,
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_available = "user_compile_flags",
|
|
|
- flags = ["%{user_compile_flags}"],
|
|
|
- iterate_over = "user_compile_flags",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "source_file",
|
|
|
- flags = ["%{source_file}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "output_file",
|
|
|
- flags = ["-o", "%{output_file}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- flag_set(
|
|
|
- actions = all_link_actions,
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_available = "user_link_flags",
|
|
|
- flags = ["%{user_link_flags}"],
|
|
|
- iterate_over = "user_link_flags",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "output_execpath",
|
|
|
- flags = ["-o", "%{output_execpath}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )
|
|
|
-
|
|
|
- # Archive actions have an entirely independent set of flags and don't
|
|
|
- # interact with either compiler or link actions.
|
|
|
- default_archiver_flags_feature = feature(
|
|
|
- name = "default_archiver_flags",
|
|
|
- enabled = True,
|
|
|
- flag_sets = [flag_set(
|
|
|
- actions = [ACTION_NAMES.cpp_link_static_library],
|
|
|
- flag_groups = [
|
|
|
- flag_group(flags = ["rcsD"]),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "output_execpath",
|
|
|
- flags = ["%{output_execpath}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "libraries_to_link",
|
|
|
- flag_groups = [
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.name}"],
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_equal = variable_with_value(
|
|
|
- name = "libraries_to_link.type",
|
|
|
- value = "object_file_group",
|
|
|
- ),
|
|
|
- flags = ["%{libraries_to_link.object_files}"],
|
|
|
- iterate_over = "libraries_to_link.object_files",
|
|
|
- ),
|
|
|
- ],
|
|
|
- iterate_over = "libraries_to_link",
|
|
|
- ),
|
|
|
- flag_group(
|
|
|
- expand_if_available = "linker_param_file",
|
|
|
- flags = ["@%{linker_param_file}"],
|
|
|
- ),
|
|
|
- ],
|
|
|
- )],
|
|
|
- )
|
|
|
+ # The order of the features determines the relative order of flags used.
|
|
|
+ features = []
|
|
|
+ features += base_features
|
|
|
+ features.append(default_flags_feature)
|
|
|
+ features += sanitizer_features
|
|
|
|
|
|
- # Now that we have built up the constituent feature definitions, compose
|
|
|
- # them, including configuration based on the target platform.
|
|
|
+ features += optimization_features
|
|
|
|
|
|
- # First, define features that are simply used to configure others.
|
|
|
- features = [
|
|
|
- feature(name = "dbg"),
|
|
|
- feature(name = "fastbuild"),
|
|
|
- feature(name = "host"),
|
|
|
- feature(name = "no_legacy_features"),
|
|
|
- feature(name = "opt"),
|
|
|
- feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_os == "linux"),
|
|
|
- feature(name = "supports_pic", enabled = True),
|
|
|
- feature(name = "supports_start_end_lib", enabled = ctx.attr.target_os == "linux"),
|
|
|
+ # TODO: Refactor target-specific feature management to be part of
|
|
|
+ # `optimization_features`.
|
|
|
+ if ctx.attr.target_cpu in ["aarch64", "arm64"]:
|
|
|
+ features.append(aarch64_cpu_flags)
|
|
|
+ else:
|
|
|
+ features.append(x86_64_cpu_flags)
|
|
|
|
|
|
- # Enable split debug info whenever debug info is requested.
|
|
|
- feature(
|
|
|
- name = "per_object_debug_info",
|
|
|
- enabled = True,
|
|
|
- # This has to be directly conditioned on requesting debug info at
|
|
|
- # all, otherwise Bazel will look for an extra output file and not
|
|
|
- # find one.
|
|
|
- requires = [feature_set(features = ["debug_info_flags"])],
|
|
|
- ),
|
|
|
- ]
|
|
|
-
|
|
|
- # The order of the features determines the relative order of flags used.
|
|
|
- # Start off adding the baseline features.
|
|
|
- features += [
|
|
|
- default_flags_feature,
|
|
|
- minimal_optimization_flags,
|
|
|
- default_optimization_flags,
|
|
|
- minimal_debug_info_flags,
|
|
|
- debug_info_flags,
|
|
|
- debug_info_compression_flags,
|
|
|
- debugger_flags,
|
|
|
- lldb_flags,
|
|
|
- gdb_flags,
|
|
|
- enable_in_dbg,
|
|
|
- preserve_call_stacks,
|
|
|
- sysroot_feature,
|
|
|
- sanitizer_common_flags,
|
|
|
- asan,
|
|
|
- asan_min_size,
|
|
|
- enable_in_fastbuild,
|
|
|
- fuzzer,
|
|
|
- layering_check,
|
|
|
- module_maps,
|
|
|
- use_module_maps,
|
|
|
- default_archiver_flags_feature,
|
|
|
- ]
|
|
|
+ features += modules_features
|
|
|
+ features += debugging_features
|
|
|
|
|
|
# Next, add the features based on the target platform. Here too the
|
|
|
- # features are order sensitive. We also setup the sysroot here.
|
|
|
+ # features are order sensitive.
|
|
|
if ctx.attr.target_os == "linux":
|
|
|
features.append(sanitizer_static_lib_flags)
|
|
|
features.append(linux_flags_feature)
|
|
|
@@ -1095,23 +410,47 @@ def _impl(ctx):
|
|
|
else:
|
|
|
fail("Unsupported target OS!")
|
|
|
|
|
|
- if ctx.attr.target_cpu in ["aarch64", "arm64"]:
|
|
|
- features.append(aarch64_cpu_flags)
|
|
|
- else:
|
|
|
- features.append(x86_64_cpu_flags)
|
|
|
+ # Next, append the libraries to link.
|
|
|
+ features += linking_features
|
|
|
|
|
|
- # Finally append the libraries to link and any final flags.
|
|
|
+ # TODO: Refactor the target-specific feature management here to be part of
|
|
|
+ # building `linking_features`.
|
|
|
+ features += [
|
|
|
+ feature(name = "supports_dynamic_linker", enabled = ctx.attr.target_os == "linux"),
|
|
|
+ feature(name = "supports_start_end_lib", enabled = ctx.attr.target_os == "linux"),
|
|
|
+ ]
|
|
|
if ctx.attr.target_os == "macos":
|
|
|
features.append(macos_link_libraries_feature)
|
|
|
else:
|
|
|
features.append(default_link_libraries_feature)
|
|
|
- features.append(final_flags_feature)
|
|
|
+
|
|
|
+ # Lastly, we add a feature that enables others in the default `fastbuild`
|
|
|
+ # mode. This is also a good place to add any project-specific features.
|
|
|
+ features.append(enable_in_fastbuild)
|
|
|
+
|
|
|
+ # Add user flags and the output flags at the end.
|
|
|
+ features.append(user_flags_feature)
|
|
|
+ features.append(output_flags_feature)
|
|
|
+ return features
|
|
|
+
|
|
|
+def _impl(ctx):
|
|
|
+ # TODO: See if this can be refactored into platform features.
|
|
|
+ if ctx.attr.target_os == "linux":
|
|
|
+ sysroot = None
|
|
|
+ elif ctx.attr.target_os == "windows":
|
|
|
+ sysroot = None
|
|
|
+ elif ctx.attr.target_os == "macos":
|
|
|
+ sysroot = sysroot_dir
|
|
|
+ elif ctx.attr.target_os == "freebsd":
|
|
|
+ sysroot = sysroot_dir
|
|
|
+ else:
|
|
|
+ fail("Unsupported target OS!")
|
|
|
|
|
|
identifier = "local-{0}-{1}".format(ctx.attr.target_cpu, ctx.attr.target_os)
|
|
|
return cc_common.create_cc_toolchain_config_info(
|
|
|
ctx = ctx,
|
|
|
- features = features,
|
|
|
- action_configs = action_configs,
|
|
|
+ features = _build_features(ctx),
|
|
|
+ action_configs = llvm_action_configs(llvm_bindir, clang_bindir),
|
|
|
cxx_builtin_include_directories = clang_include_dirs_list + [
|
|
|
# Add Clang's resource directory to the end of the builtin include
|
|
|
# directories to cover the use of sanitizer resource files by the
|
|
|
@@ -1138,7 +477,7 @@ def _impl(ctx):
|
|
|
abi_libc_version = "local",
|
|
|
|
|
|
# We do have to pass in our tool paths.
|
|
|
- tool_paths = tool_paths,
|
|
|
+ tool_paths = llvm_tool_paths(llvm_bindir, clang_bindir),
|
|
|
)
|
|
|
|
|
|
cc_toolchain_config = rule(
|