1import("//llvm/lib/DebugInfo/PDB/enable_dia.gni")
2import("//llvm/lib/Target/targets.gni")
3import("//llvm/lib/Target/targets_with_asm_parsers.gni")
4import("//llvm/lib/Target/targets_with_disassemblers.gni")
5import("//llvm/lib/Target/targets_with_mcas.gni")
6import("//llvm/triples.gni")
7import("//llvm/utils/gn/build/buildflags.gni")
8import("//llvm/utils/gn/build/libs/edit/enable.gni")
9import("//llvm/utils/gn/build/libs/pthread/enable.gni")
10import("//llvm/utils/gn/build/libs/terminfo/enable.gni")
11import("//llvm/utils/gn/build/libs/xar/enable.gni")
12import("//llvm/utils/gn/build/libs/xml/enable.gni")
13import("//llvm/utils/gn/build/libs/zlib/enable.gni")
14import("//llvm/utils/gn/build/write_cmake_config.gni")
15import("//llvm/version.gni")
16
17# Contains actions to create config.h, llvm-config.h, abi-breaking.h,
18# and the various .def files used by llvm/lib/Target.
19# Other than in the cmake build, these are created at build time, not at
20# config time. That way, they can run in parallel, and this pattern means that
21# e.g. creating the clang config header (which happens in another gn file)
22# doesn't block building lld.
23
24# The headers are created by processing the foo.h.cmake files as input,
25# to keep the gn build close to the cmake build.
26
27# Other than in the cmake build, header generation doesn't do any feature
28# checking. See also "Philosophy" in llvm/utils/gn/README.rst.
29
30##############################################################################
31# config.h, llvm-config.h, abi-breaking.h
32
33# FIXME: Several of the config settings go in a global config header but
34# are only used in a single translation unit -- so toggling that value
35# causes a full rebuild when it really only has to rebuild a single file.
36# Instead monolithing config headers, investigate using something like
37# https://is.gd/buildflag_header_gni instead (needs to be done in both the
38# cmake build and here).
39
40# FIXME: This hardcodes a bunch of settings I never use; some of them should
41# become declare_args if anyone wants to set them.
42
43declare_args() {
44  # Enable additional checks that alter the LLVM C++ ABI.
45  llvm_enable_abi_breaking_checks = llvm_enable_assertions
46
47  # Iterate unordered llvm containers in reverse.
48  llvm_enable_reverse_iteration = false
49}
50
51write_cmake_config("abi-breaking") {
52  input = "abi-breaking.h.cmake"
53  output = "$target_gen_dir/abi-breaking.h"
54  values = []
55
56  if (llvm_enable_abi_breaking_checks) {
57    values += [ "LLVM_ENABLE_ABI_BREAKING_CHECKS=1" ]
58  } else {
59    values += [ "LLVM_ENABLE_ABI_BREAKING_CHECKS=" ]
60  }
61
62  if (llvm_enable_reverse_iteration) {
63    values += [ "LLVM_ENABLE_REVERSE_ITERATION=1" ]
64  } else {
65    values += [ "LLVM_ENABLE_REVERSE_ITERATION=" ]
66  }
67}
68
69write_cmake_config("config") {
70  public_deps = [ ":llvm-config" ]
71
72  input = "config.h.cmake"
73  output = "$target_gen_dir/config.h"
74  values = [
75    "BUG_REPORT_URL=https://bugs.llvm.org/",
76    "ENABLE_BACKTRACES=1",
77    "ENABLE_CRASH_OVERRIDES=1",
78    "BACKTRACE_HEADER=execinfo.h",
79    "HAVE_CRASHREPORTERCLIENT_H=",
80    "HAVE_DECL_FE_ALL_EXCEPT=1",
81    "HAVE_DECL_FE_INEXACT=1",
82    "LLVM_ENABLE_CRASH_DUMPS=",
83    "HAVE_ERRNO_H=1",
84    "HAVE_FCNTL_H=1",
85    "HAVE_FENV_H=1",
86    "HAVE_FFI_CALL=",
87    "HAVE_FFI_FFI_H=",
88    "HAVE_FFI_H=",
89    "HAVE_LIBPFM=",
90    "HAVE_LIBPSAPI=",
91    "HAVE_MALLCTL=",
92    "HAVE_MALLINFO2=",
93    "HAVE_SIGNAL_H=1",
94    "HAVE_STD_IS_TRIVIALLY_COPYABLE=1",
95    "HAVE_STRERROR=1",
96    "HAVE_SYS_STAT_H=1",
97    "HAVE_SYS_TYPES_H=1",
98    "HAVE_VALGRIND_VALGRIND_H=",
99    "HAVE__ALLOCA=",
100    "HAVE___ALLOCA=",
101    "HAVE___ASHLDI3=",
102    "HAVE___ASHRDI3=",
103    "HAVE___CHKSTK=",
104    "HAVE___CHKSTK_MS=",
105    "HAVE___CMPDI2=",
106    "HAVE___DIVDI3=",
107    "HAVE___FIXDFDI=",
108    "HAVE___FIXSFDI=",
109    "HAVE___FLOATDIDF=",
110    "HAVE___LSHRDI3=",
111    "HAVE___MAIN=",
112    "HAVE___MODDI3=",
113    "HAVE___UDIVDI3=",
114    "HAVE___UMODDI3=",
115    "HAVE____CHKSTK=",
116    "HAVE____CHKSTK_MS=",
117    "HOST_LINK_VERSION=",
118    "LIBPFM_HAS_FIELD_CYCLES=",
119    "LLVM_TARGET_TRIPLE_ENV=",
120    "LLVM_VERSION_INFO=",
121    "LLVM_VERSION_PRINTER_SHOW_HOST_TARGET_INFO=1",
122    "PACKAGE_BUGREPORT=https://bugs.llvm.org/",
123    "PACKAGE_NAME=LLVM",
124    "PACKAGE_STRING=LLVM ${llvm_version}git",
125    "PACKAGE_VERSION=${llvm_version}git",
126    "PACKAGE_VENDOR=",
127    "RETSIGTYPE=void",
128    "LLVM_GISEL_COV_ENABLED=",
129    "LLVM_GISEL_COV_PREFIX=",
130
131    # This is both in llvm-config.h and config.h; llvm-config.h doesn't
132    # define it if it's not set while config.h defines it to empty in that case.
133    "LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple",
134
135    # FIXME: Set to 1 on mac once the 10.14 SDK is in common use.
136    "LLVM_SUPPORT_XCODE_SIGNPOSTS=",
137  ]
138
139  if (current_os == "linux" || current_os == "android") {
140    values += [
141      "HAVE_FUTIMENS=1",
142      "HAVE_LINK_H=1",
143      "HAVE_LSEEK64=1",
144      "HAVE_MALLINFO=1",
145      "HAVE_POSIX_FALLOCATE=1",
146      "HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC=1",
147    ]
148  } else {
149    values += [
150      "HAVE_FUTIMENS=",
151      "HAVE_LINK_H=",
152      "HAVE_LSEEK64=",
153      "HAVE_MALLINFO=",
154      "HAVE_POSIX_FALLOCATE=",
155      "HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC=",
156    ]
157  }
158
159  if (current_os == "mac") {
160    values += [
161      "HAVE_CRASHREPORTER_INFO=1",
162      "HAVE_DECL_ARC4RANDOM=1",
163      "HAVE_DLADDR=1",
164      "HAVE_MACH_MACH_H=1",
165      "HAVE_MALLOC_MALLOC_H=1",
166      "HAVE_MALLOC_ZONE_STATISTICS=1",
167      "HAVE_PROC_PID_RUSAGE=1",
168      "HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=1",
169      "HAVE_UNW_ADD_DYNAMIC_FDE=1",
170    ]
171  } else {
172    values += [
173      "HAVE_CRASHREPORTER_INFO=",
174      "HAVE_DECL_ARC4RANDOM=",
175      "HAVE_DLADDR=",
176      "HAVE_MACH_MACH_H=",
177      "HAVE_MALLOC_MALLOC_H=",
178      "HAVE_MALLOC_ZONE_STATISTICS=",
179      "HAVE_PROC_PID_RUSAGE=",
180      "HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC=",
181      "HAVE_UNW_ADD_DYNAMIC_FDE=",
182    ]
183  }
184
185  if (current_os == "linux" || current_os == "mac") {
186    values += [
187      "HAVE_BACKTRACE=1",
188      "HAVE_POSIX_SPAWN=1",
189      "HAVE_PTHREAD_GETNAME_NP=1",
190    ]
191  } else {
192    values += [
193      "HAVE_BACKTRACE=",
194      "HAVE_POSIX_SPAWN=",
195      "HAVE_PTHREAD_GETNAME_NP=",
196    ]
197  }
198
199  if (current_os == "win" || current_cpu == "arm") {
200    values += [
201      "HAVE_DEREGISTER_FRAME=",
202      "HAVE_REGISTER_FRAME=",
203    ]
204  } else {
205    values += [
206      "HAVE_DEREGISTER_FRAME=1",
207      "HAVE_REGISTER_FRAME=1",
208    ]
209  }
210
211  if (current_os == "win") {
212    values += [
213      "HAVE_DECL_STRERROR_S=1",
214      "HAVE_DLFCN_H=",
215      "HAVE_DLOPEN=",
216      "HAVE_FUTIMES=",
217      "HAVE_GETPAGESIZE=",
218      "HAVE_GETRLIMIT=",
219      "HAVE_GETRUSAGE=",
220      "HAVE_ISATTY=",
221      "HAVE_LIBPTHREAD=",
222      "HAVE_PTHREAD_SETNAME_NP=",
223      "HAVE_PREAD=",
224      "HAVE_PTHREAD_GETSPECIFIC=",
225      "HAVE_PTHREAD_H=",
226      "HAVE_PTHREAD_MUTEX_LOCK=",
227      "HAVE_PTHREAD_RWLOCK_INIT=",
228      "HAVE_SBRK=",
229      "HAVE_SETENV=",
230      "HAVE_SETRLIMIT=",
231      "HAVE_SIGALTSTACK=",
232      "HAVE_STRERROR_R=",
233      "HAVE_SYSCONF=",
234      "HAVE_SYS_IOCTL_H=",
235      "HAVE_SYS_MMAN_H=",
236      "HAVE_SYS_PARAM_H=",
237      "HAVE_SYS_RESOURCE_H=",
238      "HAVE_SYS_TIME_H=",
239      "HAVE_TERMIOS_H=",
240      "HAVE_UNISTD_H=",
241      "HAVE__CHSIZE_S=1",
242      "HAVE__UNWIND_BACKTRACE=",
243      "stricmp=_stricmp",
244      "strdup=_strdup",
245    ]
246  } else {
247    # POSIX-y system defaults.
248    values += [
249      "HAVE_DECL_STRERROR_S=",
250      "HAVE_DLFCN_H=1",
251      "HAVE_DLOPEN=1",
252      "HAVE_FUTIMES=1",
253      "HAVE_GETPAGESIZE=1",
254      "HAVE_GETRLIMIT=1",
255      "HAVE_GETRUSAGE=1",
256      "HAVE_ISATTY=1",
257      "HAVE_LIBPTHREAD=1",
258      "HAVE_PTHREAD_SETNAME_NP=1",
259      "HAVE_PREAD=1",
260      "HAVE_PTHREAD_GETSPECIFIC=1",
261      "HAVE_PTHREAD_H=1",
262      "HAVE_PTHREAD_MUTEX_LOCK=1",
263      "HAVE_PTHREAD_RWLOCK_INIT=1",
264      "HAVE_SBRK=1",
265      "HAVE_SETENV=1",
266      "HAVE_SETRLIMIT=1",
267      "HAVE_SIGALTSTACK=1",
268      "HAVE_STRERROR_R=1",
269      "HAVE_SYSCONF=1",
270      "HAVE_SYS_IOCTL_H=1",
271      "HAVE_SYS_MMAN_H=1",
272      "HAVE_SYS_PARAM_H=1",
273      "HAVE_SYS_RESOURCE_H=1",
274      "HAVE_SYS_TIME_H=1",
275      "HAVE_TERMIOS_H=1",
276      "HAVE_UNISTD_H=1",
277      "HAVE__CHSIZE_S=",
278      "HAVE__UNWIND_BACKTRACE=1",
279      "stricmp=",
280      "strdup=",
281    ]
282  }
283
284  if (current_os == "mac") {
285    shlib_ext = ".dylib"
286  } else if (current_os == "win") {
287    shlib_ext = ".dll"
288  } else {
289    shlib_ext = ".so"
290  }
291  values += [
292    "LLVM_PLUGIN_EXT=$shlib_ext",
293    "LTDL_SHLIB_EXT=$shlib_ext",
294  ]
295
296  if (llvm_enable_libedit) {
297    values += [ "HAVE_LIBEDIT=1" ]
298  } else {
299    values += [ "HAVE_LIBEDIT=" ]
300  }
301
302  if (llvm_enable_terminfo) {
303    values += [ "LLVM_ENABLE_TERMINFO=1" ]
304  } else {
305    values += [ "LLVM_ENABLE_TERMINFO=" ]
306  }
307
308  if (llvm_enable_dia_sdk) {
309    values += [ "LLVM_ENABLE_DIA_SDK=1" ]
310  } else {
311    values += [ "LLVM_ENABLE_DIA_SDK=" ]
312  }
313
314  if (llvm_enable_zlib) {
315    values += [ "LLVM_ENABLE_ZLIB=1" ]
316  } else {
317    values += [ "LLVM_ENABLE_ZLIB=" ]
318  }
319
320  if (llvm_enable_libxml2) {
321    values += [ "LLVM_ENABLE_LIBXML2=1" ]
322  } else {
323    values += [ "LLVM_ENABLE_LIBXML2=" ]
324  }
325}
326
327write_cmake_config("llvm-config") {
328  input = "llvm-config.h.cmake"
329  output = "$target_gen_dir/llvm-config.h"
330  values = [
331    "LLVM_DEFAULT_TARGET_TRIPLE=$llvm_target_triple",
332    "LLVM_ENABLE_DUMP=",
333    "LLVM_ENABLE_NEW_PASS_MANAGER=1",
334    "LLVM_FORCE_ENABLE_STATS=",
335    "LLVM_HAS_ATOMICS=1",
336    "LLVM_HAVE_TF_AOT=",
337    "LLVM_HAVE_TF_API=",
338    "LLVM_HOST_TRIPLE=$llvm_current_triple",
339    "LLVM_NATIVE_ARCH=$native_target",
340    "LLVM_NATIVE_ASMPARSER=1",
341    "LLVM_NATIVE_ASMPRINTER=1",
342    "LLVM_NATIVE_DISASSEMBLER=1",
343    "LLVM_NATIVE_TARGET=1",
344    "LLVM_NATIVE_TARGETINFO=1",
345    "LLVM_NATIVE_TARGETMC=1",
346    "LLVM_NATIVE_TARGETMCA=1",
347    "LLVM_USE_INTEL_JITEVENTS=",
348    "LLVM_USE_OPROFILE=",
349    "LLVM_USE_PERF=",
350    "LLVM_VERSION_MAJOR=$llvm_version_major",
351    "LLVM_VERSION_MINOR=$llvm_version_minor",
352    "LLVM_VERSION_PATCH=$llvm_version_patch",
353    "LLVM_WITH_Z3=",
354    "PACKAGE_VERSION=${llvm_version}git",
355  ]
356
357  if (current_os == "win") {
358    values += [
359      "HAVE_SYSEXITS_H=",
360      "LLVM_ON_UNIX=",
361    ]
362  } else {
363    values += [
364      "HAVE_SYSEXITS_H=1",
365      "LLVM_ON_UNIX=1",
366    ]
367  }
368
369  if (llvm_enable_libxar) {
370    values += [ "LLVM_HAVE_LIBXAR=1" ]
371  } else {
372    values += [ "LLVM_HAVE_LIBXAR=" ]
373  }
374
375  if (llvm_enable_threads) {
376    values += [ "LLVM_ENABLE_THREADS=1" ]
377  } else {
378    values += [ "LLVM_ENABLE_THREADS=" ]
379  }
380}
381
382##############################################################################
383# .def files used by llvm/lib/Target
384
385template("write_target_def_file") {
386  assert(defined(invoker.key), "must set 'key' in $target_name")
387  assert(defined(invoker.value), "must set 'value' in $target_name")
388
389  write_cmake_config(target_name) {
390    visibility = [ ":write_target_def_files" ]
391    input = "$target_name.in"
392    output = "$target_gen_dir/$target_name"
393
394    if (defined(invoker.all_targets)) {
395      all_targets = invoker.all_targets
396    } else {
397      all_targets = llvm_targets_to_build
398    }
399
400    # Build something like
401    # `LLVM_ENUM_ASM_PARSERS=LLVM_ASM_PARSER(ARM)\nLLVM_ASM_PARSER(X86)\n`. Note
402    # that \n is a literal '\' followed by a literal 'n', not a newline
403    # character.  (write_cmake_config.py replaces that with a real newline).
404    value = ""
405    foreach(target, all_targets) {
406      value = "$value${invoker.value}($target)\n"
407    }
408    if (all_targets == []) {
409      not_needed(invoker, [ "value" ])
410    }
411    values = [ "${invoker.key}=$value" ]
412  }
413}
414
415write_target_def_file("AsmParsers.def") {
416  key = "LLVM_ENUM_ASM_PARSERS"
417  value = "LLVM_ASM_PARSER"
418  all_targets = targets_with_asm_parsers
419}
420
421write_target_def_file("AsmPrinters.def") {
422  key = "LLVM_ENUM_ASM_PRINTERS"
423  value = "LLVM_ASM_PRINTER"
424}
425
426write_target_def_file("Disassemblers.def") {
427  key = "LLVM_ENUM_DISASSEMBLERS"
428  value = "LLVM_DISASSEMBLER"
429  all_targets = targets_with_disassemblers
430}
431
432write_target_def_file("Targets.def") {
433  key = "LLVM_ENUM_TARGETS"
434  value = "LLVM_TARGET"
435}
436
437write_target_def_file("TargetMCAs.def") {
438  key = "LLVM_ENUM_TARGETMCAS"
439  value = "LLVM_TARGETMCA"
440  all_targets = targets_with_mcas
441}
442
443group("write_target_def_files") {
444  visibility = [
445    "//llvm/lib/Support",
446    "//llvm/lib/Target",
447  ]
448  deps = [
449    ":AsmParsers.def",
450    ":AsmPrinters.def",
451    ":Disassemblers.def",
452    ":TargetMCAs.def",
453    ":Targets.def",
454  ]
455}
456