Enable explicit module build by use_libcxx_modules arg
This CL enables explicit clang modules for libc++ and clang's builtin headers. There are still many compile errors even if we build `base`, but we'll fix them one by one. I also leave implicit modules build with use_implicit_libcxx_modules. Bug: 40440396 Change-Id: Ie23087ff69e2ab9892625400f2cd182955cc098b Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6188686 Reviewed-by: Erik Staab <estaab@chromium.org> Commit-Queue: Takuto Ikuta <tikuta@chromium.org> Auto-Submit: Takuto Ikuta <tikuta@chromium.org> Cr-Commit-Position: refs/heads/main@{#1416006}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b06c27c680
commit
7d1b2b0b0c
build
buildtools/third_party/libc++
docs
@ -540,11 +540,21 @@ foreach(_target_type,
|
||||
]) {
|
||||
template(_target_type) {
|
||||
target(_target_type, target_name) {
|
||||
forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
|
||||
forward_variables_from(invoker,
|
||||
"*",
|
||||
TESTONLY_AND_VISIBILITY + [ "no_default_deps" ])
|
||||
forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
|
||||
if (!defined(inputs)) {
|
||||
inputs = []
|
||||
}
|
||||
if (!defined(deps)) {
|
||||
deps = []
|
||||
}
|
||||
|
||||
if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
|
||||
# This is necessary for Clang modules builds.
|
||||
deps += [ "//buildtools/third_party/libc++:std" ]
|
||||
}
|
||||
|
||||
# Consumed by the unsafe-buffers plugin during compile.
|
||||
#
|
||||
@ -622,7 +632,15 @@ foreach(_target_type,
|
||||
# //build/config:shared_library_deps
|
||||
# (This explicit list is so that grepping for these configs finds where
|
||||
# they are used.)
|
||||
deps += [ "//build/config:${_target_type}_deps" ]
|
||||
deps += [
|
||||
"//build/config:${_target_type}_deps",
|
||||
|
||||
# These are necessary for Clang modules builds.
|
||||
"//buildtools/third_party/libc++:_Builtin_limits",
|
||||
"//buildtools/third_party/libc++:_Builtin_stdarg",
|
||||
"//buildtools/third_party/libc++:_Builtin_stddef",
|
||||
"//buildtools/third_party/libc++:std",
|
||||
]
|
||||
}
|
||||
|
||||
# On Android, write shared library output file to metadata. We will use
|
||||
|
@ -42,13 +42,25 @@ declare_args() {
|
||||
# defaults to off.
|
||||
enable_iterator_debugging = false
|
||||
|
||||
# Use Clang header modules for libc++.
|
||||
# Use explicit Clang header modules for libc++.
|
||||
# This is experimental only (see crbug.com/543704).
|
||||
# For details on the current state of modules in Chromium see
|
||||
# https://chromium.googlesource.com/chromium/src/+/main/docs/modules.md
|
||||
use_libcxx_modules = false
|
||||
|
||||
# Use implicit Clang header modules for libc++.
|
||||
# This is experimental only (see crbug.com/543704).
|
||||
# For details on the current state of modules in Chromium see
|
||||
# https://chromium.googlesource.com/chromium/src/+/main/docs/modules.md
|
||||
use_implicit_libcxx_modules = false
|
||||
}
|
||||
|
||||
if (use_implicit_libcxx_modules) {
|
||||
use_libcxx_modules = true
|
||||
}
|
||||
|
||||
use_explicit_libcxx_modules = use_libcxx_modules && !use_implicit_libcxx_modules
|
||||
|
||||
assert(!use_libcxx_modules || !use_remoteexec,
|
||||
"Implicit Clang header modules don't work with remote execution.")
|
||||
|
||||
|
@ -1707,9 +1707,6 @@ config("libcxx_module") {
|
||||
"-fmodules",
|
||||
"-fmodule-map-file=" + modulemap,
|
||||
"-fno-implicit-module-maps",
|
||||
"-fbuiltin-module-map",
|
||||
"-fmodules-cache-path=" +
|
||||
rebase_path("$libcxx_module_prefix/module_cache", root_build_dir),
|
||||
|
||||
"-Xclang",
|
||||
"-fmodules-local-submodule-visibility", # required for builtins
|
||||
@ -1724,6 +1721,21 @@ config("libcxx_module") {
|
||||
# unnecessarily using extern "C".
|
||||
"-Wno-module-import-in-extern-c",
|
||||
]
|
||||
|
||||
if (use_explicit_libcxx_modules) {
|
||||
cflags_cc += [
|
||||
"-fno-implicit-modules",
|
||||
|
||||
# This is for exception handling mismatch.
|
||||
"-Wno-module-file-config-mismatch",
|
||||
]
|
||||
} else {
|
||||
cflags_cc += [
|
||||
"-fbuiltin-module-map",
|
||||
"-fmodules-cache-path=" +
|
||||
rebase_path("$libcxx_module_prefix/module_cache", root_build_dir),
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,12 +353,20 @@ template("single_gcc_toolchain") {
|
||||
tool("cxx") {
|
||||
depfile = "{{output}}.d"
|
||||
precompiled_header_type = "gcc"
|
||||
command = "$cxx $md -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} -c {{source}} -o {{output}}"
|
||||
command = "$cxx $md -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} {{module_deps_no_self}} -c {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "CXX {{output}}"
|
||||
outputs = [ "$object_subdir/{{source_name_part}}.o" ]
|
||||
}
|
||||
|
||||
tool("cxx_module") {
|
||||
depfile = "{{output}}.d"
|
||||
command = "$cxx -MD -MF $depfile ${rebuild_string}{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}${extra_cppflags}${extra_cxxflags} {{module_deps_no_self}} -fmodule-name={{label_name}} -c -x c++ -Xclang -emit-module {{source}} -o {{output}}"
|
||||
depsformat = "gcc"
|
||||
description = "CXX_MODULE {{output}}"
|
||||
outputs = [ "$object_subdir/{{source_name_part}}.pcm" ]
|
||||
}
|
||||
|
||||
tool("asm") {
|
||||
# For GCC we can just use the C compiler to compile assembly.
|
||||
depfile = "{{output}}.d"
|
||||
|
190
buildtools/third_party/libc++/BUILD.gn
vendored
190
buildtools/third_party/libc++/BUILD.gn
vendored
@ -45,11 +45,156 @@ config("winver") {
|
||||
]
|
||||
}
|
||||
|
||||
template("builtin_modules") {
|
||||
# This is a template to build clang builtin's module file.
|
||||
source_set(target_name) {
|
||||
no_default_deps = true
|
||||
if (use_explicit_libcxx_modules) {
|
||||
sources = [ "//third_party/llvm-build/Release+Asserts/lib/clang/20/include/module.modulemap" ]
|
||||
}
|
||||
|
||||
deps = []
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
} else {
|
||||
not_needed(invoker, "*")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_float") {
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_inttypes") {
|
||||
deps = [ ":_Builtin_stdint" ]
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_limits") {
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_stdalign") {
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_stdarg") {
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_stddef") {
|
||||
}
|
||||
|
||||
builtin_modules("_Builtin_stdint") {
|
||||
}
|
||||
|
||||
configs_to_add = [
|
||||
":config",
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
"//build/config/compiler:exceptions",
|
||||
"//build/config/compiler:rtti",
|
||||
]
|
||||
|
||||
configs_to_remove = [
|
||||
"//build/config/compiler:chromium_code",
|
||||
"//build/config/compiler:no_exceptions",
|
||||
"//build/config/compiler:no_rtti",
|
||||
"//build/config/coverage:default_coverage",
|
||||
]
|
||||
|
||||
template("libcxx_modules") {
|
||||
# This is a template to build libc++'s module file.
|
||||
source_set(target_name) {
|
||||
no_default_deps = true
|
||||
if (use_explicit_libcxx_modules) {
|
||||
sources = [ "//third_party/libc++/src/include/module.modulemap" ]
|
||||
}
|
||||
deps = []
|
||||
|
||||
configs -= configs_to_remove
|
||||
configs += configs_to_add
|
||||
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
} else {
|
||||
not_needed(invoker, "*")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
libcxx_modules("std") {
|
||||
deps = [
|
||||
":_Builtin_limits",
|
||||
":_Builtin_stdalign",
|
||||
":_Builtin_stdarg",
|
||||
":std_config",
|
||||
":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",
|
||||
]
|
||||
}
|
||||
|
||||
libcxx_modules("std_config") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_core") {
|
||||
deps = [
|
||||
":_Builtin_stddef",
|
||||
":_Builtin_stdint",
|
||||
]
|
||||
}
|
||||
|
||||
libcxx_modules("std_ctype_h") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_errno_h") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_fenv_h") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_float_h") {
|
||||
deps = [ ":_Builtin_float" ]
|
||||
}
|
||||
|
||||
libcxx_modules("std_inttypes_h") {
|
||||
deps = [ ":_Builtin_inttypes" ]
|
||||
}
|
||||
|
||||
libcxx_modules("std_math_h") {
|
||||
deps = [
|
||||
":_Builtin_limits",
|
||||
":std_core",
|
||||
]
|
||||
}
|
||||
|
||||
libcxx_modules("std_private_mbstate_t") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_stddef_h") {
|
||||
}
|
||||
|
||||
libcxx_modules("std_string_h") {
|
||||
deps = [ ":_Builtin_stddef" ]
|
||||
}
|
||||
|
||||
libcxx_modules("std_uchar_h") {
|
||||
deps = [ ":_Builtin_stddef" ]
|
||||
}
|
||||
|
||||
libcxx_modules("std_wctype_h") {
|
||||
}
|
||||
|
||||
if (libcxx_is_shared) {
|
||||
_libcxx_target_type = "shared_library"
|
||||
} else {
|
||||
_libcxx_target_type = "source_set"
|
||||
}
|
||||
|
||||
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
|
||||
@ -108,7 +253,6 @@ target(_libcxx_target_type, "libc++") {
|
||||
"//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",
|
||||
@ -135,6 +279,15 @@ target(_libcxx_target_type, "libc++") {
|
||||
"//third_party/libc++/src/src/verbose_abort.cpp",
|
||||
]
|
||||
|
||||
if (!use_explicit_libcxx_modules) {
|
||||
sources += [
|
||||
# TODO(crbug.com/40440396): Have a separate target for this to avoid
|
||||
# compile errors in explicit modules build due to type mismatch of
|
||||
# std::{cerr,cin,clog,cout} between declaration and definition.
|
||||
"//third_party/libc++/src/src/iostream.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
|
||||
@ -171,12 +324,10 @@ target(_libcxx_target_type, "libc++") {
|
||||
]
|
||||
}
|
||||
}
|
||||
configs -= [
|
||||
"//build/config/compiler:chromium_code",
|
||||
"//build/config/compiler:no_exceptions",
|
||||
"//build/config/compiler:no_rtti",
|
||||
"//build/config/coverage:default_coverage",
|
||||
]
|
||||
|
||||
configs -= configs_to_remove
|
||||
configs += configs_to_add
|
||||
|
||||
if (use_libcxx_modules) {
|
||||
configs -= [ "//build/config/compiler:libcxx_module" ]
|
||||
}
|
||||
@ -188,12 +339,6 @@ target(_libcxx_target_type, "libc++") {
|
||||
configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
|
||||
}
|
||||
}
|
||||
configs += [
|
||||
":config",
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
"//build/config/compiler:exceptions",
|
||||
"//build/config/compiler:rtti",
|
||||
]
|
||||
|
||||
if (libcxx_is_shared && !is_win) {
|
||||
configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
|
||||
@ -201,6 +346,7 @@ target(_libcxx_target_type, "libc++") {
|
||||
}
|
||||
|
||||
defines = []
|
||||
cflags = []
|
||||
|
||||
if (!libcxx_is_shared && !is_win) {
|
||||
if (is_apple && is_clang) {
|
||||
@ -209,7 +355,7 @@ target(_libcxx_target_type, "libc++") {
|
||||
# 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" ]
|
||||
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
|
||||
@ -229,6 +375,22 @@ target(_libcxx_target_type, "libc++") {
|
||||
|
||||
deps = [ "//third_party/llvm-libc:llvm-libc-shared" ]
|
||||
|
||||
if (use_explicit_libcxx_modules) {
|
||||
modulemap = rebase_path("//third_party/libc++/src/include/module.modulemap",
|
||||
root_build_dir)
|
||||
cflags += [
|
||||
"-fmodules",
|
||||
"-fmodule-map-file=" + modulemap,
|
||||
]
|
||||
|
||||
deps += [
|
||||
":std",
|
||||
":std_config",
|
||||
":std_core",
|
||||
":std_stddef_h",
|
||||
]
|
||||
}
|
||||
|
||||
if (!is_win) {
|
||||
defines += [ "LIBCXX_BUILDING_LIBCXXABI" ]
|
||||
if (!export_libcxxabi_from_executables) {
|
||||
|
@ -18,17 +18,17 @@ their code bases with large performance wins.
|
||||
the build system.
|
||||
|
||||
We're currently experimenting with modules for libc++ and they can be enabled
|
||||
with the GN arg `use_libcxx_modules`. Using this arg is not currently
|
||||
recommended, due to the limitations mentioned below. It is only interesting to
|
||||
people working on the feature.
|
||||
with the GN arg `use_libcxx_modules` and `use_implicit_libcxx_modules`. Using
|
||||
this arg is not currently recommended, due to the limitations mentioned below.
|
||||
It is only interesting to people working on the feature.
|
||||
|
||||
## Current limitations
|
||||
|
||||
### Implicit vs explicit modules
|
||||
|
||||
We're using implicit modules, which are created on-the-fly when Clang doesn't
|
||||
see them in the module cache. This doesn't work with remote execution since the
|
||||
cached modules aren't known to the build system.
|
||||
`use_implicit_libcxx_modules` is using implicit modules, which are created
|
||||
on-the-fly when Clang doesn't see them in the module cache. This doesn't work
|
||||
with remote execution since the cached modules aren't known to the build system.
|
||||
|
||||
The module cache is set to `<outdir>/gen/libcxx/module_cache`. Since the modules
|
||||
aren't known to ninja they aren't cleaned with `ninja -t clean` and need to be
|
||||
@ -41,6 +41,8 @@ will require support in GN and has been partially implemented
|
||||
[CL3](https://gn-review.googlesource.com/c/gn/+/9680), and
|
||||
[crbug.com/gn/373](https://crbug.com/gn/373)).
|
||||
|
||||
`use_libcxx_modules` enables explicit modules using existing features.
|
||||
|
||||
### Duplicate modules
|
||||
|
||||
Multiple pcm files are created per module. For correctness, Clang header modules
|
||||
|
Reference in New Issue
Block a user