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