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