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/bootstrap" 29 "github.com/google/blueprint/proptools" 30) 31 32var Bool = proptools.Bool 33var String = proptools.String 34var FutureApiLevel = 10000 35 36// The configuration file name 37const configFileName = "soong.config" 38const productVariablesFileName = "soong.variables" 39 40// A FileConfigurableOptions contains options which can be configured by the 41// config file. These will be included in the config struct. 42type FileConfigurableOptions struct { 43 Mega_device *bool `json:",omitempty"` 44 Host_bionic *bool `json:",omitempty"` 45} 46 47func (f *FileConfigurableOptions) SetDefaultConfig() { 48 *f = FileConfigurableOptions{} 49} 50 51// A Config object represents the entire build configuration for Android. 52type Config struct { 53 *config 54} 55 56func (c Config) BuildDir() string { 57 return c.buildDir 58} 59 60// A DeviceConfig object represents the configuration for a particular device being built. For 61// now there will only be one of these, but in the future there may be multiple devices being 62// built 63type DeviceConfig struct { 64 *deviceConfig 65} 66 67type VendorConfig interface { 68 // Bool interprets the variable named `name` as a boolean, returning true if, after 69 // lowercasing, it matches one of "1", "y", "yes", "on", or "true". Unset, or any other 70 // value will return false. 71 Bool(name string) bool 72 73 // String returns the string value of `name`. If the variable was not set, it will 74 // return the empty string. 75 String(name string) string 76 77 // IsSet returns whether the variable `name` was set by Make. 78 IsSet(name string) bool 79} 80 81type config struct { 82 FileConfigurableOptions 83 productVariables productVariables 84 85 // Only available on configs created by TestConfig 86 TestProductVariables *productVariables 87 88 PrimaryBuilder string 89 ConfigFileName string 90 ProductVariablesFileName string 91 92 Targets map[OsType][]Target 93 BuildOsVariant string 94 BuildOsCommonVariant string 95 96 deviceConfig *deviceConfig 97 98 srcDir string // the path of the root source directory 99 buildDir string // the path of the build output directory 100 101 env map[string]string 102 envLock sync.Mutex 103 envDeps map[string]string 104 envFrozen bool 105 106 inMake bool 107 108 captureBuild bool // true for tests, saves build parameters for each module 109 ignoreEnvironment bool // true for tests, returns empty from all Getenv calls 110 111 targetOpenJDK9 bool // Target 1.9 112 113 stopBefore bootstrap.StopBefore 114 115 OncePer 116} 117 118type deviceConfig struct { 119 config *config 120 OncePer 121} 122 123type vendorConfig map[string]string 124 125type jsonConfigurable interface { 126 SetDefaultConfig() 127} 128 129func loadConfig(config *config) error { 130 err := loadFromConfigFile(&config.FileConfigurableOptions, config.ConfigFileName) 131 if err != nil { 132 return err 133 } 134 135 return loadFromConfigFile(&config.productVariables, config.ProductVariablesFileName) 136} 137 138// loads configuration options from a JSON file in the cwd. 139func loadFromConfigFile(configurable jsonConfigurable, filename string) error { 140 // Try to open the file 141 configFileReader, err := os.Open(filename) 142 defer configFileReader.Close() 143 if os.IsNotExist(err) { 144 // Need to create a file, so that blueprint & ninja don't get in 145 // a dependency tracking loop. 146 // Make a file-configurable-options with defaults, write it out using 147 // a json writer. 148 configurable.SetDefaultConfig() 149 err = saveToConfigFile(configurable, filename) 150 if err != nil { 151 return err 152 } 153 } else if err != nil { 154 return fmt.Errorf("config file: could not open %s: %s", filename, err.Error()) 155 } else { 156 // Make a decoder for it 157 jsonDecoder := json.NewDecoder(configFileReader) 158 err = jsonDecoder.Decode(configurable) 159 if err != nil { 160 return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error()) 161 } 162 } 163 164 // No error 165 return nil 166} 167 168// atomically writes the config file in case two copies of soong_build are running simultaneously 169// (for example, docs generation and ninja manifest generation) 170func saveToConfigFile(config jsonConfigurable, filename string) error { 171 data, err := json.MarshalIndent(&config, "", " ") 172 if err != nil { 173 return fmt.Errorf("cannot marshal config data: %s", err.Error()) 174 } 175 176 f, err := ioutil.TempFile(filepath.Dir(filename), "config") 177 if err != nil { 178 return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error()) 179 } 180 defer os.Remove(f.Name()) 181 defer f.Close() 182 183 _, err = f.Write(data) 184 if err != nil { 185 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 186 } 187 188 _, err = f.WriteString("\n") 189 if err != nil { 190 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 191 } 192 193 f.Close() 194 os.Rename(f.Name(), filename) 195 196 return nil 197} 198 199// TestConfig returns a Config object suitable for using for tests 200func TestConfig(buildDir string, env map[string]string) Config { 201 config := &config{ 202 productVariables: productVariables{ 203 DeviceName: stringPtr("test_device"), 204 Platform_sdk_version: intPtr(26), 205 DeviceSystemSdkVersions: []string{"14", "15"}, 206 Platform_systemsdk_versions: []string{"25", "26"}, 207 AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"}, 208 AAPTPreferredConfig: stringPtr("xhdpi"), 209 AAPTCharacteristics: stringPtr("nosdcard"), 210 AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"}, 211 UncompressPrivAppDex: boolPtr(true), 212 }, 213 214 buildDir: buildDir, 215 captureBuild: true, 216 env: env, 217 } 218 config.deviceConfig = &deviceConfig{ 219 config: config, 220 } 221 config.TestProductVariables = &config.productVariables 222 223 if err := config.fromEnv(); err != nil { 224 panic(err) 225 } 226 227 return Config{config} 228} 229 230func TestArchConfigFuchsia(buildDir string, env map[string]string) Config { 231 testConfig := TestConfig(buildDir, env) 232 config := testConfig.config 233 234 config.Targets = map[OsType][]Target{ 235 Fuchsia: []Target{ 236 {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Native: true}}, 237 }, 238 BuildOs: []Target{ 239 {BuildOs, Arch{ArchType: X86_64}}, 240 }, 241 } 242 243 return testConfig 244} 245 246// TestConfig returns a Config object suitable for using for tests that need to run the arch mutator 247func TestArchConfig(buildDir string, env map[string]string) Config { 248 testConfig := TestConfig(buildDir, env) 249 config := testConfig.config 250 251 config.Targets = map[OsType][]Target{ 252 Android: []Target{ 253 {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}}, 254 {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}}, 255 }, 256 BuildOs: []Target{ 257 {BuildOs, Arch{ArchType: X86_64}}, 258 {BuildOs, Arch{ArchType: X86}}, 259 }, 260 } 261 262 config.BuildOsVariant = config.Targets[BuildOs][0].String() 263 config.BuildOsCommonVariant = getCommonTargets(config.Targets[BuildOs])[0].String() 264 265 return testConfig 266} 267 268// New creates a new Config object. The srcDir argument specifies the path to 269// the root source directory. It also loads the config file, if found. 270func NewConfig(srcDir, buildDir string) (Config, error) { 271 // Make a config with default options 272 config := &config{ 273 ConfigFileName: filepath.Join(buildDir, configFileName), 274 ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), 275 276 env: originalEnv, 277 278 srcDir: srcDir, 279 buildDir: buildDir, 280 } 281 282 config.deviceConfig = &deviceConfig{ 283 config: config, 284 } 285 286 // Sanity check the build and source directories. This won't catch strange 287 // configurations with symlinks, but at least checks the obvious cases. 288 absBuildDir, err := filepath.Abs(buildDir) 289 if err != nil { 290 return Config{}, err 291 } 292 293 absSrcDir, err := filepath.Abs(srcDir) 294 if err != nil { 295 return Config{}, err 296 } 297 298 if strings.HasPrefix(absSrcDir, absBuildDir) { 299 return Config{}, fmt.Errorf("Build dir must not contain source directory") 300 } 301 302 // Load any configurable options from the configuration file 303 err = loadConfig(config) 304 if err != nil { 305 return Config{}, err 306 } 307 308 inMakeFile := filepath.Join(buildDir, ".soong.in_make") 309 if _, err := os.Stat(inMakeFile); err == nil { 310 config.inMake = true 311 } 312 313 targets, err := decodeTargetProductVariables(config) 314 if err != nil { 315 return Config{}, err 316 } 317 318 var archConfig []archConfig 319 if Bool(config.Mega_device) { 320 archConfig = getMegaDeviceConfig() 321 } else if config.NdkAbis() { 322 archConfig = getNdkAbisConfig() 323 } 324 325 if archConfig != nil { 326 androidTargets, err := decodeArchSettings(Android, archConfig) 327 if err != nil { 328 return Config{}, err 329 } 330 targets[Android] = androidTargets 331 } 332 333 config.Targets = targets 334 config.BuildOsVariant = targets[BuildOs][0].String() 335 config.BuildOsCommonVariant = getCommonTargets(targets[BuildOs])[0].String() 336 337 if err := config.fromEnv(); err != nil { 338 return Config{}, err 339 } 340 341 return Config{config}, nil 342} 343 344func (c *config) fromEnv() error { 345 switch c.Getenv("EXPERIMENTAL_USE_OPENJDK9") { 346 case "", "1.8": 347 // Nothing, we always use OpenJDK9 348 case "true": 349 // Use OpenJDK9 and target 1.9 350 c.targetOpenJDK9 = true 351 default: 352 return fmt.Errorf(`Invalid value for EXPERIMENTAL_USE_OPENJDK9, should be "", "1.8", or "true"`) 353 } 354 355 return nil 356} 357 358func (c *config) StopBefore() bootstrap.StopBefore { 359 return c.stopBefore 360} 361 362func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { 363 c.stopBefore = stopBefore 364} 365 366var _ bootstrap.ConfigStopBefore = (*config)(nil) 367 368func (c *config) BlueprintToolLocation() string { 369 return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") 370} 371 372var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil) 373 374func (c *config) HostToolPath(ctx PathContext, tool string) Path { 375 return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool) 376} 377 378// HostSystemTool looks for non-hermetic tools from the system we're running on. 379// Generally shouldn't be used, but useful to find the XCode SDK, etc. 380func (c *config) HostSystemTool(name string) string { 381 for _, dir := range filepath.SplitList(c.Getenv("PATH")) { 382 path := filepath.Join(dir, name) 383 if s, err := os.Stat(path); err != nil { 384 continue 385 } else if m := s.Mode(); !s.IsDir() && m&0111 != 0 { 386 return path 387 } 388 } 389 return name 390} 391 392// PrebuiltOS returns the name of the host OS used in prebuilts directories 393func (c *config) PrebuiltOS() string { 394 switch runtime.GOOS { 395 case "linux": 396 return "linux-x86" 397 case "darwin": 398 return "darwin-x86" 399 default: 400 panic("Unknown GOOS") 401 } 402} 403 404// GoRoot returns the path to the root directory of the Go toolchain. 405func (c *config) GoRoot() string { 406 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) 407} 408 409func (c *config) CpPreserveSymlinksFlags() string { 410 switch runtime.GOOS { 411 case "darwin": 412 return "-R" 413 case "linux": 414 return "-d" 415 default: 416 return "" 417 } 418} 419 420func (c *config) Getenv(key string) string { 421 var val string 422 var exists bool 423 c.envLock.Lock() 424 defer c.envLock.Unlock() 425 if c.envDeps == nil { 426 c.envDeps = make(map[string]string) 427 } 428 if val, exists = c.envDeps[key]; !exists { 429 if c.envFrozen { 430 panic("Cannot access new environment variables after envdeps are frozen") 431 } 432 val, _ = c.env[key] 433 c.envDeps[key] = val 434 } 435 return val 436} 437 438func (c *config) GetenvWithDefault(key string, defaultValue string) string { 439 ret := c.Getenv(key) 440 if ret == "" { 441 return defaultValue 442 } 443 return ret 444} 445 446func (c *config) IsEnvTrue(key string) bool { 447 value := c.Getenv(key) 448 return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" 449} 450 451func (c *config) IsEnvFalse(key string) bool { 452 value := c.Getenv(key) 453 return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" 454} 455 456func (c *config) EnvDeps() map[string]string { 457 c.envLock.Lock() 458 defer c.envLock.Unlock() 459 c.envFrozen = true 460 return c.envDeps 461} 462 463func (c *config) EmbeddedInMake() bool { 464 return c.inMake 465} 466 467func (c *config) BuildId() string { 468 return String(c.productVariables.BuildId) 469} 470 471func (c *config) BuildNumberFromFile() string { 472 return String(c.productVariables.BuildNumberFromFile) 473} 474 475// DeviceName returns the name of the current device target 476// TODO: take an AndroidModuleContext to select the device name for multi-device builds 477func (c *config) DeviceName() string { 478 return *c.productVariables.DeviceName 479} 480 481func (c *config) DeviceResourceOverlays() []string { 482 return c.productVariables.DeviceResourceOverlays 483} 484 485func (c *config) ProductResourceOverlays() []string { 486 return c.productVariables.ProductResourceOverlays 487} 488 489func (c *config) PlatformVersionName() string { 490 return String(c.productVariables.Platform_version_name) 491} 492 493func (c *config) PlatformSdkVersionInt() int { 494 return *c.productVariables.Platform_sdk_version 495} 496 497func (c *config) PlatformSdkVersion() string { 498 return strconv.Itoa(c.PlatformSdkVersionInt()) 499} 500 501func (c *config) PlatformSdkCodename() string { 502 return String(c.productVariables.Platform_sdk_codename) 503} 504 505func (c *config) PlatformSecurityPatch() string { 506 return String(c.productVariables.Platform_security_patch) 507} 508 509func (c *config) PlatformPreviewSdkVersion() string { 510 return String(c.productVariables.Platform_preview_sdk_version) 511} 512 513func (c *config) PlatformMinSupportedTargetSdkVersion() string { 514 return String(c.productVariables.Platform_min_supported_target_sdk_version) 515} 516 517func (c *config) PlatformBaseOS() string { 518 return String(c.productVariables.Platform_base_os) 519} 520 521func (c *config) MinSupportedSdkVersion() int { 522 return 16 523} 524 525func (c *config) DefaultAppTargetSdkInt() int { 526 if Bool(c.productVariables.Platform_sdk_final) { 527 return c.PlatformSdkVersionInt() 528 } else { 529 return FutureApiLevel 530 } 531} 532 533func (c *config) DefaultAppTargetSdk() string { 534 if Bool(c.productVariables.Platform_sdk_final) { 535 return c.PlatformSdkVersion() 536 } else { 537 return c.PlatformSdkCodename() 538 } 539} 540 541func (c *config) AppsDefaultVersionName() string { 542 return String(c.productVariables.AppsDefaultVersionName) 543} 544 545// Codenames that are active in the current lunch target. 546func (c *config) PlatformVersionActiveCodenames() []string { 547 return c.productVariables.Platform_version_active_codenames 548} 549 550// Codenames that are available in the branch but not included in the current 551// lunch target. 552func (c *config) PlatformVersionFutureCodenames() []string { 553 return c.productVariables.Platform_version_future_codenames 554} 555 556// All possible codenames in the current branch. NB: Not named AllCodenames 557// because "all" has historically meant "active" in make, and still does in 558// build.prop. 559func (c *config) PlatformVersionCombinedCodenames() []string { 560 combined := []string{} 561 combined = append(combined, c.PlatformVersionActiveCodenames()...) 562 combined = append(combined, c.PlatformVersionFutureCodenames()...) 563 return combined 564} 565 566func (c *config) ProductAAPTConfig() []string { 567 return c.productVariables.AAPTConfig 568} 569 570func (c *config) ProductAAPTPreferredConfig() string { 571 return String(c.productVariables.AAPTPreferredConfig) 572} 573 574func (c *config) ProductAAPTCharacteristics() string { 575 return String(c.productVariables.AAPTCharacteristics) 576} 577 578func (c *config) ProductAAPTPrebuiltDPI() []string { 579 return c.productVariables.AAPTPrebuiltDPI 580} 581 582func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { 583 defaultCert := String(c.productVariables.DefaultAppCertificate) 584 if defaultCert != "" { 585 return PathForSource(ctx, filepath.Dir(defaultCert)) 586 } else { 587 return PathForSource(ctx, "build/target/product/security") 588 } 589} 590 591func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { 592 defaultCert := String(c.productVariables.DefaultAppCertificate) 593 if defaultCert != "" { 594 return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") 595 } else { 596 defaultDir := c.DefaultAppCertificateDir(ctx) 597 return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") 598 } 599} 600 601func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { 602 // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE 603 defaultCert := String(c.productVariables.DefaultAppCertificate) 604 if defaultCert == "" || filepath.Dir(defaultCert) == "build/target/product/security" { 605 // When defaultCert is unset or is set to the testkeys path, use the APEX keys 606 // that is under the module dir 607 return pathForModuleSrc(ctx) 608 } else { 609 // If not, APEX keys are under the specified directory 610 return PathForSource(ctx, filepath.Dir(defaultCert)) 611 } 612} 613 614func (c *config) AllowMissingDependencies() bool { 615 return Bool(c.productVariables.Allow_missing_dependencies) 616} 617 618func (c *config) UnbundledBuild() bool { 619 return Bool(c.productVariables.Unbundled_build) 620} 621 622func (c *config) UnbundledBuildUsePrebuiltSdks() bool { 623 return Bool(c.productVariables.Unbundled_build) && !Bool(c.productVariables.Unbundled_build_sdks_from_source) 624} 625 626func (c *config) Fuchsia() bool { 627 return Bool(c.productVariables.Fuchsia) 628} 629 630func (c *config) IsPdkBuild() bool { 631 return Bool(c.productVariables.Pdk) 632} 633 634func (c *config) MinimizeJavaDebugInfo() bool { 635 return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng) 636} 637 638func (c *config) Debuggable() bool { 639 return Bool(c.productVariables.Debuggable) 640} 641 642func (c *config) Eng() bool { 643 return Bool(c.productVariables.Eng) 644} 645 646func (c *config) DevicePrefer32BitApps() bool { 647 return Bool(c.productVariables.DevicePrefer32BitApps) 648} 649 650func (c *config) DevicePrefer32BitExecutables() bool { 651 return Bool(c.productVariables.DevicePrefer32BitExecutables) 652} 653 654func (c *config) DevicePrimaryArchType() ArchType { 655 return c.Targets[Android][0].Arch.ArchType 656} 657 658func (c *config) SkipDeviceInstall() bool { 659 return c.EmbeddedInMake() 660} 661 662func (c *config) SkipMegaDeviceInstall(path string) bool { 663 return Bool(c.Mega_device) && 664 strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product")) 665} 666 667func (c *config) SanitizeHost() []string { 668 return append([]string(nil), c.productVariables.SanitizeHost...) 669} 670 671func (c *config) SanitizeDevice() []string { 672 return append([]string(nil), c.productVariables.SanitizeDevice...) 673} 674 675func (c *config) SanitizeDeviceDiag() []string { 676 return append([]string(nil), c.productVariables.SanitizeDeviceDiag...) 677} 678 679func (c *config) SanitizeDeviceArch() []string { 680 return append([]string(nil), c.productVariables.SanitizeDeviceArch...) 681} 682 683func (c *config) EnableCFI() bool { 684 if c.productVariables.EnableCFI == nil { 685 return true 686 } else { 687 return *c.productVariables.EnableCFI 688 } 689} 690 691func (c *config) DisableScudo() bool { 692 return Bool(c.productVariables.DisableScudo) 693} 694 695func (c *config) EnableXOM() bool { 696 if c.productVariables.EnableXOM == nil { 697 return true 698 } else { 699 return Bool(c.productVariables.EnableXOM) 700 } 701} 702 703func (c *config) Android64() bool { 704 for _, t := range c.Targets[Android] { 705 if t.Arch.ArchType.Multilib == "lib64" { 706 return true 707 } 708 } 709 710 return false 711} 712 713func (c *config) UseGoma() bool { 714 return Bool(c.productVariables.UseGoma) 715} 716 717func (c *config) RunErrorProne() bool { 718 return c.IsEnvTrue("RUN_ERROR_PRONE") 719} 720 721// Returns true if -source 1.9 -target 1.9 is being passed to javac 722func (c *config) TargetOpenJDK9() bool { 723 return c.targetOpenJDK9 724} 725 726func (c *config) ClangTidy() bool { 727 return Bool(c.productVariables.ClangTidy) 728} 729 730func (c *config) TidyChecks() string { 731 if c.productVariables.TidyChecks == nil { 732 return "" 733 } 734 return *c.productVariables.TidyChecks 735} 736 737func (c *config) LibartImgHostBaseAddress() string { 738 return "0x60000000" 739} 740 741func (c *config) LibartImgDeviceBaseAddress() string { 742 archType := Common 743 if len(c.Targets[Android]) > 0 { 744 archType = c.Targets[Android][0].Arch.ArchType 745 } 746 switch archType { 747 default: 748 return "0x70000000" 749 case Mips, Mips64: 750 return "0x5C000000" 751 } 752} 753 754func (c *config) ArtUseReadBarrier() bool { 755 return Bool(c.productVariables.ArtUseReadBarrier) 756} 757 758func (c *config) EnforceRROForModule(name string) bool { 759 enforceList := c.productVariables.EnforceRROTargets 760 if enforceList != nil { 761 if len(enforceList) == 1 && (enforceList)[0] == "*" { 762 return true 763 } 764 return InList(name, enforceList) 765 } 766 return false 767} 768 769func (c *config) EnforceRROExcludedOverlay(path string) bool { 770 excluded := c.productVariables.EnforceRROExcludedOverlays 771 if excluded != nil { 772 for _, exclude := range excluded { 773 if strings.HasPrefix(path, exclude) { 774 return true 775 } 776 } 777 } 778 return false 779} 780 781func (c *config) ExportedNamespaces() []string { 782 return append([]string(nil), c.productVariables.NamespacesToExport...) 783} 784 785func (c *config) HostStaticBinaries() bool { 786 return Bool(c.productVariables.HostStaticBinaries) 787} 788 789func (c *config) UncompressPrivAppDex() bool { 790 return Bool(c.productVariables.UncompressPrivAppDex) 791} 792 793func (c *config) ModulesLoadedByPrivilegedModules() []string { 794 return c.productVariables.ModulesLoadedByPrivilegedModules 795} 796 797func (c *config) BootJars() []string { 798 return c.productVariables.BootJars 799} 800 801func (c *config) DexpreoptGlobalConfig() string { 802 return String(c.productVariables.DexpreoptGlobalConfig) 803} 804 805func (c *config) FrameworksBaseDirExists(ctx PathContext) bool { 806 return ExistentPathForSource(ctx, "frameworks", "base").Valid() 807} 808 809func (c *deviceConfig) Arches() []Arch { 810 var arches []Arch 811 for _, target := range c.config.Targets[Android] { 812 arches = append(arches, target.Arch) 813 } 814 return arches 815} 816 817func (c *deviceConfig) BinderBitness() string { 818 is32BitBinder := c.config.productVariables.Binder32bit 819 if is32BitBinder != nil && *is32BitBinder { 820 return "32" 821 } 822 return "64" 823} 824 825func (c *deviceConfig) VendorPath() string { 826 if c.config.productVariables.VendorPath != nil { 827 return *c.config.productVariables.VendorPath 828 } 829 return "vendor" 830} 831 832func (c *deviceConfig) VndkVersion() string { 833 return String(c.config.productVariables.DeviceVndkVersion) 834} 835 836func (c *deviceConfig) PlatformVndkVersion() string { 837 return String(c.config.productVariables.Platform_vndk_version) 838} 839 840func (c *deviceConfig) ExtraVndkVersions() []string { 841 return c.config.productVariables.ExtraVndkVersions 842} 843 844func (c *deviceConfig) VndkUseCoreVariant() bool { 845 return Bool(c.config.productVariables.VndkUseCoreVariant) 846} 847 848func (c *deviceConfig) SystemSdkVersions() []string { 849 return c.config.productVariables.DeviceSystemSdkVersions 850} 851 852func (c *deviceConfig) PlatformSystemSdkVersions() []string { 853 return c.config.productVariables.Platform_systemsdk_versions 854} 855 856func (c *deviceConfig) OdmPath() string { 857 if c.config.productVariables.OdmPath != nil { 858 return *c.config.productVariables.OdmPath 859 } 860 return "odm" 861} 862 863func (c *deviceConfig) ProductPath() string { 864 if c.config.productVariables.ProductPath != nil { 865 return *c.config.productVariables.ProductPath 866 } 867 return "product" 868} 869 870func (c *deviceConfig) ProductServicesPath() string { 871 if c.config.productVariables.ProductServicesPath != nil { 872 return *c.config.productVariables.ProductServicesPath 873 } 874 return "product_services" 875} 876 877func (c *deviceConfig) BtConfigIncludeDir() string { 878 return String(c.config.productVariables.BtConfigIncludeDir) 879} 880 881func (c *deviceConfig) DeviceKernelHeaderDirs() []string { 882 return c.config.productVariables.DeviceKernelHeaders 883} 884 885func (c *deviceConfig) NativeCoverageEnabled() bool { 886 return Bool(c.config.productVariables.NativeCoverage) 887} 888 889func (c *deviceConfig) CoverageEnabledForPath(path string) bool { 890 coverage := false 891 if c.config.productVariables.CoveragePaths != nil { 892 if InList("*", c.config.productVariables.CoveragePaths) || PrefixInList(path, c.config.productVariables.CoveragePaths) { 893 coverage = true 894 } 895 } 896 if coverage && c.config.productVariables.CoverageExcludePaths != nil { 897 if PrefixInList(path, c.config.productVariables.CoverageExcludePaths) { 898 coverage = false 899 } 900 } 901 return coverage 902} 903 904func (c *deviceConfig) PgoAdditionalProfileDirs() []string { 905 return c.config.productVariables.PgoAdditionalProfileDirs 906} 907 908func (c *deviceConfig) VendorSepolicyDirs() []string { 909 return c.config.productVariables.BoardVendorSepolicyDirs 910} 911 912func (c *deviceConfig) OdmSepolicyDirs() []string { 913 return c.config.productVariables.BoardOdmSepolicyDirs 914} 915 916func (c *deviceConfig) PlatPublicSepolicyDirs() []string { 917 return c.config.productVariables.BoardPlatPublicSepolicyDirs 918} 919 920func (c *deviceConfig) PlatPrivateSepolicyDirs() []string { 921 return c.config.productVariables.BoardPlatPrivateSepolicyDirs 922} 923 924func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) { 925 return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name, 926 "invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>") 927} 928 929func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) { 930 return findOverrideValue(c.config.productVariables.CertificateOverrides, name, 931 "invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>") 932} 933 934func (c *deviceConfig) OverridePackageNameFor(name string) string { 935 newName, overridden := findOverrideValue( 936 c.config.productVariables.PackageNameOverrides, 937 name, 938 "invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>") 939 if overridden { 940 return newName 941 } 942 return name 943} 944 945func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) { 946 if overrides == nil || len(overrides) == 0 { 947 return "", false 948 } 949 for _, o := range overrides { 950 split := strings.Split(o, ":") 951 if len(split) != 2 { 952 // This shouldn't happen as this is first checked in make, but just in case. 953 panic(fmt.Errorf(errorMsg, o)) 954 } 955 if matchPattern(split[0], name) { 956 return substPattern(split[0], split[1], name), true 957 } 958 } 959 return "", false 960} 961 962// SecondArchIsTranslated returns true if the primary device arch is X86 or X86_64 and the device also has an arch 963// that is Arm or Arm64. 964func (c *config) SecondArchIsTranslated() bool { 965 deviceTargets := c.Targets[Android] 966 if len(deviceTargets) < 2 { 967 return false 968 } 969 970 arch := deviceTargets[0].Arch 971 972 return (arch.ArchType == X86 || arch.ArchType == X86_64) && hasArmAndroidArch(deviceTargets) 973} 974 975func (c *config) IntegerOverflowDisabledForPath(path string) bool { 976 if c.productVariables.IntegerOverflowExcludePaths == nil { 977 return false 978 } 979 return PrefixInList(path, c.productVariables.IntegerOverflowExcludePaths) 980} 981 982func (c *config) CFIDisabledForPath(path string) bool { 983 if c.productVariables.CFIExcludePaths == nil { 984 return false 985 } 986 return PrefixInList(path, c.productVariables.CFIExcludePaths) 987} 988 989func (c *config) CFIEnabledForPath(path string) bool { 990 if c.productVariables.CFIIncludePaths == nil { 991 return false 992 } 993 return PrefixInList(path, c.productVariables.CFIIncludePaths) 994} 995 996func (c *config) XOMDisabledForPath(path string) bool { 997 if c.productVariables.XOMExcludePaths == nil { 998 return false 999 } 1000 return PrefixInList(path, c.productVariables.XOMExcludePaths) 1001} 1002 1003func (c *config) VendorConfig(name string) VendorConfig { 1004 return vendorConfig(c.productVariables.VendorVars[name]) 1005} 1006 1007func (c vendorConfig) Bool(name string) bool { 1008 v := strings.ToLower(c[name]) 1009 return v == "1" || v == "y" || v == "yes" || v == "on" || v == "true" 1010} 1011 1012func (c vendorConfig) String(name string) string { 1013 return c[name] 1014} 1015 1016func (c vendorConfig) IsSet(name string) bool { 1017 _, ok := c[name] 1018 return ok 1019} 1020 1021func (c *config) NdkAbis() bool { 1022 return Bool(c.productVariables.Ndk_abis) 1023} 1024 1025func (c *config) ExcludeDraftNdkApis() bool { 1026 return Bool(c.productVariables.Exclude_draft_ndk_apis) 1027} 1028 1029func (c *config) FlattenApex() bool { 1030 return Bool(c.productVariables.FlattenApex) 1031} 1032 1033func (c *config) EnforceSystemCertificate() bool { 1034 return Bool(c.productVariables.EnforceSystemCertificate) 1035} 1036 1037func (c *config) EnforceSystemCertificateWhitelist() []string { 1038 return c.productVariables.EnforceSystemCertificateWhitelist 1039} 1040 1041func (c *config) ProductHiddenAPIStubs() []string { 1042 return c.productVariables.ProductHiddenAPIStubs 1043} 1044 1045func (c *config) ProductHiddenAPIStubsSystem() []string { 1046 return c.productVariables.ProductHiddenAPIStubsSystem 1047} 1048 1049func (c *config) ProductHiddenAPIStubsTest() []string { 1050 return c.productVariables.ProductHiddenAPIStubsTest 1051} 1052 1053func (c *deviceConfig) TargetFSConfigGen() []string { 1054 return c.config.productVariables.TargetFSConfigGen 1055} 1056