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 android 16 17import ( 18 "encoding/json" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "path/filepath" 23 "runtime" 24 "strconv" 25 "strings" 26 "sync" 27 28 "github.com/google/blueprint" 29 "github.com/google/blueprint/bootstrap" 30 "github.com/google/blueprint/pathtools" 31 "github.com/google/blueprint/proptools" 32 33 "android/soong/android/soongconfig" 34) 35 36var Bool = proptools.Bool 37var String = proptools.String 38 39const FutureApiLevel = 10000 40 41// The configuration file name 42const configFileName = "soong.config" 43const productVariablesFileName = "soong.variables" 44 45// A FileConfigurableOptions contains options which can be configured by the 46// config file. These will be included in the config struct. 47type FileConfigurableOptions struct { 48 Mega_device *bool `json:",omitempty"` 49 Host_bionic *bool `json:",omitempty"` 50} 51 52func (f *FileConfigurableOptions) SetDefaultConfig() { 53 *f = FileConfigurableOptions{} 54} 55 56// A Config object represents the entire build configuration for Android. 57type Config struct { 58 *config 59} 60 61func (c Config) BuildDir() string { 62 return c.buildDir 63} 64 65// A DeviceConfig object represents the configuration for a particular device being built. For 66// now there will only be one of these, but in the future there may be multiple devices being 67// built 68type DeviceConfig struct { 69 *deviceConfig 70} 71 72type VendorConfig soongconfig.SoongConfig 73 74type config struct { 75 FileConfigurableOptions 76 productVariables productVariables 77 78 // Only available on configs created by TestConfig 79 TestProductVariables *productVariables 80 81 PrimaryBuilder string 82 ConfigFileName string 83 ProductVariablesFileName string 84 85 Targets map[OsType][]Target 86 BuildOSTarget Target // the Target for tools run on the build machine 87 BuildOSCommonTarget Target // the Target for common (java) tools run on the build machine 88 AndroidCommonTarget Target // the Target for common modules for the Android device 89 AndroidFirstDeviceTarget Target // the first Target for modules for the Android device 90 91 // multilibConflicts for an ArchType is true if there is earlier configured device architecture with the same 92 // multilib value. 93 multilibConflicts map[ArchType]bool 94 95 deviceConfig *deviceConfig 96 97 srcDir string // the path of the root source directory 98 buildDir string // the path of the build output directory 99 100 env map[string]string 101 envLock sync.Mutex 102 envDeps map[string]string 103 envFrozen bool 104 105 inMake bool 106 107 captureBuild bool // true for tests, saves build parameters for each module 108 ignoreEnvironment bool // true for tests, returns empty from all Getenv calls 109 110 stopBefore bootstrap.StopBefore 111 112 fs pathtools.FileSystem 113 mockBpList string 114 115 // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error 116 // in tests when a path doesn't exist. 117 testAllowNonExistentPaths bool 118 119 OncePer 120} 121 122type deviceConfig struct { 123 config *config 124 OncePer 125} 126 127type jsonConfigurable interface { 128 SetDefaultConfig() 129} 130 131func loadConfig(config *config) error { 132 err := loadFromConfigFile(&config.FileConfigurableOptions, absolutePath(config.ConfigFileName)) 133 if err != nil { 134 return err 135 } 136 137 return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) 138} 139 140// loads configuration options from a JSON file in the cwd. 141func loadFromConfigFile(configurable jsonConfigurable, filename string) error { 142 // Try to open the file 143 configFileReader, err := os.Open(filename) 144 defer configFileReader.Close() 145 if os.IsNotExist(err) { 146 // Need to create a file, so that blueprint & ninja don't get in 147 // a dependency tracking loop. 148 // Make a file-configurable-options with defaults, write it out using 149 // a json writer. 150 configurable.SetDefaultConfig() 151 err = saveToConfigFile(configurable, filename) 152 if err != nil { 153 return err 154 } 155 } else if err != nil { 156 return fmt.Errorf("config file: could not open %s: %s", filename, err.Error()) 157 } else { 158 // Make a decoder for it 159 jsonDecoder := json.NewDecoder(configFileReader) 160 err = jsonDecoder.Decode(configurable) 161 if err != nil { 162 return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error()) 163 } 164 } 165 166 // No error 167 return nil 168} 169 170// atomically writes the config file in case two copies of soong_build are running simultaneously 171// (for example, docs generation and ninja manifest generation) 172func saveToConfigFile(config jsonConfigurable, filename string) error { 173 data, err := json.MarshalIndent(&config, "", " ") 174 if err != nil { 175 return fmt.Errorf("cannot marshal config data: %s", err.Error()) 176 } 177 178 f, err := ioutil.TempFile(filepath.Dir(filename), "config") 179 if err != nil { 180 return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error()) 181 } 182 defer os.Remove(f.Name()) 183 defer f.Close() 184 185 _, err = f.Write(data) 186 if err != nil { 187 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 188 } 189 190 _, err = f.WriteString("\n") 191 if err != nil { 192 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 193 } 194 195 f.Close() 196 os.Rename(f.Name(), filename) 197 198 return nil 199} 200 201// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that 202// use the android package. 203func NullConfig(buildDir string) Config { 204 return Config{ 205 config: &config{ 206 buildDir: buildDir, 207 fs: pathtools.OsFs, 208 }, 209 } 210} 211 212// TestConfig returns a Config object suitable for using for tests 213func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 214 envCopy := make(map[string]string) 215 for k, v := range env { 216 envCopy[k] = v 217 } 218 219 // Copy the real PATH value to the test environment, it's needed by HostSystemTool() used in x86_darwin_host.go 220 envCopy["PATH"] = originalEnv["PATH"] 221 222 config := &config{ 223 productVariables: productVariables{ 224 DeviceName: stringPtr("test_device"), 225 Platform_sdk_version: intPtr(30), 226 DeviceSystemSdkVersions: []string{"14", "15"}, 227 Platform_systemsdk_versions: []string{"29", "30"}, 228 AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"}, 229 AAPTPreferredConfig: stringPtr("xhdpi"), 230 AAPTCharacteristics: stringPtr("nosdcard"), 231 AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"}, 232 UncompressPrivAppDex: boolPtr(true), 233 }, 234 235 buildDir: buildDir, 236 captureBuild: true, 237 env: envCopy, 238 239 // Set testAllowNonExistentPaths so that test contexts don't need to specify every path 240 // passed to PathForSource or PathForModuleSrc. 241 testAllowNonExistentPaths: true, 242 } 243 config.deviceConfig = &deviceConfig{ 244 config: config, 245 } 246 config.TestProductVariables = &config.productVariables 247 248 config.mockFileSystem(bp, fs) 249 250 if err := config.fromEnv(); err != nil { 251 panic(err) 252 } 253 254 return Config{config} 255} 256 257func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 258 testConfig := TestArchConfig(buildDir, env, bp, fs) 259 config := testConfig.config 260 261 config.Targets[Android] = []Target{ 262 {Android, Arch{ArchType: X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, 263 {Android, Arch{ArchType: X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", ""}, 264 {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeEnabled, "x86_64", "arm64"}, 265 {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeEnabled, "x86", "arm"}, 266 } 267 268 return testConfig 269} 270 271func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 272 testConfig := TestConfig(buildDir, env, bp, fs) 273 config := testConfig.config 274 275 config.Targets = map[OsType][]Target{ 276 Fuchsia: []Target{ 277 {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, 278 }, 279 BuildOs: []Target{ 280 {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, 281 }, 282 } 283 284 return testConfig 285} 286 287// TestConfig returns a Config object suitable for using for tests that need to run the arch mutator 288func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 289 testConfig := TestConfig(buildDir, env, bp, fs) 290 config := testConfig.config 291 292 config.Targets = map[OsType][]Target{ 293 Android: []Target{ 294 {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", ""}, 295 {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", ""}, 296 }, 297 BuildOs: []Target{ 298 {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", ""}, 299 {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", ""}, 300 }, 301 } 302 303 if runtime.GOOS == "darwin" { 304 config.Targets[BuildOs] = config.Targets[BuildOs][:1] 305 } 306 307 config.BuildOSTarget = config.Targets[BuildOs][0] 308 config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] 309 config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] 310 config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] 311 config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64") 312 config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a") 313 config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm") 314 config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon") 315 316 return testConfig 317} 318 319// New creates a new Config object. The srcDir argument specifies the path to 320// the root source directory. It also loads the config file, if found. 321func NewConfig(srcDir, buildDir string) (Config, error) { 322 // Make a config with default options 323 config := &config{ 324 ConfigFileName: filepath.Join(buildDir, configFileName), 325 ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), 326 327 env: originalEnv, 328 329 srcDir: srcDir, 330 buildDir: buildDir, 331 multilibConflicts: make(map[ArchType]bool), 332 333 fs: pathtools.NewOsFs(absSrcDir), 334 } 335 336 config.deviceConfig = &deviceConfig{ 337 config: config, 338 } 339 340 // Sanity check the build and source directories. This won't catch strange 341 // configurations with symlinks, but at least checks the obvious cases. 342 absBuildDir, err := filepath.Abs(buildDir) 343 if err != nil { 344 return Config{}, err 345 } 346 347 absSrcDir, err := filepath.Abs(srcDir) 348 if err != nil { 349 return Config{}, err 350 } 351 352 if strings.HasPrefix(absSrcDir, absBuildDir) { 353 return Config{}, fmt.Errorf("Build dir must not contain source directory") 354 } 355 356 // Load any configurable options from the configuration file 357 err = loadConfig(config) 358 if err != nil { 359 return Config{}, err 360 } 361 362 inMakeFile := filepath.Join(buildDir, ".soong.in_make") 363 if _, err := os.Stat(absolutePath(inMakeFile)); err == nil { 364 config.inMake = true 365 } 366 367 targets, err := decodeTargetProductVariables(config) 368 if err != nil { 369 return Config{}, err 370 } 371 372 // Make the CommonOS OsType available for all products. 373 targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]} 374 375 var archConfig []archConfig 376 if Bool(config.Mega_device) { 377 archConfig = getMegaDeviceConfig() 378 } else if config.NdkAbis() { 379 archConfig = getNdkAbisConfig() 380 } else if config.AmlAbis() { 381 archConfig = getAmlAbisConfig() 382 } 383 384 if archConfig != nil { 385 androidTargets, err := decodeArchSettings(Android, archConfig) 386 if err != nil { 387 return Config{}, err 388 } 389 targets[Android] = androidTargets 390 } 391 392 multilib := make(map[string]bool) 393 for _, target := range targets[Android] { 394 if seen := multilib[target.Arch.ArchType.Multilib]; seen { 395 config.multilibConflicts[target.Arch.ArchType] = true 396 } 397 multilib[target.Arch.ArchType.Multilib] = true 398 } 399 400 config.Targets = targets 401 config.BuildOSTarget = config.Targets[BuildOs][0] 402 config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] 403 if len(config.Targets[Android]) > 0 { 404 config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] 405 config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] 406 } 407 408 if err := config.fromEnv(); err != nil { 409 return Config{}, err 410 } 411 412 if Bool(config.productVariables.GcovCoverage) && Bool(config.productVariables.ClangCoverage) { 413 return Config{}, fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set") 414 } 415 416 config.productVariables.Native_coverage = proptools.BoolPtr( 417 Bool(config.productVariables.GcovCoverage) || 418 Bool(config.productVariables.ClangCoverage)) 419 420 return Config{config}, nil 421} 422 423var TestConfigOsFs = map[string][]byte{} 424 425// mockFileSystem replaces all reads with accesses to the provided map of 426// filenames to contents stored as a byte slice. 427func (c *config) mockFileSystem(bp string, fs map[string][]byte) { 428 mockFS := map[string][]byte{} 429 430 if _, exists := mockFS["Android.bp"]; !exists { 431 mockFS["Android.bp"] = []byte(bp) 432 } 433 434 for k, v := range fs { 435 mockFS[k] = v 436 } 437 438 // no module list file specified; find every file named Blueprints or Android.bp 439 pathsToParse := []string{} 440 for candidate := range mockFS { 441 base := filepath.Base(candidate) 442 if base == "Blueprints" || base == "Android.bp" { 443 pathsToParse = append(pathsToParse, candidate) 444 } 445 } 446 if len(pathsToParse) < 1 { 447 panic(fmt.Sprintf("No Blueprint or Android.bp files found in mock filesystem: %v\n", mockFS)) 448 } 449 mockFS[blueprint.MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n")) 450 451 c.fs = pathtools.MockFs(mockFS) 452 c.mockBpList = blueprint.MockModuleListFile 453} 454 455func (c *config) fromEnv() error { 456 switch c.Getenv("EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9") { 457 case "", "true": 458 // Do nothing 459 default: 460 return fmt.Errorf("The environment variable EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9 is no longer supported. Java language level 9 is now the global default.") 461 } 462 463 return nil 464} 465 466func (c *config) StopBefore() bootstrap.StopBefore { 467 return c.stopBefore 468} 469 470func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { 471 c.stopBefore = stopBefore 472} 473 474var _ bootstrap.ConfigStopBefore = (*config)(nil) 475 476func (c *config) BlueprintToolLocation() string { 477 return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") 478} 479 480var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil) 481 482func (c *config) HostToolPath(ctx PathContext, tool string) Path { 483 return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool) 484} 485 486func (c *config) HostJNIToolPath(ctx PathContext, path string) Path { 487 ext := ".so" 488 if runtime.GOOS == "darwin" { 489 ext = ".dylib" 490 } 491 return PathForOutput(ctx, "host", c.PrebuiltOS(), "lib64", path+ext) 492} 493 494func (c *config) HostJavaToolPath(ctx PathContext, path string) Path { 495 return PathForOutput(ctx, "host", c.PrebuiltOS(), "framework", path) 496} 497 498// HostSystemTool looks for non-hermetic tools from the system we're running on. 499// Generally shouldn't be used, but useful to find the XCode SDK, etc. 500func (c *config) HostSystemTool(name string) string { 501 for _, dir := range filepath.SplitList(c.Getenv("PATH")) { 502 path := filepath.Join(dir, name) 503 if s, err := os.Stat(path); err != nil { 504 continue 505 } else if m := s.Mode(); !s.IsDir() && m&0111 != 0 { 506 return path 507 } 508 } 509 return name 510} 511 512// PrebuiltOS returns the name of the host OS used in prebuilts directories 513func (c *config) PrebuiltOS() string { 514 switch runtime.GOOS { 515 case "linux": 516 return "linux-x86" 517 case "darwin": 518 return "darwin-x86" 519 default: 520 panic("Unknown GOOS") 521 } 522} 523 524// GoRoot returns the path to the root directory of the Go toolchain. 525func (c *config) GoRoot() string { 526 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) 527} 528 529func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { 530 return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) 531} 532 533func (c *config) CpPreserveSymlinksFlags() string { 534 switch runtime.GOOS { 535 case "darwin": 536 return "-R" 537 case "linux": 538 return "-d" 539 default: 540 return "" 541 } 542} 543 544func (c *config) Getenv(key string) string { 545 var val string 546 var exists bool 547 c.envLock.Lock() 548 defer c.envLock.Unlock() 549 if c.envDeps == nil { 550 c.envDeps = make(map[string]string) 551 } 552 if val, exists = c.envDeps[key]; !exists { 553 if c.envFrozen { 554 panic("Cannot access new environment variables after envdeps are frozen") 555 } 556 val, _ = c.env[key] 557 c.envDeps[key] = val 558 } 559 return val 560} 561 562func (c *config) GetenvWithDefault(key string, defaultValue string) string { 563 ret := c.Getenv(key) 564 if ret == "" { 565 return defaultValue 566 } 567 return ret 568} 569 570func (c *config) IsEnvTrue(key string) bool { 571 value := c.Getenv(key) 572 return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" 573} 574 575func (c *config) IsEnvFalse(key string) bool { 576 value := c.Getenv(key) 577 return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" 578} 579 580func (c *config) EnvDeps() map[string]string { 581 c.envLock.Lock() 582 defer c.envLock.Unlock() 583 c.envFrozen = true 584 return c.envDeps 585} 586 587func (c *config) EmbeddedInMake() bool { 588 return c.inMake 589} 590 591func (c *config) BuildId() string { 592 return String(c.productVariables.BuildId) 593} 594 595func (c *config) BuildNumberFile(ctx PathContext) Path { 596 return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) 597} 598 599// DeviceName returns the name of the current device target 600// TODO: take an AndroidModuleContext to select the device name for multi-device builds 601func (c *config) DeviceName() string { 602 return *c.productVariables.DeviceName 603} 604 605func (c *config) DeviceResourceOverlays() []string { 606 return c.productVariables.DeviceResourceOverlays 607} 608 609func (c *config) ProductResourceOverlays() []string { 610 return c.productVariables.ProductResourceOverlays 611} 612 613func (c *config) PlatformVersionName() string { 614 return String(c.productVariables.Platform_version_name) 615} 616 617func (c *config) PlatformSdkVersionInt() int { 618 return *c.productVariables.Platform_sdk_version 619} 620 621func (c *config) PlatformSdkVersion() string { 622 return strconv.Itoa(c.PlatformSdkVersionInt()) 623} 624 625func (c *config) PlatformSdkCodename() string { 626 return String(c.productVariables.Platform_sdk_codename) 627} 628 629func (c *config) PlatformSecurityPatch() string { 630 return String(c.productVariables.Platform_security_patch) 631} 632 633func (c *config) PlatformPreviewSdkVersion() string { 634 return String(c.productVariables.Platform_preview_sdk_version) 635} 636 637func (c *config) PlatformMinSupportedTargetSdkVersion() string { 638 return String(c.productVariables.Platform_min_supported_target_sdk_version) 639} 640 641func (c *config) PlatformBaseOS() string { 642 return String(c.productVariables.Platform_base_os) 643} 644 645func (c *config) MinSupportedSdkVersion() int { 646 return 16 647} 648 649func (c *config) DefaultAppTargetSdkInt() int { 650 if Bool(c.productVariables.Platform_sdk_final) { 651 return c.PlatformSdkVersionInt() 652 } else { 653 return FutureApiLevel 654 } 655} 656 657func (c *config) DefaultAppTargetSdk() string { 658 if Bool(c.productVariables.Platform_sdk_final) { 659 return c.PlatformSdkVersion() 660 } else { 661 return c.PlatformSdkCodename() 662 } 663} 664 665func (c *config) AppsDefaultVersionName() string { 666 return String(c.productVariables.AppsDefaultVersionName) 667} 668 669// Codenames that are active in the current lunch target. 670func (c *config) PlatformVersionActiveCodenames() []string { 671 return c.productVariables.Platform_version_active_codenames 672} 673 674func (c *config) ProductAAPTConfig() []string { 675 return c.productVariables.AAPTConfig 676} 677 678func (c *config) ProductAAPTPreferredConfig() string { 679 return String(c.productVariables.AAPTPreferredConfig) 680} 681 682func (c *config) ProductAAPTCharacteristics() string { 683 return String(c.productVariables.AAPTCharacteristics) 684} 685 686func (c *config) ProductAAPTPrebuiltDPI() []string { 687 return c.productVariables.AAPTPrebuiltDPI 688} 689 690func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { 691 defaultCert := String(c.productVariables.DefaultAppCertificate) 692 if defaultCert != "" { 693 return PathForSource(ctx, filepath.Dir(defaultCert)) 694 } else { 695 return PathForSource(ctx, "build/make/target/product/security") 696 } 697} 698 699func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { 700 defaultCert := String(c.productVariables.DefaultAppCertificate) 701 if defaultCert != "" { 702 return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") 703 } else { 704 defaultDir := c.DefaultAppCertificateDir(ctx) 705 return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") 706 } 707} 708 709func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { 710 // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE 711 defaultCert := String(c.productVariables.DefaultAppCertificate) 712 if defaultCert == "" || filepath.Dir(defaultCert) == "build/make/target/product/security" { 713 // When defaultCert is unset or is set to the testkeys path, use the APEX keys 714 // that is under the module dir 715 return pathForModuleSrc(ctx) 716 } else { 717 // If not, APEX keys are under the specified directory 718 return PathForSource(ctx, filepath.Dir(defaultCert)) 719 } 720} 721 722func (c *config) AllowMissingDependencies() bool { 723 return Bool(c.productVariables.Allow_missing_dependencies) 724} 725 726func (c *config) UnbundledBuild() bool { 727 return Bool(c.productVariables.Unbundled_build) 728} 729 730func (c *config) UnbundledBuildUsePrebuiltSdks() bool { 731 return Bool(c.productVariables.Unbundled_build) && !Bool(c.productVariables.Unbundled_build_sdks_from_source) 732} 733 734func (c *config) Fuchsia() bool { 735 return Bool(c.productVariables.Fuchsia) 736} 737 738func (c *config) IsPdkBuild() bool { 739 return Bool(c.productVariables.Pdk) 740} 741 742func (c *config) MinimizeJavaDebugInfo() bool { 743 return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng) 744} 745 746func (c *config) Debuggable() bool { 747 return Bool(c.productVariables.Debuggable) 748} 749 750func (c *config) Eng() bool { 751 return Bool(c.productVariables.Eng) 752} 753 754func (c *config) DevicePrefer32BitApps() bool { 755 return Bool(c.productVariables.DevicePrefer32BitApps) 756} 757 758func (c *config) DevicePrefer32BitExecutables() bool { 759 return Bool(c.productVariables.DevicePrefer32BitExecutables) 760} 761 762func (c *config) DevicePrimaryArchType() ArchType { 763 return c.Targets[Android][0].Arch.ArchType 764} 765 766func (c *config) SkipMegaDeviceInstall(path string) bool { 767 return Bool(c.Mega_device) && 768 strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product")) 769} 770 771func (c *config) SanitizeHost() []string { 772 return append([]string(nil), c.productVariables.SanitizeHost...) 773} 774 775func (c *config) SanitizeDevice() []string { 776 return append([]string(nil), c.productVariables.SanitizeDevice...) 777} 778 779func (c *config) SanitizeDeviceDiag() []string { 780 return append([]string(nil), c.productVariables.SanitizeDeviceDiag...) 781} 782 783func (c *config) SanitizeDeviceArch() []string { 784 return append([]string(nil), c.productVariables.SanitizeDeviceArch...) 785} 786 787func (c *config) EnableCFI() bool { 788 if c.productVariables.EnableCFI == nil { 789 return true 790 } else { 791 return *c.productVariables.EnableCFI 792 } 793} 794 795func (c *config) DisableScudo() bool { 796 return Bool(c.productVariables.DisableScudo) 797} 798 799func (c *config) Android64() bool { 800 for _, t := range c.Targets[Android] { 801 if t.Arch.ArchType.Multilib == "lib64" { 802 return true 803 } 804 } 805 806 return false 807} 808 809func (c *config) UseGoma() bool { 810 return Bool(c.productVariables.UseGoma) 811} 812 813func (c *config) UseRBE() bool { 814 return Bool(c.productVariables.UseRBE) 815} 816 817func (c *config) UseRBEJAVAC() bool { 818 return Bool(c.productVariables.UseRBEJAVAC) 819} 820 821func (c *config) UseRBER8() bool { 822 return Bool(c.productVariables.UseRBER8) 823} 824 825func (c *config) UseRBED8() bool { 826 return Bool(c.productVariables.UseRBED8) 827} 828 829func (c *config) UseRemoteBuild() bool { 830 return c.UseGoma() || c.UseRBE() 831} 832 833func (c *config) RunErrorProne() bool { 834 return c.IsEnvTrue("RUN_ERROR_PRONE") 835} 836 837func (c *config) XrefCorpusName() string { 838 return c.Getenv("XREF_CORPUS") 839} 840 841// Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'. 842func (c *config) XrefCuEncoding() string { 843 if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { 844 return enc 845 } 846 return "json" 847} 848 849func (c *config) EmitXrefRules() bool { 850 return c.XrefCorpusName() != "" 851} 852 853func (c *config) ClangTidy() bool { 854 return Bool(c.productVariables.ClangTidy) 855} 856 857func (c *config) TidyChecks() string { 858 if c.productVariables.TidyChecks == nil { 859 return "" 860 } 861 return *c.productVariables.TidyChecks 862} 863 864func (c *config) LibartImgHostBaseAddress() string { 865 return "0x60000000" 866} 867 868func (c *config) LibartImgDeviceBaseAddress() string { 869 archType := Common 870 if len(c.Targets[Android]) > 0 { 871 archType = c.Targets[Android][0].Arch.ArchType 872 } 873 switch archType { 874 default: 875 return "0x70000000" 876 case Mips, Mips64: 877 return "0x5C000000" 878 } 879} 880 881func (c *config) ArtUseReadBarrier() bool { 882 return Bool(c.productVariables.ArtUseReadBarrier) 883} 884 885func (c *config) EnforceRROForModule(name string) bool { 886 enforceList := c.productVariables.EnforceRROTargets 887 // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. 888 exemptedList := c.productVariables.EnforceRROExemptedTargets 889 if exemptedList != nil { 890 if InList(name, exemptedList) { 891 return false 892 } 893 } 894 if enforceList != nil { 895 if InList("*", enforceList) { 896 return true 897 } 898 return InList(name, enforceList) 899 } 900 return false 901} 902 903func (c *config) EnforceRROExcludedOverlay(path string) bool { 904 excluded := c.productVariables.EnforceRROExcludedOverlays 905 if excluded != nil { 906 return HasAnyPrefix(path, excluded) 907 } 908 return false 909} 910 911func (c *config) ExportedNamespaces() []string { 912 return append([]string(nil), c.productVariables.NamespacesToExport...) 913} 914 915func (c *config) HostStaticBinaries() bool { 916 return Bool(c.productVariables.HostStaticBinaries) 917} 918 919func (c *config) UncompressPrivAppDex() bool { 920 return Bool(c.productVariables.UncompressPrivAppDex) 921} 922 923func (c *config) ModulesLoadedByPrivilegedModules() []string { 924 return c.productVariables.ModulesLoadedByPrivilegedModules 925} 926 927// Expected format for apexJarValue = <apex name>:<jar name> 928func SplitApexJarPair(apexJarValue string) (string, string) { 929 var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2) 930 if apexJarPair == nil || len(apexJarPair) != 2 { 931 panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>", 932 apexJarValue)) 933 } 934 return apexJarPair[0], apexJarPair[1] 935} 936 937func (c *config) BootJars() []string { 938 jars := c.productVariables.BootJars 939 for _, p := range c.productVariables.UpdatableBootJars { 940 _, jar := SplitApexJarPair(p) 941 jars = append(jars, jar) 942 } 943 return jars 944} 945 946func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { 947 if c.productVariables.DexpreoptGlobalConfig == nil { 948 return nil, nil 949 } 950 path := absolutePath(*c.productVariables.DexpreoptGlobalConfig) 951 ctx.AddNinjaFileDeps(path) 952 return ioutil.ReadFile(path) 953} 954 955func (c *config) FrameworksBaseDirExists(ctx PathContext) bool { 956 return ExistentPathForSource(ctx, "frameworks", "base").Valid() 957} 958 959func (c *config) VndkSnapshotBuildArtifacts() bool { 960 return Bool(c.productVariables.VndkSnapshotBuildArtifacts) 961} 962 963func (c *config) HasMultilibConflict(arch ArchType) bool { 964 return c.multilibConflicts[arch] 965} 966 967func (c *deviceConfig) Arches() []Arch { 968 var arches []Arch 969 for _, target := range c.config.Targets[Android] { 970 arches = append(arches, target.Arch) 971 } 972 return arches 973} 974 975func (c *deviceConfig) BinderBitness() string { 976 is32BitBinder := c.config.productVariables.Binder32bit 977 if is32BitBinder != nil && *is32BitBinder { 978 return "32" 979 } 980 return "64" 981} 982 983func (c *deviceConfig) VendorPath() string { 984 if c.config.productVariables.VendorPath != nil { 985 return *c.config.productVariables.VendorPath 986 } 987 return "vendor" 988} 989 990func (c *deviceConfig) VndkVersion() string { 991 return String(c.config.productVariables.DeviceVndkVersion) 992} 993 994func (c *deviceConfig) PlatformVndkVersion() string { 995 return String(c.config.productVariables.Platform_vndk_version) 996} 997 998func (c *deviceConfig) ProductVndkVersion() string { 999 return String(c.config.productVariables.ProductVndkVersion) 1000} 1001 1002func (c *deviceConfig) ExtraVndkVersions() []string { 1003 return c.config.productVariables.ExtraVndkVersions 1004} 1005 1006func (c *deviceConfig) VndkUseCoreVariant() bool { 1007 return Bool(c.config.productVariables.VndkUseCoreVariant) 1008} 1009 1010func (c *deviceConfig) SystemSdkVersions() []string { 1011 return c.config.productVariables.DeviceSystemSdkVersions 1012} 1013 1014func (c *deviceConfig) PlatformSystemSdkVersions() []string { 1015 return c.config.productVariables.Platform_systemsdk_versions 1016} 1017 1018func (c *deviceConfig) OdmPath() string { 1019 if c.config.productVariables.OdmPath != nil { 1020 return *c.config.productVariables.OdmPath 1021 } 1022 return "odm" 1023} 1024 1025func (c *deviceConfig) ProductPath() string { 1026 if c.config.productVariables.ProductPath != nil { 1027 return *c.config.productVariables.ProductPath 1028 } 1029 return "product" 1030} 1031 1032func (c *deviceConfig) SystemExtPath() string { 1033 if c.config.productVariables.SystemExtPath != nil { 1034 return *c.config.productVariables.SystemExtPath 1035 } 1036 return "system_ext" 1037} 1038 1039func (c *deviceConfig) BtConfigIncludeDir() string { 1040 return String(c.config.productVariables.BtConfigIncludeDir) 1041} 1042 1043func (c *deviceConfig) DeviceKernelHeaderDirs() []string { 1044 return c.config.productVariables.DeviceKernelHeaders 1045} 1046 1047func (c *deviceConfig) SamplingPGO() bool { 1048 return Bool(c.config.productVariables.SamplingPGO) 1049} 1050 1051// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for 1052// path. Coverage is enabled by default when the product variable 1053// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is 1054// enabled for any path which is part of this variable (and not part of the 1055// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths 1056// represents any path. 1057func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool { 1058 coverage := false 1059 if len(c.config.productVariables.JavaCoveragePaths) == 0 || 1060 InList("*", c.config.productVariables.JavaCoveragePaths) || 1061 HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) { 1062 coverage = true 1063 } 1064 if coverage && c.config.productVariables.JavaCoverageExcludePaths != nil { 1065 if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) { 1066 coverage = false 1067 } 1068 } 1069 return coverage 1070} 1071 1072// Returns true if gcov or clang coverage is enabled. 1073func (c *deviceConfig) NativeCoverageEnabled() bool { 1074 return Bool(c.config.productVariables.GcovCoverage) || 1075 Bool(c.config.productVariables.ClangCoverage) 1076} 1077 1078func (c *deviceConfig) ClangCoverageEnabled() bool { 1079 return Bool(c.config.productVariables.ClangCoverage) 1080} 1081 1082func (c *deviceConfig) GcovCoverageEnabled() bool { 1083 return Bool(c.config.productVariables.GcovCoverage) 1084} 1085 1086// NativeCoverageEnabledForPath returns whether (GCOV- or Clang-based) native 1087// code coverage is enabled for path. By default, coverage is not enabled for a 1088// given path unless it is part of the NativeCoveragePaths product variable (and 1089// not part of the NativeCoverageExcludePaths product variable). Value "*" in 1090// NativeCoveragePaths represents any path. 1091func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool { 1092 coverage := false 1093 if c.config.productVariables.NativeCoveragePaths != nil { 1094 if InList("*", c.config.productVariables.NativeCoveragePaths) || HasAnyPrefix(path, c.config.productVariables.NativeCoveragePaths) { 1095 coverage = true 1096 } 1097 } 1098 if coverage && c.config.productVariables.NativeCoverageExcludePaths != nil { 1099 if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) { 1100 coverage = false 1101 } 1102 } 1103 return coverage 1104} 1105 1106func (c *deviceConfig) PgoAdditionalProfileDirs() []string { 1107 return c.config.productVariables.PgoAdditionalProfileDirs 1108} 1109 1110func (c *deviceConfig) VendorSepolicyDirs() []string { 1111 return c.config.productVariables.BoardVendorSepolicyDirs 1112} 1113 1114func (c *deviceConfig) OdmSepolicyDirs() []string { 1115 return c.config.productVariables.BoardOdmSepolicyDirs 1116} 1117 1118func (c *deviceConfig) PlatPublicSepolicyDirs() []string { 1119 return c.config.productVariables.BoardPlatPublicSepolicyDirs 1120} 1121 1122func (c *deviceConfig) PlatPrivateSepolicyDirs() []string { 1123 return c.config.productVariables.BoardPlatPrivateSepolicyDirs 1124} 1125 1126func (c *deviceConfig) SepolicyM4Defs() []string { 1127 return c.config.productVariables.BoardSepolicyM4Defs 1128} 1129 1130func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) { 1131 return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name, 1132 "invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>") 1133} 1134 1135func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) { 1136 return findOverrideValue(c.config.productVariables.CertificateOverrides, name, 1137 "invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>") 1138} 1139 1140func (c *deviceConfig) OverridePackageNameFor(name string) string { 1141 newName, overridden := findOverrideValue( 1142 c.config.productVariables.PackageNameOverrides, 1143 name, 1144 "invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>") 1145 if overridden { 1146 return newName 1147 } 1148 return name 1149} 1150 1151func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) { 1152 if overrides == nil || len(overrides) == 0 { 1153 return "", false 1154 } 1155 for _, o := range overrides { 1156 split := strings.Split(o, ":") 1157 if len(split) != 2 { 1158 // This shouldn't happen as this is first checked in make, but just in case. 1159 panic(fmt.Errorf(errorMsg, o)) 1160 } 1161 if matchPattern(split[0], name) { 1162 return substPattern(split[0], split[1], name), true 1163 } 1164 } 1165 return "", false 1166} 1167 1168func (c *config) IntegerOverflowDisabledForPath(path string) bool { 1169 if c.productVariables.IntegerOverflowExcludePaths == nil { 1170 return false 1171 } 1172 return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths) 1173} 1174 1175func (c *config) CFIDisabledForPath(path string) bool { 1176 if c.productVariables.CFIExcludePaths == nil { 1177 return false 1178 } 1179 return HasAnyPrefix(path, c.productVariables.CFIExcludePaths) 1180} 1181 1182func (c *config) CFIEnabledForPath(path string) bool { 1183 if c.productVariables.CFIIncludePaths == nil { 1184 return false 1185 } 1186 return HasAnyPrefix(path, c.productVariables.CFIIncludePaths) 1187} 1188 1189func (c *config) VendorConfig(name string) VendorConfig { 1190 return soongconfig.Config(c.productVariables.VendorVars[name]) 1191} 1192 1193func (c *config) NdkAbis() bool { 1194 return Bool(c.productVariables.Ndk_abis) 1195} 1196 1197func (c *config) AmlAbis() bool { 1198 return Bool(c.productVariables.Aml_abis) 1199} 1200 1201func (c *config) ExcludeDraftNdkApis() bool { 1202 return Bool(c.productVariables.Exclude_draft_ndk_apis) 1203} 1204 1205func (c *config) FlattenApex() bool { 1206 return Bool(c.productVariables.Flatten_apex) 1207} 1208 1209func (c *config) EnforceSystemCertificate() bool { 1210 return Bool(c.productVariables.EnforceSystemCertificate) 1211} 1212 1213func (c *config) EnforceSystemCertificateAllowList() []string { 1214 return c.productVariables.EnforceSystemCertificateAllowList 1215} 1216 1217func (c *config) EnforceProductPartitionInterface() bool { 1218 return Bool(c.productVariables.EnforceProductPartitionInterface) 1219} 1220 1221func (c *config) InstallExtraFlattenedApexes() bool { 1222 return Bool(c.productVariables.InstallExtraFlattenedApexes) 1223} 1224 1225func (c *config) ProductHiddenAPIStubs() []string { 1226 return c.productVariables.ProductHiddenAPIStubs 1227} 1228 1229func (c *config) ProductHiddenAPIStubsSystem() []string { 1230 return c.productVariables.ProductHiddenAPIStubsSystem 1231} 1232 1233func (c *config) ProductHiddenAPIStubsTest() []string { 1234 return c.productVariables.ProductHiddenAPIStubsTest 1235} 1236 1237func (c *deviceConfig) TargetFSConfigGen() []string { 1238 return c.config.productVariables.TargetFSConfigGen 1239} 1240 1241func (c *config) ProductPublicSepolicyDirs() []string { 1242 return c.productVariables.ProductPublicSepolicyDirs 1243} 1244 1245func (c *config) ProductPrivateSepolicyDirs() []string { 1246 return c.productVariables.ProductPrivateSepolicyDirs 1247} 1248 1249func (c *config) ProductCompatibleProperty() bool { 1250 return Bool(c.productVariables.ProductCompatibleProperty) 1251} 1252 1253func (c *config) MissingUsesLibraries() []string { 1254 return c.productVariables.MissingUsesLibraries 1255} 1256 1257func (c *deviceConfig) BoardVndkRuntimeDisable() bool { 1258 return Bool(c.config.productVariables.BoardVndkRuntimeDisable) 1259} 1260 1261func (c *deviceConfig) DeviceArch() string { 1262 return String(c.config.productVariables.DeviceArch) 1263} 1264 1265func (c *deviceConfig) DeviceArchVariant() string { 1266 return String(c.config.productVariables.DeviceArchVariant) 1267} 1268 1269func (c *deviceConfig) DeviceSecondaryArch() string { 1270 return String(c.config.productVariables.DeviceSecondaryArch) 1271} 1272 1273func (c *deviceConfig) DeviceSecondaryArchVariant() string { 1274 return String(c.config.productVariables.DeviceSecondaryArchVariant) 1275} 1276 1277func (c *deviceConfig) BoardUsesRecoveryAsBoot() bool { 1278 return Bool(c.config.productVariables.BoardUsesRecoveryAsBoot) 1279} 1280