1 import("//llvm/utils/gn/build/buildflags.gni")
2 import("//llvm/utils/gn/build/mac_sdk.gni")
3 import("//llvm/utils/gn/build/sysroot.gni")
4 import("//llvm/utils/gn/build/toolchain/compiler.gni")
5 import("//llvm/utils/gn/build/toolchain/target_flags.gni")
8 # Whether to build everything with coverage information.
9 # After building with this, run tests and then run
10 # llvm/utils/prepare-code-coverage-artifact.py \
11 # .../llvm-profdata .../llvm-cov out/gn/profiles/ report/ \
12 # out/gn/bin/llvm-undname ...
13 # to generate a HTML report for the binaries passed in the last line.
14 llvm_build_instrumented_coverage = false
16 # If set, puts relative paths in debug info.
17 # Makes the build output independent of the build directory, but makes
18 # most debuggers harder to use. See "Getting to local determinism" and
19 # "Getting debuggers to work well with locally deterministic builds" in
20 # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
21 # for more information.
22 use_relative_paths_in_debug_info = false
24 # The version of host gcc. Ignored if is_clang is true.
28 assert(!llvm_build_instrumented_coverage || is_clang,
29 "llvm_build_instrumented_coverage requires clang as host compiler")
31 config("compiler_defaults") {
34 if (!llvm_enable_assertions) {
35 defines += [ "NDEBUG" ]
38 if (llvm_enable_expensive_checks) {
39 defines += [ "EXPENSIVE_CHECKS" ]
42 asmflags = target_flags
44 ldflags = target_flags + target_ldflags
46 # Mostly for compiler-rt, see compiler-rt/cmake/config-ix.cmake
47 if (current_os == "ios") {
48 asmflags += [ "-miphoneos-version-min=8.0" ]
49 cflags += [ "-miphoneos-version-min=8.0" ]
50 ldflags += [ "-miphoneos-version-min=8.0" ]
52 if (current_os == "mac") {
53 asmflags += [ "-mmacosx-version-min=10.10" ]
54 cflags += [ "-mmacosx-version-min=10.10" ]
55 ldflags += [ "-mmacosx-version-min=10.10" ]
58 assert(symbol_level == 0 || symbol_level == 1 || symbol_level == 2,
59 "Unexpected symbol_level")
60 if (host_os != "win") {
61 if (symbol_level == 2) {
64 # For full debug-info -g builds, --gdb-index makes links ~15% slower, and
65 # gdb symbol reading time 1500% faster (lld links in 4.4 instead of 3.9s,
66 # and gdb loads and runs it in 2s instead of in 30s). It's likely that
67 # people doing symbol_level=2 want to run a debugger (since
68 # symbol_level=2 isn't the default). So this seems like the right
70 if (host_os != "mac" && use_lld) {
71 cflags += [ "-ggnu-pubnames" ] # PR34820
72 ldflags += [ "-Wl,--gdb-index" ]
74 } else if (symbol_level == 1) {
76 # For linetable-only -g1 builds, --gdb-index makes links ~8% slower, but
77 # links are 4x faster than -g builds so it's a fairly small absolute cost.
78 # On the other hand, gdb startup is well below 1s with and without the
79 # index, and people using -g1 likely don't use a debugger. So don't use
85 cflags += [ "-fdiagnostics-color" ]
87 ldflags += [ "-Wl,--color-diagnostics" ]
91 "-fvisibility-inlines-hidden",
94 if (symbol_level != 0) {
99 if (symbol_level == 1 && is_clang) {
100 cflags += [ "-gline-tables-only" ]
102 ldflags += [ "/DEBUG" ]
104 # Speed up links with ghash on windows.
105 if (use_lld && is_clang) {
106 cflags += [ "-gcodeview-ghash" ]
107 ldflags += [ "/DEBUG:GHASH" ]
122 "_CRT_SECURE_NO_DEPRECATE",
123 "_CRT_SECURE_NO_WARNINGS",
124 "_CRT_NONSTDC_NO_DEPRECATE",
125 "_CRT_NONSTDC_NO_WARNINGS",
126 "_SCL_SECURE_NO_DEPRECATE",
127 "_SCL_SECURE_NO_WARNINGS",
133 cflags += [ "/EHs-c-" ]
135 # The MSVC default value (1 MB) is not enough for parsing recursive C++
136 # templates in Clang.
137 ldflags += [ "/STACK:10000000" ]
141 if (host_os == "win" && !is_clang) {
143 # Suppress ''modifier' : used more than once' (__forceinline and inline).
146 # Suppress 'conversion from 'type1' to 'type2', possible loss of data'.
149 # Suppress 'conversion from 'size_t' to 'type', possible loss of data'.
152 # Suppress 'no matching operator delete found'.
155 # Suppress 'noexcept used with no exception handling mode specified'.
158 # Suppress 'destructor was implicitly defined as deleted'.
161 # Suppress 'unsafe mix of type <type> and type <type> in operation'.
165 if (host_os == "win") {
173 cflags += [ "-Wno-unused-parameter" ]
176 "-Wdelete-non-virtual-dtor",
177 "-Wstring-conversion",
181 # GCC's -Wcomment complains about // comments ending with '\' if the
182 # next line is also a // comment.
185 # Disable gcc's potentially uninitialized use analysis as it presents
186 # lots of false positives.
187 "-Wno-maybe-uninitialized",
190 # The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not
192 "-Wno-noexcept-type",
194 if (gcc_version >= 8) {
196 # Disable -Wclass-memaccess, a C++-only warning from GCC 8 that fires
197 # on LLVM's ADT classes.
198 "-Wno-class-memaccess",
201 if (gcc_version >= 9) {
203 # Disable -Wredundant-move on GCC>=9. GCC wants to remove std::move
204 # in code like "A foo(ConvertibleToA a) { return std::move(a); }",
205 # but this code does not compile (or uses the copy constructor
206 # instead) on clang<=3.8. Clang also has a -Wredundant-move, but it
207 # only fires when the types match exactly, so we can keep it here.
208 "-Wno-redundant-move",
212 if (is_clang && use_goma) {
213 # goma converts all paths to lowercase on the server, breaking this
215 cflags += [ "-Wno-nonportable-include-path" ]
219 # On Windows, the linker is not invoked through the compiler driver.
220 if (use_lld && host_os != "win") {
221 ldflags += [ "-fuse-ld=lld" ]
224 if (llvm_build_instrumented_coverage) {
226 "-fcoverage-mapping",
228 # Using an absolute path here is lame, but it's used at test execution
229 # time to generate the profiles, and lit doesn't specify a fixed folder
230 # for test execution -- so this is the only way to get all profiles into
231 # a single folder like llvm/utils/prepare-code-coverage-artifact.py
233 "-fprofile-instr-generate=" +
234 rebase_path("$root_build_dir/profiles/%4m.profraw"),
237 # goma has a bug where it writes the server-side absolute path.
239 # FIXME: Instead, set this to `.` for deterministic builds and pass
240 # the build dir to prepare-code-coverage-artifact.py instead.
241 cflags += [ "-fcoverage-compilation-dir=" + rebase_path(root_build_dir) ]
244 if (host_os != "win") {
245 ldflags += [ "-fprofile-instr-generate" ]
249 # Deterministic build setup, see
250 # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
251 if (current_os == "win") {
252 ldflags += [ "/pdbaltpath:%_PDB%" ]
256 "-no-canonical-prefixes",
259 if (current_os == "win") {
260 cflags += [ "-fmsc-version=1916" ]
262 cflags += [ "/Brepro" ]
263 ldflags += [ "/Brepro" ]
266 if (use_relative_paths_in_debug_info) {
268 "-fdebug-compilation-dir",
274 if (current_os == "win") {
275 assert(is_clang, "sysroot only works with clang-cl as host compiler")
276 cflags += [ "/winsysroot" + rebase_path(sysroot, root_build_dir) ]
277 } else if (current_os != "ios" && current_os != "mac") {
278 cflags += [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ]
281 if ((current_os == "ios" || current_os == "mac") &&
282 (clang_base_path != "" || sysroot != "")) {
283 if (current_os == "ios" && current_cpu == "arm64") {
284 sdk_path = ios_sdk_path
285 } else if (current_os == "ios" && current_cpu == "x64") {
286 sdk_path = iossim_sdk_path
287 } else if (current_os == "mac") {
288 sdk_path = mac_sdk_path
292 rebase_path(sdk_path, root_build_dir),
296 rebase_path(sdk_path, root_build_dir),
299 if (sysroot != "" && current_os != "win" && is_clang) {
300 cflags += [ "-Wpoison-system-directories" ]
303 !use_goma || sysroot != "",
304 "goma needs a sysroot: run `llvm/utils/sysroot.py make-fake --out-dir=sysroot` and add `sysroot = \"//sysroot\"` to your args.gn")
307 assert(is_clang && current_os == "linux",
308 "ubsan only supported on Linux/Clang")
310 "-fsanitize=undefined",
311 "-fno-sanitize-recover=all",
313 ldflags += [ "-fsanitize=undefined" ]
317 assert(is_clang && (current_os == "ios" || current_os == "linux" ||
318 current_os == "mac"),
319 "asan only supported on iOS/Clang, Linux/Clang, and macOS/Clang")
320 cflags += [ "-fsanitize=address" ]
321 ldflags += [ "-fsanitize=address" ]
325 assert(is_clang && current_os == "linux",
326 "tsan only supported on Linux/Clang")
327 cflags += [ "-fsanitize=thread" ]
328 ldflags += [ "-fsanitize=thread" ]
332 assert(is_clang, "ThinLTO only supported on Clang")
336 cflags += [ "-flto=thin" ]
338 if (host_os == "win") {
340 "/opt:lldlto=" + lto_opt_level,
341 "/opt:lldltojobs=" + max_jobs_per_lto_link,
346 "-Wl,--thinlto-jobs=" + max_jobs_per_lto_link,
347 "-Wl,--lto-O" + lto_opt_level,
353 config("no_exceptions") {
354 if (host_os != "win") {
355 cflags_cc = [ "-fno-exceptions" ]
360 if (current_os == "win") {
361 cflags_cc = [ "/GR-" ]
363 cflags_cc = [ "-fno-rtti" ]
367 # To make an archive that can be distributed, you need to remove this config and
368 # set complete_static_lib.
369 config("thin_archive") {
370 if (current_os != "ios" && current_os != "mac" && current_os != "win") {
375 config("llvm_code") {
378 "$root_gen_dir/llvm/include",
380 if (current_os != "win") {
388 "$root_gen_dir/lld/include",
392 config("clang_code") {
393 if (host_os != "win") {
394 cflags = [ "-fno-strict-aliasing" ]
398 "$root_gen_dir/clang/include",
403 include_dirs = [ "//compiler-rt/lib" ]
407 "-gline-tables-only",
408 "-fvisibility=hidden",
410 assert(is_clang, "CRT code is always built with just-built clang")
412 "-Werror=thread-safety",
413 "-Werror=thread-safety-reference",
414 "-Werror=thread-safety-beta",
418 config("warn_covered_switch_default") {
420 cflags = [ "-Wcovered-switch-default" ]