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