1declare_args() {
2  host_ar = ar
3  host_cc = cc
4  host_cxx = cxx
5
6  if (is_android) {
7    if (host_os == "win") {
8      target_ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar.exe"
9      target_cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang.exe"
10      target_cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++.exe"
11    } else {
12      target_ar = "$ndk/toolchains/$ndk_gccdir-4.9/prebuilt/$ndk_host/$ndk_target/bin/ar"
13      target_cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
14      target_cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
15    }
16  } else {
17    target_ar = ar
18    target_cc = cc
19    target_cxx = cxx
20  }
21
22  cc_wrapper = ""
23}
24
25if (host_os == "win") {
26  python = "python.bat"
27  stamp = "cmd.exe /c echo >"
28} else {
29  python = "python"
30  stamp = "touch"
31}
32
33toolchain("msvc") {
34  lib_dir_switch = "/LIBPATH:"
35
36  if (msvc == 2015) {
37    bin = "$win_vc/bin/amd64"
38  } else {
39    bin = "$win_vc/Tools/MSVC/$win_toolchain_version/bin/HostX64/$target_cpu"
40  }
41
42  env_setup = ""
43  if (target_cpu == "x86") {
44    # Toolchain asset includes a script that configures for x86 building.
45    # We don't support x86 builds with local MSVC installations.
46    env_setup = "cmd /c $win_sdk/bin/SetEnv.cmd /x86 && "
47  }
48
49  cl_m32_flag = ""
50  if (clang_win != "") {
51    if (target_cpu == "x86") {
52      # cl.exe knows implicitly by the choice of executable that it's targeting
53      # x86, but clang-cl.exe needs to be told when targeting non-host
54      # platforms. (All our builders are x86-64, so x86 is always non-host.)
55      cl_m32_flag = "-m32"
56    }
57    cl = "$clang_win/bin/clang-cl.exe"
58  } else {
59    cl = "$bin/cl.exe"
60  }
61
62  tool("asm") {
63    _ml = "ml"
64    if (target_cpu == "x64") {
65      _ml += "64"
66    }
67    command = "$env_setup $bin/$_ml.exe /nologo /c /Fo {{output}} {{source}}"
68    outputs = [
69      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
70    ]
71    description = "assemble {{source}}"
72  }
73
74  tool("cc") {
75    rspfile = "{{output}}.rsp"
76    precompiled_header_type = "msvc"
77    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
78
79    # Label names may have spaces so pdbname must be quoted.
80    command = "$env_setup $cc_wrapper \"$cl\" /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
81    depsformat = "msvc"
82    outputs = [
83      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
84    ]
85    rspfile_content =
86        "{{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_c}}"
87    description = "compile {{source}}"
88  }
89
90  tool("cxx") {
91    rspfile = "{{output}}.rsp"
92    precompiled_header_type = "msvc"
93    pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
94
95    # Label names may have spaces so pdbname must be quoted.
96    command = "$env_setup $cc_wrapper \"$cl\" /nologo /showIncludes /FC @$rspfile /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
97    depsformat = "msvc"
98    outputs = [
99      "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
100    ]
101    rspfile_content =
102        "{{defines}} {{include_dirs}} {{cflags}} $cl_m32_flag {{cflags_cc}}"
103    description = "compile {{source}}"
104  }
105
106  tool("alink") {
107    rspfile = "{{output}}.rsp"
108
109    command = "$env_setup $bin/lib.exe /nologo /ignore:4221 {{arflags}} /OUT:{{output}} @$rspfile"
110    outputs = [
111      # Ignore {{output_extension}} and always use .lib, there's no reason to
112      # allow targets to override this extension on Windows.
113      "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
114    ]
115    default_output_extension = ".lib"
116    default_output_dir = "{{target_out_dir}}"
117
118    # inputs_newline works around a fixed per-line buffer size in the linker.
119    rspfile_content = "{{inputs_newline}}"
120    description = "link {{output}}"
121  }
122
123  tool("solink") {
124    dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
125    libname = "${dllname}.lib"
126    pdbname = "${dllname}.pdb"
127    rspfile = "${dllname}.rsp"
128
129    command = "$env_setup $bin/link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile"
130    outputs = [
131      dllname,
132      libname,
133      pdbname,
134    ]
135    default_output_extension = ".dll"
136    default_output_dir = "{{root_out_dir}}"
137
138    link_output = libname
139    depend_output = libname
140    runtime_outputs = [
141      dllname,
142      pdbname,
143    ]
144
145    # I don't quite understand this.  Aping Chrome's toolchain/win/BUILD.gn.
146    restat = true
147
148    # inputs_newline works around a fixed per-line buffer size in the linker.
149    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
150    description = "link {{output}}"
151  }
152
153  tool("link") {
154    exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}"
155    pdbname = "$exename.pdb"
156    rspfile = "$exename.rsp"
157
158    command =
159        "$env_setup $bin/link.exe /nologo /OUT:$exename /PDB:$pdbname @$rspfile"
160
161    default_output_extension = ".exe"
162    default_output_dir = "{{root_out_dir}}"
163    outputs = [
164      exename,
165    ]
166
167    # inputs_newline works around a fixed per-line buffer size in the linker.
168    rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}"
169    description = "link {{output}}"
170  }
171
172  tool("stamp") {
173    command = "$stamp {{output}}"
174    description = "stamp {{output}}"
175  }
176
177  tool("copy") {
178    cp_py = rebase_path("../cp.py")
179    command = "$python $cp_py {{source}} {{output}}"
180    description = "copy {{source}} {{output}}"
181  }
182}
183
184template("gcc_like_toolchain") {
185  toolchain(target_name) {
186    ar = invoker.ar
187    cc = invoker.cc
188    cxx = invoker.cxx
189    lib_switch = "-l"
190    lib_dir_switch = "-L"
191
192    tool("cc") {
193      depfile = "{{output}}.d"
194      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
195      depsformat = "gcc"
196      outputs = [
197        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
198      ]
199      description = "compile {{source}}"
200    }
201
202    tool("cxx") {
203      depfile = "{{output}}.d"
204      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
205      depsformat = "gcc"
206      outputs = [
207        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
208      ]
209      description = "compile {{source}}"
210    }
211
212    tool("objc") {
213      depfile = "{{output}}.d"
214      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_objc}} -c {{source}} -o {{output}}"
215      depsformat = "gcc"
216      outputs = [
217        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
218      ]
219      description = "compile {{source}}"
220    }
221
222    tool("objcxx") {
223      depfile = "{{output}}.d"
224      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}"
225      depsformat = "gcc"
226      outputs = [
227        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
228      ]
229      description = "compile {{source}}"
230    }
231
232    tool("asm") {
233      depfile = "{{output}}.d"
234      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
235      depsformat = "gcc"
236      outputs = [
237        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
238      ]
239      description = "assemble {{source}}"
240    }
241
242    tool("alink") {
243      rspfile = "{{output}}.rsp"
244      rspfile_content = "{{inputs}}"
245      ar_py = rebase_path("../ar.py")
246      command = "$python $ar_py $ar {{output}} $rspfile"
247      outputs = [
248        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
249      ]
250      default_output_extension = ".a"
251      output_prefix = "lib"
252      description = "link {{output}}"
253    }
254
255    tool("solink") {
256      soname = "{{target_output_name}}{{output_extension}}"
257
258      rpath = "-Wl,-soname,$soname"
259      if (is_mac) {
260        rpath = "-Wl,-install_name,@rpath/$soname"
261      }
262
263      command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
264      outputs = [
265        "{{root_out_dir}}/$soname",
266      ]
267      output_prefix = "lib"
268      default_output_extension = ".so"
269      description = "link {{output}}"
270    }
271
272    tool("link") {
273      command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
274      outputs = [
275        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
276      ]
277      description = "link {{output}}"
278    }
279
280    tool("stamp") {
281      command = "$stamp {{output}}"
282      description = "stamp {{output}}"
283    }
284
285    tool("copy") {
286      cp_py = rebase_path("../cp.py")
287      command = "$python $cp_py {{source}} {{output}}"
288      description = "copy {{source}} {{output}}"
289    }
290
291    tool("copy_bundle_data") {
292      cp_py = rebase_path("../cp.py")
293      command = "$python $cp_py {{source}} {{output}}"
294      description = "copy_bundle_data {{source}} {{output}}"
295    }
296
297    # We don't currently have any xcasset files so make this a NOP
298    tool("compile_xcassets") {
299      command = "true"
300      description = "compile_xcassets {{output}}"
301    }
302
303    toolchain_args = {
304      current_cpu = invoker.cpu
305      current_os = invoker.os
306    }
307  }
308}
309
310gcc_like_toolchain("gcc_like") {
311  cpu = current_cpu
312  os = current_os
313  ar = target_ar
314  cc = target_cc
315  cxx = target_cxx
316}
317
318gcc_like_toolchain("gcc_like_host") {
319  cpu = host_cpu
320  os = host_os
321  ar = host_ar
322  cc = host_cc
323  cxx = host_cxx
324}
325