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 15 package config 16 17 import ( 18 "fmt" 19 "path/filepath" 20 21 "android/soong/android" 22 ) 23 24 type toolchainFactory func(arch android.Arch) Toolchain 25 26 var toolchainFactories = make(map[android.OsType]map[android.ArchType]toolchainFactory) 27 28 func 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 35 func 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 44 type 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 WindresFlags() string 74 75 Is64Bit() bool 76 77 ShlibSuffix() string 78 ExecutableSuffix() string 79 80 SanitizerRuntimeLibraryArch() string 81 82 AvailableLibraries() []string 83 84 Bionic() bool 85 } 86 87 type toolchainBase struct { 88 } 89 90 func (toolchainBase) InstructionSetFlags(s string) (string, error) { 91 if s != "" { 92 return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s) 93 } 94 return "", nil 95 } 96 97 func (toolchainBase) ClangInstructionSetFlags(s string) (string, error) { 98 if s != "" { 99 return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s) 100 } 101 return "", nil 102 } 103 104 func (toolchainBase) ToolchainCflags() string { 105 return "" 106 } 107 108 func (toolchainBase) ToolchainLdflags() string { 109 return "" 110 } 111 112 func (toolchainBase) ToolchainClangCflags() string { 113 return "" 114 } 115 116 func (toolchainBase) ToolchainClangLdflags() string { 117 return "" 118 } 119 120 func (toolchainBase) ClangSupported() bool { 121 return true 122 } 123 124 func (toolchainBase) ShlibSuffix() string { 125 return ".so" 126 } 127 128 func (toolchainBase) ExecutableSuffix() string { 129 return "" 130 } 131 132 func (toolchainBase) ClangAsflags() string { 133 return "" 134 } 135 136 func (toolchainBase) YasmFlags() string { 137 return "" 138 } 139 140 func (toolchainBase) WindresFlags() string { 141 return "" 142 } 143 144 func (toolchainBase) SanitizerRuntimeLibraryArch() string { 145 return "" 146 } 147 148 func (toolchainBase) AvailableLibraries() []string { 149 return []string{} 150 } 151 152 func (toolchainBase) Bionic() bool { 153 return true 154 } 155 156 func (t toolchainBase) ToolPath() string { 157 return "" 158 } 159 160 type toolchain64Bit struct { 161 toolchainBase 162 } 163 164 func (toolchain64Bit) Is64Bit() bool { 165 return true 166 } 167 168 type toolchain32Bit struct { 169 toolchainBase 170 } 171 172 func (toolchain32Bit) Is64Bit() bool { 173 return false 174 } 175 176 func copyVariantFlags(m map[string][]string) map[string][]string { 177 ret := make(map[string][]string, len(m)) 178 for k, v := range m { 179 l := make([]string, len(m[k])) 180 for i := range m[k] { 181 l[i] = v[i] 182 } 183 ret[k] = l 184 } 185 return ret 186 } 187 188 func variantOrDefault(variants map[string]string, choice string) string { 189 if ret, ok := variants[choice]; ok { 190 return ret 191 } 192 return variants[""] 193 } 194 195 func addPrefix(list []string, prefix string) []string { 196 for i := range list { 197 list[i] = prefix + list[i] 198 } 199 return list 200 } 201 202 func SanitizerRuntimeLibrary(t Toolchain, sanitizer string) string { 203 arch := t.SanitizerRuntimeLibraryArch() 204 if arch == "" { 205 return "" 206 } 207 return "libclang_rt." + sanitizer + "-" + arch + "-android" 208 } 209 210 func AddressSanitizerRuntimeLibrary(t Toolchain) string { 211 return SanitizerRuntimeLibrary(t, "asan") 212 } 213 214 func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string { 215 return SanitizerRuntimeLibrary(t, "ubsan_standalone") 216 } 217 218 func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string { 219 return SanitizerRuntimeLibrary(t, "ubsan_minimal") 220 } 221 222 func ThreadSanitizerRuntimeLibrary(t Toolchain) string { 223 return SanitizerRuntimeLibrary(t, "tsan") 224 } 225 226 func ProfileRuntimeLibrary(t Toolchain) string { 227 return SanitizerRuntimeLibrary(t, "profile") 228 } 229 230 func ToolPath(t Toolchain) string { 231 if p := t.ToolPath(); p != "" { 232 return p 233 } 234 return filepath.Join(t.GccRoot(), t.GccTriple(), "bin") 235 } 236 237 var inList = android.InList 238