1// Copyright (C) 2016 The Android Open Source Project 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 art 16 17import ( 18 "android/soong/android" 19 "android/soong/cc" 20 "fmt" 21 "sync" 22 23 "github.com/google/blueprint" 24) 25 26var supportedArches = []string{"arm", "arm64", "mips", "mips64", "x86", "x86_64"} 27 28func globalFlags(ctx android.BaseContext) ([]string, []string) { 29 var cflags []string 30 var asflags []string 31 32 opt := envDefault(ctx, "ART_NDEBUG_OPT_FLAG", "-O3") 33 cflags = append(cflags, opt) 34 35 tlab := false 36 37 gcType := envDefault(ctx, "ART_DEFAULT_GC_TYPE", "CMS") 38 39 if envTrue(ctx, "ART_TEST_DEBUG_GC") { 40 gcType = "SS" 41 tlab = true 42 } 43 44 cflags = append(cflags, "-DART_DEFAULT_GC_TYPE_IS_"+gcType) 45 if tlab { 46 cflags = append(cflags, "-DART_USE_TLAB=1") 47 } 48 49 if !envFalse(ctx, "ART_ENABLE_VDEX") { 50 cflags = append(cflags, "-DART_ENABLE_VDEX") 51 } 52 53 imtSize := envDefault(ctx, "ART_IMT_SIZE", "43") 54 cflags = append(cflags, "-DIMT_SIZE="+imtSize) 55 56 if envTrue(ctx, "ART_HEAP_POISONING") { 57 cflags = append(cflags, "-DART_HEAP_POISONING=1") 58 asflags = append(asflags, "-DART_HEAP_POISONING=1") 59 } 60 61 if !envFalse(ctx, "ART_USE_READ_BARRIER") && ctx.AConfig().ArtUseReadBarrier() { 62 // Used to change the read barrier type. Valid values are BAKER, BROOKS, 63 // TABLELOOKUP. The default is BAKER. 64 barrierType := envDefault(ctx, "ART_READ_BARRIER_TYPE", "BAKER") 65 cflags = append(cflags, 66 "-DART_USE_READ_BARRIER=1", 67 "-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1") 68 asflags = append(asflags, 69 "-DART_USE_READ_BARRIER=1", 70 "-DART_READ_BARRIER_TYPE_IS_"+barrierType+"=1") 71 } 72 73 if envTrue(ctx, "ART_USE_OLD_ARM_BACKEND") { 74 // Used to enable the old, pre-VIXL ARM code generator. 75 cflags = append(cflags, "-DART_USE_OLD_ARM_BACKEND=1") 76 asflags = append(asflags, "-DART_USE_OLD_ARM_BACKEND=1") 77 } 78 79 return cflags, asflags 80} 81 82func debugFlags(ctx android.BaseContext) []string { 83 var cflags []string 84 85 opt := envDefault(ctx, "ART_DEBUG_OPT_FLAG", "-O2") 86 cflags = append(cflags, opt) 87 88 return cflags 89} 90 91func deviceFlags(ctx android.BaseContext) []string { 92 var cflags []string 93 deviceFrameSizeLimit := 1736 94 if len(ctx.AConfig().SanitizeDevice()) > 0 { 95 deviceFrameSizeLimit = 7400 96 } 97 cflags = append(cflags, 98 fmt.Sprintf("-Wframe-larger-than=%d", deviceFrameSizeLimit), 99 fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", deviceFrameSizeLimit), 100 ) 101 102 cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.AConfig().LibartImgDeviceBaseAddress()) 103 if envTrue(ctx, "ART_TARGET_LINUX") { 104 cflags = append(cflags, "-DART_TARGET_LINUX") 105 } else { 106 cflags = append(cflags, "-DART_TARGET_ANDROID") 107 } 108 minDelta := envDefault(ctx, "LIBART_IMG_TARGET_MIN_BASE_ADDRESS_DELTA", "-0x1000000") 109 maxDelta := envDefault(ctx, "LIBART_IMG_TARGET_MAX_BASE_ADDRESS_DELTA", "0x1000000") 110 cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta) 111 cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta) 112 113 return cflags 114} 115 116func hostFlags(ctx android.BaseContext) []string { 117 var cflags []string 118 hostFrameSizeLimit := 1736 119 if len(ctx.AConfig().SanitizeHost()) > 0 { 120 // art/test/137-cfi/cfi.cc 121 // error: stack frame size of 1944 bytes in function 'Java_Main_unwindInProcess' 122 hostFrameSizeLimit = 6400 123 } 124 cflags = append(cflags, 125 fmt.Sprintf("-Wframe-larger-than=%d", hostFrameSizeLimit), 126 fmt.Sprintf("-DART_FRAME_SIZE_LIMIT=%d", hostFrameSizeLimit), 127 ) 128 129 cflags = append(cflags, "-DART_BASE_ADDRESS="+ctx.AConfig().LibartImgHostBaseAddress()) 130 minDelta := envDefault(ctx, "LIBART_IMG_HOST_MIN_BASE_ADDRESS_DELTA", "-0x1000000") 131 maxDelta := envDefault(ctx, "LIBART_IMG_HOST_MAX_BASE_ADDRESS_DELTA", "0x1000000") 132 cflags = append(cflags, "-DART_BASE_ADDRESS_MIN_DELTA="+minDelta) 133 cflags = append(cflags, "-DART_BASE_ADDRESS_MAX_DELTA="+maxDelta) 134 135 return cflags 136} 137 138func globalDefaults(ctx android.LoadHookContext) { 139 type props struct { 140 Target struct { 141 Android struct { 142 Cflags []string 143 } 144 Host struct { 145 Cflags []string 146 } 147 } 148 Cflags []string 149 Asflags []string 150 } 151 152 p := &props{} 153 p.Cflags, p.Asflags = globalFlags(ctx) 154 p.Target.Android.Cflags = deviceFlags(ctx) 155 p.Target.Host.Cflags = hostFlags(ctx) 156 ctx.AppendProperties(p) 157} 158 159func debugDefaults(ctx android.LoadHookContext) { 160 type props struct { 161 Cflags []string 162 } 163 164 p := &props{} 165 p.Cflags = debugFlags(ctx) 166 ctx.AppendProperties(p) 167} 168 169func customLinker(ctx android.LoadHookContext) { 170 linker := envDefault(ctx, "CUSTOM_TARGET_LINKER", "") 171 if linker != "" { 172 type props struct { 173 DynamicLinker string 174 } 175 176 p := &props{} 177 p.DynamicLinker = linker 178 ctx.AppendProperties(p) 179 } 180} 181 182func prefer32Bit(ctx android.LoadHookContext) { 183 if envTrue(ctx, "HOST_PREFER_32_BIT") { 184 type props struct { 185 Target struct { 186 Host struct { 187 Compile_multilib string 188 } 189 } 190 } 191 192 p := &props{} 193 p.Target.Host.Compile_multilib = "prefer32" 194 ctx.AppendProperties(p) 195 } 196} 197 198func testMap(config android.Config) map[string][]string { 199 return config.Once("artTests", func() interface{} { 200 return make(map[string][]string) 201 }).(map[string][]string) 202} 203 204func testInstall(ctx android.InstallHookContext) { 205 testMap := testMap(ctx.AConfig()) 206 207 var name string 208 if ctx.Host() { 209 name = "host_" 210 } else { 211 name = "device_" 212 } 213 name += ctx.Arch().ArchType.String() + "_" + ctx.ModuleName() 214 215 artTestMutex.Lock() 216 defer artTestMutex.Unlock() 217 218 tests := testMap[name] 219 tests = append(tests, ctx.Path().RelPathString()) 220 testMap[name] = tests 221} 222 223var artTestMutex sync.Mutex 224 225func init() { 226 android.RegisterModuleType("art_cc_library", artLibrary) 227 android.RegisterModuleType("art_cc_binary", artBinary) 228 android.RegisterModuleType("art_cc_test", artTest) 229 android.RegisterModuleType("art_cc_test_library", artTestLibrary) 230 android.RegisterModuleType("art_cc_defaults", artDefaultsFactory) 231 android.RegisterModuleType("art_global_defaults", artGlobalDefaultsFactory) 232 android.RegisterModuleType("art_debug_defaults", artDebugDefaultsFactory) 233} 234 235func artGlobalDefaultsFactory() (blueprint.Module, []interface{}) { 236 module, props := artDefaultsFactory() 237 android.AddLoadHook(module, globalDefaults) 238 239 return module, props 240} 241 242func artDebugDefaultsFactory() (blueprint.Module, []interface{}) { 243 module, props := artDefaultsFactory() 244 android.AddLoadHook(module, debugDefaults) 245 246 return module, props 247} 248 249func artDefaultsFactory() (blueprint.Module, []interface{}) { 250 c := &codegenProperties{} 251 module, props := cc.DefaultsFactory(c) 252 android.AddLoadHook(module, func(ctx android.LoadHookContext) { codegen(ctx, c, true) }) 253 254 return module, props 255} 256 257func artLibrary() (blueprint.Module, []interface{}) { 258 library, _ := cc.NewLibrary(android.HostAndDeviceSupported) 259 module, props := library.Init() 260 261 props = installCodegenCustomizer(module, props, true) 262 263 return module, props 264} 265 266func artBinary() (blueprint.Module, []interface{}) { 267 binary, _ := cc.NewBinary(android.HostAndDeviceSupported) 268 module, props := binary.Init() 269 270 android.AddLoadHook(module, customLinker) 271 android.AddLoadHook(module, prefer32Bit) 272 return module, props 273} 274 275func artTest() (blueprint.Module, []interface{}) { 276 test := cc.NewTest(android.HostAndDeviceSupported) 277 module, props := test.Init() 278 279 props = installCodegenCustomizer(module, props, false) 280 281 android.AddLoadHook(module, customLinker) 282 android.AddLoadHook(module, prefer32Bit) 283 android.AddInstallHook(module, testInstall) 284 return module, props 285} 286 287func artTestLibrary() (blueprint.Module, []interface{}) { 288 test := cc.NewTestLibrary(android.HostAndDeviceSupported) 289 module, props := test.Init() 290 291 props = installCodegenCustomizer(module, props, false) 292 293 android.AddLoadHook(module, prefer32Bit) 294 android.AddInstallHook(module, testInstall) 295 return module, props 296} 297 298func envDefault(ctx android.BaseContext, key string, defaultValue string) string { 299 ret := ctx.AConfig().Getenv(key) 300 if ret == "" { 301 return defaultValue 302 } 303 return ret 304} 305 306func envTrue(ctx android.BaseContext, key string) bool { 307 return ctx.AConfig().Getenv(key) == "true" 308} 309 310func envFalse(ctx android.BaseContext, key string) bool { 311 return ctx.AConfig().Getenv(key) == "false" 312} 313