1// Copyright 2019 The Android Open Source Project
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	"android/soong/android"
19)
20
21type Toolchain interface {
22	RustTriple() string
23	ToolchainRustFlags() string
24	ToolchainLinkFlags() string
25
26	SharedLibSuffix() string
27	StaticLibSuffix() string
28	RlibSuffix() string
29	DylibSuffix() string
30	ProcMacroSuffix() string
31	ExecutableSuffix() string
32
33	Is64Bit() bool
34	Supported() bool
35
36	Bionic() bool
37
38	LibclangRuntimeLibraryArch() string
39}
40
41type toolchainBase struct {
42}
43
44func (toolchainBase) RustTriple() string {
45	panic("toolchainBase does not define a triple.")
46}
47
48func (toolchainBase) ToolchainRustFlags() string {
49	panic("toolchainBase does not provide rust flags.")
50}
51
52func (toolchainBase) ToolchainLinkFlags() string {
53	panic("toolchainBase does not provide link flags.")
54}
55
56func (toolchainBase) Is64Bit() bool {
57	panic("toolchainBase cannot determine datapath width.")
58}
59
60func (toolchainBase) Bionic() bool {
61	return true
62}
63
64type toolchain64Bit struct {
65	toolchainBase
66}
67
68func (toolchain64Bit) Is64Bit() bool {
69	return true
70}
71
72type toolchain32Bit struct {
73	toolchainBase
74}
75
76func (toolchain32Bit) Is64Bit() bool {
77	return false
78}
79
80func (toolchain32Bit) Bionic() bool {
81	return true
82}
83
84func (toolchainBase) ExecutableSuffix() string {
85	return ""
86}
87
88func (toolchainBase) SharedLibSuffix() string {
89	return ".so"
90}
91
92func (toolchainBase) StaticLibSuffix() string {
93	return ".a"
94}
95
96func (toolchainBase) RlibSuffix() string {
97	return ".rlib"
98}
99func (toolchainBase) DylibSuffix() string {
100	return ".dylib.so"
101}
102
103func (toolchainBase) ProcMacroSuffix() string {
104	return ".so"
105}
106
107func (toolchainBase) Supported() bool {
108	return false
109}
110
111func (toolchainBase) LibclangRuntimeLibraryArch() string {
112	return ""
113}
114
115func BuiltinsRuntimeLibrary(t Toolchain) string {
116	return LibclangRuntimeLibrary(t, "builtins")
117}
118
119func LibFuzzerRuntimeLibrary(t Toolchain) string {
120	return LibclangRuntimeLibrary(t, "fuzzer")
121}
122
123func LibclangRuntimeLibrary(t Toolchain, library string) string {
124	arch := t.LibclangRuntimeLibraryArch()
125	if arch == "" {
126		return ""
127	}
128	if !t.Bionic() {
129		return "libclang_rt." + library + "-" + arch
130	}
131	return "libclang_rt." + library + "-" + arch + "-android"
132}
133
134func LibRustRuntimeLibrary(t Toolchain, library string) string {
135	arch := t.LibclangRuntimeLibraryArch()
136	if arch == "" {
137		return ""
138	}
139	if !t.Bionic() {
140		return "librustc_rt." + library + "-" + arch
141	}
142	return "librustc_rt." + library + "-" + arch + "-android"
143}
144
145func toolchainBaseFactory() Toolchain {
146	return &toolchainBase{}
147}
148
149type toolchainFactory func(arch android.Arch) Toolchain
150
151var toolchainFactories = make(map[android.OsType]map[android.ArchType]toolchainFactory)
152
153func registerToolchainFactory(os android.OsType, arch android.ArchType, factory toolchainFactory) {
154	if toolchainFactories[os] == nil {
155		toolchainFactories[os] = make(map[android.ArchType]toolchainFactory)
156	}
157	toolchainFactories[os][arch] = factory
158}
159
160func FindToolchain(os android.OsType, arch android.Arch) Toolchain {
161	factory := toolchainFactories[os][arch.ArchType]
162	if factory == nil {
163		return toolchainBaseFactory()
164	}
165	return factory(arch)
166}
167