• 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		return nil
40	}
41	return factory(arch)
42}
43
44type Toolchain interface {
45	Name() string
46
47	GccRoot() string
48	GccTriple() string
49	// GccVersion should return a real value, not a ninja reference
50	GccVersion() string
51	ToolPath() string
52
53	ToolchainCflags() string
54	ToolchainLdflags() string
55	Cflags() string
56	Cppflags() string
57	Ldflags() string
58	IncludeFlags() string
59	InstructionSetFlags(string) (string, error)
60
61	ClangSupported() bool
62	ClangTriple() string
63	ToolchainClangCflags() string
64	ToolchainClangLdflags() string
65	ClangAsflags() string
66	ClangCflags() string
67	ClangCppflags() string
68	ClangLdflags() string
69	ClangInstructionSetFlags(string) (string, error)
70
71	YasmFlags() string
72
73	Is64Bit() bool
74
75	ShlibSuffix() string
76	ExecutableSuffix() string
77
78	SanitizerRuntimeLibraryArch() string
79
80	AvailableLibraries() []string
81
82	Bionic() bool
83}
84
85type toolchainBase struct {
86}
87
88func (toolchainBase) InstructionSetFlags(s string) (string, error) {
89	if s != "" {
90		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
91	}
92	return "", nil
93}
94
95func (toolchainBase) ClangInstructionSetFlags(s string) (string, error) {
96	if s != "" {
97		return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s)
98	}
99	return "", nil
100}
101
102func (toolchainBase) ToolchainCflags() string {
103	return ""
104}
105
106func (toolchainBase) ToolchainLdflags() string {
107	return ""
108}
109
110func (toolchainBase) ToolchainClangCflags() string {
111	return ""
112}
113
114func (toolchainBase) ToolchainClangLdflags() string {
115	return ""
116}
117
118func (toolchainBase) ClangSupported() bool {
119	return true
120}
121
122func (toolchainBase) ShlibSuffix() string {
123	return ".so"
124}
125
126func (toolchainBase) ExecutableSuffix() string {
127	return ""
128}
129
130func (toolchainBase) ClangAsflags() string {
131	return ""
132}
133
134func (toolchainBase) YasmFlags() string {
135	return ""
136}
137
138func (toolchainBase) SanitizerRuntimeLibraryArch() string {
139	return ""
140}
141
142func (toolchainBase) AvailableLibraries() []string {
143	return []string{}
144}
145
146func (toolchainBase) Bionic() bool {
147	return true
148}
149
150func (t toolchainBase) ToolPath() string {
151	return ""
152}
153
154type toolchain64Bit struct {
155	toolchainBase
156}
157
158func (toolchain64Bit) Is64Bit() bool {
159	return true
160}
161
162type toolchain32Bit struct {
163	toolchainBase
164}
165
166func (toolchain32Bit) Is64Bit() bool {
167	return false
168}
169
170func copyVariantFlags(m map[string][]string) map[string][]string {
171	ret := make(map[string][]string, len(m))
172	for k, v := range m {
173		l := make([]string, len(m[k]))
174		for i := range m[k] {
175			l[i] = v[i]
176		}
177		ret[k] = l
178	}
179	return ret
180}
181
182func variantOrDefault(variants map[string]string, choice string) string {
183	if ret, ok := variants[choice]; ok {
184		return ret
185	}
186	return variants[""]
187}
188
189func addPrefix(list []string, prefix string) []string {
190	for i := range list {
191		list[i] = prefix + list[i]
192	}
193	return list
194}
195
196func indexList(s string, list []string) int {
197	for i, l := range list {
198		if l == s {
199			return i
200		}
201	}
202
203	return -1
204}
205
206func inList(s string, list []string) bool {
207	return indexList(s, list) != -1
208}
209
210func AddressSanitizerRuntimeLibrary(t Toolchain) string {
211	arch := t.SanitizerRuntimeLibraryArch()
212	if arch == "" {
213		return ""
214	}
215	return "libclang_rt.asan-" + arch + "-android.so"
216}
217
218func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string {
219	arch := t.SanitizerRuntimeLibraryArch()
220	if arch == "" {
221		return ""
222	}
223	return "libclang_rt.ubsan_standalone-" + arch + "-android.so"
224}
225
226func ToolPath(t Toolchain) string {
227	if p := t.ToolPath(); p != "" {
228		return p
229	}
230	return filepath.Join(t.GccRoot(), t.GccTriple(), "bin")
231}
232