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 20 "android/soong/android" 21) 22 23type toolchainFactory func(arch android.Arch) Toolchain 24 25var toolchainFactories = make(map[android.OsType]map[android.ArchType]toolchainFactory) 26 27func registerToolchainFactory(os android.OsType, arch android.ArchType, factory toolchainFactory) { 28 if toolchainFactories[os] == nil { 29 toolchainFactories[os] = make(map[android.ArchType]toolchainFactory) 30 } 31 toolchainFactories[os][arch] = factory 32} 33 34type toolchainContext interface { 35 Os() android.OsType 36 Arch() android.Arch 37} 38 39type conversionContext interface { 40 BazelConversionMode() bool 41} 42 43func FindToolchainWithContext(ctx toolchainContext) Toolchain { 44 t, err := findToolchain(ctx.Os(), ctx.Arch()) 45 if err != nil { 46 if c, ok := ctx.(conversionContext); ok && c.BazelConversionMode() { 47 // TODO(b/179123288): determine conversion for toolchain 48 return &toolchainX86_64{} 49 } else { 50 panic(err) 51 } 52 } 53 return t 54} 55 56func FindToolchain(os android.OsType, arch android.Arch) Toolchain { 57 t, err := findToolchain(os, arch) 58 if err != nil { 59 panic(err) 60 } 61 return t 62} 63 64func findToolchain(os android.OsType, arch android.Arch) (Toolchain, error) { 65 factory := toolchainFactories[os][arch.ArchType] 66 if factory == nil { 67 return nil, fmt.Errorf("Toolchain not found for %s arch %q", os.String(), arch.String()) 68 } 69 return factory(arch), nil 70} 71 72type Toolchain interface { 73 Name() string 74 75 GccRoot() string 76 GccTriple() string 77 // GccVersion should return a real value, not a ninja reference 78 GccVersion() string 79 80 IncludeFlags() string 81 82 ClangTriple() string 83 ToolchainCflags() string 84 ToolchainLdflags() string 85 Asflags() string 86 Cflags() string 87 Cppflags() string 88 Ldflags() string 89 Lldflags() string 90 InstructionSetFlags(string) (string, error) 91 92 ndkTriple() string 93 94 YasmFlags() string 95 96 Is64Bit() bool 97 98 ShlibSuffix() string 99 ExecutableSuffix() string 100 101 LibclangRuntimeLibraryArch() string 102 103 AvailableLibraries() []string 104 105 CrtBeginStaticBinary() []string 106 CrtBeginSharedBinary() []string 107 CrtBeginSharedLibrary() []string 108 CrtEndStaticBinary() []string 109 CrtEndSharedBinary() []string 110 CrtEndSharedLibrary() []string 111 112 // DefaultSharedLibraries returns the list of shared libraries that will be added to all 113 // targets unless they explicitly specify system_shared_libs. 114 DefaultSharedLibraries() []string 115 116 Bionic() bool 117 Glibc() bool 118 Musl() bool 119} 120 121type toolchainBase struct { 122} 123 124func (t *toolchainBase) ndkTriple() string { 125 return "" 126} 127 128func NDKTriple(toolchain Toolchain) string { 129 triple := toolchain.ndkTriple() 130 if triple == "" { 131 // Use the clang triple if there is no explicit NDK triple 132 triple = toolchain.ClangTriple() 133 } 134 return triple 135} 136 137func (toolchainBase) InstructionSetFlags(s string) (string, error) { 138 if s != "" { 139 return "", fmt.Errorf("instruction_set: %s is not a supported instruction set", s) 140 } 141 return "", nil 142} 143 144func (toolchainBase) ToolchainCflags() string { 145 return "" 146} 147 148func (toolchainBase) ToolchainLdflags() string { 149 return "" 150} 151 152func (toolchainBase) ShlibSuffix() string { 153 return ".so" 154} 155 156func (toolchainBase) ExecutableSuffix() string { 157 return "" 158} 159 160func (toolchainBase) Asflags() string { 161 return "" 162} 163 164func (toolchainBase) YasmFlags() string { 165 return "" 166} 167 168func (toolchainBase) LibclangRuntimeLibraryArch() string { 169 return "" 170} 171 172func (toolchainBase) AvailableLibraries() []string { 173 return nil 174} 175 176func (toolchainBase) CrtBeginStaticBinary() []string { return nil } 177func (toolchainBase) CrtBeginSharedBinary() []string { return nil } 178func (toolchainBase) CrtBeginSharedLibrary() []string { return nil } 179func (toolchainBase) CrtEndStaticBinary() []string { return nil } 180func (toolchainBase) CrtEndSharedBinary() []string { return nil } 181func (toolchainBase) CrtEndSharedLibrary() []string { return nil } 182 183func (toolchainBase) DefaultSharedLibraries() []string { 184 return nil 185} 186 187func (toolchainBase) Bionic() bool { 188 return false 189} 190 191func (toolchainBase) Glibc() bool { 192 return false 193} 194 195func (toolchainBase) Musl() bool { 196 return false 197} 198 199type toolchain64Bit struct { 200 toolchainBase 201} 202 203func (toolchain64Bit) Is64Bit() bool { 204 return true 205} 206 207type toolchain32Bit struct { 208 toolchainBase 209} 210 211func (toolchain32Bit) Is64Bit() bool { 212 return false 213} 214 215func variantOrDefault(variants map[string]string, choice string) string { 216 if ret, ok := variants[choice]; ok { 217 return ret 218 } 219 return variants[""] 220} 221 222func addPrefix(list []string, prefix string) []string { 223 for i := range list { 224 list[i] = prefix + list[i] 225 } 226 return list 227} 228 229func LibclangRuntimeLibrary(t Toolchain, library string) string { 230 return "libclang_rt." + library 231} 232 233func BuiltinsRuntimeLibrary(t Toolchain) string { 234 return LibclangRuntimeLibrary(t, "builtins") 235} 236 237func AddressSanitizerRuntimeLibrary(t Toolchain) string { 238 return LibclangRuntimeLibrary(t, "asan") 239} 240 241func HWAddressSanitizerRuntimeLibrary(t Toolchain) string { 242 return LibclangRuntimeLibrary(t, "hwasan") 243} 244 245func HWAddressSanitizerStaticLibrary(t Toolchain) string { 246 return LibclangRuntimeLibrary(t, "hwasan_static") 247} 248 249func UndefinedBehaviorSanitizerRuntimeLibrary(t Toolchain) string { 250 return LibclangRuntimeLibrary(t, "ubsan_standalone") 251} 252 253func UndefinedBehaviorSanitizerMinimalRuntimeLibrary(t Toolchain) string { 254 return LibclangRuntimeLibrary(t, "ubsan_minimal") 255} 256 257func ThreadSanitizerRuntimeLibrary(t Toolchain) string { 258 return LibclangRuntimeLibrary(t, "tsan") 259} 260 261func ScudoRuntimeLibrary(t Toolchain) string { 262 return LibclangRuntimeLibrary(t, "scudo") 263} 264 265func ScudoMinimalRuntimeLibrary(t Toolchain) string { 266 return LibclangRuntimeLibrary(t, "scudo_minimal") 267} 268 269func LibFuzzerRuntimeLibrary(t Toolchain) string { 270 return LibclangRuntimeLibrary(t, "fuzzer") 271} 272 273var inList = android.InList 274