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 config
16
17import (
18	"strings"
19
20	"android/soong/android"
21)
22
23var (
24	windowsCflags = []string{
25		"-DUSE_MINGW",
26		"-DWIN32_LEAN_AND_MEAN",
27		"-Wno-unused-parameter",
28
29		// Workaround differences in inttypes.h between host and target.
30		//See bug 12708004.
31		"-D__STDC_FORMAT_MACROS",
32		"-D__STDC_CONSTANT_MACROS",
33
34		// Use C99-compliant printf functions (%zd).
35		"-D__USE_MINGW_ANSI_STDIO=1",
36		// Admit to using >= Windows 7. Both are needed because of <_mingw.h>.
37		"-D_WIN32_WINNT=0x0601",
38		"-DWINVER=0x0601",
39		// Get 64-bit off_t and related functions.
40		"-D_FILE_OFFSET_BITS=64",
41
42		"--sysroot ${WindowsGccRoot}/${WindowsGccTriple}",
43	}
44	windowsClangCflags = append(ClangFilterUnknownCflags(windowsCflags), []string{}...)
45
46	windowsIncludeFlags = []string{
47		"-isystem ${WindowsGccRoot}/${WindowsGccTriple}/include",
48	}
49
50	windowsClangCppflags = []string{}
51
52	windowsX86ClangCppflags = []string{}
53
54	windowsX8664ClangCppflags = []string{}
55
56	windowsLdflags = []string{
57		"--enable-stdcall-fixup",
58		"-Wl,--dynamicbase",
59		"-Wl,--nxcompat",
60	}
61	windowsLldflags = []string{
62		"-Wl,--Xlink=-Brepro", // Enable deterministic build
63	}
64	windowsClangLdflags  = append(ClangFilterUnknownCflags(windowsLdflags), []string{}...)
65	windowsClangLldflags = append(ClangFilterUnknownLldflags(windowsClangLdflags), windowsLldflags...)
66
67	windowsX86Cflags = []string{
68		"-m32",
69	}
70
71	windowsX8664Cflags = []string{
72		"-m64",
73	}
74
75	windowsX86Ldflags = []string{
76		"-m32",
77		"-Wl,--large-address-aware",
78		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib32",
79		"-static-libgcc",
80	}
81	windowsX86ClangLdflags = append(ClangFilterUnknownCflags(windowsX86Ldflags), []string{
82		"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
83		"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
84		"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3/32",
85		"-B${WindowsGccRoot}/${WindowsGccTriple}/lib32",
86	}...)
87	windowsX86ClangLldflags = ClangFilterUnknownLldflags(windowsX86ClangLdflags)
88
89	windowsX8664Ldflags = []string{
90		"-m64",
91		"-L${WindowsGccRoot}/${WindowsGccTriple}/lib64",
92		"-Wl,--high-entropy-va",
93		"-static-libgcc",
94	}
95	windowsX8664ClangLdflags = append(ClangFilterUnknownCflags(windowsX8664Ldflags), []string{
96		"-B${WindowsGccRoot}/${WindowsGccTriple}/bin",
97		"-B${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
98		"-L${WindowsGccRoot}/lib/gcc/${WindowsGccTriple}/4.8.3",
99		"-B${WindowsGccRoot}/${WindowsGccTriple}/lib64",
100	}...)
101	windowsX8664ClangLldflags = ClangFilterUnknownLldflags(windowsX8664ClangLdflags)
102
103	windowsAvailableLibraries = addPrefix([]string{
104		"gdi32",
105		"imagehlp",
106		"iphlpapi",
107		"netapi32",
108		"oleaut32",
109		"ole32",
110		"opengl32",
111		"powrprof",
112		"psapi",
113		"pthread",
114		"userenv",
115		"uuid",
116		"version",
117		"ws2_32",
118		"windowscodecs",
119	}, "-l")
120)
121
122const (
123	windowsGccVersion = "4.8"
124)
125
126func init() {
127	pctx.StaticVariable("WindowsGccVersion", windowsGccVersion)
128
129	pctx.SourcePathVariable("WindowsGccRoot",
130		"prebuilts/gcc/${HostPrebuiltTag}/host/x86_64-w64-mingw32-${WindowsGccVersion}")
131
132	pctx.StaticVariable("WindowsGccTriple", "x86_64-w64-mingw32")
133
134	pctx.StaticVariable("WindowsClangCflags", strings.Join(windowsClangCflags, " "))
135	pctx.StaticVariable("WindowsClangLdflags", strings.Join(windowsClangLdflags, " "))
136	pctx.StaticVariable("WindowsClangLldflags", strings.Join(windowsClangLldflags, " "))
137	pctx.StaticVariable("WindowsClangCppflags", strings.Join(windowsClangCppflags, " "))
138
139	pctx.StaticVariable("WindowsX86ClangCflags",
140		strings.Join(ClangFilterUnknownCflags(windowsX86Cflags), " "))
141	pctx.StaticVariable("WindowsX8664ClangCflags",
142		strings.Join(ClangFilterUnknownCflags(windowsX8664Cflags), " "))
143	pctx.StaticVariable("WindowsX86ClangLdflags", strings.Join(windowsX86ClangLdflags, " "))
144	pctx.StaticVariable("WindowsX86ClangLldflags", strings.Join(windowsX86ClangLldflags, " "))
145	pctx.StaticVariable("WindowsX8664ClangLdflags", strings.Join(windowsX8664ClangLdflags, " "))
146	pctx.StaticVariable("WindowsX8664ClangLldflags", strings.Join(windowsX8664ClangLldflags, " "))
147	pctx.StaticVariable("WindowsX86ClangCppflags", strings.Join(windowsX86ClangCppflags, " "))
148	pctx.StaticVariable("WindowsX8664ClangCppflags", strings.Join(windowsX8664ClangCppflags, " "))
149
150	pctx.StaticVariable("WindowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
151	// Yasm flags
152	pctx.StaticVariable("WindowsX86YasmFlags", "-f win32 -m x86")
153	pctx.StaticVariable("WindowsX8664YasmFlags", "-f win64 -m amd64")
154}
155
156type toolchainWindows struct {
157	cFlags, ldFlags string
158}
159
160type toolchainWindowsX86 struct {
161	toolchain32Bit
162	toolchainWindows
163}
164
165type toolchainWindowsX8664 struct {
166	toolchain64Bit
167	toolchainWindows
168}
169
170func (t *toolchainWindowsX86) Name() string {
171	return "x86"
172}
173
174func (t *toolchainWindowsX8664) Name() string {
175	return "x86_64"
176}
177
178func (t *toolchainWindows) GccRoot() string {
179	return "${config.WindowsGccRoot}"
180}
181
182func (t *toolchainWindows) GccTriple() string {
183	return "${config.WindowsGccTriple}"
184}
185
186func (t *toolchainWindows) GccVersion() string {
187	return windowsGccVersion
188}
189
190func (t *toolchainWindows) IncludeFlags() string {
191	return "${config.WindowsIncludeFlags}"
192}
193
194func (t *toolchainWindowsX86) WindresFlags() string {
195	return "-F pe-i386"
196}
197
198func (t *toolchainWindowsX8664) WindresFlags() string {
199	return "-F pe-x86-64"
200}
201
202func (t *toolchainWindowsX86) ClangTriple() string {
203	return "i686-windows-gnu"
204}
205
206func (t *toolchainWindowsX8664) ClangTriple() string {
207	return "x86_64-pc-windows-gnu"
208}
209
210func (t *toolchainWindowsX86) ClangCflags() string {
211	return "${config.WindowsClangCflags} ${config.WindowsX86ClangCflags}"
212}
213
214func (t *toolchainWindowsX8664) ClangCflags() string {
215	return "${config.WindowsClangCflags} ${config.WindowsX8664ClangCflags}"
216}
217
218func (t *toolchainWindowsX86) ClangCppflags() string {
219	return "${config.WindowsClangCppflags} ${config.WindowsX86ClangCppflags}"
220}
221
222func (t *toolchainWindowsX8664) ClangCppflags() string {
223	return "${config.WindowsClangCppflags} ${config.WindowsX8664ClangCppflags}"
224}
225
226func (t *toolchainWindowsX86) ClangLdflags() string {
227	return "${config.WindowsClangLdflags} ${config.WindowsX86ClangLdflags}"
228}
229
230func (t *toolchainWindowsX86) ClangLldflags() string {
231	return "${config.WindowsClangLldflags} ${config.WindowsX86ClangLldflags}"
232}
233
234func (t *toolchainWindowsX8664) ClangLdflags() string {
235	return "${config.WindowsClangLdflags} ${config.WindowsX8664ClangLdflags}"
236}
237
238func (t *toolchainWindowsX8664) ClangLldflags() string {
239	return "${config.WindowsClangLldflags} ${config.WindowsX8664ClangLldflags}"
240}
241
242func (t *toolchainWindowsX86) YasmFlags() string {
243	return "${config.WindowsX86YasmFlags}"
244}
245
246func (t *toolchainWindowsX8664) YasmFlags() string {
247	return "${config.WindowsX8664YasmFlags}"
248}
249
250func (t *toolchainWindows) ShlibSuffix() string {
251	return ".dll"
252}
253
254func (t *toolchainWindows) ExecutableSuffix() string {
255	return ".exe"
256}
257
258func (t *toolchainWindows) AvailableLibraries() []string {
259	return windowsAvailableLibraries
260}
261
262func (t *toolchainWindows) Bionic() bool {
263	return false
264}
265
266var toolchainWindowsX86Singleton Toolchain = &toolchainWindowsX86{}
267var toolchainWindowsX8664Singleton Toolchain = &toolchainWindowsX8664{}
268
269func windowsX86ToolchainFactory(arch android.Arch) Toolchain {
270	return toolchainWindowsX86Singleton
271}
272
273func windowsX8664ToolchainFactory(arch android.Arch) Toolchain {
274	return toolchainWindowsX8664Singleton
275}
276
277func init() {
278	registerToolchainFactory(android.Windows, android.X86, windowsX86ToolchainFactory)
279	registerToolchainFactory(android.Windows, android.X86_64, windowsX8664ToolchainFactory)
280}
281