# Copyright 2017 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/clang/clang.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/toolchain/rbe.gni")
import("//build_overrides/build.gni")
declare_args() {
# Use in-tree libc++ (buildtools/third_party/libc++ and
# buildtools/third_party/libc++abi) instead of the system C++ library for C++
# standard library support.
#
# WARNING: Bringing your own C++ standard library is deprecated and will not
# be supported in the future. This flag will be removed.
use_custom_libcxx = true
# Use libc++ instead of stdlibc++ when using the host_cpu toolchain, even if
# use_custom_libcxx is false. This is useful for cross-compiles where a custom
# toolchain for the target_cpu has been set as the default toolchain, but
# use_custom_libcxx should still be true when building for the host. The
# expected usage is to set use_custom_libcxx=false and
# use_custom_libcxx_for_host=true in the passed in buildargs.
#
# WARNING: Bringing your own C++ standard library is deprecated and will not
# be supported in the future. This flag will be removed.
use_custom_libcxx_for_host = true
# Builds libcxx Natvis into the symbols for type visualization.
# Set to false to workaround http://crbug.com/966676 and
# http://crbug.com/966687.
libcxx_natvis_include = true
# When set, enables libc++ debug mode with iterator debugging.
#
# Iterator debugging is generally useful for catching bugs. But it can
# introduce extra locking to check the state of an iterator against the state
# of the current object. For iterator- and thread-heavy code, this can
# significantly slow execution - two orders of magnitude slowdown has been
# seen (crbug.com/903553) and iterator debugging also slows builds by making
# generation of snapshot_blob.bin take ~40-60 s longer. Therefore this
# defaults to off.
enable_iterator_debugging = false
# Build atomic support from in-tree compiler-rt.
#
# Apple platforms provide the intrinsics from a different library, and the
# implementations in compiler-rt are outdated, so avoid building them in this
# case.
use_llvm_libatomic = !is_apple
}
use_custom_libcxx =
use_custom_libcxx || (use_custom_libcxx_for_host && !is_a_target_toolchain)
declare_args() {
# WARNING: Setting this to a non-default value is highly discouraged.
# If true, libc++ will be built as a shared library; otherwise libc++ will be
# linked statically. Setting this to something other than the default is
# unsupported and can be broken by libc++ rolls. Note that if this is set to
# true, you must also set libcxx_abi_unstable=false, which is bad for
# performance and memory use.
libcxx_is_shared = use_custom_libcxx && is_component_build
# In case the C++ standard library implementation used is libstdc++, then
# enable its own hardening checks. As we cannot determine in GN if libstdc++
# is used or not, by default enable it for Linux without the custom libc++.
#
# WARNING: Bringing your own C++ standard library is deprecated and will not
# be supported in the future. This flag will be removed.
use_safe_libstdcxx = is_linux && !use_custom_libcxx
# Use explicit Clang header modules for libc++.
# We'll gradually expand supported platform of modules
# (https://crbug.com/40440396).
# For details on the current state of modules in Chromium see
# https://chromium.googlesource.com/chromium/src/+/main/docs/modules.md
#
# TODO(https://crbug.com/440260716): Enable for Cronet in AOSP once gn2bp
# supports copy targets.
use_clang_modules =
use_custom_libcxx &&
# Clang modules doesn't work with translation_unit used in codesearch
# pipeline http://b/436082487.
!enable_kythe_annotations && is_clang &&
clang_modules_platform_supported && using_tested_sysroot &&
# reclient and icecc don't handle headers in modulemap config.
!use_reclient && !is_cronet_for_aosp_build && cc_wrapper != "icecc"
}
# The saigo libc++ is distinct from the custom hermetic libc++. However, since
# the Chrome team controls the saigo toolchain, it is safe to unconditionally
# enable libc++ hardening there as well.
use_safe_libcxx = use_custom_libcxx && enable_safe_libcxx
# libc++abi needs to be exported from executables to be picked up by shared
# libraries on certain instrumented builds.
export_libcxxabi_from_executables =
use_custom_libcxx && !is_apple && !is_win && !is_component_build &&
(is_asan || is_ubsan_vptr)
# On Android, many shared libraries get loaded from the context of a JRE. In
# this case, there's no "main executable" to export libc++abi from. We could
# export libc++abi from each "toplevel" shared library instead, but that would
# require adding an explicit dependency for each one, and might introduce
# subtle, hard-to-fix problems down the line if the dependency is missing.
#
# export_libcxxabi_from_executables was added to avoid having an RPATH set in
# static sanitizer builds just for executables to find libc++. But on Android,
# the Bionic dynamic loader doesn't even look at RPATH; instead, LD_LIBRARY_PATH
# is set for tests. Because of this, we make libc++ a shared library on android
# since it should get loaded properly.
if (is_android && export_libcxxabi_from_executables) {
export_libcxxabi_from_executables = false
libcxx_is_shared = true
}
if (use_clang_modules) {
libcxx_prefix = "${root_build_dir}/gen/third_party/libc++/src"
libcxx_modulemap =
read_file("//third_party/libc++/src/include/module.modulemap.in",
"string")
libcxx_modulemap = string_replace(libcxx_modulemap,
"@LIBCXX_CONFIG_SITE_MODULE_ENTRY@",
"textual header \"__config_site\"")
# vcruntime_exception.h is where std::bad_alloc is declared on windows, for
# example. Thus, it needs to be re-exported from the standard library.
# Since it's used in multiple places and has #pragma once it can't be textual.
# Note: Clang doesn't complain when you attempt to export a nonexistent
# module, so this still works fine on non-windows platforms.
libcxx_modulemap =
string_replace(libcxx_modulemap,
"header \"__exception/exception.h\"",
"header \"__exception/exception.h\"" +
" export sys_stage1.vcruntime_exception_h")
libcxx_modulemap = string_replace(libcxx_modulemap,
"header \"__new/align_val_t.h\"",
"header \"__new/align_val_t.h\"" +
" export sys_stage1.vcruntime_new_h")
libcxx_modulemap =
string_replace(libcxx_modulemap,
"header \"__new/exceptions.h\"",
"header \"__new/exceptions.h\"" +
" export sys_stage1.vcruntime_exception_h")
libcxx_modulemap =
string_replace(libcxx_modulemap,
"header \"__new/new_handler.h\"",
"header \"__new/new_handler.h\" export sys_stage1.new_h")
write_file("${libcxx_prefix}/include/module.modulemap", libcxx_modulemap)
} else {
libcxx_prefix = "//third_party/libc++/src"
}
libcxxabi_prefix = "//third_party/libc++abi/src"
assert(!(is_ios && libcxx_is_shared),
"Can't build libc++ as a shared library on iOS.")
if (libcxx_is_shared) {
libcxx_target_type = "shared_library"
} else if (is_win) {
libcxx_target_type = "source_set"
} else {
# Build as a static_library instead of a source_set when possible. Static
# library semantics are more ideal for libc++, because they ensure that only
# libc++ object files needed to satisfy unresolved symbols at link time are
# actually linked into the output. Especially for small targets with minimal
# use of libc++, this can provide space savings and a more predictable result,
# and cut down on the number of unnecessary static initializers.
libcxx_target_type = "static_library"
}
if (libcxx_target_type == "shared_library" ||
export_libcxxabi_from_executables) {
# libc++'s target type follows that of libc++, except:
# - When libc++ is built as a shared_library, libc++abi should be a
# source_set, so that libc++abi can be be linked into the libc++
# shared_library in full.
# - When exporting libc++abi from executables, libc++abi should be a
# source_set, so that all of libc++abi is linked into executables
# regardless of whether they directly depend on any particular portion of
# it.
libcxxabi_target_type = "source_set"
} else {
libcxxabi_target_type = libcxx_target_type
}
# Chromium will require using its libc++ library implementation. Warn if the
# current configuration is not using it.
if ((!use_custom_libcxx || !use_custom_libcxx_for_host) &&
# Standalone use of //build outside of Chromium can disable libc++.
build_with_chromium &&
# Try to avoid spamming the console lots. It's not actually
# toolchain-specific.
current_toolchain == default_toolchain) {
print("*********************************************************************")
print("WARNING: Support for linking against a C++ standard library other ")
print(" than the one in-tree (buildtools/third_party/libc++) is deprecated")
print(" and support for this will end. We plan to remove this option in ")
print(" M138.")
print("*********************************************************************")
}