• 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	"path/filepath"
20
21	"android/soong/android"
22)
23
24type toolchainFactory func(arch android.Arch) Toolchain
25
26var toolchainFactories = make(map[android.OsType]map[android.ArchType]toolchainFactory)
27
28func registerToolchainFactory(os android.OsType, arch android.ArchType, factory toolchainFactory) {
29	if toolchainFactories[os] == nil {
30		toolchainFactories[os] = make(map[android.ArchType]toolchainFactory)
31	}
32	toolchainFactories[os][arch] = factory
33}
34
35func FindToolchain(os android.OsType, arch android.Arch) Toolchain {
36	factory := toolchainFactories[os][arch.ArchType]
37	if factory == nil {
38		panic(fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String()))
39	}
40	return factory(arch)
41}
42
43type Toolchain interface {
44	Name() string
45
46	GccRoot() string
47	GccTriple() string
48	// GccVersion should return a real value, not a ninja reference
49	GccVersion() string
50	ToolPath() string
51
52	IncludeFlags() string
53
54	ClangTriple() string
55	ToolchainClangCflags() string
56	ToolchainClangLdflags() string
57	ClangAsflags() string
58	ClangCflags() string
59	ClangCppflags() string
60	ClangLdflags() string
61	ClangLldflags() string
62	ClangInstructionSetFlags(string) (string, error)
63
64	ndkTriple() string
65
66	YasmFlags() string
67
68	WindresFlags() string
69
70	Is64Bit() bool
71
72	ShlibSuffix() string
73	ExecutableSuffix() string
74
75	LibclangRuntimeLibraryArch() string
76
77	AvailableLibraries() []string
78
79	Bionic() bool
80}
81
82type toolchainBase struct {
83}
84
85func (t *toolchainBase) ndkTriple() string {
86	return ""
87}
88
89func NDKTriple(toolchain Toolchain) string {
90	triple := toolchain.ndkTriple()
91	if triple == "" {
92		// Use the clang triple if there is no explicit NDK triple
93		triple = toolchain.ClangTriple()
94	}
95	return triple
96}
97
98func (toolchainBase) ClangInstructionSetFlags(s string) (string, error) {
99	if s != "" {
100		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
101	}
102	return "", nil
103}
104
105func (toolchainBase) ToolchainClangCflags() string {
106	return ""
107}
108
109func (toolchainBase) ToolchainClangLdflags() string {
110	return ""
111}
112
113func (toolchainBase) ShlibSuffix() string {
114	return ".so"
115}
116
117func (toolchainBase) ExecutableSuffix() string {
118	return ""
119}
120
121func (toolchainBase) ClangAsflags() string {
122	return ""
123}
124
125func (toolchainBase) YasmFlags() string {
126	return ""
127}
128
129func (toolchainBase) WindresFlags() string {
130	return ""
131}
132
133func (toolchainBase) LibclangRuntimeLibraryArch() string {
134	return ""
135}
136
137func (toolchainBase) AvailableLibraries() []string {
138	return []string{}
139}
140
141func (toolchainBase) Bionic() bool {
142	return true
143}
144
145func (t toolchainBase) ToolPath() string {
146	return ""
147}
148
149type toolchain64Bit struct {
150	toolchainBase
151}
152
153func (toolchain64Bit) Is64Bit() bool {
154	return true
155}
156
157type toolchain32Bit struct {
158	toolchainBase
159}
160
161func (toolchain32Bit) Is64Bit() bool {
162	return false
163}
164
165func variantOrDefault(variants map[string]string, choice string) string {
166	if ret, ok := variants[choice]; ok {
167		return ret
168	}
169	return variants[""]
170}
171
172func addPrefix(list []string, prefix string) []string {
173	for i := range list {
174		list[i] = prefix + list[i]
175	}
176	return list
177}
178
179func LibclangRuntimeLibrary(t Toolchain, library string) string {
180	arch := t.LibclangRuntimeLibraryArch()
181	if arch == "" {
182		return ""
183	}
184	return "libclang_rt." + library + "-" + arch + "-android"
185}
186
187func BuiltinsRuntimeLibrary(t Toolchain) string {
188	return LibclangRuntimeLibrary(t, "builtins")
189}
190
191func AddressSanitizerRuntimeLibrary(t Toolchain) string {
192	return LibclangRuntimeLibrary(t, "asan")
193}
194
195func HWAddressSanitizerRuntimeLibrary(t Toolchain) string {
196	return LibclangRuntimeLibrary(t, "hwasan")
197}
198
199func HWAddressSanitizerStaticLibrary(t Toolchain) string {
200	return LibclangRuntimeLibrary(t, "hwasan_static")
201}
202
203func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
204	return LibclangRuntimeLibrary(t, "ubsan_standalone")
205}
206
207func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string {
208	return LibclangRuntimeLibrary(t, "ubsan_minimal")
209}
210
211func ThreadSanitizerRuntimeLibrary(t Toolchain) string {
212	return LibclangRuntimeLibrary(t, "tsan")
213}
214
215func ProfileRuntimeLibrary(t Toolchain) string {
216	return LibclangRuntimeLibrary(t, "profile")
217}
218
219func ScudoRuntimeLibrary(t Toolchain) string {
220	return LibclangRuntimeLibrary(t, "scudo")
221}
222
223func ScudoMinimalRuntimeLibrary(t Toolchain) string {
224	return LibclangRuntimeLibrary(t, "scudo_minimal")
225}
226
227func ToolPath(t Toolchain) string {
228	if p := t.ToolPath(); p != "" {
229		return p
230	}
231	return filepath.Join(t.GccRoot(), t.GccTriple(), "bin")
232}
233
234var inList = android.InList
235