1# Copyright 2018 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5template("gcc_toolchain") {
6  toolchain(target_name) {
7    assert(defined(invoker.ar), "Caller must define ar command.")
8    assert(defined(invoker.cc), "Caller must define cc command.")
9    assert(defined(invoker.cxx), "Caller must define cxx command.")
10    assert(defined(invoker.ld), "Caller must define ld command.")
11    forward_variables_from(invoker,
12                           [
13                             "ar",
14                             "cc",
15                             "cxx",
16                             "ld",
17                           ])
18
19    toolchain_args = {
20      forward_variables_from(invoker.toolchain_args, "*")
21
22      # The host toolchain needs to be preserved by all secondary toolchains.
23      # For futher explanation, see
24      # https://gn.googlesource.com/gn/+/refs/heads/master/docs/reference.md#toolchain-overview
25      host_toolchain = host_toolchain
26    }
27
28    lib_switch = "-l"
29    lib_dir_switch = "-L"
30
31    object_prefix = "{{source_out_dir}}/{{label_name}}."
32
33    tool("cc") {
34      depfile = "{{output}}.d"
35      command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
36      depsformat = "gcc"
37      description = "CC {{output}}"
38      outputs = [
39        "$object_prefix{{source_name_part}}.o",
40      ]
41    }
42
43    tool("cxx") {
44      depfile = "{{output}}.d"
45      command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
46      depsformat = "gcc"
47      description = "CXX {{output}}"
48      outputs = [
49        "$object_prefix{{source_name_part}}.o",
50      ]
51    }
52
53    tool("asm") {
54      depfile = "{{output}}.d"
55      command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
56      depsformat = "gcc"
57      description = "ASM {{output}}"
58      outputs = [
59        "$object_prefix{{source_name_part}}.o",
60      ]
61    }
62
63    tool("alink") {
64      rspfile = "{{output}}.rsp"
65      command = "rm -f {{output}} && $ar rcs {{output}} @$rspfile"
66      description = "AR {{target_output_name}}{{output_extension}}"
67      rspfile_content = "{{inputs}}"
68      outputs = [
69        "{{output_dir}}/{{target_output_name}}{{output_extension}}",
70      ]
71      default_output_dir = "{{target_out_dir}}"
72      default_output_extension = ".a"
73      output_prefix = "lib"
74    }
75
76    tool("solink") {
77      soname = "{{target_output_name}}{{output_extension}}"  # e.g. "libfoo.so".
78      sofile = "{{output_dir}}/$soname"
79      rspfile = soname + ".rsp"
80
81      command =
82          "$ld -shared {{ldflags}} -o $sofile -Wl,-soname=$soname @$rspfile"
83      rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}"
84
85      description = "SOLINK {{output}}"
86
87      # Use this for {{output_extension}} expansions unless a target manually
88      # overrides it (in which case {{output_extension}} will be what the target
89      # specifies).
90      default_output_extension = ".so"
91
92      # Use this for {{output_dir}} expansions unless a target manually overrides
93      # it (in which case {{output_dir}} will be what the target specifies).
94      default_output_dir = "{{root_out_dir}}"
95
96      outputs = [
97        sofile,
98      ]
99      link_output = sofile
100      depend_output = sofile
101      output_prefix = "lib"
102    }
103
104    tool("link") {
105      outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
106      rspfile = "$outfile.rsp"
107
108      # These extra ldflags allow an executable to search for shared libraries in
109      # the current working directory.
110      additional_executable_ldflags = "-Wl,-rpath=\$ORIGIN/ -Wl,-rpath-link="
111      command = "$ld {{ldflags}} $additional_executable_ldflags -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}"
112      description = "LINK $outfile"
113      default_output_dir = "{{root_out_dir}}"
114      rspfile_content = "{{inputs}}"
115      outputs = [
116        outfile,
117      ]
118    }
119
120    tool("stamp") {
121      command = "touch {{output}}"
122      description = "STAMP {{output}}"
123    }
124
125    tool("copy") {
126      command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
127      description = "COPY {{source}} {{output}}"
128    }
129  }
130}
131
132template("clang_toolchain") {
133  prefix = rebase_path("$clang_base_path/bin", root_build_dir)
134
135  gcc_toolchain(target_name) {
136    ar = "$prefix/llvm-ar"
137    cc = "$prefix/clang"
138    cxx = "$prefix/clang++"
139    ld = cxx
140    toolchain_args = {
141      forward_variables_from(invoker.toolchain_args, "*")
142      is_clang = true
143    }
144  }
145}
146
147clang_toolchain("clang_x64") {
148  toolchain_args = {
149    current_cpu = "x64"
150    current_os = "linux"
151  }
152}
153
154clang_toolchain("clang_x86") {
155  toolchain_args = {
156    current_cpu = "x86"
157    current_os = "linux"
158  }
159}
160
161clang_toolchain("clang_arm") {
162  toolchain_args = {
163    current_cpu = "arm"
164    current_os = "linux"
165  }
166}
167
168clang_toolchain("clang_arm64") {
169  toolchain_args = {
170    current_cpu = "arm64"
171    current_os = "linux"
172  }
173}
174
175gcc_toolchain("gcc_x64") {
176  ar = "ar"
177  cc = "gcc"
178  cxx = "g++"
179  ld = cxx
180  toolchain_args = {
181    current_cpu = "x64"
182    current_os = "linux"
183    is_gcc = true
184  }
185}
186
187gcc_toolchain("gcc_x86") {
188  ar = "ar"
189  cc = "gcc"
190  cxx = "g++"
191  ld = cxx
192  toolchain_args = {
193    current_cpu = "x86"
194    current_os = "linux"
195    is_gcc = true
196  }
197}
198
199gcc_toolchain("gcc_arm") {
200  ar = "ar"
201  cc = "gcc"
202  cxx = "g++"
203  ld = cxx
204  toolchain_args = {
205    current_cpu = "arm"
206    current_os = "linux"
207    is_gcc = true
208  }
209}
210
211gcc_toolchain("gcc_arm64") {
212  ar = "ar"
213  cc = "gcc"
214  cxx = "g++"
215  ld = cxx
216  toolchain_args = {
217    current_cpu = "arm64"
218    current_os = "linux"
219    is_gcc = true
220  }
221}
222