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 90 // multilibConflicts for an ArchType is true if there is earlier configured device architecture with the same 91 // multilib value. 92 multilibConflicts map[ArchType]bool 93 94 deviceConfig *deviceConfig 95 96 srcDir string // the path of the root source directory 97 buildDir string // the path of the build output directory 98 moduleListFile string // the path to the file which lists blueprint files to parse. 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.TestProductVariables.DeviceArch = proptools.StringPtr("arm64") 311 config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a") 312 config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm") 313 config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon") 314 315 return testConfig 316} 317 318// New creates a new Config object. The srcDir argument specifies the path to 319// the root source directory. It also loads the config file, if found. 320func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { 321 // Make a config with default options 322 config := &config{ 323 ConfigFileName: filepath.Join(buildDir, configFileName), 324 ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), 325 326 env: originalEnv, 327 328 srcDir: srcDir, 329 buildDir: buildDir, 330 multilibConflicts: make(map[ArchType]bool), 331 332 moduleListFile: moduleListFile, 333 fs: pathtools.NewOsFs(absSrcDir), 334 } 335 336 config.deviceConfig = &deviceConfig{ 337 config: config, 338 } 339 340 // Soundness check of the build and source directories. This won't catch strange 341 // configurations with symlinks, but at least checks the obvious case. 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 } 406 407 if err := config.fromEnv(); err != nil { 408 return Config{}, err 409 } 410 411 if Bool(config.productVariables.GcovCoverage) && Bool(config.productVariables.ClangCoverage) { 412 return Config{}, fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set") 413 } 414 415 config.productVariables.Native_coverage = proptools.BoolPtr( 416 Bool(config.productVariables.GcovCoverage) || 417 Bool(config.productVariables.ClangCoverage)) 418 419 return Config{config}, nil 420} 421 422var TestConfigOsFs = map[string][]byte{} 423 424// mockFileSystem replaces all reads with accesses to the provided map of 425// filenames to contents stored as a byte slice. 426func (c *config) mockFileSystem(bp string, fs map[string][]byte) { 427 mockFS := map[string][]byte{} 428 429 if _, exists := mockFS["Android.bp"]; !exists { 430 mockFS["Android.bp"] = []byte(bp) 431 } 432 433 for k, v := range fs { 434 mockFS[k] = v 435 } 436 437 // no module list file specified; find every file named Blueprints or Android.bp 438 pathsToParse := []string{} 439 for candidate := range mockFS { 440 base := filepath.Base(candidate) 441 if base == "Blueprints" || base == "Android.bp" { 442 pathsToParse = append(pathsToParse, candidate) 443 } 444 } 445 if len(pathsToParse) < 1 { 446 panic(fmt.Sprintf("No Blueprint or Android.bp files found in mock filesystem: %v\n", mockFS)) 447 } 448 mockFS[blueprint.MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n")) 449 450 c.fs = pathtools.MockFs(mockFS) 451 c.mockBpList = blueprint.MockModuleListFile 452} 453 454func (c *config) fromEnv() error { 455 switch c.Getenv("EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9") { 456 case "", "true": 457 // Do nothing 458 default: 459 return fmt.Errorf("The environment variable EXPERIMENTAL_JAVA_LANGUAGE_LEVEL_9 is no longer supported. Java language level 9 is now the global default.") 460 } 461 462 return nil 463} 464 465func (c *config) StopBefore() bootstrap.StopBefore { 466 return c.stopBefore 467} 468 469func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { 470 c.stopBefore = stopBefore 471} 472 473var _ bootstrap.ConfigStopBefore = (*config)(nil) 474 475func (c *config) BlueprintToolLocation() string { 476 return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") 477} 478 479var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil) 480 481func (c *config) HostToolPath(ctx PathContext, tool string) Path { 482 return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool) 483} 484 485func (c *config) HostJNIToolPath(ctx PathContext, path string) Path { 486 ext := ".so" 487 if runtime.GOOS == "darwin" { 488 ext = ".dylib" 489 } 490 return PathForOutput(ctx, "host", c.PrebuiltOS(), "lib64", path+ext) 491} 492 493func (c *config) HostJavaToolPath(ctx PathContext, path string) Path { 494 return PathForOutput(ctx, "host", c.PrebuiltOS(), "framework", path) 495} 496 497// HostSystemTool looks for non-hermetic tools from the system we're running on. 498// Generally shouldn't be used, but useful to find the XCode SDK, etc. 499func (c *config) HostSystemTool(name string) string { 500 for _, dir := range filepath.SplitList(c.Getenv("PATH")) { 501 path := filepath.Join(dir, name) 502 if s, err := os.Stat(path); err != nil { 503 continue 504 } else if m := s.Mode(); !s.IsDir() && m&0111 != 0 { 505 return path 506 } 507 } 508 return name 509} 510 511// PrebuiltOS returns the name of the host OS used in prebuilts directories 512func (c *config) PrebuiltOS() string { 513 switch runtime.GOOS { 514 case "linux": 515 return "linux-x86" 516 case "darwin": 517 return "darwin-x86" 518 default: 519 panic("Unknown GOOS") 520 } 521} 522 523// GoRoot returns the path to the root directory of the Go toolchain. 524func (c *config) GoRoot() string { 525 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) 526} 527 528func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { 529 return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) 530} 531 532func (c *config) CpPreserveSymlinksFlags() string { 533 switch runtime.GOOS { 534 case "darwin": 535 return "-R" 536 case "linux": 537 return "-d" 538 default: 539 return "" 540 } 541} 542 543func (c *config) Getenv(key string) string { 544 var val string 545 var exists bool 546 c.envLock.Lock() 547 defer c.envLock.Unlock() 548 if c.envDeps == nil { 549 c.envDeps = make(map[string]string) 550 } 551 if val, exists = c.envDeps[key]; !exists { 552 if c.envFrozen { 553 panic("Cannot access new environment variables after envdeps are frozen") 554 } 555 val, _ = c.env[key] 556 c.envDeps[key] = val 557 } 558 return val 559} 560 561func (c *config) GetenvWithDefault(key string, defaultValue string) string { 562 ret := c.Getenv(key) 563 if ret == "" { 564 return defaultValue 565 } 566 return ret 567} 568 569func (c *config) IsEnvTrue(key string) bool { 570 value := c.Getenv(key) 571 return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" 572} 573 574func (c *config) IsEnvFalse(key string) bool { 575 value := c.Getenv(key) 576 return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" 577} 578 579func (c *config) EnvDeps() map[string]string { 580 c.envLock.Lock() 581 defer c.envLock.Unlock() 582 c.envFrozen = true 583 return c.envDeps 584} 585 586func (c *config) EmbeddedInMake() bool { 587 return c.inMake 588} 589 590func (c *config) BuildId() string { 591 return String(c.productVariables.BuildId) 592} 593 594func (c *config) BuildNumberFile(ctx PathContext) Path { 595 return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) 596} 597 598// DeviceName returns the name of the current device target 599// TODO: take an AndroidModuleContext to select the device name for multi-device builds 600func (c *config) DeviceName() string { 601 return *c.productVariables.DeviceName 602} 603 604func (c *config) DeviceResourceOverlays() []string { 605 return c.productVariables.DeviceResourceOverlays 606} 607 608func (c *config) ProductResourceOverlays() []string { 609 return c.productVariables.ProductResourceOverlays 610} 611 612func (c *config) PlatformVersionName() string { 613 return String(c.productVariables.Platform_version_name) 614} 615 616func (c *config) PlatformSdkVersionInt() int { 617 return *c.productVariables.Platform_sdk_version 618} 619 620func (c *config) PlatformSdkVersion() string { 621 return strconv.Itoa(c.PlatformSdkVersionInt()) 622} 623 624func (c *config) PlatformSdkCodename() string { 625 return String(c.productVariables.Platform_sdk_codename) 626} 627 628func (c *config) PlatformSecurityPatch() string { 629 return String(c.productVariables.Platform_security_patch) 630} 631 632func (c *config) PlatformPreviewSdkVersion() string { 633 return String(c.productVariables.Platform_preview_sdk_version) 634} 635 636func (c *config) PlatformMinSupportedTargetSdkVersion() string { 637 return String(c.productVariables.Platform_min_supported_target_sdk_version) 638} 639 640func (c *config) PlatformBaseOS() string { 641 return String(c.productVariables.Platform_base_os) 642} 643 644func (c *config) MinSupportedSdkVersion() int { 645 return 16 646} 647 648func (c *config) DefaultAppTargetSdkInt() int { 649 if Bool(c.productVariables.Platform_sdk_final) { 650 return c.PlatformSdkVersionInt() 651 } else { 652 return FutureApiLevel 653 } 654} 655 656func (c *config) DefaultAppTargetSdk() string { 657 if Bool(c.productVariables.Platform_sdk_final) { 658 return c.PlatformSdkVersion() 659 } else { 660 return c.PlatformSdkCodename() 661 } 662} 663 664func (c *config) AppsDefaultVersionName() string { 665 return String(c.productVariables.AppsDefaultVersionName) 666} 667 668// Codenames that are active in the current lunch target. 669func (c *config) PlatformVersionActiveCodenames() []string { 670 return c.productVariables.Platform_version_active_codenames 671} 672 673func (c *config) ProductAAPTConfig() []string { 674 return c.productVariables.AAPTConfig 675} 676 677func (c *config) ProductAAPTPreferredConfig() string { 678 return String(c.productVariables.AAPTPreferredConfig) 679} 680 681func (c *config) ProductAAPTCharacteristics() string { 682 return String(c.productVariables.AAPTCharacteristics) 683} 684 685func (c *config) ProductAAPTPrebuiltDPI() []string { 686 return c.productVariables.AAPTPrebuiltDPI 687} 688 689func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { 690 defaultCert := String(c.productVariables.DefaultAppCertificate) 691 if defaultCert != "" { 692 return PathForSource(ctx, filepath.Dir(defaultCert)) 693 } else { 694 return PathForSource(ctx, "build/make/target/product/security") 695 } 696} 697 698func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { 699 defaultCert := String(c.productVariables.DefaultAppCertificate) 700 if defaultCert != "" { 701 return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") 702 } else { 703 defaultDir := c.DefaultAppCertificateDir(ctx) 704 return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") 705 } 706} 707 708func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { 709 // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE 710 defaultCert := String(c.productVariables.DefaultAppCertificate) 711 if defaultCert == "" || filepath.Dir(defaultCert) == "build/make/target/product/security" { 712 // When defaultCert is unset or is set to the testkeys path, use the APEX keys 713 // that is under the module dir 714 return pathForModuleSrc(ctx) 715 } else { 716 // If not, APEX keys are under the specified directory 717 return PathForSource(ctx, filepath.Dir(defaultCert)) 718 } 719} 720 721func (c *config) AllowMissingDependencies() bool { 722 return Bool(c.productVariables.Allow_missing_dependencies) 723} 724 725// Returns true if building without full platform sources. 726func (c *config) UnbundledBuild() bool { 727 return Bool(c.productVariables.Unbundled_build) 728} 729 730// Returns true if building apps that aren't bundled with the platform. 731// UnbundledBuild() is always true when this is true. 732func (c *config) UnbundledBuildApps() bool { 733 return Bool(c.productVariables.Unbundled_build_apps) 734} 735 736func (c *config) UnbundledBuildUsePrebuiltSdks() bool { 737 return Bool(c.productVariables.Unbundled_build) && !Bool(c.productVariables.Unbundled_build_sdks_from_source) 738} 739 740func (c *config) Fuchsia() bool { 741 return Bool(c.productVariables.Fuchsia) 742} 743 744func (c *config) IsPdkBuild() bool { 745 return Bool(c.productVariables.Pdk) 746} 747 748func (c *config) MinimizeJavaDebugInfo() bool { 749 return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng) 750} 751 752func (c *config) Debuggable() bool { 753 return Bool(c.productVariables.Debuggable) 754} 755 756func (c *config) Eng() bool { 757 return Bool(c.productVariables.Eng) 758} 759 760func (c *config) DevicePrimaryArchType() ArchType { 761 return c.Targets[Android][0].Arch.ArchType 762} 763 764func (c *config) SkipMegaDeviceInstall(path string) bool { 765 return Bool(c.Mega_device) && 766 strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product")) 767} 768 769func (c *config) SanitizeHost() []string { 770 return append([]string(nil), c.productVariables.SanitizeHost...) 771} 772 773func (c *config) SanitizeDevice() []string { 774 return append([]string(nil), c.productVariables.SanitizeDevice...) 775} 776 777func (c *config) SanitizeDeviceDiag() []string { 778 return append([]string(nil), c.productVariables.SanitizeDeviceDiag...) 779} 780 781func (c *config) SanitizeDeviceArch() []string { 782 return append([]string(nil), c.productVariables.SanitizeDeviceArch...) 783} 784 785func (c *config) EnableCFI() bool { 786 if c.productVariables.EnableCFI == nil { 787 return true 788 } else { 789 return *c.productVariables.EnableCFI 790 } 791} 792 793func (c *config) DisableScudo() bool { 794 return Bool(c.productVariables.DisableScudo) 795} 796 797func (c *config) Android64() bool { 798 for _, t := range c.Targets[Android] { 799 if t.Arch.ArchType.Multilib == "lib64" { 800 return true 801 } 802 } 803 804 return false 805} 806 807func (c *config) UseGoma() bool { 808 return Bool(c.productVariables.UseGoma) 809} 810 811func (c *config) UseRBE() bool { 812 return Bool(c.productVariables.UseRBE) 813} 814 815func (c *config) UseRBEJAVAC() bool { 816 return Bool(c.productVariables.UseRBEJAVAC) 817} 818 819func (c *config) UseRBER8() bool { 820 return Bool(c.productVariables.UseRBER8) 821} 822 823func (c *config) UseRBED8() bool { 824 return Bool(c.productVariables.UseRBED8) 825} 826 827func (c *config) UseRemoteBuild() bool { 828 return c.UseGoma() || c.UseRBE() 829} 830 831func (c *config) RunErrorProne() bool { 832 return c.IsEnvTrue("RUN_ERROR_PRONE") 833} 834 835func (c *config) XrefCorpusName() string { 836 return c.Getenv("XREF_CORPUS") 837} 838 839// Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'. 840func (c *config) XrefCuEncoding() string { 841 if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { 842 return enc 843 } 844 return "json" 845} 846 847func (c *config) EmitXrefRules() bool { 848 return c.XrefCorpusName() != "" 849} 850 851func (c *config) ClangTidy() bool { 852 return Bool(c.productVariables.ClangTidy) 853} 854 855func (c *config) TidyChecks() string { 856 if c.productVariables.TidyChecks == nil { 857 return "" 858 } 859 return *c.productVariables.TidyChecks 860} 861 862func (c *config) LibartImgHostBaseAddress() string { 863 return "0x60000000" 864} 865 866func (c *config) LibartImgDeviceBaseAddress() string { 867 return "0x70000000" 868} 869 870func (c *config) ArtUseReadBarrier() bool { 871 return Bool(c.productVariables.ArtUseReadBarrier) 872} 873 874func (c *config) EnforceRROForModule(name string) bool { 875 enforceList := c.productVariables.EnforceRROTargets 876 // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. 877 exemptedList := c.productVariables.EnforceRROExemptedTargets 878 if len(exemptedList) > 0 { 879 if InList(name, exemptedList) { 880 return false 881 } 882 } 883 if len(enforceList) > 0 { 884 if InList("*", enforceList) { 885 return true 886 } 887 return InList(name, enforceList) 888 } 889 return false 890} 891 892func (c *config) EnforceRROExcludedOverlay(path string) bool { 893 excluded := c.productVariables.EnforceRROExcludedOverlays 894 if len(excluded) > 0 { 895 return HasAnyPrefix(path, excluded) 896 } 897 return false 898} 899 900func (c *config) ExportedNamespaces() []string { 901 return append([]string(nil), c.productVariables.NamespacesToExport...) 902} 903 904func (c *config) HostStaticBinaries() bool { 905 return Bool(c.productVariables.HostStaticBinaries) 906} 907 908func (c *config) UncompressPrivAppDex() bool { 909 return Bool(c.productVariables.UncompressPrivAppDex) 910} 911 912func (c *config) ModulesLoadedByPrivilegedModules() []string { 913 return c.productVariables.ModulesLoadedByPrivilegedModules 914} 915 916// Expected format for apexJarValue = <apex name>:<jar name> 917func SplitApexJarPair(ctx PathContext, str string) (string, string) { 918 pair := strings.SplitN(str, ":", 2) 919 if len(pair) == 2 { 920 return pair[0], pair[1] 921 } else { 922 reportPathErrorf(ctx, "malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str) 923 return "error-apex", "error-jar" 924 } 925} 926 927func GetJarsFromApexJarPairs(ctx PathContext, apexJarPairs []string) []string { 928 modules := make([]string, len(apexJarPairs)) 929 for i, p := range apexJarPairs { 930 _, jar := SplitApexJarPair(ctx, p) 931 modules[i] = jar 932 } 933 return modules 934} 935 936func (c *config) BootJars() []string { 937 ctx := NullPathContext{Config{ 938 config: c, 939 }} 940 return append(GetJarsFromApexJarPairs(ctx, c.productVariables.BootJars), 941 GetJarsFromApexJarPairs(ctx, c.productVariables.UpdatableBootJars)...) 942} 943 944func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { 945 if c.productVariables.DexpreoptGlobalConfig == nil { 946 return nil, nil 947 } 948 path := absolutePath(*c.productVariables.DexpreoptGlobalConfig) 949 ctx.AddNinjaFileDeps(path) 950 return ioutil.ReadFile(path) 951} 952 953func (c *config) FrameworksBaseDirExists(ctx PathContext) bool { 954 return ExistentPathForSource(ctx, "frameworks", "base").Valid() 955} 956 957func (c *config) VndkSnapshotBuildArtifacts() bool { 958 return Bool(c.productVariables.VndkSnapshotBuildArtifacts) 959} 960 961func (c *config) HasMultilibConflict(arch ArchType) bool { 962 return c.multilibConflicts[arch] 963} 964 965func (c *deviceConfig) Arches() []Arch { 966 var arches []Arch 967 for _, target := range c.config.Targets[Android] { 968 arches = append(arches, target.Arch) 969 } 970 return arches 971} 972 973func (c *deviceConfig) BinderBitness() string { 974 is32BitBinder := c.config.productVariables.Binder32bit 975 if is32BitBinder != nil && *is32BitBinder { 976 return "32" 977 } 978 return "64" 979} 980 981func (c *deviceConfig) VendorPath() string { 982 if c.config.productVariables.VendorPath != nil { 983 return *c.config.productVariables.VendorPath 984 } 985 return "vendor" 986} 987 988func (c *deviceConfig) VndkVersion() string { 989 return String(c.config.productVariables.DeviceVndkVersion) 990} 991 992func (c *deviceConfig) PlatformVndkVersion() string { 993 return String(c.config.productVariables.Platform_vndk_version) 994} 995 996func (c *deviceConfig) ProductVndkVersion() string { 997 return String(c.config.productVariables.ProductVndkVersion) 998} 999 1000func (c *deviceConfig) ExtraVndkVersions() []string { 1001 return c.config.productVariables.ExtraVndkVersions 1002} 1003 1004func (c *deviceConfig) VndkUseCoreVariant() bool { 1005 return Bool(c.config.productVariables.VndkUseCoreVariant) 1006} 1007 1008func (c *deviceConfig) SystemSdkVersions() []string { 1009 return c.config.productVariables.DeviceSystemSdkVersions 1010} 1011 1012func (c *deviceConfig) PlatformSystemSdkVersions() []string { 1013 return c.config.productVariables.Platform_systemsdk_versions 1014} 1015 1016func (c *deviceConfig) OdmPath() string { 1017 if c.config.productVariables.OdmPath != nil { 1018 return *c.config.productVariables.OdmPath 1019 } 1020 return "odm" 1021} 1022 1023func (c *deviceConfig) ProductPath() string { 1024 if c.config.productVariables.ProductPath != nil { 1025 return *c.config.productVariables.ProductPath 1026 } 1027 return "product" 1028} 1029 1030func (c *deviceConfig) SystemExtPath() string { 1031 if c.config.productVariables.SystemExtPath != nil { 1032 return *c.config.productVariables.SystemExtPath 1033 } 1034 return "system_ext" 1035} 1036 1037func (c *deviceConfig) BtConfigIncludeDir() string { 1038 return String(c.config.productVariables.BtConfigIncludeDir) 1039} 1040 1041func (c *deviceConfig) DeviceKernelHeaderDirs() []string { 1042 return c.config.productVariables.DeviceKernelHeaders 1043} 1044 1045func (c *deviceConfig) SamplingPGO() bool { 1046 return Bool(c.config.productVariables.SamplingPGO) 1047} 1048 1049// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for 1050// path. Coverage is enabled by default when the product variable 1051// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is 1052// enabled for any path which is part of this variable (and not part of the 1053// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths 1054// represents any path. 1055func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool { 1056 coverage := false 1057 if len(c.config.productVariables.JavaCoveragePaths) == 0 || 1058 InList("*", c.config.productVariables.JavaCoveragePaths) || 1059 HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) { 1060 coverage = true 1061 } 1062 if coverage && len(c.config.productVariables.JavaCoverageExcludePaths) > 0 { 1063 if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) { 1064 coverage = false 1065 } 1066 } 1067 return coverage 1068} 1069 1070// Returns true if gcov or clang coverage is enabled. 1071func (c *deviceConfig) NativeCoverageEnabled() bool { 1072 return Bool(c.config.productVariables.GcovCoverage) || 1073 Bool(c.config.productVariables.ClangCoverage) 1074} 1075 1076func (c *deviceConfig) ClangCoverageEnabled() bool { 1077 return Bool(c.config.productVariables.ClangCoverage) 1078} 1079 1080func (c *deviceConfig) GcovCoverageEnabled() bool { 1081 return Bool(c.config.productVariables.GcovCoverage) 1082} 1083 1084// NativeCoverageEnabledForPath returns whether (GCOV- or Clang-based) native 1085// code coverage is enabled for path. By default, coverage is not enabled for a 1086// given path unless it is part of the NativeCoveragePaths product variable (and 1087// not part of the NativeCoverageExcludePaths product variable). Value "*" in 1088// NativeCoveragePaths represents any path. 1089func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool { 1090 coverage := false 1091 if len(c.config.productVariables.NativeCoveragePaths) > 0 { 1092 if InList("*", c.config.productVariables.NativeCoveragePaths) || HasAnyPrefix(path, c.config.productVariables.NativeCoveragePaths) { 1093 coverage = true 1094 } 1095 } 1096 if coverage && len(c.config.productVariables.NativeCoverageExcludePaths) > 0 { 1097 if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) { 1098 coverage = false 1099 } 1100 } 1101 return coverage 1102} 1103 1104func (c *deviceConfig) PgoAdditionalProfileDirs() []string { 1105 return c.config.productVariables.PgoAdditionalProfileDirs 1106} 1107 1108func (c *deviceConfig) VendorSepolicyDirs() []string { 1109 return c.config.productVariables.BoardVendorSepolicyDirs 1110} 1111 1112func (c *deviceConfig) OdmSepolicyDirs() []string { 1113 return c.config.productVariables.BoardOdmSepolicyDirs 1114} 1115 1116func (c *deviceConfig) PlatPublicSepolicyDirs() []string { 1117 return c.config.productVariables.BoardPlatPublicSepolicyDirs 1118} 1119 1120func (c *deviceConfig) PlatPrivateSepolicyDirs() []string { 1121 return c.config.productVariables.BoardPlatPrivateSepolicyDirs 1122} 1123 1124func (c *deviceConfig) SepolicyM4Defs() []string { 1125 return c.config.productVariables.BoardSepolicyM4Defs 1126} 1127 1128func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) { 1129 return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name, 1130 "invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>") 1131} 1132 1133func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) { 1134 return findOverrideValue(c.config.productVariables.CertificateOverrides, name, 1135 "invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>") 1136} 1137 1138func (c *deviceConfig) OverridePackageNameFor(name string) string { 1139 newName, overridden := findOverrideValue( 1140 c.config.productVariables.PackageNameOverrides, 1141 name, 1142 "invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>") 1143 if overridden { 1144 return newName 1145 } 1146 return name 1147} 1148 1149func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) { 1150 if overrides == nil || len(overrides) == 0 { 1151 return "", false 1152 } 1153 for _, o := range overrides { 1154 split := strings.Split(o, ":") 1155 if len(split) != 2 { 1156 // This shouldn't happen as this is first checked in make, but just in case. 1157 panic(fmt.Errorf(errorMsg, o)) 1158 } 1159 if matchPattern(split[0], name) { 1160 return substPattern(split[0], split[1], name), true 1161 } 1162 } 1163 return "", false 1164} 1165 1166func (c *config) IntegerOverflowDisabledForPath(path string) bool { 1167 if len(c.productVariables.IntegerOverflowExcludePaths) == 0 { 1168 return false 1169 } 1170 return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths) 1171} 1172 1173func (c *config) CFIDisabledForPath(path string) bool { 1174 if len(c.productVariables.CFIExcludePaths) == 0 { 1175 return false 1176 } 1177 return HasAnyPrefix(path, c.productVariables.CFIExcludePaths) 1178} 1179 1180func (c *config) CFIEnabledForPath(path string) bool { 1181 if len(c.productVariables.CFIIncludePaths) == 0 { 1182 return false 1183 } 1184 return HasAnyPrefix(path, c.productVariables.CFIIncludePaths) 1185} 1186 1187func (c *config) VendorConfig(name string) VendorConfig { 1188 return soongconfig.Config(c.productVariables.VendorVars[name]) 1189} 1190 1191func (c *config) NdkAbis() bool { 1192 return Bool(c.productVariables.Ndk_abis) 1193} 1194 1195func (c *config) AmlAbis() bool { 1196 return Bool(c.productVariables.Aml_abis) 1197} 1198 1199func (c *config) ExcludeDraftNdkApis() bool { 1200 return Bool(c.productVariables.Exclude_draft_ndk_apis) 1201} 1202 1203func (c *config) FlattenApex() bool { 1204 return Bool(c.productVariables.Flatten_apex) 1205} 1206 1207func (c *config) EnforceSystemCertificate() bool { 1208 return Bool(c.productVariables.EnforceSystemCertificate) 1209} 1210 1211func (c *config) EnforceSystemCertificateAllowList() []string { 1212 return c.productVariables.EnforceSystemCertificateAllowList 1213} 1214 1215func (c *config) EnforceProductPartitionInterface() bool { 1216 return Bool(c.productVariables.EnforceProductPartitionInterface) 1217} 1218 1219func (c *config) InstallExtraFlattenedApexes() bool { 1220 return Bool(c.productVariables.InstallExtraFlattenedApexes) 1221} 1222 1223func (c *config) ProductHiddenAPIStubs() []string { 1224 return c.productVariables.ProductHiddenAPIStubs 1225} 1226 1227func (c *config) ProductHiddenAPIStubsSystem() []string { 1228 return c.productVariables.ProductHiddenAPIStubsSystem 1229} 1230 1231func (c *config) ProductHiddenAPIStubsTest() []string { 1232 return c.productVariables.ProductHiddenAPIStubsTest 1233} 1234 1235func (c *deviceConfig) TargetFSConfigGen() []string { 1236 return c.config.productVariables.TargetFSConfigGen 1237} 1238 1239func (c *config) ProductPublicSepolicyDirs() []string { 1240 return c.productVariables.ProductPublicSepolicyDirs 1241} 1242 1243func (c *config) ProductPrivateSepolicyDirs() []string { 1244 return c.productVariables.ProductPrivateSepolicyDirs 1245} 1246 1247func (c *config) ProductCompatibleProperty() bool { 1248 return Bool(c.productVariables.ProductCompatibleProperty) 1249} 1250 1251func (c *config) MissingUsesLibraries() []string { 1252 return c.productVariables.MissingUsesLibraries 1253} 1254 1255func (c *deviceConfig) DeviceArch() string { 1256 return String(c.config.productVariables.DeviceArch) 1257} 1258 1259func (c *deviceConfig) DeviceArchVariant() string { 1260 return String(c.config.productVariables.DeviceArchVariant) 1261} 1262 1263func (c *deviceConfig) DeviceSecondaryArch() string { 1264 return String(c.config.productVariables.DeviceSecondaryArch) 1265} 1266 1267func (c *deviceConfig) DeviceSecondaryArchVariant() string { 1268 return String(c.config.productVariables.DeviceSecondaryArchVariant) 1269} 1270 1271func (c *deviceConfig) BoardUsesRecoveryAsBoot() bool { 1272 return Bool(c.config.productVariables.BoardUsesRecoveryAsBoot) 1273} 1274 1275func (c *deviceConfig) BoardKernelBinaries() []string { 1276 return c.config.productVariables.BoardKernelBinaries 1277} 1278