[Coverage] MCDC: Move findIndependencePairs deferred into MCDCRecord (#121188)
[llvm-project.git] / llvm / utils / gn / build / BUILD.gn
blob9b5254e4c9f0b1e7fc4d2c545d1a3054816d6b01
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")
7 declare_args() {
8   # Whether to build everything with test coverage information.
9   # After building with this, run tests and then run
10   #    llvm/utils/prepare-code-coverage-artifact.py \
11   #        --compilation-dir=out/gn \
12   #        .../llvm-profdata .../llvm-cov out/gn/profiles/ report/ \
13   #        out/gn/bin/llvm-undname ...
14   # to generate a HTML report for the binaries passed in the last line.
15   llvm_build_instrumented_coverage = false
17   # Whether to build everything with instrumentation for PGO
18   # After building with this:
19   # 1. Remove old profile data with `rm *.profraw`
20   # 2. Run the built instrumented binaries.
21   #    This will produce *.profraw files in the current working directory.
22   # 3. Run `llvm-profdata merge *.profraw -o llvm.profdata` to merge them.
23   # 4. Then build again, with this set to false, and with
24   #    `llvm_pgo_use = "//llvm.profdata"` set to use the created profile.
25   llvm_pgo_instrument = false
27   # If non-empty, path to merged profiling data used for optimization
28   # See documentation for llvm_pgo_instrument for how to create profile data.
29   llvm_pgo_use = ""
31   # If set, puts relative paths in debug info.
32   # Makes the build output independent of the build directory, but makes
33   # most debuggers harder to use. See "Getting to local determinism" and
34   # "Getting debuggers to work well with locally deterministic builds" in
35   # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
36   # for more information.
37   use_relative_paths_in_debug_info = false
39   # The version of host gcc. Ignored if is_clang is true.
40   gcc_version = 9
43 assert(!llvm_build_instrumented_coverage || is_clang,
44        "llvm_build_instrumented_coverage requires clang as host compiler")
45 assert(!llvm_pgo_instrument || is_clang,
46        "llvm_pgo_instrument requires clang as host compiler")
47 assert(llvm_pgo_use == "" || is_clang,
48        "llvm_pgo_use requires clang as host compiler")
49 assert(!llvm_pgo_instrument || llvm_pgo_use == "",
50        "set at most one of llvm_pgo_instrument and llvm_pgo_use")
52 config("compiler_defaults") {
53   defines = []
55   if (!llvm_enable_assertions) {
56     defines += [ "NDEBUG" ]
57   }
59   if (llvm_enable_expensive_checks) {
60     defines += [ "EXPENSIVE_CHECKS" ]
61   }
63   asmflags = target_flags
64   cflags = target_flags + target_cflags
65   cflags_cc = []
66   ldflags = target_flags + target_ldflags
68   # Mostly for compiler-rt, see compiler-rt/cmake/config-ix.cmake
69   if (current_os == "ios") {
70     asmflags += [ "-miphoneos-version-min=8.0" ]
71     cflags += [ "-miphoneos-version-min=8.0" ]
72     ldflags += [ "-miphoneos-version-min=8.0" ]
73   }
74   if (current_os == "mac") {
75     asmflags += [ "-mmacos-version-min=$mac_deployment_target" ]
76     cflags += [ "-mmacos-version-min=$mac_deployment_target" ]
77     ldflags += [ "-mmacos-version-min=$mac_deployment_target" ]
78   }
80   assert(symbol_level == 0 || symbol_level == 1 || symbol_level == 2,
81          "Unexpected symbol_level")
82   if (current_os != "win") {
83     if (symbol_level == 2) {
84       cflags += [ "-g" ]
86       # For full debug-info -g builds, --gdb-index makes links ~15% slower, and
87       # gdb symbol reading time 1500% faster (lld links in 4.4 instead of 3.9s,
88       # and gdb loads and runs it in 2s instead of in 30s).  It's likely that
89       # people doing symbol_level=2 want to run a debugger (since
90       # symbol_level=2 isn't the default). So this seems like the right
91       # tradeoff.
92       if (current_os != "mac" && use_lld) {
93         cflags += [ "-ggnu-pubnames" ]  # PR34820
94         ldflags += [ "-Wl,--gdb-index" ]
96         # Use debug fission. In this mode, detailed debug information is
97         # written to a .dwo file next to each .o file instead of into the .o
98         # file directly. The linker then only links the .o files, which contain
99         # a pointer to each .dwo file. The debugger then reads debug info out
100         # of all the .dwo files instead of from the binary.
101         #
102         # (The dwp tool can link all the debug info together into a single
103         # "debug info binary", but that's not done as part of the build.)
104         #
105         # This requires `-Wl,--gdb-index` (above) to work well.
106         #
107         # With lld, this reduces link time:
108         # - in release + symbol_level=2 builds: From 2.3s to 1.3s
109         # - in debug builds: From 5.2s to 4.6s
110         #
111         # Time needed for gdb startup and setting a breakpoint is comparable,
112         # the time from from `r` to hititng a breakpoint on main goes from 4s
113         # to 2s.
114         #
115         # (macOS's linker always keeps debug info out of its output executables
116         # and debuggers there also know to load debug info from the .o files.
117         # macOS also has a debug info linker like dwp, it's called dsymutil.
118         # This happens by default, so there's no need to pass a flag there.)
119         cflags += [ "-gsplit-dwarf" ]
120         ldflags += [ "-gsplit-dwarf" ]  # Needed for ThinLTO builds.
121       }
122     } else if (symbol_level == 1) {
123       cflags += [ "-g1" ]
124       # For linetable-only -g1 builds, --gdb-index makes links ~8% slower, but
125       # links are 4x faster than -g builds so it's a fairly small absolute cost.
126       # On the other hand, gdb startup is well below 1s with and without the
127       # index, and people using -g1 likely don't use a debugger. So don't use
128       # the flag here.
129       # Linetables always go in the .o file, even with -gsplit-dwarf, so there's
130       # no point in passing -gsplit-dwarf here.
131     }
132     if (is_optimized) {
133       cflags += [ "-O3" ]
134     }
135     cflags += [ "-fdiagnostics-color" ]
136     if (use_lld) {
137       ldflags += [ "-Wl,--color-diagnostics" ]
138     }
139     cflags_cc += [
140       "-std=c++17",
141       "-fvisibility-inlines-hidden",
142     ]
143   } else {
144     if (symbol_level != 0) {
145       cflags += [
146         "/Zi",
147         "/FS",
148       ]
149       if (symbol_level == 1 && is_clang) {
150         cflags += [ "-gline-tables-only" ]
151       }
152       ldflags += [ "/DEBUG" ]
154       # Speed up links with ghash on windows.
155       if (use_lld && is_clang) {
156         cflags += [ "-gcodeview-ghash" ]
157         ldflags += [ "/DEBUG:GHASH" ]
158       }
159     }
160     if (is_optimized) {
161       cflags += [
162         "/O2",
163         "/Gw",
164         "/Zc:inline",
165       ]
166       ldflags += [
167         "/OPT:REF",
168         "/OPT:ICF",
169       ]
170     }
171     defines += [
172       "_CRT_SECURE_NO_DEPRECATE",
173       "_CRT_SECURE_NO_WARNINGS",
174       "_CRT_NONSTDC_NO_DEPRECATE",
175       "_CRT_NONSTDC_NO_WARNINGS",
176       "_SCL_SECURE_NO_DEPRECATE",
177       "_SCL_SECURE_NO_WARNINGS",
179       "_HAS_EXCEPTIONS=0",
180       "_UNICODE",
181       "UNICODE",
182     ]
183     cflags += [ "/EHs-c-" ]
184     cflags_cc += [ "/std:c++17" ]
186     if (!is_clang) {
187       # expand __VA_ARGS__ in "OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__)"
188       cflags += [ "/Zc:preprocessor" ]
190       # cl.exe doesn't set __cplusplus correctly by default.
191       # clang-cl gets it right by default, so don't needlessly add the flag there.
192       cflags_cc += [ "/Zc:__cplusplus" ]
193     }
195     # The MSVC default value (1 MB) is not enough for parsing recursive C++
196     # templates in Clang.
197     ldflags += [ "/STACK:10000000" ]
198   }
200   # Warning setup.
201   if (current_os == "win" && !is_clang) {
202     cflags += [
203       # Suppress ''modifier' : used more than once' (__forceinline and inline).
204       "-wd4141",
206       # Suppress 'conversion from 'type1' to 'type2', possible loss of data'.
207       "-wd4244",
209       # Suppress 'conversion from 'size_t' to 'type', possible loss of data'.
210       "-wd4267",
212       # Suppress 'no matching operator delete found'.
213       "-wd4291",
215       # Suppress 'noexcept used with no exception handling mode specified'.
216       "-wd4577",
218       # Suppress 'destructor was implicitly defined as deleted'.
219       "-wd4624",
221       # Suppress 'unsafe mix of type <type> and type <type> in operation'.
222       "-wd4805",
223     ]
224   } else {
225     if (current_os == "win") {
226       cflags += [ "/W4" ]
227     } else {
228       cflags += [
229         "-Wall",
230         "-Wextra",
231       ]
232     }
233     cflags += [ "-Wno-unused-parameter" ]
234     if (is_clang) {
235       cflags += [
236         "-Wdelete-non-virtual-dtor",
237         "-Wstring-conversion",
238       ]
239     } else {
240       cflags += [
241         # GCC's -Wcomment complains about // comments ending with '\' if the
242         # next line is also a // comment.
243         "-Wno-comment",
245         # Disable gcc's potentially uninitialized use analysis as it presents
246         # lots of false positives.
247         "-Wno-maybe-uninitialized",
248       ]
249       cflags_cc += [
250         # The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not
251         # useful.
252         "-Wno-noexcept-type",
253       ]
254       if (gcc_version >= 8) {
255         cflags_cc += [
256           # Disable -Wclass-memaccess, a C++-only warning from GCC 8 that fires
257           # on LLVM's ADT classes.
258           "-Wno-class-memaccess",
259         ]
260       }
261       if (gcc_version >= 9) {
262         cflags_cc += [
263           # Disable -Wredundant-move on GCC>=9. GCC wants to remove std::move
264           # in code like "A foo(ConvertibleToA a) { return std::move(a); }",
265           # but this code does not compile (or uses the copy constructor
266           # instead) on clang<=3.8. Clang also has a -Wredundant-move, but it
267           # only fires when the types match exactly, so we can keep it here.
268           "-Wno-redundant-move",
269         ]
270       }
271     }
272   }
274   # On Windows, the linker is not invoked through the compiler driver.
275   if (use_lld && current_os != "win") {
276     ldflags += [ "-fuse-ld=lld" ]
277   }
279   if (llvm_build_instrumented_coverage) {
280     cflags += [
281       "-fcoverage-mapping",
283       # For build determinism. Using this requires passing --compilation-dir to
284       # llvm/utils/prepare-code-coverage-artifact.py.
285       "-fcoverage-compilation-dir=.",
287       # Using an absolute path here is lame, but it's used at test execution
288       # time to generate the profiles, and lit doesn't specify a fixed folder
289       # for test execution -- so this is the only way to get all profiles into
290       # a single folder like llvm/utils/prepare-code-coverage-artifact.py
291       # expects.
292       "-fprofile-instr-generate=" +
293           rebase_path("$root_build_dir/profiles/%4m.profraw"),
294     ]
295     if (current_os != "win") {
296       ldflags += [ "-fprofile-instr-generate" ]
297     }
298   }
299   if (llvm_pgo_instrument) {
300     cflags += [ "-fprofile-generate" ]
301     if (current_os != "win") {
302       ldflags += [ "-fprofile-generate" ]
303     }
304   }
305   if (llvm_pgo_use != "") {
306     cflags += [
307       "-fprofile-use=" + rebase_path(llvm_pgo_use, root_build_dir),
309       # There are always quite a few diags like
310       #     warning: foo.cpp: Function control flow change detected
311       #              (hash mismatch) [-Wbackend-plugin]
312       # in a PGO build. Since they're not unexpected, silence them.
313       "-Wno-backend-plugin",
314     ]
315   }
317   # Deterministic build setup, see
318   # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
319   if (current_os == "win") {
320     ldflags += [ "/pdbaltpath:%_PDB%" ]
321   }
322   if (is_clang) {
323     cflags += [
324       "-no-canonical-prefixes",
325       "-Werror=date-time",
326     ]
327     if (current_os == "win") {
328       cflags += [ "-fmsc-version=1926" ]
329       if (use_lld) {
330         cflags += [ "/Brepro" ]
331         ldflags += [ "/Brepro" ]
332       }
333     }
334     if (use_relative_paths_in_debug_info) {
335       cflags += [ "-fdebug-compilation-dir=." ]
336     }
337   }
338   if (sysroot != "") {
339     if (current_os == "win") {
340       assert(is_clang, "sysroot only works with clang-cl as host compiler")
341       cflags += [ "/winsysroot" + rebase_path(sysroot, root_build_dir) ]
342       if (use_lld) {
343         ldflags += [ "/winsysroot:" + rebase_path(sysroot, root_build_dir) ]
345         # FIXME: Remove once PR54409 is fixed.
346         if (current_cpu == "x64") {
347           ldflags += [ "/machine:x64" ]
348         } else if (current_cpu == "x86") {
349           ldflags += [ "/machine:x86" ]
350         }
351       }
352     } else if (current_os != "ios" && current_os != "mac" &&
353                current_os != "android") {
354       cflags += [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ]
355     }
356   }
357   if ((current_os == "ios" || current_os == "mac") &&
358       (clang_base_path != "" || sysroot != "")) {
359     if (current_os == "ios" && current_cpu == "arm64") {
360       sdk_path = ios_sdk_path
361     } else if (current_os == "ios" && current_cpu == "x64") {
362       sdk_path = iossim_sdk_path
363     } else if (current_os == "mac") {
364       sdk_path = mac_sdk_path
365     }
366     cflags += [
367       "-isysroot",
368       rebase_path(sdk_path, root_build_dir),
369     ]
370     ldflags += [
371       "-isysroot",
372       rebase_path(sdk_path, root_build_dir),
373     ]
374   }
375   if (sysroot != "" && current_os != "win" && is_clang) {
376     cflags += [ "-Wpoison-system-directories" ]
377   }
379   if (use_ubsan) {
380     assert(is_clang && (current_os == "ios" || current_os == "linux" ||
381                             current_os == "mac"),
382            "ubsan only supported on iOS/Clang, Linux/Clang, or macOS/Clang")
383     cflags += [
384       "-fsanitize=undefined",
385       "-fno-sanitize=vptr,function",
386       "-fno-sanitize-recover=all",
387     ]
388     ldflags += [ "-fsanitize=undefined" ]
389   }
391   if (use_asan) {
392     assert(is_clang && (current_os == "ios" || current_os == "linux" ||
393                             current_os == "mac"),
394            "asan only supported on iOS/Clang, Linux/Clang, or macOS/Clang")
395     cflags += [ "-fsanitize=address" ]
396     ldflags += [ "-fsanitize=address" ]
397   }
399   if (use_tsan) {
400     assert(is_clang && current_os == "linux",
401            "tsan only supported on Linux/Clang")
402     cflags += [ "-fsanitize=thread" ]
403     ldflags += [ "-fsanitize=thread" ]
404   }
406   if (use_thinlto) {
407     assert(is_clang, "ThinLTO only supported on Clang")
409     lto_opt_level = 2
411     cflags += [ "-flto=thin" ]
413     if (current_os == "win") {
414       ldflags += [
415         "/opt:lldlto=" + lto_opt_level,
416         "/opt:lldltojobs=" + max_jobs_per_lto_link,
417       ]
418     } else {
419       ldflags += [
420         "-flto=thin",
421         "-Wl,--thinlto-jobs=" + max_jobs_per_lto_link,
422         "-Wl,--lto-O" + lto_opt_level,
423       ]
424     }
425   }
427   cflags_objcc = cflags_cc
430 config("no_exceptions") {
431   cflags_cc = []
432   if (current_os != "win") {
433     cflags_cc += [ "-fno-exceptions" ]
434   }
435   cflags_objcc = cflags_cc
438 config("no_rtti") {
439   if (current_os == "win") {
440     cflags_cc = [ "/GR-" ]
441   } else {
442     cflags_cc = [ "-fno-rtti" ]
443   }
444   cflags_objcc = cflags_cc
447 config("zdefs") {
448   # -Wl,-z,defs doesn't work with sanitizers.
449   # https://clang.llvm.org/docs/AddressSanitizer.html
450   if (current_os != "ios" && current_os != "mac" && current_os != "win" &&
451       !(use_asan || use_tsan || use_ubsan)) {
452     ldflags = [ "-Wl,-z,defs" ]
453   }
456 # To make an archive that can be distributed, you need to remove this config and
457 # set complete_static_lib.
458 config("thin_archive") {
459   if (current_os != "ios" && current_os != "mac" && current_os != "win") {
460     arflags = [ "-T" ]
461   }
464 config("llvm_code") {
465   include_dirs = [
466     "//llvm/include",
467     "$root_gen_dir/llvm/include",
468   ]
469   if (current_os != "win") {
470     cflags = [ "-fPIC" ]
471   }
474 config("lld_code") {
475   include_dirs = [
476     "//lld/include",
477     "$root_gen_dir/lld/include",
478   ]
481 config("clang_code") {
482   if (current_os != "win") {
483     cflags = [ "-fno-strict-aliasing" ]
484   }
485   include_dirs = [
486     "//clang/include",
487     "$root_gen_dir/clang/include",
488   ]
491 config("bolt_code") {
492   include_dirs = [
493     "//bolt/include",
494     "$root_gen_dir/bolt/include",
495   ]
498 config("crt_code") {
499   include_dirs = [ "//compiler-rt/lib" ]
500   cflags = [
501     "-fno-builtin",
502     "-gline-tables-only",
503   ]
504   if (current_os != "win") {
505     cflags += [
506       "-fPIC",
507       "-funwind-tables",
508       "-fvisibility=hidden",
509     ]
510   } else {
511     cflags += [
512       # Disable thread safe initialization for static locals. ASan shouldn't need it.
513       # Thread safe initialization assumes that the CRT has already been initialized, but ASan initializes before the CRT.
514       "/Zc:threadSafeInit-",
515     ]
516   }
517   if (is_clang) {
518     cflags += [
519       "-Werror=thread-safety",
520       "-Werror=thread-safety-reference",
521       "-Werror=thread-safety-beta",
522     ]
523   }
526 config("lldb_code") {
527   if (current_os != "win") {
528     cflags = [ "-fno-strict-aliasing" ]
529   }
530   include_dirs = [
531     "//lldb/include",
532     "$root_gen_dir/lldb/include",
533   ]
536 config("warn_covered_switch_default") {
537   if (is_clang) {
538     cflags = [ "-Wcovered-switch-default" ]
539   }