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 if !t.Bionic() { 185 return "libclang_rt." + library + "-" + arch 186 } 187 return "libclang_rt." + library + "-" + arch + "-android" 188} 189 190func BuiltinsRuntimeLibrary(t Toolchain) string { 191 return LibclangRuntimeLibrary(t, "builtins") 192} 193 194func AddressSanitizerRuntimeLibrary(t Toolchain) string { 195 return LibclangRuntimeLibrary(t, "asan") 196} 197 198func HWAddressSanitizerRuntimeLibrary(t Toolchain) string { 199 return LibclangRuntimeLibrary(t, "hwasan") 200} 201 202func HWAddressSanitizerStaticLibrary(t Toolchain) string { 203 return LibclangRuntimeLibrary(t, "hwasan_static") 204} 205 206func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string { 207 return LibclangRuntimeLibrary(t, "ubsan_standalone") 208} 209 210func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string { 211 return LibclangRuntimeLibrary(t, "ubsan_minimal") 212} 213 214func ThreadSanitizerRuntimeLibrary(t Toolchain) string { 215 return LibclangRuntimeLibrary(t, "tsan") 216} 217 218func ProfileRuntimeLibrary(t Toolchain) string { 219 return LibclangRuntimeLibrary(t, "profile") 220} 221 222func ScudoRuntimeLibrary(t Toolchain) string { 223 return LibclangRuntimeLibrary(t, "scudo") 224} 225 226func ScudoMinimalRuntimeLibrary(t Toolchain) string { 227 return LibclangRuntimeLibrary(t, "scudo_minimal") 228} 229 230func LibFuzzerRuntimeLibrary(t Toolchain) string { 231 return LibclangRuntimeLibrary(t, "fuzzer") 232} 233 234func ToolPath(t Toolchain) string { 235 if p := t.ToolPath(); p != "" { 236 return p 237 } 238 return filepath.Join(t.GccRoot(), t.GccTriple(), "bin") 239} 240 241var inList = android.InList 242