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	"fmt"
19	"strings"
20
21	"android/soong/android"
22)
23
24func init() {
25	pctx.StaticVariable("DarwinAvailableLibraries", strings.Join(darwinAvailableLibraries, " "))
26	pctx.StaticVariable("LinuxAvailableLibraries", strings.Join(linuxAvailableLibraries, " "))
27	pctx.StaticVariable("WindowsAvailableLibraries", strings.Join(windowsAvailableLibraries, " "))
28}
29
30type toolchainFactory func(arch android.Arch) Toolchain
31
32var toolchainFactories = make(map[android.OsType]map[android.ArchType]toolchainFactory)
33
34func registerToolchainFactory(os android.OsType, arch android.ArchType, factory toolchainFactory) {
35	if toolchainFactories[os] == nil {
36		toolchainFactories[os] = make(map[android.ArchType]toolchainFactory)
37	}
38	toolchainFactories[os][arch] = factory
39}
40
41type toolchainContext interface {
42	Os() android.OsType
43	Arch() android.Arch
44}
45
46func FindToolchainWithContext(ctx toolchainContext) Toolchain {
47	t, err := findToolchain(ctx.Os(), ctx.Arch())
48	if err != nil {
49		panic(err)
50	}
51	return t
52}
53
54func FindToolchain(os android.OsType, arch android.Arch) Toolchain {
55	t, err := findToolchain(os, arch)
56	if err != nil {
57		panic(err)
58	}
59	return t
60}
61
62func findToolchain(os android.OsType, arch android.Arch) (Toolchain, error) {
63	factory := toolchainFactories[os][arch.ArchType]
64	if factory == nil {
65		return nil, fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String())
66	}
67	return factory(arch), nil
68}
69
70type Toolchain interface {
71	Name() string
72
73	IncludeFlags() string
74
75	ClangTriple() string
76	ToolchainCflags() string
77	ToolchainLdflags() string
78	Asflags() string
79	Cflags() string
80	Cppflags() string
81	Ldflags() string
82	Lldflags() string
83	InstructionSetFlags(string) (string, error)
84
85	ndkTriple() string
86
87	YasmFlags() string
88
89	Is64Bit() bool
90
91	ShlibSuffix() string
92	ExecutableSuffix() string
93
94	LibclangRuntimeLibraryArch() string
95
96	AvailableLibraries() []string
97
98	CrtBeginStaticBinary() []string
99	CrtBeginSharedBinary() []string
100	CrtBeginSharedLibrary() []string
101	CrtEndStaticBinary() []string
102	CrtEndSharedBinary() []string
103	CrtEndSharedLibrary() []string
104	CrtPadSegmentSharedLibrary() []string
105
106	// DefaultSharedLibraries returns the list of shared libraries that will be added to all
107	// targets unless they explicitly specify system_shared_libs.
108	DefaultSharedLibraries() []string
109
110	Bionic() bool
111	Glibc() bool
112	Musl() bool
113}
114
115type toolchainBase struct {
116}
117
118func (t *toolchainBase) ndkTriple() string {
119	return ""
120}
121
122func NDKTriple(toolchain Toolchain) string {
123	triple := toolchain.ndkTriple()
124	if triple == "" {
125		// Use the clang triple if there is no explicit NDK triple
126		triple = toolchain.ClangTriple()
127	}
128	return triple
129}
130
131func (toolchainBase) InstructionSetFlags(s string) (string, error) {
132	if s != "" {
133		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
134	}
135	return "", nil
136}
137
138func (toolchainBase) ToolchainCflags() string {
139	return ""
140}
141
142func (toolchainBase) ToolchainLdflags() string {
143	return ""
144}
145
146func (toolchainBase) Asflags() string {
147	return ""
148}
149
150func (toolchainBase) YasmFlags() string {
151	return ""
152}
153
154func (toolchainBase) LibclangRuntimeLibraryArch() string {
155	return ""
156}
157
158type toolchainNoCrt struct{}
159
160func (toolchainNoCrt) CrtBeginStaticBinary() []string       { return nil }
161func (toolchainNoCrt) CrtBeginSharedBinary() []string       { return nil }
162func (toolchainNoCrt) CrtBeginSharedLibrary() []string      { return nil }
163func (toolchainNoCrt) CrtEndStaticBinary() []string         { return nil }
164func (toolchainNoCrt) CrtEndSharedBinary() []string         { return nil }
165func (toolchainNoCrt) CrtEndSharedLibrary() []string        { return nil }
166func (toolchainNoCrt) CrtPadSegmentSharedLibrary() []string { return nil }
167
168func (toolchainBase) DefaultSharedLibraries() []string {
169	return nil
170}
171
172func (toolchainBase) Bionic() bool {
173	return false
174}
175
176func (toolchainBase) Glibc() bool {
177	return false
178}
179
180func (toolchainBase) Musl() bool {
181	return false
182}
183
184type toolchain64Bit struct {
185}
186
187func (toolchain64Bit) Is64Bit() bool {
188	return true
189}
190
191type toolchain32Bit struct {
192}
193
194func (toolchain32Bit) Is64Bit() bool {
195	return false
196}
197
198func variantOrDefault(variants map[string]string, choice string) string {
199	if ret, ok := variants[choice]; ok {
200		return ret
201	}
202	return variants[""]
203}
204
205func addPrefix(list []string, prefix string) []string {
206	for i := range list {
207		list[i] = prefix + list[i]
208	}
209	return list
210}
211
212func LibclangRuntimeLibrary(library string) string {
213	return "libclang_rt." + library
214}
215
216func BuiltinsRuntimeLibrary() string {
217	return LibclangRuntimeLibrary("builtins")
218}
219
220func AddressSanitizerRuntimeLibrary() string {
221	return LibclangRuntimeLibrary("asan")
222}
223
224func AddressSanitizerStaticRuntimeLibrary() string {
225	return LibclangRuntimeLibrary("asan.static")
226}
227
228func AddressSanitizerCXXStaticRuntimeLibrary() string {
229	return LibclangRuntimeLibrary("asan_cxx.static")
230}
231
232func HWAddressSanitizerRuntimeLibrary() string {
233	return LibclangRuntimeLibrary("hwasan")
234}
235
236func HWAddressSanitizerStaticLibrary() string {
237	return LibclangRuntimeLibrary("hwasan_static")
238}
239
240func UndefinedBehaviorSanitizerRuntimeLibrary() string {
241	return LibclangRuntimeLibrary("ubsan_standalone")
242}
243
244func UndefinedBehaviorSanitizerMinimalRuntimeLibrary() string {
245	return LibclangRuntimeLibrary("ubsan_minimal")
246}
247
248func ThreadSanitizerRuntimeLibrary() string {
249	return LibclangRuntimeLibrary("tsan")
250}
251
252func ScudoRuntimeLibrary() string {
253	return LibclangRuntimeLibrary("scudo")
254}
255
256func ScudoMinimalRuntimeLibrary() string {
257	return LibclangRuntimeLibrary("scudo_minimal")
258}
259
260func LibFuzzerRuntimeLibrary() string {
261	return LibclangRuntimeLibrary("fuzzer")
262}
263
264func LibFuzzerRuntimeInterceptors() string {
265	return LibclangRuntimeLibrary("fuzzer_interceptors")
266}
267