• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 Google Inc. All rights reserved.
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//     http://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
15package cc
16
17import (
18	"fmt"
19	"strings"
20
21	"android/soong/common"
22)
23
24var (
25	armToolchainCflags = []string{
26		"-mthumb-interwork",
27	}
28
29	armCflags = []string{
30		"-fno-exceptions", // from build/core/combo/select.mk
31		"-Wno-multichar",  // from build/core/combo/select.mk
32		"-msoft-float",
33		"-ffunction-sections",
34		"-fdata-sections",
35		"-funwind-tables",
36		"-fstack-protector-strong",
37		"-Wa,--noexecstack",
38		"-Werror=format-security",
39		"-D_FORTIFY_SOURCE=2",
40		"-fno-short-enums",
41		"-no-canonical-prefixes",
42		"-fno-canonical-system-headers",
43
44		"-fno-builtin-sin",
45		"-fno-strict-volatile-bitfields",
46
47		// TARGET_RELEASE_CFLAGS
48		"-DNDEBUG",
49		"-g",
50		"-Wstrict-aliasing=2",
51		"-fgcse-after-reload",
52		"-frerun-cse-after-loop",
53		"-frename-registers",
54	}
55
56	armCppflags = []string{
57		"-fvisibility-inlines-hidden",
58	}
59
60	armLdflags = []string{
61		"-Wl,-z,noexecstack",
62		"-Wl,-z,relro",
63		"-Wl,-z,now",
64		"-Wl,--build-id=md5",
65		"-Wl,--warn-shared-textrel",
66		"-Wl,--fatal-warnings",
67		"-Wl,--icf=safe",
68		"-Wl,--hash-style=gnu",
69		"-Wl,--no-undefined-version",
70	}
71
72	armArmCflags = []string{
73		"-O2",
74		"-fomit-frame-pointer",
75		"-fstrict-aliasing",
76		"-funswitch-loops",
77	}
78
79	armThumbCflags = []string{
80		"-mthumb",
81		"-Os",
82		"-fomit-frame-pointer",
83		"-fno-strict-aliasing",
84	}
85
86	armArchVariantCflags = map[string][]string{
87		"armv5te": []string{
88			"-march=armv5te",
89			"-mtune=xscale",
90			"-D__ARM_ARCH_5__",
91			"-D__ARM_ARCH_5T__",
92			"-D__ARM_ARCH_5E__",
93			"-D__ARM_ARCH_5TE__",
94		},
95		"armv7-a": []string{
96			"-march=armv7-a",
97			"-mfloat-abi=softfp",
98			"-mfpu=vfpv3-d16",
99		},
100		"armv7-a-neon": []string{
101			"-mfloat-abi=softfp",
102			"-mfpu=neon",
103		},
104	}
105
106	armCpuVariantCflags = map[string][]string{
107		"cortex-a7": []string{
108			"-mcpu=cortex-a7",
109		},
110		"cortex-a8": []string{
111			"-mcpu=cortex-a8",
112		},
113		"cortex-a15": []string{
114			"-mcpu=cortex-a15",
115			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
116			// don't advertise.
117			"-D__ARM_FEATURE_LPAE=1",
118		},
119	}
120
121	armClangCpuVariantCflags  = copyVariantFlags(armCpuVariantCflags)
122	armClangArchVariantCflags = copyVariantFlags(armArchVariantCflags)
123)
124
125const (
126	armGccVersion = "4.9"
127)
128
129func copyVariantFlags(m map[string][]string) map[string][]string {
130	ret := make(map[string][]string, len(m))
131	for k, v := range m {
132		l := make([]string, len(m[k]))
133		for i := range m[k] {
134			l[i] = v[i]
135		}
136		ret[k] = l
137	}
138	return ret
139}
140
141func init() {
142	replaceFirst := func(slice []string, from, to string) {
143		if slice[0] != from {
144			panic(fmt.Errorf("Expected %q, found %q", from, to))
145		}
146
147		slice[0] = to
148	}
149
150	replaceFirst(armClangArchVariantCflags["armv5te"], "-march=armv5te", "-march=armv5t")
151	armClangCpuVariantCflags["krait"] = []string{
152		"-mcpu=krait",
153		"-mfpu=neon-vfpv4",
154	}
155
156	pctx.StaticVariable("armGccVersion", armGccVersion)
157
158	pctx.SourcePathVariable("armGccRoot",
159		"prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
160
161	pctx.StaticVariable("armGccTriple", "arm-linux-androideabi")
162
163	pctx.StaticVariable("armToolchainCflags", strings.Join(armToolchainCflags, " "))
164	pctx.StaticVariable("armCflags", strings.Join(armCflags, " "))
165	pctx.StaticVariable("armLdflags", strings.Join(armLdflags, " "))
166	pctx.StaticVariable("armCppflags", strings.Join(armCppflags, " "))
167	pctx.StaticVariable("armIncludeFlags", strings.Join([]string{
168		"-isystem ${LibcRoot}/arch-arm/include",
169		"-isystem ${LibcRoot}/include",
170		"-isystem ${LibcRoot}/kernel/uapi",
171		"-isystem ${LibcRoot}/kernel/uapi/asm-arm",
172		"-isystem ${LibmRoot}/include",
173		"-isystem ${LibmRoot}/include/arm",
174	}, " "))
175
176	// Extended cflags
177
178	// ARM vs. Thumb instruction set flags
179	pctx.StaticVariable("armArmCflags", strings.Join(armArmCflags, " "))
180	pctx.StaticVariable("armThumbCflags", strings.Join(armThumbCflags, " "))
181
182	// Architecture variant cflags
183	pctx.StaticVariable("armArmv5TECflags", strings.Join(armArchVariantCflags["armv5te"], " "))
184	pctx.StaticVariable("armArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " "))
185	pctx.StaticVariable("armArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " "))
186
187	// Cpu variant cflags
188	pctx.StaticVariable("armCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " "))
189	pctx.StaticVariable("armCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " "))
190	pctx.StaticVariable("armCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " "))
191
192	// Clang cflags
193	pctx.StaticVariable("armToolchainClangCflags", strings.Join(clangFilterUnknownCflags(armToolchainCflags), " "))
194	pctx.StaticVariable("armClangCflags", strings.Join(clangFilterUnknownCflags(armCflags), " "))
195	pctx.StaticVariable("armClangLdflags", strings.Join(clangFilterUnknownCflags(armLdflags), " "))
196	pctx.StaticVariable("armClangCppflags", strings.Join(clangFilterUnknownCflags(armCppflags), " "))
197
198	// Clang ARM vs. Thumb instruction set cflags
199	pctx.StaticVariable("armClangArmCflags", strings.Join(clangFilterUnknownCflags(armArmCflags), " "))
200	pctx.StaticVariable("armClangThumbCflags", strings.Join(clangFilterUnknownCflags(armThumbCflags), " "))
201
202	// Clang cpu variant cflags
203	pctx.StaticVariable("armClangArmv5TECflags",
204		strings.Join(armClangArchVariantCflags["armv5te"], " "))
205	pctx.StaticVariable("armClangArmv7ACflags",
206		strings.Join(armClangArchVariantCflags["armv7-a"], " "))
207	pctx.StaticVariable("armClangArmv7ANeonCflags",
208		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
209
210	// Clang cpu variant cflags
211	pctx.StaticVariable("armClangCortexA7Cflags",
212		strings.Join(armClangCpuVariantCflags["cortex-a7"], " "))
213	pctx.StaticVariable("armClangCortexA8Cflags",
214		strings.Join(armClangCpuVariantCflags["cortex-a8"], " "))
215	pctx.StaticVariable("armClangCortexA15Cflags",
216		strings.Join(armClangCpuVariantCflags["cortex-a15"], " "))
217	pctx.StaticVariable("armClangKraitCflags",
218		strings.Join(armClangCpuVariantCflags["krait"], " "))
219}
220
221var (
222	armArchVariantCflagsVar = map[string]string{
223		"armv5te":      "${armArmv5TECflags}",
224		"armv7-a":      "${armArmv7ACflags}",
225		"armv7-a-neon": "${armArmv7ANeonCflags}",
226	}
227
228	armCpuVariantCflagsVar = map[string]string{
229		"":               "",
230		"cortex-a7":      "${armCortexA7Cflags}",
231		"cortex-a8":      "${armCortexA8Cflags}",
232		"cortex-a15":     "${armCortexA15Cflags}",
233		"cortex-a53":     "${armCortexA7Cflags}",
234		"cortex-a53.a57": "${armCortexA7Cflags}",
235		"krait":          "${armCortexA15Cflags}",
236		"denver":         "${armCortexA15Cflags}",
237	}
238
239	armClangArchVariantCflagsVar = map[string]string{
240		"armv5te":      "${armClangArmv5TECflags}",
241		"armv7-a":      "${armClangArmv7ACflags}",
242		"armv7-a-neon": "${armClangArmv7ANeonCflags}",
243	}
244
245	armClangCpuVariantCflagsVar = map[string]string{
246		"":               "",
247		"cortex-a7":      "${armClangCortexA7Cflags}",
248		"cortex-a8":      "${armClangCortexA8Cflags}",
249		"cortex-a15":     "${armClangCortexA15Cflags}",
250		"cortex-a53":     "${armClangCortexA7Cflags}",
251		"cortex-a53.a57": "${armClangCortexA7Cflags}",
252		"krait":          "${armClangKraitCflags}",
253		"denver":         "${armClangCortexA15Cflags}",
254	}
255)
256
257type toolchainArm struct {
258	toolchain32Bit
259	ldflags                               string
260	toolchainCflags, toolchainClangCflags string
261}
262
263func (t *toolchainArm) Name() string {
264	return "arm"
265}
266
267func (t *toolchainArm) GccRoot() string {
268	return "${armGccRoot}"
269}
270
271func (t *toolchainArm) GccTriple() string {
272	return "${armGccTriple}"
273}
274
275func (t *toolchainArm) GccVersion() string {
276	return armGccVersion
277}
278
279func (t *toolchainArm) ToolchainCflags() string {
280	return t.toolchainCflags
281}
282
283func (t *toolchainArm) Cflags() string {
284	return "${armCflags}"
285}
286
287func (t *toolchainArm) Cppflags() string {
288	return "${armCppflags}"
289}
290
291func (t *toolchainArm) Ldflags() string {
292	return t.ldflags
293}
294
295func (t *toolchainArm) IncludeFlags() string {
296	return "${armIncludeFlags}"
297}
298
299func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) {
300	switch isa {
301	case "arm":
302		return "${armArmCflags}", nil
303	case "thumb", "":
304		return "${armThumbCflags}", nil
305	default:
306		return t.toolchainBase.InstructionSetFlags(isa)
307	}
308}
309
310func (t *toolchainArm) ClangTriple() string {
311	return "${armGccTriple}"
312}
313
314func (t *toolchainArm) ToolchainClangCflags() string {
315	return t.toolchainClangCflags
316}
317
318func (t *toolchainArm) ClangCflags() string {
319	return "${armClangCflags}"
320}
321
322func (t *toolchainArm) ClangCppflags() string {
323	return "${armClangCppflags}"
324}
325
326func (t *toolchainArm) ClangLdflags() string {
327	return t.ldflags
328}
329
330func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) {
331	switch isa {
332	case "arm":
333		return "${armClangArmCflags}", nil
334	case "thumb", "":
335		return "${armClangThumbCflags}", nil
336	default:
337		return t.toolchainBase.ClangInstructionSetFlags(isa)
338	}
339}
340
341func armToolchainFactory(arch common.Arch) Toolchain {
342	var fixCortexA8 string
343	switch arch.CpuVariant {
344	case "cortex-a8", "":
345		// Generic ARM might be a Cortex A8 -- better safe than sorry
346		fixCortexA8 = "-Wl,--fix-cortex-a8"
347	default:
348		fixCortexA8 = "-Wl,--no-fix-cortex-a8"
349	}
350
351	return &toolchainArm{
352		toolchainCflags: strings.Join([]string{
353			"${armToolchainCflags}",
354			armArchVariantCflagsVar[arch.ArchVariant],
355			armCpuVariantCflagsVar[arch.CpuVariant],
356		}, " "),
357		ldflags: strings.Join([]string{
358			"${armLdflags}",
359			fixCortexA8,
360		}, " "),
361		toolchainClangCflags: strings.Join([]string{
362			"${armToolchainClangCflags}",
363			armClangArchVariantCflagsVar[arch.ArchVariant],
364			armClangCpuVariantCflagsVar[arch.CpuVariant],
365		}, " "),
366	}
367}
368
369func init() {
370	registerDeviceToolchainFactory(common.Arm, armToolchainFactory)
371}
372