Home | History | Annotate | Download | only in config
      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