blob: 290f1638c45f776a772e91b1260b5ae6ce04f266 [file] [log] [blame]
Andrew Scull23e93a82018-10-26 14:56:04 +01001# Copyright 2018 Google LLC
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15declare_args() {
16 # Set by arch toolchain. Prefix for binutils tools.
17 tool_prefix = ""
18}
19
20# Template for embedded toolchains; there is no support for C++ or libraries.
21# Instead, use source_set to group source together.
22template("embedded_cc_toolchain") {
23 toolchain(target_name) {
24 assert(defined(invoker.cc), "\"cc\" must be defined for ${target_name}.")
25 assert(defined(invoker.ld), "\"ld\" must be defined for ${target_name}.")
26
27 # Collect extra flags from the toolchain.
28 extra_defines = ""
29 extra_cflags = "-flto -ffunction-sections -fdata-sections"
30 extra_ldflags = "--gc-sections -pie"
31 if (defined(invoker.extra_defines)) {
32 extra_defines += " ${invoker.extra_defines}"
33 }
34 if (defined(invoker.extra_cflags)) {
35 extra_cflags += " ${invoker.extra_cflags}"
36 }
37 if (defined(invoker.extra_ldflags)) {
38 extra_ldflags += " ${invoker.extra_ldflags}"
39 }
40
41 # Define the tools.
42 tool("cc") {
43 depfile = "{{output}}.d"
44 command = "${invoker.cc} -MMD -MF $depfile ${extra_defines} {{defines}} {{include_dirs}} ${extra_cflags} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
45 depsformat = "gcc"
46 description = "CC {{output}}"
47 outputs = [
48 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
49 ]
50 }
51
52 tool("asm") {
53 depfile = "{{output}}.d"
54 command = "${invoker.cc} -MMD -MF $depfile ${extra_defines} {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
55 depsformat = "gcc"
56 description = "ASM {{output}}"
57 outputs = [
58 "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
59 ]
60 }
61
62 tool("link") {
63 outfile = "{{output_dir}}/{{target_output_name}}{{output_extension}}"
64 rspfile = "$outfile.rsp"
65 command = "${invoker.ld} ${extra_ldflags} {{ldflags}} -o $outfile --start-group @$rspfile --end-group"
66 description = "LINK $outfile"
67 default_output_dir = "{{root_out_dir}}"
68 rspfile_content = "{{inputs}}"
69 outputs = [
70 outfile,
71 ]
72 }
73
74 tool("stamp") {
75 command = "touch {{output}}"
76 description = "STAMP {{output}}"
77 }
78
79 tool("copy") {
80 command = "cp -af {{source}} {{output}}"
81 description = "COPY {{source}} {{output}}"
82 }
83
84 toolchain_args = {
85 forward_variables_from(invoker.toolchain_args, "*")
86 }
87 }
88}
89
90# Specialize for clang.
91template("embedded_clang_toolchain") {
92 assert(defined(invoker.target),
93 "\"target\" must be defined for ${target_name}.")
94 assert(defined(invoker.tool_prefix),
95 "\"tool_prefix\" must be defined for ${target_name}.")
96
97 embedded_cc_toolchain(target_name) {
98 cc = "clang -target ${invoker.target} -fcolor-diagnostics"
99 ld = "ld.lld --color-diagnostics"
100
101 extra_defines = ""
102 extra_cflags = ""
103 extra_ldflags = "-O2 -lto-O2 --icf=all --fatal-warnings"
104 if (defined(invoker.extra_defines)) {
105 extra_defines += " ${invoker.extra_defines}"
106 }
107 if (defined(invoker.extra_cflags)) {
108 extra_cflags += " ${invoker.extra_cflags}"
109 }
110 if (defined(invoker.extra_ldflags)) {
111 extra_ldflags += " ${invoker.extra_ldflags}"
112 }
113
114 toolchain_args = {
115 tool_prefix = invoker.tool_prefix
116 if (defined(invoker.toolchain_args)) {
117 forward_variables_from(invoker.toolchain_args, "*")
118 }
119 }
120 }
121}
122
123# Specialize for gcc.
124template("embedded_gcc_toolchain") {
125 assert(defined(invoker.tool_prefix),
126 "\"tool_prefix\" must be defined for ${target_name}.")
127
128 embedded_cc_toolchain(target_name) {
129 cc = "${invoker.tool_prefix}gcc -fdiagnostics-color=always"
130 ld = "${invoker.tool_prefix}ld"
131
132 extra_defines = ""
133 extra_cflags = ""
134 extra_ldflags = ""
135 if (defined(invoker.extra_defines)) {
136 extra_defines += " ${invoker.extra_defines}"
137 }
138 if (defined(invoker.extra_cflags)) {
139 extra_cflags += " ${invoker.extra_cflags}"
140 }
141 if (defined(invoker.extra_ldflags)) {
142 extra_ldflags += " ${invoker.extra_ldflags}"
143 }
144
145 toolchain_args = {
146 tool_prefix = invoker.tool_prefix
147 if (defined(invoker.toolchain_args)) {
148 forward_variables_from(invoker.toolchain_args, "*")
149 }
150 }
151 }
152}
153
154# Expand to clang and gcc variants.
155template("embedded_platform_toolchain") {
156 assert(defined(invoker.arch), "\"arch\" must be defined for ${target_name}.")
157 assert(defined(invoker.target),
158 "\"target\" must be defined for ${target_name}.")
159 assert(defined(invoker.tool_prefix),
160 "\"tool_prefix\" must be defined for ${target_name}.")
161 assert(defined(invoker.origin_address),
162 "\"origin_address\" must be defined for ${target_name}.")
163 assert(defined(invoker.max_cpus),
164 "\"max_cpus\" must be defined for ${target_name}.")
165 assert(defined(invoker.max_vms),
166 "\"max_vms\" must be defined for ${target_name}.")
167
168 defines = ""
169 cflags = "-fno-stack-protector -fno-builtin -ffreestanding -fpic"
170 ldflags = "--defsym=ORIGIN_ADDRESS=${invoker.origin_address}"
171 if (defined(invoker.extra_defines)) {
172 defines += " ${invoker.extra_defines}"
173 }
174 if (defined(invoker.extra_cflags)) {
175 cflags += " ${invoker.extra_cflags}"
176 }
177 if (defined(invoker.extra_ldflags)) {
178 ldflags += " ${invoker.extra_ldflags}"
179 }
180
181 embedded_clang_toolchain("${target_name}_clang") {
182 target = invoker.target
183 tool_prefix = invoker.tool_prefix
184 extra_defines = defines
185 extra_cflags = cflags
186 extra_ldflags = ldflags
187 toolchain_args = {
Andrew Scullb401ba32018-11-09 10:30:54 +0000188 use_platform = true
189 plat_name = invoker.target_name
190 plat_arch = invoker.arch
191 plat_max_cpus = invoker.max_cpus
192 plat_max_vms = invoker.max_vms
Andrew Scull23e93a82018-10-26 14:56:04 +0100193 if (defined(invoker.toolchain_args)) {
194 forward_variables_from(invoker.toolchain_args, "*")
195 }
196 }
197 }
198
199 embedded_gcc_toolchain("${target_name}_gcc") {
200 tool_prefix = invoker.tool_prefix
201 extra_defines = defines
202 extra_cflags = cflags
203 extra_ldflags = ldflags
204 toolchain_args = {
Andrew Scullb401ba32018-11-09 10:30:54 +0000205 use_platform = true
206 plat_name = invoker.target_name
207 plat_arch = invoker.arch
208 plat_max_cpus = invoker.max_cpus
209 plat_max_vms = invoker.max_vms
Andrew Scull23e93a82018-10-26 14:56:04 +0100210 if (defined(invoker.toolchain_args)) {
211 forward_variables_from(invoker.toolchain_args, "*")
212 }
213 }
214 }
215}
216
217# Specialize for different architectures.
218
219template("aarch64_toolchain") {
220 assert(defined(invoker.cpu), "\"cpu\" must be defiend for ${target_name}.")
221 assert(defined(invoker.origin_address),
222 "\"origin_address\" must be defined for ${target_name}.")
223 assert(defined(invoker.use_pl011),
224 "\"use_pl011\" must be defined for ${target_name}.")
225 assert(defined(invoker.max_cpus),
226 "\"max_cpus\" must be defined for ${target_name}.")
227 assert(defined(invoker.max_vms),
228 "\"max_vms\" must be defined for ${target_name}.")
229
230 embedded_platform_toolchain(target_name) {
231 forward_variables_from(invoker,
232 [
233 "origin_address",
234 "max_cpus",
235 "max_vms",
236 ])
237 arch = "aarch64"
238 target = "aarch64-none-eabi"
239 tool_prefix = "aarch64-linux-gnu-" # TODO: this isn't right for bare metal but it works.
240 extra_cflags = "-mcpu=${invoker.cpu} -mstrict-align"
241
242 if (invoker.use_pl011) {
243 assert(defined(invoker.pl011_base_address),
244 "\"pl011_base_address\" must be defined for ${target_name}.")
245 extra_defines = "-DPL011_BASE=${invoker.pl011_base_address}"
246 }
247
248 toolchain_args = {
249 arch_aarch64_use_pl011 = invoker.use_pl011
250 }
251 }
252}