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 cc 16 17 import ( 18 "fmt" 19 "strings" 20 21 "android/soong/common" 22 ) 23 24 var ( 25 armToolchainCflags = []string{ 26 "-mthumb-interwork", 27 } 28 29 armCflags = []string{ 30 "-fno-exceptions", // from build/core/combo/select.mk 31 "-Wno-multichar", // from build/core/combo/select.mk 32 "-msoft-float", 33 "-ffunction-sections", 34 "-fdata-sections", 35 "-funwind-tables", 36 "-fstack-protector-strong", 37 "-Wa,--noexecstack", 38 "-Werror=format-security", 39 "-D_FORTIFY_SOURCE=2", 40 "-fno-short-enums", 41 "-no-canonical-prefixes", 42 "-fno-canonical-system-headers", 43 44 "-fno-builtin-sin", 45 "-fno-strict-volatile-bitfields", 46 47 // TARGET_RELEASE_CFLAGS 48 "-DNDEBUG", 49 "-g", 50 "-Wstrict-aliasing=2", 51 "-fgcse-after-reload", 52 "-frerun-cse-after-loop", 53 "-frename-registers", 54 } 55 56 armCppflags = []string{ 57 "-fvisibility-inlines-hidden", 58 } 59 60 armLdflags = []string{ 61 "-Wl,-z,noexecstack", 62 "-Wl,-z,relro", 63 "-Wl,-z,now", 64 "-Wl,--build-id=md5", 65 "-Wl,--warn-shared-textrel", 66 "-Wl,--fatal-warnings", 67 "-Wl,--icf=safe", 68 "-Wl,--hash-style=gnu", 69 "-Wl,--no-undefined-version", 70 } 71 72 armArmCflags = []string{ 73 "-O2", 74 "-fomit-frame-pointer", 75 "-fstrict-aliasing", 76 "-funswitch-loops", 77 } 78 79 armThumbCflags = []string{ 80 "-mthumb", 81 "-Os", 82 "-fomit-frame-pointer", 83 "-fno-strict-aliasing", 84 } 85 86 armArchVariantCflags = map[string][]string{ 87 "armv5te": []string{ 88 "-march=armv5te", 89 "-mtune=xscale", 90 "-D__ARM_ARCH_5__", 91 "-D__ARM_ARCH_5T__", 92 "-D__ARM_ARCH_5E__", 93 "-D__ARM_ARCH_5TE__", 94 }, 95 "armv7-a": []string{ 96 "-march=armv7-a", 97 "-mfloat-abi=softfp", 98 "-mfpu=vfpv3-d16", 99 }, 100 "armv7-a-neon": []string{ 101 "-mfloat-abi=softfp", 102 "-mfpu=neon", 103 }, 104 } 105 106 armCpuVariantCflags = map[string][]string{ 107 "cortex-a7": []string{ 108 "-mcpu=cortex-a7", 109 }, 110 "cortex-a8": []string{ 111 "-mcpu=cortex-a8", 112 }, 113 "cortex-a15": []string{ 114 "-mcpu=cortex-a15", 115 // Fake an ARM compiler flag as these processors support LPAE which GCC/clang 116 // don't advertise. 117 "-D__ARM_FEATURE_LPAE=1", 118 }, 119 } 120 121 armClangCpuVariantCflags = copyVariantFlags(armCpuVariantCflags) 122 armClangArchVariantCflags = copyVariantFlags(armArchVariantCflags) 123 ) 124 125 const ( 126 armGccVersion = "4.9" 127 ) 128 129 func copyVariantFlags(m map[string][]string) map[string][]string { 130 ret := make(map[string][]string, len(m)) 131 for k, v := range m { 132 l := make([]string, len(m[k])) 133 for i := range m[k] { 134 l[i] = v[i] 135 } 136 ret[k] = l 137 } 138 return ret 139 } 140 141 func init() { 142 replaceFirst := func(slice []string, from, to string) { 143 if slice[0] != from { 144 panic(fmt.Errorf("Expected %q, found %q", from, to)) 145 } 146 147 slice[0] = to 148 } 149 150 replaceFirst(armClangArchVariantCflags["armv5te"], "-march=armv5te", "-march=armv5t") 151 armClangCpuVariantCflags["krait"] = []string{ 152 "-mcpu=krait", 153 "-mfpu=neon-vfpv4", 154 } 155 156 pctx.StaticVariable("armGccVersion", armGccVersion) 157 158 pctx.SourcePathVariable("armGccRoot", 159 "prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}") 160 161 pctx.StaticVariable("armGccTriple", "arm-linux-androideabi") 162 163 pctx.StaticVariable("armToolchainCflags", strings.Join(armToolchainCflags, " ")) 164 pctx.StaticVariable("armCflags", strings.Join(armCflags, " ")) 165 pctx.StaticVariable("armLdflags", strings.Join(armLdflags, " ")) 166 pctx.StaticVariable("armCppflags", strings.Join(armCppflags, " ")) 167 pctx.StaticVariable("armIncludeFlags", strings.Join([]string{ 168 "-isystem ${LibcRoot}/arch-arm/include", 169 "-isystem ${LibcRoot}/include", 170 "-isystem ${LibcRoot}/kernel/uapi", 171 "-isystem ${LibcRoot}/kernel/uapi/asm-arm", 172 "-isystem ${LibmRoot}/include", 173 "-isystem ${LibmRoot}/include/arm", 174 }, " ")) 175 176 // Extended cflags 177 178 // ARM vs. Thumb instruction set flags 179 pctx.StaticVariable("armArmCflags", strings.Join(armArmCflags, " ")) 180 pctx.StaticVariable("armThumbCflags", strings.Join(armThumbCflags, " ")) 181 182 // Architecture variant cflags 183 pctx.StaticVariable("armArmv5TECflags", strings.Join(armArchVariantCflags["armv5te"], " ")) 184 pctx.StaticVariable("armArmv7ACflags", strings.Join(armArchVariantCflags["armv7-a"], " ")) 185 pctx.StaticVariable("armArmv7ANeonCflags", strings.Join(armArchVariantCflags["armv7-a-neon"], " ")) 186 187 // Cpu variant cflags 188 pctx.StaticVariable("armCortexA7Cflags", strings.Join(armCpuVariantCflags["cortex-a7"], " ")) 189 pctx.StaticVariable("armCortexA8Cflags", strings.Join(armCpuVariantCflags["cortex-a8"], " ")) 190 pctx.StaticVariable("armCortexA15Cflags", strings.Join(armCpuVariantCflags["cortex-a15"], " ")) 191 192 // Clang cflags 193 pctx.StaticVariable("armToolchainClangCflags", strings.Join(clangFilterUnknownCflags(armToolchainCflags), " ")) 194 pctx.StaticVariable("armClangCflags", strings.Join(clangFilterUnknownCflags(armCflags), " ")) 195 pctx.StaticVariable("armClangLdflags", strings.Join(clangFilterUnknownCflags(armLdflags), " ")) 196 pctx.StaticVariable("armClangCppflags", strings.Join(clangFilterUnknownCflags(armCppflags), " ")) 197 198 // Clang ARM vs. Thumb instruction set cflags 199 pctx.StaticVariable("armClangArmCflags", strings.Join(clangFilterUnknownCflags(armArmCflags), " ")) 200 pctx.StaticVariable("armClangThumbCflags", strings.Join(clangFilterUnknownCflags(armThumbCflags), " ")) 201 202 // Clang cpu variant cflags 203 pctx.StaticVariable("armClangArmv5TECflags", 204 strings.Join(armClangArchVariantCflags["armv5te"], " ")) 205 pctx.StaticVariable("armClangArmv7ACflags", 206 strings.Join(armClangArchVariantCflags["armv7-a"], " ")) 207 pctx.StaticVariable("armClangArmv7ANeonCflags", 208 strings.Join(armClangArchVariantCflags["armv7-a-neon"], " ")) 209 210 // Clang cpu variant cflags 211 pctx.StaticVariable("armClangCortexA7Cflags", 212 strings.Join(armClangCpuVariantCflags["cortex-a7"], " ")) 213 pctx.StaticVariable("armClangCortexA8Cflags", 214 strings.Join(armClangCpuVariantCflags["cortex-a8"], " ")) 215 pctx.StaticVariable("armClangCortexA15Cflags", 216 strings.Join(armClangCpuVariantCflags["cortex-a15"], " ")) 217 pctx.StaticVariable("armClangKraitCflags", 218 strings.Join(armClangCpuVariantCflags["krait"], " ")) 219 } 220 221 var ( 222 armArchVariantCflagsVar = map[string]string{ 223 "armv5te": "${armArmv5TECflags}", 224 "armv7-a": "${armArmv7ACflags}", 225 "armv7-a-neon": "${armArmv7ANeonCflags}", 226 } 227 228 armCpuVariantCflagsVar = map[string]string{ 229 "": "", 230 "cortex-a7": "${armCortexA7Cflags}", 231 "cortex-a8": "${armCortexA8Cflags}", 232 "cortex-a15": "${armCortexA15Cflags}", 233 "cortex-a53": "${armCortexA7Cflags}", 234 "cortex-a53.a57": "${armCortexA7Cflags}", 235 "krait": "${armCortexA15Cflags}", 236 "denver": "${armCortexA15Cflags}", 237 } 238 239 armClangArchVariantCflagsVar = map[string]string{ 240 "armv5te": "${armClangArmv5TECflags}", 241 "armv7-a": "${armClangArmv7ACflags}", 242 "armv7-a-neon": "${armClangArmv7ANeonCflags}", 243 } 244 245 armClangCpuVariantCflagsVar = map[string]string{ 246 "": "", 247 "cortex-a7": "${armClangCortexA7Cflags}", 248 "cortex-a8": "${armClangCortexA8Cflags}", 249 "cortex-a15": "${armClangCortexA15Cflags}", 250 "cortex-a53": "${armClangCortexA7Cflags}", 251 "cortex-a53.a57": "${armClangCortexA7Cflags}", 252 "krait": "${armClangKraitCflags}", 253 "denver": "${armClangCortexA15Cflags}", 254 } 255 ) 256 257 type toolchainArm struct { 258 toolchain32Bit 259 ldflags string 260 toolchainCflags, toolchainClangCflags string 261 } 262 263 func (t *toolchainArm) Name() string { 264 return "arm" 265 } 266 267 func (t *toolchainArm) GccRoot() string { 268 return "${armGccRoot}" 269 } 270 271 func (t *toolchainArm) GccTriple() string { 272 return "${armGccTriple}" 273 } 274 275 func (t *toolchainArm) GccVersion() string { 276 return armGccVersion 277 } 278 279 func (t *toolchainArm) ToolchainCflags() string { 280 return t.toolchainCflags 281 } 282 283 func (t *toolchainArm) Cflags() string { 284 return "${armCflags}" 285 } 286 287 func (t *toolchainArm) Cppflags() string { 288 return "${armCppflags}" 289 } 290 291 func (t *toolchainArm) Ldflags() string { 292 return t.ldflags 293 } 294 295 func (t *toolchainArm) IncludeFlags() string { 296 return "${armIncludeFlags}" 297 } 298 299 func (t *toolchainArm) InstructionSetFlags(isa string) (string, error) { 300 switch isa { 301 case "arm": 302 return "${armArmCflags}", nil 303 case "thumb", "": 304 return "${armThumbCflags}", nil 305 default: 306 return t.toolchainBase.InstructionSetFlags(isa) 307 } 308 } 309 310 func (t *toolchainArm) ClangTriple() string { 311 return "${armGccTriple}" 312 } 313 314 func (t *toolchainArm) ToolchainClangCflags() string { 315 return t.toolchainClangCflags 316 } 317 318 func (t *toolchainArm) ClangCflags() string { 319 return "${armClangCflags}" 320 } 321 322 func (t *toolchainArm) ClangCppflags() string { 323 return "${armClangCppflags}" 324 } 325 326 func (t *toolchainArm) ClangLdflags() string { 327 return t.ldflags 328 } 329 330 func (t *toolchainArm) ClangInstructionSetFlags(isa string) (string, error) { 331 switch isa { 332 case "arm": 333 return "${armClangArmCflags}", nil 334 case "thumb", "": 335 return "${armClangThumbCflags}", nil 336 default: 337 return t.toolchainBase.ClangInstructionSetFlags(isa) 338 } 339 } 340 341 func armToolchainFactory(arch common.Arch) Toolchain { 342 var fixCortexA8 string 343 switch arch.CpuVariant { 344 case "cortex-a8", "": 345 // Generic ARM might be a Cortex A8 -- better safe than sorry 346 fixCortexA8 = "-Wl,--fix-cortex-a8" 347 default: 348 fixCortexA8 = "-Wl,--no-fix-cortex-a8" 349 } 350 351 return &toolchainArm{ 352 toolchainCflags: strings.Join([]string{ 353 "${armToolchainCflags}", 354 armArchVariantCflagsVar[arch.ArchVariant], 355 armCpuVariantCflagsVar[arch.CpuVariant], 356 }, " "), 357 ldflags: strings.Join([]string{ 358 "${armLdflags}", 359 fixCortexA8, 360 }, " "), 361 toolchainClangCflags: strings.Join([]string{ 362 "${armToolchainClangCflags}", 363 armClangArchVariantCflagsVar[arch.ArchVariant], 364 armClangCpuVariantCflagsVar[arch.CpuVariant], 365 }, " "), 366 } 367 } 368 369 func init() { 370 registerDeviceToolchainFactory(common.Arm, armToolchainFactory) 371 } 372