mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Pass `-fno-exceptions` when building the toolchain. We do not use
exceptions, so we do not have any try/catch in main, so uncaught
exceptions just unwind and exit. They do not hit our signal handler and
we do not print the stack trace.
Instead of adding a try/catch in main, and redirecting that, we can
build with `-fno-exceptions`. This turns any throw into an `abort()`.
And indeed with that flag, the following code crashes and prints a stack
trace:
```cpp
std::variant<int, bool> a = {1};
std::get<bool>(a);
```
Note that libc++ and libc++abi need to be built with exceptions enabled.
It is explicitly allowed to use different compiler flags when building
these libraries even though they share some headers with users of the
libraries, so this does not cause ODR violations.
Fixes #5225
304 lines
11 KiB
Python
304 lines
11 KiB
Python
# 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
|
|
|
|
"""Definitions of general C++ `cc_toolchain_config` features."""
|
|
|
|
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES", "ACTION_NAME_GROUPS")
|
|
load(
|
|
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
|
|
"feature",
|
|
"flag_group",
|
|
"flag_set",
|
|
"with_feature_set",
|
|
)
|
|
load(
|
|
":cc_toolchain_actions.bzl",
|
|
"preprocessor_compile_actions",
|
|
)
|
|
|
|
clang_feature = feature(
|
|
name = "clang",
|
|
enabled = True,
|
|
flag_sets = [
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_compile_actions + ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [
|
|
flag_group(flags = [
|
|
"-no-canonical-prefixes",
|
|
"-fcolor-diagnostics",
|
|
]),
|
|
flag_group(
|
|
expand_if_available = "sysroot",
|
|
flags = ["--sysroot=%{sysroot}"],
|
|
),
|
|
],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_compile_actions,
|
|
flag_groups = [
|
|
flag_group(flags = [
|
|
# Compile actions shouldn't link anything.
|
|
"-c",
|
|
]),
|
|
|
|
# Flags controlling the production of specific outputs from
|
|
# compile actions.
|
|
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 = "dependency_file",
|
|
flags = ["-MD", "-MF", "%{dependency_file}"],
|
|
),
|
|
flag_group(
|
|
expand_if_available = "output_file",
|
|
flags = ["-frandom-seed=%{output_file}"],
|
|
),
|
|
],
|
|
),
|
|
flag_set(
|
|
# Flags specific to compiling C++ sources.
|
|
actions = ACTION_NAME_GROUPS.all_cpp_compile_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
"-fno-exceptions",
|
|
"-std=c++20",
|
|
])],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_compile_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
"-ffunction-sections",
|
|
"-fdata-sections",
|
|
])],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_compile_actions,
|
|
flag_groups = [flag_group(
|
|
expand_if_available = "pic",
|
|
flags = ["-fPIC"],
|
|
)],
|
|
),
|
|
flag_set(
|
|
actions = preprocessor_compile_actions,
|
|
flag_groups = [
|
|
flag_group(flags = [
|
|
# Disable a warning and override builtin macros to
|
|
# ensure a hermetic build.
|
|
"-Wno-builtin-macro-redefined",
|
|
"-D__DATE__=\"redacted\"",
|
|
"-D__TIMESTAMP__=\"redacted\"",
|
|
"-D__TIME__=\"redacted\"",
|
|
]),
|
|
flag_group(
|
|
flags = ["-D%{preprocessor_defines}"],
|
|
iterate_over = "preprocessor_defines",
|
|
),
|
|
flag_group(
|
|
expand_if_available = "includes",
|
|
flags = ["-include", "%{includes}"],
|
|
iterate_over = "includes",
|
|
),
|
|
flag_group(
|
|
flags = ["-iquote", "%{quote_include_paths}"],
|
|
iterate_over = "quote_include_paths",
|
|
),
|
|
flag_group(
|
|
flags = ["-I%{include_paths}"],
|
|
iterate_over = "include_paths",
|
|
),
|
|
flag_group(
|
|
flags = ["-isystem", "%{system_include_paths}"],
|
|
iterate_over = "system_include_paths",
|
|
),
|
|
],
|
|
),
|
|
flag_set(
|
|
actions = [
|
|
ACTION_NAMES.cpp_link_dynamic_library,
|
|
ACTION_NAMES.cpp_link_nodeps_dynamic_library,
|
|
],
|
|
flag_groups = [flag_group(flags = ["-shared"])],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [
|
|
flag_group(
|
|
expand_if_available = "strip_debug_symbols",
|
|
flags = ["-Wl,-S"],
|
|
),
|
|
flag_group(
|
|
expand_if_available = "library_search_directories",
|
|
flags = ["-L%{library_search_directories}"],
|
|
iterate_over = "library_search_directories",
|
|
),
|
|
flag_group(
|
|
expand_if_available =
|
|
"runtime_library_search_directories",
|
|
iterate_over = "runtime_library_search_directories",
|
|
flags = [
|
|
"-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}",
|
|
],
|
|
),
|
|
],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [
|
|
flag_group(
|
|
flags = [
|
|
"-fuse-ld=lld",
|
|
# Force the C++ standard library and runtime libraries
|
|
# to be statically linked. This works even with libc++
|
|
# and libunwind despite the names, provided libc++ is
|
|
# built with the CMake option:
|
|
# - `-DCMAKE_POSITION_INDEPENDENT_CODE=ON`
|
|
"-static-libstdc++",
|
|
"-static-libgcc",
|
|
# Link with Clang's runtime library. This is always
|
|
# linked statically.
|
|
"-rtlib=compiler-rt",
|
|
# Link with pthread.
|
|
"-lpthread",
|
|
],
|
|
),
|
|
],
|
|
with_features = [with_feature_set(["linux_target"])],
|
|
),
|
|
flag_set(
|
|
actions = [ACTION_NAMES.cpp_link_executable],
|
|
flag_groups = [flag_group(
|
|
expand_if_available = "force_pic",
|
|
flags = ["-pie"],
|
|
)],
|
|
with_features = [with_feature_set([
|
|
"linux_target",
|
|
"freebsd_target",
|
|
])],
|
|
),
|
|
flag_set(
|
|
actions = [ACTION_NAMES.cpp_link_executable],
|
|
flag_groups = [flag_group(
|
|
expand_if_available = "force_pic",
|
|
flags = ["-fpie"],
|
|
)],
|
|
with_features = [with_feature_set(["macos_target"])],
|
|
),
|
|
],
|
|
)
|
|
|
|
clang_warnings_feature = feature(
|
|
name = "clang_warnings",
|
|
enabled = True,
|
|
flag_sets = [flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_compile_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
"-Werror",
|
|
"-Wall",
|
|
"-Wextra",
|
|
"-Wthread-safety",
|
|
"-Wself-assign",
|
|
"-Wimplicit-fallthrough",
|
|
"-Wctad-maybe-unsupported",
|
|
"-Wextra-semi",
|
|
"-Wmissing-prototypes",
|
|
"-Wzero-as-null-pointer-constant",
|
|
"-Wdelete-non-virtual-dtor",
|
|
|
|
# TODO: Regression that warns on anonymous unions; remove depending
|
|
# on fix.
|
|
"-Wno-missing-designated-field-initializers",
|
|
])],
|
|
)],
|
|
)
|
|
|
|
# Libc++ HARDENING_MODE has 4 possible values:
|
|
# https://libcxx.llvm.org/Hardening.html#notes-for-users
|
|
#
|
|
# Do not enable DEBUG hardening mode, even for -c dbg, because its performance
|
|
# impact on llvm-symbolizer is too severe -- this flag results in symbolization
|
|
# becoming quadratic in the number of debug symbols, in practice meaning it
|
|
# never completes.
|
|
_libcpp_debug_flags = [
|
|
"-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE",
|
|
]
|
|
_libcpp_release_flags = [
|
|
"-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST",
|
|
]
|
|
|
|
def libcxx_feature(llvm_bindir = None, clang_bindir = None):
|
|
"""Builds a libc++ feature.
|
|
|
|
Returns:
|
|
The feature for use with `cc_toolchain_config`.
|
|
|
|
Args:
|
|
llvm_bindir: Optional LLVM installation `bin` directory, causes the
|
|
feature to look for adjacent installed libraries.
|
|
clang_bindir: Optional Clang installation `bin` directory, causes the
|
|
feature to look for adjacent installed libraries if different from
|
|
`llvm_bindir`.
|
|
"""
|
|
|
|
# Explicitly add LLVM libs to the search path to preempt the
|
|
# detected GCC installation's library paths. Those might have a
|
|
# system installed libc++ and we want to find the one next to
|
|
# our Clang.
|
|
extra_link_flags = []
|
|
if llvm_bindir:
|
|
extra_link_flags.append("-L" + llvm_bindir + "/../lib")
|
|
if clang_bindir and clang_bindir != llvm_bindir:
|
|
extra_link_flags.append("-L" + clang_bindir + "/../lib")
|
|
|
|
return feature(
|
|
name = "libcxx",
|
|
enabled = True,
|
|
flag_sets = [
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cpp_compile_actions + ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
"-stdlib=libc++",
|
|
])],
|
|
with_features = [
|
|
# libc++ is only used on non-Windows platforms.
|
|
with_feature_set(not_features = ["windows_target"]),
|
|
],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cpp_compile_actions,
|
|
flag_groups = [flag_group(flags = _libcpp_debug_flags)],
|
|
with_features = [with_feature_set(not_features = ["opt"])],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cpp_compile_actions,
|
|
flag_groups = [flag_group(flags = _libcpp_release_flags)],
|
|
with_features = [with_feature_set(features = ["opt"])],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [flag_group(flags = [
|
|
"-unwindlib=libunwind",
|
|
])],
|
|
with_features = [
|
|
# libc++ is only used on non-Windows platforms.
|
|
with_feature_set(not_features = ["windows_target"]),
|
|
],
|
|
),
|
|
flag_set(
|
|
actions = ACTION_NAME_GROUPS.all_cc_link_actions,
|
|
flag_groups = [flag_group(flags = extra_link_flags + [
|
|
# Force linking the static libc++abi archive here. This
|
|
# *should* be linked automatically, but not every release of
|
|
# LLVM correctly sets the CMake flags to do so.
|
|
"-l:libc++abi.a",
|
|
])],
|
|
with_features = [with_feature_set(["linux_target"])],
|
|
),
|
|
],
|
|
)
|