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