109467b48Spatrickimport("//llvm/utils/gn/build/toolchain/compiler.gni") 209467b48Spatrick 309467b48Spatrickdeclare_args() { 409467b48Spatrick # If is_goma is true, the location of the goma client install. 573471bf0Spatrick # Set this to the output of `goma_ctl goma_dir`. 6*d415bd75Srobert goma_dir = "" 709467b48Spatrick} 809467b48Spatrick 973471bf0Spatrickassert(!use_goma || goma_dir != "", 10*d415bd75Srobert "set `goma_dir` to the output of `goma_ctl goma_dir` in your args.gn") 1173471bf0Spatrick 1209467b48Spatricktemplate("unix_toolchain") { 1309467b48Spatrick toolchain(target_name) { 14*d415bd75Srobert # https://groups.google.com/a/chromium.org/g/gn-dev/c/F_lv5T-tNDM 15097a140dSpatrick forward_variables_from(invoker.toolchain_args, "*") 16097a140dSpatrick not_needed("*") 17097a140dSpatrick 1809467b48Spatrick forward_variables_from(invoker, "*") 1909467b48Spatrick 20097a140dSpatrick cc = "cc" 21097a140dSpatrick cxx = "c++" 22097a140dSpatrick 23097a140dSpatrick if (clang_base_path != "") { 2473471bf0Spatrick cc = rebase_path(clang_base_path, root_build_dir) + "/bin/clang" 2573471bf0Spatrick cxx = rebase_path(clang_base_path, root_build_dir) + "/bin/clang++" 26097a140dSpatrick } 27097a140dSpatrick 28097a140dSpatrick ld = cxx # Don't use goma wrapper for linking. 29097a140dSpatrick if (use_goma) { 30097a140dSpatrick cc = "$goma_dir/gomacc $cc" 31097a140dSpatrick cxx = "$goma_dir/gomacc $cxx" 32097a140dSpatrick } 33097a140dSpatrick 3409467b48Spatrick tool("cc") { 3509467b48Spatrick depfile = "{{output}}.d" 3609467b48Spatrick command = "$cc -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}" 3709467b48Spatrick depsformat = "gcc" 3809467b48Spatrick description = "CC {{output}}" 39097a140dSpatrick outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ] 4009467b48Spatrick } 4109467b48Spatrick 4209467b48Spatrick tool("cxx") { 4309467b48Spatrick depfile = "{{output}}.d" 4409467b48Spatrick command = "$cxx -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}" 4509467b48Spatrick depsformat = "gcc" 4609467b48Spatrick description = "CXX {{output}}" 47097a140dSpatrick outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ] 4809467b48Spatrick } 4909467b48Spatrick 50*d415bd75Srobert tool("objcxx") { 51*d415bd75Srobert depfile = "{{output}}.d" 52*d415bd75Srobert command = "$cxx -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_objcc}}" 53*d415bd75Srobert depsformat = "gcc" 54*d415bd75Srobert description = "OBJCXX {{output}}" 55*d415bd75Srobert outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ] 56*d415bd75Srobert } 57*d415bd75Srobert 5809467b48Spatrick tool("asm") { 5909467b48Spatrick depfile = "{{output}}.d" 6009467b48Spatrick command = "$cc -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{asmflags}}" 6109467b48Spatrick depsformat = "gcc" 6209467b48Spatrick description = "ASM {{output}}" 63097a140dSpatrick outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ] 6409467b48Spatrick } 6509467b48Spatrick 6609467b48Spatrick tool("alink") { 6773471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 68097a140dSpatrick command = "libtool -D -static -no_warning_for_no_symbols {{arflags}} -o {{output}} {{inputs}}" 6909467b48Spatrick } else { 7009467b48Spatrick # Remove the output file first so that ar doesn't try to modify the 7109467b48Spatrick # existing file. 7209467b48Spatrick command = 7309467b48Spatrick "rm -f {{output}} && $ar rcsD {{arflags}} {{output}} {{inputs}}" 7409467b48Spatrick } 7509467b48Spatrick description = "AR {{output}}" 76097a140dSpatrick outputs = [ "{{output_dir}}/{{target_output_name}}.a" ] 7709467b48Spatrick output_prefix = "lib" 7809467b48Spatrick default_output_dir = "{{root_out_dir}}/lib" 7909467b48Spatrick } 8009467b48Spatrick 8173471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 8273471bf0Spatrick # gn < 1693 (e214b5d35898) doesn't support |frameworks|, requiring 8373471bf0Spatrick # frameworks to be listed in |libs|, but gn >= 1808 (3028c6a426a4) forbids 8473471bf0Spatrick # frameworks from appearing in |libs|. This assertion provides a helpful 8573471bf0Spatrick # cue to upgrade, and is much more user-friendly than the failure that 8673471bf0Spatrick # occurs when an older gn encounters |frameworks|. 8773471bf0Spatrick # 8873471bf0Spatrick # gn_version doesn’t actually exist in gn < 1709 (52cb644a3fb4), and 8973471bf0Spatrick # defined(gn_version) doesn't actually work as expected 9073471bf0Spatrick # (https://crbug.com/gn/183), so 1709 is the true minimum enforced by 9173471bf0Spatrick # this construct, and if gn_version is not available, this line will still 9273471bf0Spatrick # be blamed, making the resolution somewhat discoverable. 9373471bf0Spatrick assert(gn_version >= 1693, 9473471bf0Spatrick "Your GN is too old! " + 9573471bf0Spatrick "Update it, perhaps by running llvm/utils/gn/get.py") 9673471bf0Spatrick } 9773471bf0Spatrick 98*d415bd75Srobert # Make these apply to all tools below. 99*d415bd75Srobert lib_switch = "-l" 100*d415bd75Srobert lib_dir_switch = "-L" 101*d415bd75Srobert 10209467b48Spatrick tool("solink") { 10309467b48Spatrick outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}" 10473471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 10573471bf0Spatrick command = "$ld -shared {{ldflags}} -o $outfile {{inputs}} {{libs}} {{frameworks}}" 10609467b48Spatrick default_output_extension = ".dylib" 10709467b48Spatrick } else { 108*d415bd75Srobert command = "$ld -shared {{ldflags}} -Wl,-soname,{{target_output_name}}{{output_extension}} -o $outfile {{inputs}} {{libs}}" 10909467b48Spatrick default_output_extension = ".so" 11009467b48Spatrick } 11109467b48Spatrick description = "SOLINK $outfile" 112097a140dSpatrick outputs = [ outfile ] 11309467b48Spatrick output_prefix = "lib" 11409467b48Spatrick default_output_dir = "{{root_out_dir}}/lib" 11509467b48Spatrick } 11609467b48Spatrick 11709467b48Spatrick tool("solink_module") { 11809467b48Spatrick outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}" 11973471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 12073471bf0Spatrick command = "$ld -shared {{ldflags}} -Wl,-flat_namespace -Wl,-undefined,suppress -o $outfile {{inputs}} {{libs}} {{frameworks}}" 12109467b48Spatrick default_output_extension = ".dylib" 12209467b48Spatrick } else { 123097a140dSpatrick command = "$ld -shared {{ldflags}} -Wl,-soname,{{target_output_name}}{{output_extension}} -o $outfile {{inputs}} {{libs}}" 12409467b48Spatrick default_output_extension = ".so" 12509467b48Spatrick } 12609467b48Spatrick description = "SOLINK $outfile" 127097a140dSpatrick outputs = [ outfile ] 12809467b48Spatrick default_output_dir = "{{root_out_dir}}/lib" 12909467b48Spatrick } 13009467b48Spatrick 13109467b48Spatrick tool("link") { 13209467b48Spatrick outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}" 13373471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 13473471bf0Spatrick command = 13573471bf0Spatrick "$ld {{ldflags}} -o $outfile {{inputs}} {{libs}} {{frameworks}}" 13609467b48Spatrick } else { 137097a140dSpatrick command = "$ld {{ldflags}} -o $outfile -Wl,--start-group {{inputs}} -Wl,--end-group {{libs}}" 13809467b48Spatrick } 13909467b48Spatrick description = "LINK $outfile" 140097a140dSpatrick outputs = [ outfile ] 14109467b48Spatrick 14209467b48Spatrick # Setting this allows targets to override the default executable output by 14309467b48Spatrick # setting output_dir. 14409467b48Spatrick default_output_dir = "{{root_out_dir}}/bin" 14509467b48Spatrick } 14609467b48Spatrick 14709467b48Spatrick copy_command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})" 14809467b48Spatrick tool("copy") { 14909467b48Spatrick command = copy_command 15009467b48Spatrick description = "COPY {{source}} {{output}}" 15109467b48Spatrick } 15209467b48Spatrick 15373471bf0Spatrick if (current_os == "ios" || current_os == "mac") { 15409467b48Spatrick tool("copy_bundle_data") { 15573471bf0Spatrick # https://github.com/nico/hack/blob/master/notes/copydir.md 15673471bf0Spatrick _copydir = "cd {{source}} && " + 15773471bf0Spatrick "find . | cpio -pdl \"\$OLDPWD\"/{{output}} 2>/dev/null" 15809467b48Spatrick command = "rm -rf {{output}} && if [[ -d {{source}} ]]; then " + 15909467b48Spatrick _copydir + "; else " + copy_command + "; fi" 16009467b48Spatrick description = "COPY_BUNDLE_DATA {{source}} {{output}}" 16109467b48Spatrick } 16209467b48Spatrick tool("compile_xcassets") { 16309467b48Spatrick command = "false" 16409467b48Spatrick description = "The LLVM build doesn't use any xcasset files" 16509467b48Spatrick } 16609467b48Spatrick } 16709467b48Spatrick 16809467b48Spatrick tool("stamp") { 16909467b48Spatrick command = "touch {{output}}" 17009467b48Spatrick description = "STAMP {{output}}" 17109467b48Spatrick } 17209467b48Spatrick } 17309467b48Spatrick} 17409467b48Spatrick 17509467b48Spatrickunix_toolchain("unix") { 17673471bf0Spatrick if (current_os != "ios" && current_os != "mac") { 177*d415bd75Srobert if (clang_base_path != "") { 178*d415bd75Srobert ar = rebase_path(clang_base_path, root_build_dir) + "/bin/llvm-ar" 179*d415bd75Srobert } else { 18009467b48Spatrick ar = "ar" 18109467b48Spatrick } 182*d415bd75Srobert } 18309467b48Spatrick 18409467b48Spatrick toolchain_args = { 18509467b48Spatrick current_os = host_os 18609467b48Spatrick current_cpu = host_cpu 18709467b48Spatrick } 18809467b48Spatrick} 18909467b48Spatrick 19009467b48Spatrick# This template defines a toolchain that uses just-built clang and lld 19109467b48Spatrick# as compiler and linker. 19209467b48Spatricktemplate("stage2_unix_toolchain") { 19309467b48Spatrick unix_toolchain(target_name) { 194097a140dSpatrick toolchain_args = { 195097a140dSpatrick forward_variables_from(invoker.toolchain_args, "*") 19609467b48Spatrick 19773471bf0Spatrick clang_base_path = root_build_dir 198097a140dSpatrick use_goma = false 19909467b48Spatrick } 20009467b48Spatrick 20109467b48Spatrick deps = [ 20209467b48Spatrick "//:clang($host_toolchain)", 20309467b48Spatrick "//:lld($host_toolchain)", 20409467b48Spatrick ] 205*d415bd75Srobert if (toolchain_args.current_os != "ios" && 206*d415bd75Srobert toolchain_args.current_os != "mac") { 207097a140dSpatrick ar = "bin/llvm-ar" 20809467b48Spatrick deps += [ "//:llvm-ar($host_toolchain)" ] 20909467b48Spatrick } 21009467b48Spatrick } 21109467b48Spatrick} 21209467b48Spatrick 21309467b48Spatrickstage2_unix_toolchain("stage2_unix") { 21409467b48Spatrick toolchain_args = { 21509467b48Spatrick current_os = host_os 21609467b48Spatrick current_cpu = host_cpu 21709467b48Spatrick } 21809467b48Spatrick} 21909467b48Spatrick 22009467b48Spatrickif (android_ndk_path != "") { 22109467b48Spatrick stage2_unix_toolchain("stage2_android_aarch64") { 22209467b48Spatrick toolchain_args = { 22309467b48Spatrick current_os = "android" 22409467b48Spatrick current_cpu = "arm64" 22509467b48Spatrick } 22609467b48Spatrick } 22709467b48Spatrick 22809467b48Spatrick stage2_unix_toolchain("stage2_android_arm") { 22909467b48Spatrick toolchain_args = { 23009467b48Spatrick current_os = "android" 23109467b48Spatrick current_cpu = "arm" 23209467b48Spatrick } 23309467b48Spatrick } 23409467b48Spatrick} 23509467b48Spatrick 23673471bf0Spatrickif (host_os == "mac") { 23773471bf0Spatrick stage2_unix_toolchain("stage2_ios_aarch64") { 23873471bf0Spatrick toolchain_args = { 23973471bf0Spatrick current_os = "ios" 24073471bf0Spatrick current_cpu = "arm64" 24173471bf0Spatrick } 24273471bf0Spatrick } 24373471bf0Spatrick 24473471bf0Spatrick stage2_unix_toolchain("stage2_iossim_x64") { 24573471bf0Spatrick toolchain_args = { 24673471bf0Spatrick current_os = "ios" 24773471bf0Spatrick current_cpu = "x64" 24873471bf0Spatrick } 24973471bf0Spatrick } 25073471bf0Spatrick} 25173471bf0Spatrick 252*d415bd75Srobertstage2_unix_toolchain("stage2_baremetal_aarch64") { 253*d415bd75Srobert toolchain_args = { 254*d415bd75Srobert current_os = "baremetal" 255*d415bd75Srobert current_cpu = "arm64" 256*d415bd75Srobert 257*d415bd75Srobert # FIXME: These should be set in all toolchains building sanitizers, 258*d415bd75Srobert # see discussion at https://reviews.llvm.org/D127906#3587329 259*d415bd75Srobert use_asan = false 260*d415bd75Srobert use_tsan = false 261*d415bd75Srobert use_ubsan = false 262*d415bd75Srobert } 263*d415bd75Srobert} 264*d415bd75Srobert 26573471bf0Spatricktemplate("win_toolchain") { 26673471bf0Spatrick toolchain(target_name) { 26773471bf0Spatrick # https://groups.google.com/a/chromium.org/d/msg/gn-dev/F_lv5T-tNDM 26873471bf0Spatrick forward_variables_from(invoker.toolchain_args, "*") 26973471bf0Spatrick not_needed("*") 27073471bf0Spatrick 27173471bf0Spatrick forward_variables_from(invoker, "*") 27273471bf0Spatrick 27309467b48Spatrick cl = "cl" 27409467b48Spatrick link = "link" 27509467b48Spatrick 27609467b48Spatrick if (clang_base_path != "") { 27773471bf0Spatrick cl = rebase_path(clang_base_path, root_build_dir) + "/bin/clang-cl" 27809467b48Spatrick if (use_lld) { 27973471bf0Spatrick link = rebase_path(clang_base_path, root_build_dir) + "/bin/lld-link" 28009467b48Spatrick } 28109467b48Spatrick } 28209467b48Spatrick 28309467b48Spatrick if (use_goma) { 28409467b48Spatrick cl = "$goma_dir/gomacc $cl" 28509467b48Spatrick } 28609467b48Spatrick 28709467b48Spatrick tool("cc") { 28809467b48Spatrick command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}" 28909467b48Spatrick depsformat = "msvc" 29009467b48Spatrick description = "CC {{output}}" 291097a140dSpatrick outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ] 29209467b48Spatrick } 29309467b48Spatrick 29409467b48Spatrick tool("cxx") { 29509467b48Spatrick command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}" 29609467b48Spatrick depsformat = "msvc" 29709467b48Spatrick description = "CXX {{output}}" 298097a140dSpatrick outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ] 29909467b48Spatrick } 30009467b48Spatrick 30109467b48Spatrick tool("alink") { 30209467b48Spatrick command = "$link /lib /nologo {{arflags}} /out:{{output}} {{inputs}}" 30309467b48Spatrick description = "LIB {{output}}" 304097a140dSpatrick outputs = [ "{{output_dir}}/{{target_output_name}}.lib" ] 30509467b48Spatrick default_output_dir = "{{root_out_dir}}/lib" 30609467b48Spatrick } 30709467b48Spatrick 308*d415bd75Srobert # Make these apply to all tools below. 309*d415bd75Srobert lib_switch = "" 310*d415bd75Srobert lib_dir_switch = "/LIBPATH:" 311*d415bd75Srobert 31209467b48Spatrick tool("solink") { 31309467b48Spatrick outprefix = "{{output_dir}}/{{target_output_name}}" 31409467b48Spatrick dllfile = "$outprefix{{output_extension}}" 31509467b48Spatrick libfile = "$outprefix.lib" 31609467b48Spatrick pdbfile = "$outprefix.pdb" 317097a140dSpatrick command = "$link /nologo /dll {{ldflags}} /out:$dllfile /implib:$libfile /pdb:$pdbfile {{inputs}} {{libs}} " 31809467b48Spatrick description = "LINK $dllfile" 31909467b48Spatrick link_output = libfile 32009467b48Spatrick depend_output = libfile 32109467b48Spatrick runtime_outputs = [ dllfile ] 32209467b48Spatrick outputs = [ 32309467b48Spatrick dllfile, 32409467b48Spatrick libfile, 32509467b48Spatrick ] 32609467b48Spatrick default_output_extension = ".dll" 32709467b48Spatrick restat = true 32809467b48Spatrick 32909467b48Spatrick # Put dlls next to the executables in bin/ on Windows, since Windows 33009467b48Spatrick # doesn't have a configurable rpath. This matches initialization of 33109467b48Spatrick # module_dir to bin/ in AddLLVM.cmake's set_output_directory(). 33209467b48Spatrick default_output_dir = "{{root_out_dir}}/bin" 33309467b48Spatrick } 33409467b48Spatrick 33509467b48Spatrick # Plugins for opt and clang and so on don't work in LLVM's Windows build 33609467b48Spatrick # since the code doesn't have export annotations, but there are a few 33709467b48Spatrick # standalone loadable modules used for unit-testing LLVM's dynamic library 33809467b48Spatrick # loading code. 33909467b48Spatrick tool("solink_module") { 34009467b48Spatrick outprefix = "{{output_dir}}/{{target_output_name}}" 34109467b48Spatrick dllfile = "$outprefix{{output_extension}}" 34209467b48Spatrick pdbfile = "$outprefix.pdb" 343097a140dSpatrick command = "$link /nologo /dll {{ldflags}} /out:$dllfile /pdb:$pdbfile {{inputs}} {{libs}} " 34409467b48Spatrick description = "LINK_MODULE $dllfile" 345097a140dSpatrick outputs = [ dllfile ] 34609467b48Spatrick runtime_outputs = outputs 34709467b48Spatrick default_output_extension = ".dll" 34809467b48Spatrick 34909467b48Spatrick # No default_output_dir, all clients set output_dir. 35009467b48Spatrick } 35109467b48Spatrick 35209467b48Spatrick tool("link") { 35309467b48Spatrick outprefix = "{{output_dir}}/{{target_output_name}}" 35409467b48Spatrick outfile = "$outprefix{{output_extension}}" 35509467b48Spatrick pdbfile = "$outprefix.pdb" 356097a140dSpatrick command = "$link /nologo {{ldflags}} /out:$outfile /pdb:$pdbfile {{inputs}} {{libs}}" 35709467b48Spatrick description = "LINK $outfile" 358097a140dSpatrick outputs = [ outfile ] 35909467b48Spatrick default_output_extension = ".exe" 36009467b48Spatrick 36109467b48Spatrick # Setting this allows targets to override the default executable output by 36209467b48Spatrick # setting output_dir. 36309467b48Spatrick default_output_dir = "{{root_out_dir}}/bin" 36409467b48Spatrick } 36509467b48Spatrick 36609467b48Spatrick tool("copy") { 36709467b48Spatrick # GN hands out slash-using paths, but cmd's copy needs backslashes. 36809467b48Spatrick # Use cmd's %foo:a=b% substitution feature to convert. 36909467b48Spatrick command = "cmd /c set source=\"{{source}}\" & set output=\"{{output}}\" & call copy /Y %source:/=\% %output:\=/% > nul" 37009467b48Spatrick description = "COPY {{source}} {{output}}" 37109467b48Spatrick } 37209467b48Spatrick 37309467b48Spatrick tool("stamp") { 37409467b48Spatrick command = "cmd /c type nul > {{output}}" 37509467b48Spatrick description = "STAMP {{output}}" 37609467b48Spatrick } 37773471bf0Spatrick } 37873471bf0Spatrick} 37909467b48Spatrick 38073471bf0Spatrickwin_toolchain("win") { 38109467b48Spatrick toolchain_args = { 38209467b48Spatrick current_os = "win" 38309467b48Spatrick current_cpu = host_cpu 38409467b48Spatrick } 38509467b48Spatrick} 38673471bf0Spatrick 38773471bf0Spatrickwin_toolchain("stage2_win") { 38873471bf0Spatrick toolchain_args = { 38973471bf0Spatrick current_os = host_os 39073471bf0Spatrick current_cpu = host_cpu 39173471bf0Spatrick 39273471bf0Spatrick clang_base_path = root_build_dir 39373471bf0Spatrick use_goma = false 39473471bf0Spatrick } 39573471bf0Spatrick deps = [ 39673471bf0Spatrick "//:clang($host_toolchain)", 39773471bf0Spatrick "//:lld($host_toolchain)", 39873471bf0Spatrick ] 39973471bf0Spatrick} 400*d415bd75Srobert 401*d415bd75Srobertwin_toolchain("stage2_win_x86") { 402*d415bd75Srobert toolchain_args = { 403*d415bd75Srobert current_os = host_os 404*d415bd75Srobert current_cpu = "x86" 405*d415bd75Srobert 406*d415bd75Srobert clang_base_path = root_build_dir 407*d415bd75Srobert use_goma = false 408*d415bd75Srobert } 409*d415bd75Srobert deps = [ 410*d415bd75Srobert "//:clang($host_toolchain)", 411*d415bd75Srobert "//:lld($host_toolchain)", 412*d415bd75Srobert ] 413*d415bd75Srobert} 414