xref: /netbsd-src/external/apache2/llvm/dist/llvm/utils/gn/build/BUILD.gn (revision 82d56013d7b633d116a93943de88e08335357a7c)
1import("//llvm/utils/gn/build/buildflags.gni")
2import("//llvm/utils/gn/build/mac_sdk.gni")
3import("//llvm/utils/gn/build/sysroot.gni")
4import("//llvm/utils/gn/build/toolchain/compiler.gni")
5import("//llvm/utils/gn/build/toolchain/target_flags.gni")
6
7declare_args() {
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
15
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
23
24  # The version of host gcc. Ignored if is_clang is true.
25  gcc_version = 9
26}
27
28assert(!llvm_build_instrumented_coverage || is_clang,
29       "llvm_build_instrumented_coverage requires clang as host compiler")
30
31config("compiler_defaults") {
32  defines = []
33
34  if (!llvm_enable_assertions) {
35    defines += [ "NDEBUG" ]
36  }
37
38  if (llvm_enable_expensive_checks) {
39    defines += [ "EXPENSIVE_CHECKS" ]
40  }
41
42  asmflags = target_flags
43  cflags = target_flags
44  ldflags = target_flags + target_ldflags
45
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" ]
51  }
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" ]
56  }
57
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) {
62      cflags += [ "-g" ]
63
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
69      # tradeoff.
70      if (host_os != "mac" && use_lld) {
71        cflags += [ "-ggnu-pubnames" ]  # PR34820
72        ldflags += [ "-Wl,--gdb-index" ]
73      }
74    } else if (symbol_level == 1) {
75      cflags += [ "-g1" ]
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
80      # the flag here.
81    }
82    if (is_optimized) {
83      cflags += [ "-O3" ]
84    }
85    cflags += [ "-fdiagnostics-color" ]
86    if (use_lld) {
87      ldflags += [ "-Wl,--color-diagnostics" ]
88    }
89    cflags_cc = [
90      "-std=c++14",
91      "-fvisibility-inlines-hidden",
92    ]
93  } else {
94    if (symbol_level != 0) {
95      cflags += [
96        "/Zi",
97        "/FS",
98      ]
99      if (symbol_level == 1 && is_clang) {
100        cflags += [ "-gline-tables-only" ]
101      }
102      ldflags += [ "/DEBUG" ]
103
104      # Speed up links with ghash on windows.
105      if (use_lld && is_clang) {
106        cflags += [ "-gcodeview-ghash" ]
107        ldflags += [ "/DEBUG:GHASH" ]
108      }
109    }
110    if (is_optimized) {
111      cflags += [
112        "/O2",
113        "/Gw",
114        "/Zc:inline",
115      ]
116      ldflags += [
117        "/OPT:REF",
118        "/OPT:ICF",
119      ]
120    }
121    defines += [
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",
128
129      "_HAS_EXCEPTIONS=0",
130      "_UNICODE",
131      "UNICODE",
132    ]
133    cflags += [ "/EHs-c-" ]
134
135    # The MSVC default value (1 MB) is not enough for parsing recursive C++
136    # templates in Clang.
137    ldflags += [ "/STACK:10000000" ]
138  }
139
140  # Warning setup.
141  if (host_os == "win" && !is_clang) {
142    cflags += [
143      # Suppress ''modifier' : used more than once' (__forceinline and inline).
144      "-wd4141",
145
146      # Suppress 'conversion from 'type1' to 'type2', possible loss of data'.
147      "-wd4244",
148
149      # Suppress 'conversion from 'size_t' to 'type', possible loss of data'.
150      "-wd4267",
151
152      # Suppress 'no matching operator delete found'.
153      "-wd4291",
154
155      # Suppress 'noexcept used with no exception handling mode specified'.
156      "-wd4577",
157
158      # Suppress 'destructor was implicitly defined as deleted'.
159      "-wd4624",
160
161      # Suppress 'unsafe mix of type <type> and type <type> in operation'.
162      "-wd4805",
163    ]
164  } else {
165    if (host_os == "win") {
166      cflags += [ "/W4" ]
167    } else {
168      cflags += [
169        "-Wall",
170        "-Wextra",
171      ]
172    }
173    cflags += [ "-Wno-unused-parameter" ]
174    if (is_clang) {
175      cflags += [
176        "-Wdelete-non-virtual-dtor",
177        "-Wstring-conversion",
178      ]
179    } else {
180      cflags += [
181        # GCC's -Wcomment complains about // comments ending with '\' if the
182        # next line is also a // comment.
183        "-Wno-comment",
184
185        # Disable gcc's potentially uninitialized use analysis as it presents
186        # lots of false positives.
187        "-Wno-maybe-uninitialized",
188      ]
189      cflags_cc += [
190        # The LLVM libraries have no stable C++ API, so -Wnoexcept-type is not
191        # useful.
192        "-Wno-noexcept-type",
193      ]
194      if (gcc_version >= 8) {
195        cflags_cc += [
196          # Disable -Wclass-memaccess, a C++-only warning from GCC 8 that fires
197          # on LLVM's ADT classes.
198          "-Wno-class-memaccess",
199        ]
200      }
201      if (gcc_version >= 9) {
202        cflags_cc += [
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",
209        ]
210      }
211    }
212    if (is_clang && use_goma) {
213      # goma converts all paths to lowercase on the server, breaking this
214      # warning.
215      cflags += [ "-Wno-nonportable-include-path" ]
216    }
217  }
218
219  # On Windows, the linker is not invoked through the compiler driver.
220  if (use_lld && host_os != "win") {
221    ldflags += [ "-fuse-ld=lld" ]
222  }
223
224  if (llvm_build_instrumented_coverage) {
225    cflags += [
226      "-fcoverage-mapping",
227
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
232      # expects.
233      "-fprofile-instr-generate=" +
234          rebase_path("$root_build_dir/profiles/%4m.profraw"),
235    ]
236    if (host_os != "win") {
237      ldflags += [ "-fprofile-instr-generate" ]
238    }
239  }
240
241  # Deterministic build setup, see
242  # http://blog.llvm.org/2019/11/deterministic-builds-with-clang-and-lld.html
243  if (current_os == "win") {
244    ldflags += [ "/pdbaltpath:%_PDB%" ]
245  }
246  if (is_clang) {
247    cflags += [
248      "-no-canonical-prefixes",
249      "-Werror=date-time",
250    ]
251    if (current_os == "win") {
252      cflags += [ "-fmsc-version=1916" ]
253      if (use_lld) {
254        cflags += [ "/Brepro" ]
255        ldflags += [ "/Brepro" ]
256      }
257    }
258    if (use_relative_paths_in_debug_info) {
259      cflags += [
260        "-fdebug-compilation-dir",
261        ".",
262      ]
263    }
264  }
265  if (sysroot != "") {
266    if (current_os == "win") {
267      assert(is_clang, "sysroot only works with clang-cl as host compiler")
268      cflags += [ "/winsysroot" + rebase_path(sysroot, root_build_dir) ]
269    } else if (current_os != "ios" && current_os != "mac") {
270      cflags += [ "--sysroot=" + rebase_path(sysroot, root_build_dir) ]
271    }
272  }
273  if ((current_os == "ios" || current_os == "mac") &&
274      (clang_base_path != "" || sysroot != "")) {
275    if (current_os == "ios" && current_cpu == "arm64") {
276      sdk_path = ios_sdk_path
277    } else if (current_os == "ios" && current_cpu == "x64") {
278      sdk_path = iossim_sdk_path
279    } else if (current_os == "mac") {
280      sdk_path = mac_sdk_path
281    }
282    cflags += [
283      "-isysroot",
284      rebase_path(sdk_path, root_build_dir),
285    ]
286    ldflags += [
287      "-isysroot",
288      rebase_path(sdk_path, root_build_dir),
289    ]
290  }
291  if (sysroot != "" && current_os != "win" && is_clang) {
292    cflags += [ "-Wpoison-system-directories" ]
293  }
294  assert(
295      !use_goma || sysroot != "",
296      "goma needs a sysroot: run `llvm/utils/sysroot.py make-fake --out-dir=sysroot` and add `sysroot = \"//sysroot\"` to your args.gn")
297
298  if (use_ubsan) {
299    assert(is_clang && current_os == "linux",
300           "ubsan only supported on Linux/Clang")
301    cflags += [ "-fsanitize=undefined" ]
302    ldflags += [ "-fsanitize=undefined" ]
303  }
304
305  if (use_asan) {
306    assert(is_clang && current_os == "linux",
307           "asan only supported on Linux/Clang")
308    cflags += [ "-fsanitize=address" ]
309    ldflags += [ "-fsanitize=address" ]
310  }
311
312  if (use_tsan) {
313    assert(is_clang && current_os == "linux",
314           "tsan only supported on Linux/Clang")
315    cflags += [ "-fsanitize=thread" ]
316    ldflags += [ "-fsanitize=thread" ]
317  }
318
319  if (use_thinlto) {
320    assert(is_clang, "ThinLTO only supported on Clang")
321
322    lto_opt_level = 2
323
324    cflags += [ "-flto=thin" ]
325
326    if (host_os == "win") {
327      ldflags += [
328        "/opt:lldlto=" + lto_opt_level,
329        "/opt:lldltojobs=" + max_jobs_per_lto_link,
330      ]
331    } else {
332      ldflags += [
333        "-flto=thin",
334        "-Wl,--thinlto-jobs=" + max_jobs_per_lto_link,
335        "-Wl,--lto-O" + lto_opt_level,
336      ]
337    }
338  }
339}
340
341config("no_exceptions") {
342  if (host_os != "win") {
343    cflags_cc = [ "-fno-exceptions" ]
344  }
345}
346
347config("no_rtti") {
348  if (current_os == "win") {
349    cflags_cc = [ "/GR-" ]
350  } else {
351    cflags_cc = [ "-fno-rtti" ]
352  }
353}
354
355# To make an archive that can be distributed, you need to remove this config and
356# set complete_static_lib.
357config("thin_archive") {
358  if (current_os != "ios" && current_os != "mac" && current_os != "win") {
359    arflags = [ "-T" ]
360  }
361}
362
363config("llvm_code") {
364  include_dirs = [
365    "//llvm/include",
366    "$root_gen_dir/llvm/include",
367  ]
368}
369
370config("lld_code") {
371  include_dirs = [
372    "//lld/include",
373    "$root_gen_dir/lld/include",
374  ]
375}
376
377config("clang_code") {
378  if (host_os != "win") {
379    cflags = [ "-fno-strict-aliasing" ]
380  }
381  include_dirs = [
382    "//clang/include",
383    "$root_gen_dir/clang/include",
384  ]
385}
386
387config("crt_code") {
388  include_dirs = [ "//compiler-rt/lib" ]
389  cflags = [
390    "-fPIC",
391    "-funwind-tables",
392    "-gline-tables-only",
393    "-fvisibility=hidden",
394  ]
395}
396
397config("warn_covered_switch_default") {
398  if (is_clang) {
399    cflags = [ "-Wcovered-switch-default" ]
400  }
401}
402