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