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