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		"-fdiagnostics-color",
26
27		"-Wa,--noexecstack",
28
29		"-fPIC",
30
31		"-U_FORTIFY_SOURCE",
32		"-D_FORTIFY_SOURCE=2",
33		"-fstack-protector",
34
35		// Workaround differences in inttypes.h between host and target.
36		//See bug 12708004.
37		"-D__STDC_FORMAT_MACROS",
38		"-D__STDC_CONSTANT_MACROS",
39	}
40
41	linuxLdflags = []string{
42		"-Wl,-z,noexecstack",
43		"-Wl,-z,relro",
44		"-Wl,-z,now",
45		"-Wl,--no-undefined-version",
46	}
47
48	// Extended cflags
49	linuxX86Cflags = []string{
50		"-msse3",
51		"-mfpmath=sse",
52		"-m32",
53		"-march=prescott",
54		"-D_FILE_OFFSET_BITS=64",
55		"-D_LARGEFILE_SOURCE=1",
56	}
57
58	linuxX8664Cflags = []string{
59		"-m64",
60	}
61
62	linuxX86Ldflags = []string{
63		"-m32",
64	}
65
66	linuxX8664Ldflags = []string{
67		"-m64",
68	}
69
70	linuxClangCflags = append(ClangFilterUnknownCflags(linuxCflags), []string{
71		"--gcc-toolchain=${LinuxGccRoot}",
72		"--sysroot ${LinuxGccRoot}/sysroot",
73		"-fstack-protector-strong",
74	}...)
75
76	linuxClangLdflags = append(ClangFilterUnknownCflags(linuxLdflags), []string{
77		"--gcc-toolchain=${LinuxGccRoot}",
78		"--sysroot ${LinuxGccRoot}/sysroot",
79	}...)
80
81	linuxClangLldflags = ClangFilterUnknownLldflags(linuxClangLdflags)
82
83	linuxX86ClangLdflags = append(ClangFilterUnknownCflags(linuxX86Ldflags), []string{
84		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
85		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}/32",
86		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib32",
87	}...)
88
89	linuxX86ClangLldflags = ClangFilterUnknownLldflags(linuxX86ClangLdflags)
90
91	linuxX8664ClangLdflags = append(ClangFilterUnknownCflags(linuxX8664Ldflags), []string{
92		"-B${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
93		"-L${LinuxGccRoot}/lib/gcc/${LinuxGccTriple}/${LinuxGccVersion}",
94		"-L${LinuxGccRoot}/${LinuxGccTriple}/lib64",
95	}...)
96
97	linuxX8664ClangLldflags = ClangFilterUnknownLldflags(linuxX8664ClangLdflags)
98
99	linuxAvailableLibraries = addPrefix([]string{
100		"c",
101		"dl",
102		"gcc",
103		"gcc_s",
104		"m",
105		"ncurses",
106		"pthread",
107		"resolv",
108		"rt",
109		"util",
110	}, "-l")
111)
112
113const (
114	linuxGccVersion   = "4.8.3"
115	linuxGlibcVersion = "2.17"
116)
117
118func init() {
119	pctx.StaticVariable("LinuxGccVersion", linuxGccVersion)
120	pctx.StaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
121	// Most places use the full GCC version. A few only use up to the first two numbers.
122	if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
123		pctx.StaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
124	} else {
125		pctx.StaticVariable("ShortLinuxGccVersion", linuxGccVersion)
126	}
127
128	pctx.SourcePathVariable("LinuxGccRoot",
129		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
130
131	pctx.StaticVariable("LinuxGccTriple", "x86_64-linux")
132
133	pctx.StaticVariable("LinuxClangCflags", strings.Join(linuxClangCflags, " "))
134	pctx.StaticVariable("LinuxClangLdflags", strings.Join(linuxClangLdflags, " "))
135	pctx.StaticVariable("LinuxClangLldflags", strings.Join(linuxClangLldflags, " "))
136
137	pctx.StaticVariable("LinuxX86ClangCflags",
138		strings.Join(ClangFilterUnknownCflags(linuxX86Cflags), " "))
139	pctx.StaticVariable("LinuxX8664ClangCflags",
140		strings.Join(ClangFilterUnknownCflags(linuxX8664Cflags), " "))
141	pctx.StaticVariable("LinuxX86ClangLdflags", strings.Join(linuxX86ClangLdflags, " "))
142	pctx.StaticVariable("LinuxX86ClangLldflags", strings.Join(linuxX86ClangLldflags, " "))
143	pctx.StaticVariable("LinuxX8664ClangLdflags", strings.Join(linuxX8664ClangLdflags, " "))
144	pctx.StaticVariable("LinuxX8664ClangLldflags", strings.Join(linuxX8664ClangLldflags, " "))
145	// Yasm flags
146	pctx.StaticVariable("LinuxX86YasmFlags", "-f elf32 -m x86")
147	pctx.StaticVariable("LinuxX8664YasmFlags", "-f elf64 -m amd64")
148}
149
150type toolchainLinux struct {
151	cFlags, ldFlags string
152}
153
154type toolchainLinuxX86 struct {
155	toolchain32Bit
156	toolchainLinux
157}
158
159type toolchainLinuxX8664 struct {
160	toolchain64Bit
161	toolchainLinux
162}
163
164func (t *toolchainLinuxX86) Name() string {
165	return "x86"
166}
167
168func (t *toolchainLinuxX8664) Name() string {
169	return "x86_64"
170}
171
172func (t *toolchainLinux) GccRoot() string {
173	return "${config.LinuxGccRoot}"
174}
175
176func (t *toolchainLinux) GccTriple() string {
177	return "${config.LinuxGccTriple}"
178}
179
180func (t *toolchainLinux) GccVersion() string {
181	return linuxGccVersion
182}
183
184func (t *toolchainLinux) IncludeFlags() string {
185	return ""
186}
187
188func (t *toolchainLinuxX86) ClangTriple() string {
189	return "i686-linux-gnu"
190}
191
192func (t *toolchainLinuxX86) ClangCflags() string {
193	return "${config.LinuxClangCflags} ${config.LinuxX86ClangCflags}"
194}
195
196func (t *toolchainLinuxX86) ClangCppflags() string {
197	return ""
198}
199
200func (t *toolchainLinuxX8664) ClangTriple() string {
201	return "x86_64-linux-gnu"
202}
203
204func (t *toolchainLinuxX8664) ClangCflags() string {
205	return "${config.LinuxClangCflags} ${config.LinuxX8664ClangCflags}"
206}
207
208func (t *toolchainLinuxX8664) ClangCppflags() string {
209	return ""
210}
211
212func (t *toolchainLinuxX86) ClangLdflags() string {
213	return "${config.LinuxClangLdflags} ${config.LinuxX86ClangLdflags}"
214}
215
216func (t *toolchainLinuxX86) ClangLldflags() string {
217	return "${config.LinuxClangLldflags} ${config.LinuxX86ClangLldflags}"
218}
219
220func (t *toolchainLinuxX8664) ClangLdflags() string {
221	return "${config.LinuxClangLdflags} ${config.LinuxX8664ClangLdflags}"
222}
223
224func (t *toolchainLinuxX8664) ClangLldflags() string {
225	return "${config.LinuxClangLldflags} ${config.LinuxX8664ClangLldflags}"
226}
227
228func (t *toolchainLinuxX86) YasmFlags() string {
229	return "${config.LinuxX86YasmFlags}"
230}
231
232func (t *toolchainLinuxX8664) YasmFlags() string {
233	return "${config.LinuxX8664YasmFlags}"
234}
235
236func (toolchainLinuxX86) LibclangRuntimeLibraryArch() string {
237	return "i386"
238}
239
240func (toolchainLinuxX8664) LibclangRuntimeLibraryArch() string {
241	return "x86_64"
242}
243
244func (t *toolchainLinux) AvailableLibraries() []string {
245	return linuxAvailableLibraries
246}
247
248func (t *toolchainLinux) Bionic() bool {
249	return false
250}
251
252var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{}
253var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{}
254
255func linuxX86ToolchainFactory(arch android.Arch) Toolchain {
256	return toolchainLinuxX86Singleton
257}
258
259func linuxX8664ToolchainFactory(arch android.Arch) Toolchain {
260	return toolchainLinuxX8664Singleton
261}
262
263func init() {
264	registerToolchainFactory(android.Linux, android.X86, linuxX86ToolchainFactory)
265	registerToolchainFactory(android.Linux, android.X86_64, linuxX8664ToolchainFactory)
266}
267