# Copyright 2015 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/c++/c++.gni")
import("//build/config/sanitizers/sanitizers.gni")
import("//build/toolchain/toolchain.gni")
import("//arkweb/build/config/sanitizers/sanitizers.gni")
import("//buildtools/third_party/libc++/libcxx_headers.gni")
import("//buildtools/third_party/libc++/modules.gni")
if (is_mac) {
import("//build/config/mac/mac_sdk.gni")
}
# Used by libc++ and libc++abi.
# See //build/config/c++:runtime_library for the config used by users of libc++.
config("config") {
configs = [
":extra_flags",
":stdver",
]
}
config("extra_flags") {
cflags = [
"-fstrict-aliasing",
"-Wundef",
]
if (is_win) {
cflags += [
# libc++ wants to redefine the macros WIN32_LEAN_AND_MEAN and _CRT_RAND_S
# in its implementation.
"-Wno-macro-redefined",
]
} else {
cflags += [ "-fPIC" ]
}
defines = [ "_LIBCPP_BUILDING_LIBRARY" ]
}
config("stdver") {
if (is_win) {
cflags_cc = [
# We want to use a uniform C++ version across all of chromium, but
# upstream libc++ requires C++23 so we have to make an exception here.
# No other target should override the default -std= flag.
"-std:c++23preview",
]
} else {
cflags_cc = [ "-std=c++23" ]
}
}
# Explicitly set version macros to Windows 7 to prevent libc++ from adding a
# hard dependency on GetSystemTimePreciseAsFileTime, which was introduced in
# Windows 8.
config("winver") {
defines = [
"NTDDI_VERSION=NTDDI_WIN7",
"_WIN32_WINNT=_WIN32_WINNT_WIN7",
"WINVER=_WIN32_WINNT_WIN7",
]
}
config("builtin_modulemap") {
cflags_cc = [ clang_arg_prefix + "-fbuiltin-module-map" ]
}
modulemap_config("libcxx_modulemap") {
source =
"${root_build_dir}/gen/third_party/libc++/src/include/module.modulemap"
}
if (current_toolchain == default_toolchain) {
# The Clang modules build requires libc++ headers, __assertion_handler, and
# __config_site to be in the same directory.
#
# To avoid redundant work, the copy targets are declared only in the default
# toolchain. This prevents unnecessary copies in multi-toolchain builds and
# allows Siso to use its precomputed tree for the default toolchain's `gen`
# directory.
#
# Note: there are setups where clang_modules is enabled for some, but not all,
# toolchains (see https://crrev.com/c/6849070). So, this copy must happen
# unconditionally.
copy("copy_libcxx_headers") {
sources = libcxx_headers
outputs = [ "{{source_gen_dir}}/{{source_file_part}}" ]
# Rely on `:libcxx_headers` instead: it abstract away the default toolchain
# optimization and the internal copy.
visibility = [ ":libcxx_headers" ]
}
# Note: there are setups where clang_modules is enabled for some, but not all,
# toolchains (see https://crrev.com/c/6849070). So, this copy must happen
# unconditionally.
copy("copy_custom_headers") {
sources = [
"__assertion_handler",
"__config_site",
]
outputs = [
"${root_gen_dir}/third_party/libc++/src/include/{{source_file_part}}",
]
# Rely on `:custom_headers` instead: it abstract away the default toolchain
# optimization and the internal copy.
visibility = [ ":custom_headers" ]
}
}
# TODO(https://crbug.com/440260716): This intermediate target can be removed
# once Cronet's gn2bp supports copy targets with multiple outputs.
group("libcxx_headers") {
if (use_clang_modules) {
deps = [ ":copy_libcxx_headers($default_toolchain)" ]
}
}
# TODO(https://crbug.com/440260716): This intermediate target can be removed
# once Cronet's gn2bp supports copy targets with multiple outputs.
group("custom_headers") {
if (use_clang_modules) {
deps = [ ":copy_custom_headers($default_toolchain)" ]
}
}
if (use_clang_modules && use_xcode_symlinks && !use_autogenerated_modules) {
# sysroot_modulemaps can be inside the build directory. This no-op action
# declares the modulemap files as outputs to satisfy GN's dependency
# tracking when other targets use them as inputs.
action("copy_sysroot_modulemaps") {
script = "//build/noop.py"
outputs = sysroot_modulemaps
}
}
if (use_autogenerated_modules && use_clang_modules) {
group("all_modules") {
# If this doesn't exist, you'll need to run build/modules/modularize.py for that platform.
public_deps = [ "//build/modules/${module_platform}:all_modules" ]
public_configs = [ "//build/config/compiler:libcxx_module" ]
}
config("all_modulemap_configs") {
configs = [ "//build/modules/${module_platform}:all_modulemap_configs" ]
}
} else if (use_clang_modules) {
if (is_apple) {
DarwinBasic_module("MachO") {
public_deps = [
":_Builtin_stdbool",
":_Builtin_stdint",
":_DarwinFoundation3",
":std_string_h",
]
}
DarwinFoundation1_module("_DarwinFoundation1") {
public_deps = [ ":_AvailabilityInternal" ]
}
DarwinFoundation1_module("_AvailabilityInternal") {
}
DarwinFoundation2_module("_DarwinFoundation2") {
public_deps = [
":_Builtin_stdarg",
":_Builtin_stddef",
":_DarwinFoundation1",
]
}
DarwinFoundation2_module("alloca") {
public_deps = [ ":_DarwinFoundation2" ]
}
DarwinFoundation3_module("_DarwinFoundation3") {
public_deps = [
":_Builtin_stdint",
":_DarwinFoundation2",
":std_ctype_h",
]
}
DarwinFoundation3_module("xlocale") {
public_deps = [
":_DarwinFoundation1",
":_DarwinFoundation2",
]
}
group("all_sysroot") {
public_deps = [
":MachO",
":_AvailabilityInternal",
":_DarwinFoundation1",
":_DarwinFoundation2",
":_DarwinFoundation3",
":alloca",
":xlocale",
]
}
group("sysroot_ctype") {
public_deps = [ ":_DarwinFoundation2" ]
}
group("sysroot_errno") {
public_deps = [ ":_DarwinFoundation1" ]
}
group("sysroot_fenv") {
public_deps = [ ":_DarwinFoundation1" ]
}
group("sysroot_inttypes") {
public_deps = [ ":_DarwinFoundation3" ]
}
group("sysroot_limits") {
public_deps = [ ":_DarwinFoundation1" ]
}
group("sysroot_locale") {
}
group("sysroot_math") {
}
group("sysroot_pthread") {
}
group("sysroot_stdatomic") {
public_deps = []
}
group("sysroot_stdint") {
public_deps = [ ":_DarwinFoundation2" ]
}
group("sysroot_stdlib") {
public_deps = [ ":_DarwinFoundation3" ]
}
group("sysroot_string") {
public_deps = [ ":_DarwinFoundation2" ]
}
group("sysroot_uchar") {
public_deps = []
}
group("sysroot_wchar") {
public_deps = [ ":_DarwinFoundation3" ]
}
group("sysroot_wctype") {
public_deps = [ ":_DarwinFoundation3" ]
}
}
builtin_module("_Builtin_float") {
}
builtin_module("_Builtin_intrinsics") {
public_deps = [
":std_core",
":sysroot_stdlib",
]
if (current_cpu == "arm" || current_cpu == "arm64") {
# <arm_acle.h> includes <stdint.h> which requires _Builtin_stdint module.
public_deps += [ ":_Builtin_stdint" ]
}
}
builtin_module("_Builtin_inttypes") {
public_deps = [ ":sysroot_inttypes" ]
}
builtin_module("_Builtin_limits") {
public_deps = [
":std_float_h",
":sysroot_limits",
]
}
builtin_module("_Builtin_stdalign") {
}
builtin_module("_Builtin_stdarg") {
}
builtin_module("_Builtin_stdatomic") {
public_deps = [
":_Builtin_stddef",
":_Builtin_stdint",
":sysroot_stdatomic",
]
}
builtin_module("_Builtin_stdbool") {
}
builtin_module("_Builtin_stddef") {
}
builtin_module("_Builtin_stdint") {
public_deps = [ ":sysroot_stdint" ]
}
builtin_module("_Builtin_unwind") {
public_deps = [ ":_Builtin_stdint" ]
}
builtin_module("ptrauth") {
}
group("all_builtins") {
public_deps = [
"//buildtools/third_party/libc++:_Builtin_float",
"//buildtools/third_party/libc++:_Builtin_intrinsics",
"//buildtools/third_party/libc++:_Builtin_inttypes",
"//buildtools/third_party/libc++:_Builtin_limits",
"//buildtools/third_party/libc++:_Builtin_stdalign",
"//buildtools/third_party/libc++:_Builtin_stdarg",
"//buildtools/third_party/libc++:_Builtin_stdatomic",
"//buildtools/third_party/libc++:_Builtin_stdbool",
"//buildtools/third_party/libc++:_Builtin_stddef",
"//buildtools/third_party/libc++:_Builtin_stdint",
"//buildtools/third_party/libc++:_Builtin_unwind",
"//buildtools/third_party/libc++:ptrauth",
]
}
libcxx_module("std") {
public_deps = [
":_Builtin_limits",
":_Builtin_stdalign",
":std_core",
":std_ctype_h",
":std_errno_h",
":std_fenv_h",
":std_float_h",
":std_inttypes_h",
":std_math_h",
":std_private_mbstate_t",
":std_string_h",
":std_uchar_h",
":std_wctype_h",
":sysroot_locale",
":sysroot_pthread",
]
if (is_apple) {
public_deps += [
# __locale_dir/support/apple.h includes __locale_dir/support/bsd_like.h,
# which includes xlocale.h.
":xlocale",
]
}
}
textual_module("std_config") {
}
libcxx_module("std_core") {
public_deps = [
":_Builtin_stddef",
":_Builtin_stdint",
":std_config",
]
}
libcxx_module("std_ctype_h") {
public_deps = [
":std_config",
":sysroot_ctype",
]
}
libcxx_module("std_errno_h") {
public_deps = [
":std_config",
":sysroot_errno",
]
}
libcxx_module("std_fenv_h") {
public_deps = [
":std_config",
":sysroot_fenv",
]
}
libcxx_module("std_float_h") {
public_deps = [
":_Builtin_float",
":std_config",
]
}
libcxx_module("std_inttypes_h") {
public_deps = [
":_Builtin_inttypes",
":std_config",
]
}
libcxx_module("std_math_h") {
public_deps = [
":std_core",
":sysroot_math",
":sysroot_stdlib",
]
}
libcxx_module("std_private_mbstate_t") {
public_deps = [
":std_config",
":sysroot_wchar",
]
}
libcxx_module("std_stdatomic_h") {
public_deps = [
":_Builtin_stdatomic",
":std_config",
":sysroot_stdint",
]
}
libcxx_module("std_string_h") {
public_deps = [
":std_config",
":sysroot_string",
]
}
libcxx_module("std_uchar_h") {
public_deps = [
":std_private_mbstate_t",
":sysroot_uchar",
]
}
libcxx_module("std_wctype_h") {
public_deps = [
":std_config",
":sysroot_wctype",
]
}
group("all_std") {
# There are more modules than this, but since the others are purely
# textual, they don't need to be compiled to a pcm.
public_deps = [
":std",
":std_core",
":std_ctype_h",
":std_errno_h",
":std_fenv_h",
":std_float_h",
":std_inttypes_h",
":std_math_h",
":std_private_mbstate_t",
":std_stdatomic_h",
":std_string_h",
":std_uchar_h",
":std_wctype_h",
]
}
config("sysroot_modulemaps") {
cflags_cc = []
foreach(modulemap, sysroot_modulemaps) {
cflags_cc +=
[ "-fmodule-map-file=" + rebase_path(modulemap, root_build_dir) ]
}
}
group("all_modules") {
public_deps = [
":all_builtins",
":all_std",
":all_sysroot",
]
public_configs = [ "//build/config/compiler:libcxx_module" ]
}
} else {
# This is a no-op target for when use_clang_modules = false. It is
# still referenced in BUILDCONFIG.gn.
group("all_modules") {
}
}
target(libcxx_target_type, "libc++") {
# Most things that need to depend on libc++ should do so via the implicit
# 'common_deps' dependency below. Some targets that package libc++.so may
# need to explicitly depend on libc++.
visibility = [
"//build/config:common_deps",
"//third_party/catapult/devil",
]
if (is_linux) {
# This target packages libc++.so, so must have an explicit dependency on
# libc++.
visibility +=
[ "//remoting/host/linux:remoting_me2me_host_copy_user_session" ]
}
if (build_with_chromium && is_win && is_component_build) {
# PartitionAlloc uses no_default_deps=true when is_win && is_component_build
# but it depends on libc++. So need to add an explicit dependency on
# libc++.
visibility +=
[ "//base/allocator/partition_allocator/src/partition_alloc:*" ]
}
if (libcxx_is_shared) {
no_default_deps = true
}
if (is_linux && !is_clang) {
libs = [ "atomic" ]
}
inputs = [
"__assertion_handler",
"__config_site",
]
# TODO(crbug.com/40273848): Move this build file to third_party/libc++/BUILD.gn
# once submodule migration is done.
sources = [
"//third_party/libc++/src/src/algorithm.cpp",
"//third_party/libc++/src/src/any.cpp",
"//third_party/libc++/src/src/atomic.cpp",
"//third_party/libc++/src/src/barrier.cpp",
"//third_party/libc++/src/src/bind.cpp",
"//third_party/libc++/src/src/call_once.cpp",
"//third_party/libc++/src/src/charconv.cpp",
"//third_party/libc++/src/src/chrono.cpp",
"//third_party/libc++/src/src/condition_variable.cpp",
"//third_party/libc++/src/src/condition_variable_destructor.cpp",
"//third_party/libc++/src/src/error_category.cpp",
"//third_party/libc++/src/src/exception.cpp",
"//third_party/libc++/src/src/filesystem/directory_iterator.cpp",
"//third_party/libc++/src/src/filesystem/filesystem_error.cpp",
"//third_party/libc++/src/src/filesystem/operations.cpp",
"//third_party/libc++/src/src/filesystem/path.cpp",
"//third_party/libc++/src/src/functional.cpp",
"//third_party/libc++/src/src/future.cpp",
"//third_party/libc++/src/src/hash.cpp",
"//third_party/libc++/src/src/ios.cpp",
"//third_party/libc++/src/src/ios.instantiations.cpp",
"//third_party/libc++/src/src/iostream.cpp",
"//third_party/libc++/src/src/locale.cpp",
"//third_party/libc++/src/src/memory.cpp",
"//third_party/libc++/src/src/mutex.cpp",
"//third_party/libc++/src/src/mutex_destructor.cpp",
"//third_party/libc++/src/src/new_handler.cpp",
"//third_party/libc++/src/src/new_helpers.cpp",
"//third_party/libc++/src/src/optional.cpp",
"//third_party/libc++/src/src/random.cpp",
"//third_party/libc++/src/src/random_shuffle.cpp",
"//third_party/libc++/src/src/regex.cpp",
"//third_party/libc++/src/src/ryu/d2fixed.cpp",
"//third_party/libc++/src/src/ryu/d2s.cpp",
"//third_party/libc++/src/src/ryu/f2s.cpp",
"//third_party/libc++/src/src/shared_mutex.cpp",
"//third_party/libc++/src/src/stdexcept.cpp",
"//third_party/libc++/src/src/string.cpp",
"//third_party/libc++/src/src/strstream.cpp",
"//third_party/libc++/src/src/system_error.cpp",
"//third_party/libc++/src/src/thread.cpp",
"//third_party/libc++/src/src/typeinfo.cpp",
"//third_party/libc++/src/src/valarray.cpp",
"//third_party/libc++/src/src/variant.cpp",
"//third_party/libc++/src/src/vector.cpp",
"//third_party/libc++/src/src/verbose_abort.cpp",
]
if (is_apple || (!is_asan && !is_tsan && !is_msan)) {
# In {a,t,m}san configurations, operator new and operator delete will be
# provided by the sanitizer runtime library. Since libc++ defines these
# symbols with weak linkage, and the *san runtime uses strong linkage, it
# should technically be OK to include this file, but it's removed to be
# explicit.
sources += [ "//third_party/libc++/src/src/new.cpp" ]
}
if (is_linux) {
# These sources are necessary for the Centipede fuzzer,
# which currently only needs to run on Linux.
sources += [
"//third_party/libc++/src/src/filesystem/directory_entry.cpp",
"//third_party/libc++/src/src/filesystem/filesystem_clock.cpp",
]
}
include_dirs = [ "//third_party/libc++/src/src" ]
if (is_win) {
sources += [
"//third_party/libc++/src/src/support/win32/locale_win32.cpp",
"//third_party/libc++/src/src/support/win32/support.cpp",
"//third_party/libc++/src/src/support/win32/thread_win32.cpp",
]
configs -= [ "//build/config/win:winver" ]
configs += [ ":winver" ]
if (libcxx_natvis_include) {
inputs += [
# libc++.natvis listed as an input here instead of in
# //build/config/c++:runtime_library to prevent unnecessary size
# increase in generated build files.
"//build/config/c++/libc++.natvis",
]
}
}
# Enable exceptions and rtti for libc++, but disable them in modules targets
# so that modules can be used for other chromium targets which don't enable
# exception and rtti.
configs -= configs_to_remove + [
"//build/config/compiler:no_exceptions",
"//build/config/compiler:no_rtti",
]
configs += configs_to_add + [
"//build/config/compiler:exceptions",
"//build/config/compiler:rtti",
]
deps = [
":custom_headers",
":libcxx_headers",
"//third_party/llvm-libc:llvm-libc-shared",
]
if(use_custom_libcxx && enable_cfi_protection) {
configs -= [
"//arkweb/build/config/sanitizers:ptrauth_base",
"//arkweb/build/config/sanitizers:armv83a",
]
}
if (use_clang_modules) {
# TODO(https://github.com/llvm/llvm-project/issues/127012): We don't enable
# Clang modules for libc++ as libc++'s iostream.cpp has ODR issue
# (https://crbug.com/40440396#comment81). Also we don't take care about the
# libc++'s build performance much.
# (https://crrev.com/c/6248376/4#message-0ddf8e6a0f3ce1eb1654f7025280d8ed75cf2e81)
# This removes deps to libc++'s modules from libc++'s build as libc++
# doesn't support modules build itself.
use_libcxx_modules = false
}
if ((is_android || is_apple) && libcxx_is_shared) {
# Use libc++_chrome to avoid conflicting with system libc++
output_name = "libc++_chrome"
if (is_android) {
# See crbug.com/1076244#c11 for more detail.
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
}
}
if (libcxx_is_shared && !is_win) {
configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
configs += [ "//build/config/gcc:symbol_visibility_default" ]
}
defines = []
cflags = []
if (!libcxx_is_shared && !is_win) {
if (is_apple && is_clang) {
# We want operator new/delete to be private on Mac, but these functions
# are implicitly created by the compiler for each translation unit, as
# specified in the C++ spec 3.7.4p2, which makes them always have default
# visibility. This option is needed to force hidden visibility since
# -fvisibility=hidden doesn't have the desired effect.
cflags += [ "-fvisibility-global-new-delete=force-hidden" ]
} else {
# This resets the visibility to default only for the various
# flavors of operator new and operator delete. These symbols
# are weak and get overriden by Chromium-provided ones, but if
# these symbols had hidden visibility, this would make the
# Chromium symbols hidden too because elf visibility rules
# require that linkers use the least visible form when merging.
# We want operator new to be public, so that our allocator is
# able to intercept allocations from other shared libraries.
# TODO(lld): Ask lld for a --force-public-visibility flag or
# similar to that overrides the default elf merging rules, and
# make the allocator's gn config pass that to all its dependencies,
# then remove this override here.
defines += [ "_LIBCPP_OVERRIDABLE_FUNC_VIS=__attribute__((__visibility__(\"default\")))" ]
}
}
if (!is_win) {
defines += [ "LIBCXX_BUILDING_LIBCXXABI" ]
if (!export_libcxxabi_from_executables) {
deps += [ "//buildtools/third_party/libc++abi" ]
}
}
# Disabling -Wexit-time-destructors, as libc++ uses `static string` objects
# for locale code.
configs += [ "//build/config/compiler:no_exit_time_destructors" ]
}