1// Copyright 2016 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 config
16
17import (
18	"strings"
19
20	"android/soong/android"
21)
22
23var (
24	linuxCflags = []string{
25		"-Wa,--noexecstack",
26
27		"-fPIC",
28
29		"-U_FORTIFY_SOURCE",
30		"-D_FORTIFY_SOURCE=2",
31		"-fstack-protector",
32
33		"--gcc-toolchain=${LinuxGccRoot}",
34		"-fstack-protector-strong",
35	}
36
37	linuxGlibcCflags = []string{
38		"--sysroot ${LinuxGccRoot}/sysroot",
39	}
40
41	linuxMuslCflags = []string{
42		"-D_LIBCPP_HAS_MUSL_LIBC",
43		"-DANDROID_HOST_MUSL",
44		"-nostdlibinc",
45		"--sysroot /dev/null",
46	}
47
48	linuxLdflags = []string{
49		"-Wl,-z,noexecstack",
50		"-Wl,-z,relro",
51		"-Wl,-z,now",
52		"-Wl,--no-undefined-version",
53
54		"--gcc-toolchain=${LinuxGccRoot}",
55	}
56
57	linuxLldflags = append(linuxLdflags,
58		"-Wl,--compress-debug-sections=zstd",
59	)
60
61	linuxGlibcLdflags = []string{
62		"--sysroot ${LinuxGccRoot}/sysroot",
63	}
64
65	linuxMuslLdflags = []string{
66		"-nostdlib",
67		"--sysroot /dev/null",
68	}
69
70	// Extended cflags
71	linuxX86Cflags = []string{
72		"-msse3",
73		"-m32",
74		"-march=prescott",
75		"-D_FILE_OFFSET_BITS=64",
76		"-D_LARGEFILE_SOURCE=1",
77	}
78
79	linuxX8664Cflags = []string{
80		"-m64",
81	}
82
83	linuxX86Ldflags = []string{
84		"-m32",
85		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
86		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
87		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
88	}
89
90	linuxX8664Ldflags = []string{
91		"-m64",
92		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
93		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
94		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib64",
95	}
96
97	linuxAvailableLibraries = addPrefix([]string{
98		"c",
99		"dl",
100		"gcc",
101		"gcc_s",
102		"m",
103		"ncurses",
104		"pthread",
105		"resolv",
106		"rt",
107		"util",
108	}, "-l")
109
110	muslCrtBeginStaticBinary, muslCrtEndStaticBinary   = []string{"libc_musl_crtbegin_static"}, []string{"libc_musl_crtend"}
111	muslCrtBeginSharedBinary, muslCrtEndSharedBinary   = []string{"libc_musl_crtbegin_dynamic"}, []string{"libc_musl_crtend"}
112	muslCrtBeginSharedLibrary, muslCrtEndSharedLibrary = []string{"libc_musl_crtbegin_so"}, []string{"libc_musl_crtend_so"}
113
114	MuslDefaultSharedLibraries = []string{"libc_musl"}
115)
116
117const (
118	linuxGccVersion   = "4.8.3"
119	linuxGlibcVersion = "2.17"
120)
121
122func init() {
123	pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
124	pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
125
126	// Most places use the full GCC version. A few only use up to the first two numbers.
127	if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
128		pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
129	} else {
130		pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion)
131	}
132
133	pctx.SourcePathVariable("LinuxGccRoot",
134		"prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
135
136	pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
137
138	pctx.StaticVariable("LinuxCflags", strings.Join(linuxCflags, " "))
139	pctx.StaticVariable("LinuxLdflags", strings.Join(linuxLdflags, " "))
140	pctx.StaticVariable("LinuxLldflags", strings.Join(linuxLldflags, " "))
141	pctx.StaticVariable("LinuxGlibcCflags", strings.Join(linuxGlibcCflags, " "))
142	pctx.StaticVariable("LinuxGlibcLdflags", strings.Join(linuxGlibcLdflags, " "))
143	pctx.StaticVariable("LinuxGlibcLldflags", strings.Join(linuxGlibcLdflags, " "))
144	pctx.StaticVariable("LinuxMuslCflags", strings.Join(linuxMuslCflags, " "))
145	pctx.StaticVariable("LinuxMuslLdflags", strings.Join(linuxMuslLdflags, " "))
146	pctx.StaticVariable("LinuxMuslLldflags", strings.Join(linuxMuslLdflags, " "))
147
148	pctx.StaticVariable("LinuxX86Cflags", strings.Join(linuxX86Cflags, " "))
149	pctx.StaticVariable("LinuxX8664Cflags", strings.Join(linuxX8664Cflags, " "))
150	pctx.StaticVariable("LinuxX86Ldflags", strings.Join(linuxX86Ldflags, " "))
151	pctx.StaticVariable("LinuxX86Lldflags", strings.Join(linuxX86Ldflags, " "))
152	pctx.StaticVariable("LinuxX8664Ldflags", strings.Join(linuxX8664Ldflags, " "))
153	pctx.StaticVariable("LinuxX8664Lldflags", strings.Join(linuxX8664Ldflags, " "))
154	// Yasm flags
155	pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
156	pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
157}
158
159type toolchainLinux struct {
160	toolchainBase
161	cFlags, ldFlags string
162}
163
164type toolchainLinuxX86 struct {
165	toolchain32Bit
166	toolchainLinux
167}
168
169type toolchainLinuxX8664 struct {
170	toolchain64Bit
171	toolchainLinux
172}
173
174func (t *toolchainLinuxX86) Name() string {
175	return "x86"
176}
177
178func (t *toolchainLinuxX8664) Name() string {
179	return "x86_64"
180}
181
182func (t *toolchainLinux) IncludeFlags() string {
183	return ""
184}
185
186func (t *toolchainLinuxX86) Cflags() string {
187	return "${config.LinuxCflags} ${config.LinuxX86Cflags}"
188}
189
190func (t *toolchainLinuxX86) Cppflags() string {
191	return ""
192}
193
194func (t *toolchainLinuxX8664) Cflags() string {
195	return "${config.LinuxCflags} ${config.LinuxX8664Cflags}"
196}
197
198func (t *toolchainLinuxX8664) Cppflags() string {
199	return ""
200}
201
202func (t *toolchainLinuxX86) Ldflags() string {
203	return "${config.LinuxLdflags} ${config.LinuxX86Ldflags}"
204}
205
206func (t *toolchainLinuxX86) Lldflags() string {
207	return "${config.LinuxLldflags} ${config.LinuxX86Lldflags}"
208}
209
210func (t *toolchainLinuxX8664) Ldflags() string {
211	return "${config.LinuxLdflags} ${config.LinuxX8664Ldflags}"
212}
213
214func (t *toolchainLinuxX8664) Lldflags() string {
215	return "${config.LinuxLldflags} ${config.LinuxX8664Lldflags}"
216}
217
218func (t *toolchainLinuxX86) YasmFlags() string {
219	return "${config.LinuxX86YasmFlags}"
220}
221
222func (t *toolchainLinuxX8664) YasmFlags() string {
223	return "${config.LinuxX8664YasmFlags}"
224}
225
226func (toolchainLinuxX86) LibclangRuntimeLibraryArch() string {
227	return "i386"
228}
229
230func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string {
231	return "x86_64"
232}
233
234func (t *toolchainLinux) AvailableLibraries() []string {
235	return linuxAvailableLibraries
236}
237
238func (toolchainLinux) ShlibSuffix() string {
239	return ".so"
240}
241
242func (toolchainLinux) ExecutableSuffix() string {
243	return ""
244}
245
246// glibc specialization of the linux toolchain
247
248type toolchainGlibc struct {
249	toolchainNoCrt
250}
251
252func (toolchainGlibc) Glibc() bool { return true }
253
254func (toolchainGlibc) Cflags() string {
255	return "${config.LinuxGlibcCflags}"
256}
257
258func (toolchainGlibc) Ldflags() string {
259	return "${config.LinuxGlibcLdflags}"
260}
261
262func (toolchainGlibc) Lldflags() string {
263	return "${config.LinuxGlibcLldflags}"
264}
265
266type toolchainLinuxGlibcX86 struct {
267	toolchainLinuxX86
268	toolchainGlibc
269}
270
271type toolchainLinuxGlibcX8664 struct {
272	toolchainLinuxX8664
273	toolchainGlibc
274}
275
276func (t *toolchainLinuxGlibcX86) ClangTriple() string {
277	return "i686-linux-gnu"
278}
279
280func (t *toolchainLinuxGlibcX86) Cflags() string {
281	return t.toolchainLinuxX86.Cflags() + " " + t.toolchainGlibc.Cflags()
282}
283
284func (t *toolchainLinuxGlibcX86) Ldflags() string {
285	return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainGlibc.Ldflags()
286}
287
288func (t *toolchainLinuxGlibcX86) Lldflags() string {
289	return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainGlibc.Lldflags()
290}
291
292func (t *toolchainLinuxGlibcX8664) ClangTriple() string {
293	return "x86_64-linux-gnu"
294}
295
296func (t *toolchainLinuxGlibcX8664) Cflags() string {
297	return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainGlibc.Cflags()
298}
299
300func (t *toolchainLinuxGlibcX8664) Ldflags() string {
301	return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainGlibc.Ldflags()
302}
303
304func (t *toolchainLinuxGlibcX8664) Lldflags() string {
305	return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainGlibc.Lldflags()
306}
307
308var toolchainLinuxGlibcX86Singleton Toolchain = &toolchainLinuxGlibcX86{}
309var toolchainLinuxGlibcX8664Singleton Toolchain = &toolchainLinuxGlibcX8664{}
310
311func linuxGlibcX86ToolchainFactory(arch android.Arch) Toolchain {
312	return toolchainLinuxGlibcX86Singleton
313}
314
315func linuxGlibcX8664ToolchainFactory(arch android.Arch) Toolchain {
316	return toolchainLinuxGlibcX8664Singleton
317}
318
319// musl specialization of the linux toolchain
320
321type toolchainMusl struct {
322}
323
324func (toolchainMusl) Musl() bool { return true }
325
326func (toolchainMusl) CrtBeginStaticBinary() []string       { return muslCrtBeginStaticBinary }
327func (toolchainMusl) CrtBeginSharedBinary() []string       { return muslCrtBeginSharedBinary }
328func (toolchainMusl) CrtBeginSharedLibrary() []string      { return muslCrtBeginSharedLibrary }
329func (toolchainMusl) CrtEndStaticBinary() []string         { return muslCrtEndStaticBinary }
330func (toolchainMusl) CrtEndSharedBinary() []string         { return muslCrtEndSharedBinary }
331func (toolchainMusl) CrtEndSharedLibrary() []string        { return muslCrtEndSharedLibrary }
332func (toolchainMusl) CrtPadSegmentSharedLibrary() []string { return nil }
333
334func (toolchainMusl) DefaultSharedLibraries() []string { return MuslDefaultSharedLibraries }
335
336func (toolchainMusl) Cflags() string {
337	return "${config.LinuxMuslCflags}"
338}
339
340func (toolchainMusl) Ldflags() string {
341	return "${config.LinuxMuslLdflags}"
342}
343
344func (toolchainMusl) Lldflags() string {
345	return "${config.LinuxMuslLldflags}"
346}
347
348type toolchainLinuxMuslX86 struct {
349	toolchainLinuxX86
350	toolchainMusl
351}
352
353type toolchainLinuxMuslX8664 struct {
354	toolchainLinuxX8664
355	toolchainMusl
356}
357
358func (t *toolchainLinuxMuslX86) ClangTriple() string {
359	return "i686-linux-musl"
360}
361
362func (t *toolchainLinuxMuslX86) Cflags() string {
363	return t.toolchainLinuxX86.Cflags() + " " + t.toolchainMusl.Cflags()
364}
365
366func (t *toolchainLinuxMuslX86) Ldflags() string {
367	return t.toolchainLinuxX86.Ldflags() + " " + t.toolchainMusl.Ldflags()
368}
369
370func (t *toolchainLinuxMuslX86) Lldflags() string {
371	return t.toolchainLinuxX86.Lldflags() + " " + t.toolchainMusl.Lldflags()
372}
373
374func (t *toolchainLinuxMuslX8664) ClangTriple() string {
375	return "x86_64-linux-musl"
376}
377
378func (t *toolchainLinuxMuslX8664) Cflags() string {
379	return t.toolchainLinuxX8664.Cflags() + " " + t.toolchainMusl.Cflags()
380}
381
382func (t *toolchainLinuxMuslX8664) Ldflags() string {
383	return t.toolchainLinuxX8664.Ldflags() + " " + t.toolchainMusl.Ldflags()
384}
385
386func (t *toolchainLinuxMuslX8664) Lldflags() string {
387	return t.toolchainLinuxX8664.Lldflags() + " " + t.toolchainMusl.Lldflags()
388}
389
390var toolchainLinuxMuslX86Singleton Toolchain = &toolchainLinuxMuslX86{}
391var toolchainLinuxMuslX8664Singleton Toolchain = &toolchainLinuxMuslX8664{}
392
393func linuxMuslX86ToolchainFactory(arch android.Arch) Toolchain {
394	return toolchainLinuxMuslX86Singleton
395}
396
397func linuxMuslX8664ToolchainFactory(arch android.Arch) Toolchain {
398	return toolchainLinuxMuslX8664Singleton
399}
400
401func init() {
402	registerToolchainFactory(android.Linux, android.X86, linuxGlibcX86ToolchainFactory)
403	registerToolchainFactory(android.Linux, android.X86_64, linuxGlibcX8664ToolchainFactory)
404	registerToolchainFactory(android.LinuxMusl, android.X86, linuxMuslX86ToolchainFactory)
405	registerToolchainFactory(android.LinuxMusl, android.X86_64, linuxMuslX8664ToolchainFactory)
406}
407