| # 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("//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") { |
| 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" ] |
| } |
| |
| # We want to use a uniform C++ version across all of chromium, but |
| # upstream libc++ requires C++26 so we have to make an exception here. |
| # No other target should override the default -std= flag. |
| if (is_win) { |
| # cl.exe does not yet have a C++26 flag. clang-cl maps c++latest to C++26. |
| cflags_cc = [ "-std:c++latest" ] |
| } else { |
| cflags_cc = [ "-std=c++26" ] |
| } |
| |
| defines = [ "_LIBCPP_BUILDING_LIBRARY" ] |
| } |
| |
| # 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 && !use_unified_system_module) { |
| # The Clang modules build requires libc++ headers, __assertion_handler, |
| # __config_site, and module.modulemap 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. |
| action("copy_libcxx_headers") { |
| script = "sync_dir.py" |
| inputs = libcxx_headers |
| response_file_contents = |
| rebase_path(inputs, "//third_party/libc++/src/include/") |
| outputs = [ "$target_gen_dir/copy_headers.stamp" ] |
| |
| foreach(input, inputs) { |
| outputs += [ "${root_build_dir}/gen/third_party/libc++/src/include/" + |
| rebase_path(input, "//third_party/libc++/src/include/") ] |
| } |
| |
| args = [ |
| "--stamp", |
| rebase_path(outputs[0], root_build_dir), |
| "--source-dir", |
| rebase_path("//third_party/libc++/src/include/", root_build_dir), |
| "--output-dir", |
| rebase_path("${root_build_dir}/gen/third_party/libc++/src/include/", |
| root_build_dir), |
| "--except", |
| "__assertion_handler", |
| "--except", |
| "__config_site", |
| "--except", |
| "module.modulemap", |
| "{{response_file_name}}", |
| ] |
| |
| # Rely on `:headers` instead: it abstract away the default toolchain |
| # optimization and the internal copy. |
| visibility = [ ":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 `:headers` instead: it abstract away the default toolchain |
| # optimization and the internal copy. |
| visibility = [ ":headers" ] |
| } |
| } |
| |
| # TODO(https://crbug.com/440260716): This intermediate target can be removed |
| # once Cronet's gn2bp supports copy targets with multiple outputs. |
| group("headers") { |
| # Unified modules don't need to worry about the custom headers and libcxx |
| # headers being in the same directory, so don't need to copy them. |
| if (use_clang_modules && !use_unified_system_module) { |
| deps = [ |
| ":copy_custom_headers($default_toolchain)", |
| ":copy_libcxx_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 |
| } |
| } |
| |
| # The unified system module means that we have a single module for the whole |
| # sysroot + libc++ + builtins. |
| if (use_clang_modules && use_unified_system_module) { |
| group("all_modules") { |
| public_deps = [ "//build/modules:system" ] |
| } |
| # Autogenerated modules generates the modulemaps automatically for each system. |
| # It is being deprecated in favor of the unified system module. |
| } else 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" ] |
| } |
| |
| 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 = [ ":sysroot_limits" ] |
| } |
| |
| builtin_module("_Builtin_stdalign") { |
| } |
| |
| builtin_module("_Builtin_stdarg") { |
| } |
| |
| builtin_module("_Builtin_stdbool") { |
| } |
| |
| builtin_module("_Builtin_stdckdint") { |
| } |
| |
| 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_stdbool", |
| "//buildtools/third_party/libc++:_Builtin_stdckdint", |
| "//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_float", |
| ":_Builtin_limits", |
| ":_Builtin_stdalign", |
| ":std_core", |
| ":std_ctype_h", |
| ":std_errno_h", |
| ":std_fenv_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_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 = [ ":std" ] |
| } |
| |
| 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_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 -= [ |
| "//build/config/compiler:chromium_code", |
| "//build/config/compiler:no_exceptions", |
| "//build/config/compiler:no_rtti", |
| "//build/config/coverage:default_coverage", |
| ] |
| configs += [ |
| ":config", |
| "//build/config/compiler:no_chromium_code", |
| "//build/config/compiler:exceptions", |
| "//build/config/compiler:rtti", |
| ] |
| |
| deps = [ |
| ":headers", |
| "//third_party/llvm-libc:llvm-libc-shared", |
| ] |
| |
| 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" ] |
| } |