|
|
import("//llvm/utils/gn/build/toolchain/compiler.gni")
|
|
|
|
|
|
declare_args() {
|
|
|
# If is_goma is true, the location of the goma client install.
|
|
|
if (host_os == "win") {
|
|
|
goma_dir = "C:/src/goma/goma-win64"
|
|
|
} else {
|
|
|
goma_dir = getenv("HOME") + "/goma"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
template("unix_toolchain") {
|
|
|
toolchain(target_name) {
|
|
|
# https://groups.google.com/a/chromium.org/d/msg/gn-dev/F_lv5T-tNDM
|
|
|
forward_variables_from(invoker.toolchain_args, "*")
|
|
|
not_needed("*")
|
|
|
|
|
|
forward_variables_from(invoker, "*")
|
|
|
|
|
|
cc = "cc"
|
|
|
cxx = "c++"
|
|
|
|
|
|
if (clang_base_path != "") {
|
|
|
cc = "$clang_base_path/bin/clang"
|
|
|
cxx = "$clang_base_path/bin/clang++"
|
|
|
}
|
|
|
|
|
|
ld = cxx # Don't use goma wrapper for linking.
|
|
|
if (use_goma) {
|
|
|
cc = "$goma_dir/gomacc $cc"
|
|
|
cxx = "$goma_dir/gomacc $cxx"
|
|
|
}
|
|
|
|
|
|
tool("cc") {
|
|
|
depfile = "{{output}}.d"
|
|
|
command = "$cc -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
|
|
|
depsformat = "gcc"
|
|
|
description = "CC {{output}}"
|
|
|
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
|
|
|
}
|
|
|
|
|
|
tool("cxx") {
|
|
|
depfile = "{{output}}.d"
|
|
|
command = "$cxx -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
|
|
|
depsformat = "gcc"
|
|
|
description = "CXX {{output}}"
|
|
|
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
|
|
|
}
|
|
|
|
|
|
tool("asm") {
|
|
|
depfile = "{{output}}.d"
|
|
|
command = "$cc -MMD -MF $depfile -o {{output}} -c {{source}} {{defines}} {{include_dirs}} {{asmflags}}"
|
|
|
depsformat = "gcc"
|
|
|
description = "ASM {{output}}"
|
|
|
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
|
|
|
}
|
|
|
|
|
|
tool("alink") {
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
command = "libtool -D -static -no_warning_for_no_symbols {{arflags}} -o {{output}} {{inputs}}"
|
|
|
} else {
|
|
|
# Remove the output file first so that ar doesn't try to modify the
|
|
|
# existing file.
|
|
|
command =
|
|
|
"rm -f {{output}} && $ar rcsD {{arflags}} {{output}} {{inputs}}"
|
|
|
}
|
|
|
description = "AR {{output}}"
|
|
|
outputs = [ "{{output_dir}}/{{target_output_name}}.a" ]
|
|
|
output_prefix = "lib"
|
|
|
default_output_dir = "{{root_out_dir}}/lib"
|
|
|
}
|
|
|
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
# gn < 1693 (e214b5d35898) doesn't support |frameworks|, requiring
|
|
|
# frameworks to be listed in |libs|, but gn >= 1808 (3028c6a426a4) forbids
|
|
|
# frameworks from appearing in |libs|. This assertion provides a helpful
|
|
|
# cue to upgrade, and is much more user-friendly than the failure that
|
|
|
# occurs when an older gn encounters |frameworks|.
|
|
|
#
|
|
|
# gn_version doesn’t actually exist in gn < 1709 (52cb644a3fb4), and
|
|
|
# defined(gn_version) doesn't actually work as expected
|
|
|
# (https://crbug.com/gn/183), so 1709 is the true minimum enforced by
|
|
|
# this construct, and if gn_version is not available, this line will still
|
|
|
# be blamed, making the resolution somewhat discoverable.
|
|
|
assert(gn_version >= 1693,
|
|
|
"Your GN is too old! " +
|
|
|
"Update it, perhaps by running llvm/utils/gn/get.py")
|
|
|
}
|
|
|
|
|
|
tool("solink") {
|
|
|
outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
command = "$ld -shared {{ldflags}} -o $outfile {{inputs}} {{libs}} {{frameworks}}"
|
|
|
default_output_extension = ".dylib"
|
|
|
} else {
|
|
|
command = "$ld -shared {{ldflags}} -Wl,-z,defs -Wl,-soname,{{target_output_name}}{{output_extension}} -o $outfile {{inputs}} {{libs}}"
|
|
|
default_output_extension = ".so"
|
|
|
}
|
|
|
description = "SOLINK $outfile"
|
|
|
outputs = [ outfile ]
|
|
|
lib_switch = "-l"
|
|
|
output_prefix = "lib"
|
|
|
default_output_dir = "{{root_out_dir}}/lib"
|
|
|
}
|
|
|
|
|
|
tool("solink_module") {
|
|
|
outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
command = "$ld -shared {{ldflags}} -Wl,-flat_namespace -Wl,-undefined,suppress -o $outfile {{inputs}} {{libs}} {{frameworks}}"
|
|
|
default_output_extension = ".dylib"
|
|
|
} else {
|
|
|
command = "$ld -shared {{ldflags}} -Wl,-soname,{{target_output_name}}{{output_extension}} -o $outfile {{inputs}} {{libs}}"
|
|
|
default_output_extension = ".so"
|
|
|
}
|
|
|
description = "SOLINK $outfile"
|
|
|
outputs = [ outfile ]
|
|
|
lib_switch = "-l"
|
|
|
default_output_dir = "{{root_out_dir}}/lib"
|
|
|
}
|
|
|
|
|
|
tool("link") {
|
|
|
outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
command =
|
|
|
"$ld {{ldflags}} -o $outfile {{inputs}} {{libs}} {{frameworks}}"
|
|
|
} else {
|
|
|
command = "$ld {{ldflags}} -o $outfile -Wl,--start-group {{inputs}} -Wl,--end-group {{libs}}"
|
|
|
}
|
|
|
description = "LINK $outfile"
|
|
|
outputs = [ outfile ]
|
|
|
lib_switch = "-l"
|
|
|
|
|
|
# Setting this allows targets to override the default executable output by
|
|
|
# setting output_dir.
|
|
|
default_output_dir = "{{root_out_dir}}/bin"
|
|
|
}
|
|
|
|
|
|
copy_command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
|
|
|
tool("copy") {
|
|
|
command = copy_command
|
|
|
description = "COPY {{source}} {{output}}"
|
|
|
}
|
|
|
|
|
|
if (current_os == "ios" || current_os == "mac") {
|
|
|
tool("copy_bundle_data") {
|
|
|
# http://serverfault.com/q/209888/43689
|
|
|
_copydir = "mkdir -p {{output}} && cd {{source}} && " +
|
|
|
"pax -rwl . \"\$OLDPWD\"/{{output}}"
|
|
|
command = "rm -rf {{output}} && if [[ -d {{source}} ]]; then " +
|
|
|
_copydir + "; else " + copy_command + "; fi"
|
|
|
description = "COPY_BUNDLE_DATA {{source}} {{output}}"
|
|
|
}
|
|
|
tool("compile_xcassets") {
|
|
|
command = "false"
|
|
|
description = "The LLVM build doesn't use any xcasset files"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
tool("stamp") {
|
|
|
command = "touch {{output}}"
|
|
|
description = "STAMP {{output}}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
unix_toolchain("unix") {
|
|
|
if (current_os != "ios" && current_os != "mac") {
|
|
|
ar = "ar"
|
|
|
}
|
|
|
|
|
|
toolchain_args = {
|
|
|
current_os = host_os
|
|
|
current_cpu = host_cpu
|
|
|
}
|
|
|
}
|
|
|
|
|
|
# This template defines a toolchain that uses just-built clang and lld
|
|
|
# as compiler and linker.
|
|
|
template("stage2_unix_toolchain") {
|
|
|
unix_toolchain(target_name) {
|
|
|
toolchain_args = {
|
|
|
forward_variables_from(invoker.toolchain_args, "*")
|
|
|
|
|
|
clang_base_path = "."
|
|
|
use_goma = false
|
|
|
}
|
|
|
|
|
|
deps = [
|
|
|
"//:clang($host_toolchain)",
|
|
|
"//:lld($host_toolchain)",
|
|
|
]
|
|
|
if (current_os != "ios" && current_os != "mac") {
|
|
|
ar = "bin/llvm-ar"
|
|
|
deps += [ "//:llvm-ar($host_toolchain)" ]
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
stage2_unix_toolchain("stage2_unix") {
|
|
|
toolchain_args = {
|
|
|
current_os = host_os
|
|
|
current_cpu = host_cpu
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (android_ndk_path != "") {
|
|
|
stage2_unix_toolchain("stage2_android_aarch64") {
|
|
|
toolchain_args = {
|
|
|
current_os = "android"
|
|
|
current_cpu = "arm64"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
stage2_unix_toolchain("stage2_android_arm") {
|
|
|
toolchain_args = {
|
|
|
current_os = "android"
|
|
|
current_cpu = "arm"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (host_os == "mac") {
|
|
|
stage2_unix_toolchain("stage2_ios_aarch64") {
|
|
|
toolchain_args = {
|
|
|
current_os = "ios"
|
|
|
current_cpu = "arm64"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
stage2_unix_toolchain("stage2_iossim_x64") {
|
|
|
toolchain_args = {
|
|
|
current_os = "ios"
|
|
|
current_cpu = "x64"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
toolchain("win") {
|
|
|
cl = "cl"
|
|
|
link = "link"
|
|
|
|
|
|
if (clang_base_path != "") {
|
|
|
cl = "$clang_base_path/bin/clang-cl"
|
|
|
if (use_lld) {
|
|
|
link = "$clang_base_path/bin/lld-link"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (use_goma) {
|
|
|
cl = "$goma_dir/gomacc $cl"
|
|
|
}
|
|
|
|
|
|
tool("cc") {
|
|
|
command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
|
|
|
depsformat = "msvc"
|
|
|
description = "CC {{output}}"
|
|
|
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
|
|
|
}
|
|
|
|
|
|
tool("cxx") {
|
|
|
command = "$cl /nologo /showIncludes /Fo{{output}} /c {{source}} {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
|
|
|
depsformat = "msvc"
|
|
|
description = "CXX {{output}}"
|
|
|
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
|
|
|
}
|
|
|
|
|
|
tool("alink") {
|
|
|
command = "$link /lib /nologo {{arflags}} /out:{{output}} {{inputs}}"
|
|
|
description = "LIB {{output}}"
|
|
|
outputs = [ "{{output_dir}}/{{target_output_name}}.lib" ]
|
|
|
default_output_dir = "{{root_out_dir}}/lib"
|
|
|
}
|
|
|
|
|
|
tool("solink") {
|
|
|
outprefix = "{{output_dir}}/{{target_output_name}}"
|
|
|
dllfile = "$outprefix{{output_extension}}"
|
|
|
libfile = "$outprefix.lib"
|
|
|
pdbfile = "$outprefix.pdb"
|
|
|
command = "$link /nologo /dll {{ldflags}} /out:$dllfile /implib:$libfile /pdb:$pdbfile {{inputs}} {{libs}} "
|
|
|
description = "LINK $dllfile"
|
|
|
link_output = libfile
|
|
|
depend_output = libfile
|
|
|
runtime_outputs = [ dllfile ]
|
|
|
outputs = [
|
|
|
dllfile,
|
|
|
libfile,
|
|
|
]
|
|
|
lib_switch = ""
|
|
|
default_output_extension = ".dll"
|
|
|
restat = true
|
|
|
|
|
|
# Put dlls next to the executables in bin/ on Windows, since Windows
|
|
|
# doesn't have a configurable rpath. This matches initialization of
|
|
|
# module_dir to bin/ in AddLLVM.cmake's set_output_directory().
|
|
|
default_output_dir = "{{root_out_dir}}/bin"
|
|
|
}
|
|
|
|
|
|
# Plugins for opt and clang and so on don't work in LLVM's Windows build
|
|
|
# since the code doesn't have export annotations, but there are a few
|
|
|
# standalone loadable modules used for unit-testing LLVM's dynamic library
|
|
|
# loading code.
|
|
|
tool("solink_module") {
|
|
|
outprefix = "{{output_dir}}/{{target_output_name}}"
|
|
|
dllfile = "$outprefix{{output_extension}}"
|
|
|
pdbfile = "$outprefix.pdb"
|
|
|
command = "$link /nologo /dll {{ldflags}} /out:$dllfile /pdb:$pdbfile {{inputs}} {{libs}} "
|
|
|
description = "LINK_MODULE $dllfile"
|
|
|
outputs = [ dllfile ]
|
|
|
lib_switch = ""
|
|
|
runtime_outputs = outputs
|
|
|
default_output_extension = ".dll"
|
|
|
|
|
|
# No default_output_dir, all clients set output_dir.
|
|
|
}
|
|
|
|
|
|
tool("link") {
|
|
|
outprefix = "{{output_dir}}/{{target_output_name}}"
|
|
|
outfile = "$outprefix{{output_extension}}"
|
|
|
pdbfile = "$outprefix.pdb"
|
|
|
command = "$link /nologo {{ldflags}} /out:$outfile /pdb:$pdbfile {{inputs}} {{libs}}"
|
|
|
description = "LINK $outfile"
|
|
|
outputs = [ outfile ]
|
|
|
lib_switch = ""
|
|
|
default_output_extension = ".exe"
|
|
|
|
|
|
# Setting this allows targets to override the default executable output by
|
|
|
# setting output_dir.
|
|
|
default_output_dir = "{{root_out_dir}}/bin"
|
|
|
}
|
|
|
|
|
|
tool("copy") {
|
|
|
# GN hands out slash-using paths, but cmd's copy needs backslashes.
|
|
|
# Use cmd's %foo:a=b% substitution feature to convert.
|
|
|
command = "cmd /c set source=\"{{source}}\" & set output=\"{{output}}\" & call copy /Y %source:/=\% %output:\=/% > nul"
|
|
|
description = "COPY {{source}} {{output}}"
|
|
|
}
|
|
|
|
|
|
tool("stamp") {
|
|
|
command = "cmd /c type nul > {{output}}"
|
|
|
description = "STAMP {{output}}"
|
|
|
}
|
|
|
|
|
|
toolchain_args = {
|
|
|
current_os = "win"
|
|
|
current_cpu = host_cpu
|
|
|
}
|
|
|
}
|