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 17// This is the primary location to write and read all configuration values and 18// product variables necessary for soong_build's operation. 19 20import ( 21 "encoding/json" 22 "errors" 23 "fmt" 24 "io/ioutil" 25 "os" 26 "path/filepath" 27 "runtime" 28 "strconv" 29 "strings" 30 "sync" 31 32 "github.com/google/blueprint" 33 "github.com/google/blueprint/bootstrap" 34 "github.com/google/blueprint/pathtools" 35 "github.com/google/blueprint/proptools" 36 37 "android/soong/android/soongconfig" 38 "android/soong/remoteexec" 39) 40 41// Bool re-exports proptools.Bool for the android package. 42var Bool = proptools.Bool 43 44// String re-exports proptools.String for the android package. 45var String = proptools.String 46 47// StringDefault re-exports proptools.StringDefault for the android package. 48var StringDefault = proptools.StringDefault 49 50// FutureApiLevelInt is a placeholder constant for unreleased API levels. 51const FutureApiLevelInt = 10000 52 53// FutureApiLevel represents unreleased API levels. 54var FutureApiLevel = ApiLevel{ 55 value: "current", 56 number: FutureApiLevelInt, 57 isPreview: true, 58} 59 60// The product variables file name, containing product config from Kati. 61const productVariablesFileName = "soong.variables" 62 63// A Config object represents the entire build configuration for Android. 64type Config struct { 65 *config 66} 67 68// BuildDir returns the build output directory for the configuration. 69func (c Config) BuildDir() string { 70 return c.buildDir 71} 72 73func (c Config) NinjaBuildDir() string { 74 return c.buildDir 75} 76 77func (c Config) DebugCompilation() bool { 78 return false // Never compile Go code in the main build for debugging 79} 80 81func (c Config) SrcDir() string { 82 return c.srcDir 83} 84 85// A DeviceConfig object represents the configuration for a particular device 86// being built. For now there will only be one of these, but in the future there 87// may be multiple devices being built. 88type DeviceConfig struct { 89 *deviceConfig 90} 91 92// VendorConfig represents the configuration for vendor-specific behavior. 93type VendorConfig soongconfig.SoongConfig 94 95// Definition of general build configuration for soong_build. Some of these 96// product configuration values are read from Kati-generated soong.variables. 97type config struct { 98 // Options configurable with soong.variables 99 productVariables productVariables 100 101 // Only available on configs created by TestConfig 102 TestProductVariables *productVariables 103 104 // A specialized context object for Bazel/Soong mixed builds and migration 105 // purposes. 106 BazelContext BazelContext 107 108 ProductVariablesFileName string 109 110 Targets map[OsType][]Target 111 BuildOSTarget Target // the Target for tools run on the build machine 112 BuildOSCommonTarget Target // the Target for common (java) tools run on the build machine 113 AndroidCommonTarget Target // the Target for common modules for the Android device 114 AndroidFirstDeviceTarget Target // the first Target for modules for the Android device 115 116 // multilibConflicts for an ArchType is true if there is earlier configured 117 // device architecture with the same multilib value. 118 multilibConflicts map[ArchType]bool 119 120 deviceConfig *deviceConfig 121 122 srcDir string // the path of the root source directory 123 buildDir string // the path of the build output directory 124 moduleListFile string // the path to the file which lists blueprint files to parse. 125 126 env map[string]string 127 envLock sync.Mutex 128 envDeps map[string]string 129 envFrozen bool 130 131 // Changes behavior based on whether Kati runs after soong_build, or if soong_build 132 // runs standalone. 133 katiEnabled bool 134 135 captureBuild bool // true for tests, saves build parameters for each module 136 ignoreEnvironment bool // true for tests, returns empty from all Getenv calls 137 138 stopBefore bootstrap.StopBefore 139 140 fs pathtools.FileSystem 141 mockBpList string 142 143 bp2buildPackageConfig Bp2BuildConfig 144 bp2buildModuleTypeConfig map[string]bool 145 146 // If testAllowNonExistentPaths is true then PathForSource and PathForModuleSrc won't error 147 // in tests when a path doesn't exist. 148 TestAllowNonExistentPaths bool 149 150 // The list of files that when changed, must invalidate soong_build to 151 // regenerate build.ninja. 152 ninjaFileDepsSet sync.Map 153 154 OncePer 155} 156 157type deviceConfig struct { 158 config *config 159 OncePer 160} 161 162type jsonConfigurable interface { 163 SetDefaultConfig() 164} 165 166func loadConfig(config *config) error { 167 return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) 168} 169 170// loadFromConfigFile loads and decodes configuration options from a JSON file 171// in the current working directory. 172func loadFromConfigFile(configurable jsonConfigurable, filename string) error { 173 // Try to open the file 174 configFileReader, err := os.Open(filename) 175 defer configFileReader.Close() 176 if os.IsNotExist(err) { 177 // Need to create a file, so that blueprint & ninja don't get in 178 // a dependency tracking loop. 179 // Make a file-configurable-options with defaults, write it out using 180 // a json writer. 181 configurable.SetDefaultConfig() 182 err = saveToConfigFile(configurable, filename) 183 if err != nil { 184 return err 185 } 186 } else if err != nil { 187 return fmt.Errorf("config file: could not open %s: %s", filename, err.Error()) 188 } else { 189 // Make a decoder for it 190 jsonDecoder := json.NewDecoder(configFileReader) 191 err = jsonDecoder.Decode(configurable) 192 if err != nil { 193 return fmt.Errorf("config file: %s did not parse correctly: %s", filename, err.Error()) 194 } 195 } 196 197 // No error 198 return nil 199} 200 201// atomically writes the config file in case two copies of soong_build are running simultaneously 202// (for example, docs generation and ninja manifest generation) 203func saveToConfigFile(config jsonConfigurable, filename string) error { 204 data, err := json.MarshalIndent(&config, "", " ") 205 if err != nil { 206 return fmt.Errorf("cannot marshal config data: %s", err.Error()) 207 } 208 209 f, err := ioutil.TempFile(filepath.Dir(filename), "config") 210 if err != nil { 211 return fmt.Errorf("cannot create empty config file %s: %s", filename, err.Error()) 212 } 213 defer os.Remove(f.Name()) 214 defer f.Close() 215 216 _, err = f.Write(data) 217 if err != nil { 218 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 219 } 220 221 _, err = f.WriteString("\n") 222 if err != nil { 223 return fmt.Errorf("default config file: %s could not be written: %s", filename, err.Error()) 224 } 225 226 f.Close() 227 os.Rename(f.Name(), filename) 228 229 return nil 230} 231 232// NullConfig returns a mostly empty Config for use by standalone tools like dexpreopt_gen that 233// use the android package. 234func NullConfig(buildDir string) Config { 235 return Config{ 236 config: &config{ 237 buildDir: buildDir, 238 fs: pathtools.OsFs, 239 }, 240 } 241} 242 243// TestConfig returns a Config object for testing. 244func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 245 envCopy := make(map[string]string) 246 for k, v := range env { 247 envCopy[k] = v 248 } 249 250 // Copy the real PATH value to the test environment, it's needed by 251 // NonHermeticHostSystemTool() used in x86_darwin_host.go 252 envCopy["PATH"] = os.Getenv("PATH") 253 254 config := &config{ 255 productVariables: productVariables{ 256 DeviceName: stringPtr("test_device"), 257 Platform_sdk_version: intPtr(30), 258 Platform_sdk_codename: stringPtr("S"), 259 Platform_version_active_codenames: []string{"S"}, 260 DeviceSystemSdkVersions: []string{"14", "15"}, 261 Platform_systemsdk_versions: []string{"29", "30"}, 262 AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"}, 263 AAPTPreferredConfig: stringPtr("xhdpi"), 264 AAPTCharacteristics: stringPtr("nosdcard"), 265 AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"}, 266 UncompressPrivAppDex: boolPtr(true), 267 ShippingApiLevel: stringPtr("30"), 268 }, 269 270 buildDir: buildDir, 271 captureBuild: true, 272 env: envCopy, 273 274 // Set testAllowNonExistentPaths so that test contexts don't need to specify every path 275 // passed to PathForSource or PathForModuleSrc. 276 TestAllowNonExistentPaths: true, 277 278 BazelContext: noopBazelContext{}, 279 } 280 config.deviceConfig = &deviceConfig{ 281 config: config, 282 } 283 config.TestProductVariables = &config.productVariables 284 285 config.mockFileSystem(bp, fs) 286 287 config.bp2buildModuleTypeConfig = map[string]bool{} 288 289 return Config{config} 290} 291 292func fuchsiaTargets() map[OsType][]Target { 293 return map[OsType][]Target{ 294 Fuchsia: { 295 {Fuchsia, Arch{ArchType: Arm64, ArchVariant: "", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, 296 }, 297 BuildOs: { 298 {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, 299 }, 300 } 301} 302 303var PrepareForTestSetDeviceToFuchsia = FixtureModifyConfig(func(config Config) { 304 config.Targets = fuchsiaTargets() 305}) 306 307func modifyTestConfigToSupportArchMutator(testConfig Config) { 308 config := testConfig.config 309 310 config.Targets = map[OsType][]Target{ 311 Android: []Target{ 312 {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false}, 313 {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false}, 314 }, 315 BuildOs: []Target{ 316 {BuildOs, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false}, 317 {BuildOs, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false}, 318 }, 319 } 320 321 if runtime.GOOS == "darwin" { 322 config.Targets[BuildOs] = config.Targets[BuildOs][:1] 323 } 324 325 config.BuildOSTarget = config.Targets[BuildOs][0] 326 config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] 327 config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] 328 config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] 329 config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64") 330 config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a") 331 config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm") 332 config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon") 333} 334 335// TestArchConfig returns a Config object suitable for using for tests that 336// need to run the arch mutator. 337func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { 338 testConfig := TestConfig(buildDir, env, bp, fs) 339 modifyTestConfigToSupportArchMutator(testConfig) 340 return testConfig 341} 342 343// ConfigForAdditionalRun is a config object which is "reset" for another 344// bootstrap run. Only per-run data is reset. Data which needs to persist across 345// multiple runs in the same program execution is carried over (such as Bazel 346// context or environment deps). 347func ConfigForAdditionalRun(c Config) (Config, error) { 348 newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile, c.env) 349 if err != nil { 350 return Config{}, err 351 } 352 newConfig.BazelContext = c.BazelContext 353 newConfig.envDeps = c.envDeps 354 return newConfig, nil 355} 356 357// NewConfig creates a new Config object. The srcDir argument specifies the path 358// to the root source directory. It also loads the config file, if found. 359func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[string]string) (Config, error) { 360 // Make a config with default options. 361 config := &config{ 362 ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), 363 364 env: availableEnv, 365 366 srcDir: srcDir, 367 buildDir: buildDir, 368 multilibConflicts: make(map[ArchType]bool), 369 370 moduleListFile: moduleListFile, 371 fs: pathtools.NewOsFs(absSrcDir), 372 } 373 374 config.deviceConfig = &deviceConfig{ 375 config: config, 376 } 377 378 // Soundness check of the build and source directories. This won't catch strange 379 // configurations with symlinks, but at least checks the obvious case. 380 absBuildDir, err := filepath.Abs(buildDir) 381 if err != nil { 382 return Config{}, err 383 } 384 385 absSrcDir, err := filepath.Abs(srcDir) 386 if err != nil { 387 return Config{}, err 388 } 389 390 if strings.HasPrefix(absSrcDir, absBuildDir) { 391 return Config{}, fmt.Errorf("Build dir must not contain source directory") 392 } 393 394 // Load any configurable options from the configuration file 395 err = loadConfig(config) 396 if err != nil { 397 return Config{}, err 398 } 399 400 KatiEnabledMarkerFile := filepath.Join(buildDir, ".soong.kati_enabled") 401 if _, err := os.Stat(absolutePath(KatiEnabledMarkerFile)); err == nil { 402 config.katiEnabled = true 403 } 404 405 // Sets up the map of target OSes to the finer grained compilation targets 406 // that are configured from the product variables. 407 targets, err := decodeTargetProductVariables(config) 408 if err != nil { 409 return Config{}, err 410 } 411 412 // Make the CommonOS OsType available for all products. 413 targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]} 414 415 var archConfig []archConfig 416 if config.NdkAbis() { 417 archConfig = getNdkAbisConfig() 418 } else if config.AmlAbis() { 419 archConfig = getAmlAbisConfig() 420 } 421 422 if archConfig != nil { 423 androidTargets, err := decodeArchSettings(Android, archConfig) 424 if err != nil { 425 return Config{}, err 426 } 427 targets[Android] = androidTargets 428 } 429 430 multilib := make(map[string]bool) 431 for _, target := range targets[Android] { 432 if seen := multilib[target.Arch.ArchType.Multilib]; seen { 433 config.multilibConflicts[target.Arch.ArchType] = true 434 } 435 multilib[target.Arch.ArchType.Multilib] = true 436 } 437 438 // Map of OS to compilation targets. 439 config.Targets = targets 440 441 // Compilation targets for host tools. 442 config.BuildOSTarget = config.Targets[BuildOs][0] 443 config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] 444 445 // Compilation targets for Android. 446 if len(config.Targets[Android]) > 0 { 447 config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] 448 config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] 449 } 450 451 if Bool(config.productVariables.GcovCoverage) && Bool(config.productVariables.ClangCoverage) { 452 return Config{}, fmt.Errorf("GcovCoverage and ClangCoverage cannot both be set") 453 } 454 455 config.productVariables.Native_coverage = proptools.BoolPtr( 456 Bool(config.productVariables.GcovCoverage) || 457 Bool(config.productVariables.ClangCoverage)) 458 459 config.BazelContext, err = NewBazelContext(config) 460 config.bp2buildPackageConfig = bp2buildDefaultConfig 461 config.bp2buildModuleTypeConfig = make(map[string]bool) 462 463 return Config{config}, err 464} 465 466// mockFileSystem replaces all reads with accesses to the provided map of 467// filenames to contents stored as a byte slice. 468func (c *config) mockFileSystem(bp string, fs map[string][]byte) { 469 mockFS := map[string][]byte{} 470 471 if _, exists := mockFS["Android.bp"]; !exists { 472 mockFS["Android.bp"] = []byte(bp) 473 } 474 475 for k, v := range fs { 476 mockFS[k] = v 477 } 478 479 // no module list file specified; find every file named Blueprints or Android.bp 480 pathsToParse := []string{} 481 for candidate := range mockFS { 482 base := filepath.Base(candidate) 483 if base == "Blueprints" || base == "Android.bp" { 484 pathsToParse = append(pathsToParse, candidate) 485 } 486 } 487 if len(pathsToParse) < 1 { 488 panic(fmt.Sprintf("No Blueprint or Android.bp files found in mock filesystem: %v\n", mockFS)) 489 } 490 mockFS[blueprint.MockModuleListFile] = []byte(strings.Join(pathsToParse, "\n")) 491 492 c.fs = pathtools.MockFs(mockFS) 493 c.mockBpList = blueprint.MockModuleListFile 494} 495 496func (c *config) StopBefore() bootstrap.StopBefore { 497 return c.stopBefore 498} 499 500// SetStopBefore configures soong_build to exit earlier at a specific point. 501func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { 502 c.stopBefore = stopBefore 503} 504 505func (c *config) SetAllowMissingDependencies() { 506 c.productVariables.Allow_missing_dependencies = proptools.BoolPtr(true) 507} 508 509var _ bootstrap.ConfigStopBefore = (*config)(nil) 510 511// BlueprintToolLocation returns the directory containing build system tools 512// from Blueprint, like soong_zip and merge_zips. 513func (c *config) BlueprintToolLocation() string { 514 return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") 515} 516 517var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil) 518 519func (c *config) HostToolPath(ctx PathContext, tool string) Path { 520 return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool) 521} 522 523func (c *config) HostJNIToolPath(ctx PathContext, path string) Path { 524 ext := ".so" 525 if runtime.GOOS == "darwin" { 526 ext = ".dylib" 527 } 528 return PathForOutput(ctx, "host", c.PrebuiltOS(), "lib64", path+ext) 529} 530 531func (c *config) HostJavaToolPath(ctx PathContext, path string) Path { 532 return PathForOutput(ctx, "host", c.PrebuiltOS(), "framework", path) 533} 534 535// PrebuiltOS returns the name of the host OS used in prebuilts directories. 536func (c *config) PrebuiltOS() string { 537 switch runtime.GOOS { 538 case "linux": 539 return "linux-x86" 540 case "darwin": 541 return "darwin-x86" 542 default: 543 panic("Unknown GOOS") 544 } 545} 546 547// GoRoot returns the path to the root directory of the Go toolchain. 548func (c *config) GoRoot() string { 549 return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) 550} 551 552// PrebuiltBuildTool returns the path to a tool in the prebuilts directory containing 553// checked-in tools, like Kati, Ninja or Toybox, for the current host OS. 554func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { 555 return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) 556} 557 558// CpPreserveSymlinksFlags returns the host-specific flag for the cp(1) command 559// to preserve symlinks. 560func (c *config) CpPreserveSymlinksFlags() string { 561 switch runtime.GOOS { 562 case "darwin": 563 return "-R" 564 case "linux": 565 return "-d" 566 default: 567 return "" 568 } 569} 570 571func (c *config) Getenv(key string) string { 572 var val string 573 var exists bool 574 c.envLock.Lock() 575 defer c.envLock.Unlock() 576 if c.envDeps == nil { 577 c.envDeps = make(map[string]string) 578 } 579 if val, exists = c.envDeps[key]; !exists { 580 if c.envFrozen { 581 panic("Cannot access new environment variables after envdeps are frozen") 582 } 583 val, _ = c.env[key] 584 c.envDeps[key] = val 585 } 586 return val 587} 588 589func (c *config) GetenvWithDefault(key string, defaultValue string) string { 590 ret := c.Getenv(key) 591 if ret == "" { 592 return defaultValue 593 } 594 return ret 595} 596 597func (c *config) IsEnvTrue(key string) bool { 598 value := c.Getenv(key) 599 return value == "1" || value == "y" || value == "yes" || value == "on" || value == "true" 600} 601 602func (c *config) IsEnvFalse(key string) bool { 603 value := c.Getenv(key) 604 return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" 605} 606 607// EnvDeps returns the environment variables this build depends on. The first 608// call to this function blocks future reads from the environment. 609func (c *config) EnvDeps() map[string]string { 610 c.envLock.Lock() 611 defer c.envLock.Unlock() 612 c.envFrozen = true 613 return c.envDeps 614} 615 616func (c *config) KatiEnabled() bool { 617 return c.katiEnabled 618} 619 620func (c *config) BuildId() string { 621 return String(c.productVariables.BuildId) 622} 623 624// BuildNumberFile returns the path to a text file containing metadata 625// representing the current build's number. 626// 627// Rules that want to reference the build number should read from this file 628// without depending on it. They will run whenever their other dependencies 629// require them to run and get the current build number. This ensures they don't 630// rebuild on every incremental build when the build number changes. 631func (c *config) BuildNumberFile(ctx PathContext) Path { 632 return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) 633} 634 635// DeviceName returns the name of the current device target. 636// TODO: take an AndroidModuleContext to select the device name for multi-device builds 637func (c *config) DeviceName() string { 638 return *c.productVariables.DeviceName 639} 640 641func (c *config) DeviceResourceOverlays() []string { 642 return c.productVariables.DeviceResourceOverlays 643} 644 645func (c *config) ProductResourceOverlays() []string { 646 return c.productVariables.ProductResourceOverlays 647} 648 649func (c *config) PlatformVersionName() string { 650 return String(c.productVariables.Platform_version_name) 651} 652 653func (c *config) PlatformSdkVersion() ApiLevel { 654 return uncheckedFinalApiLevel(*c.productVariables.Platform_sdk_version) 655} 656 657func (c *config) PlatformSdkCodename() string { 658 return String(c.productVariables.Platform_sdk_codename) 659} 660 661func (c *config) PlatformSecurityPatch() string { 662 return String(c.productVariables.Platform_security_patch) 663} 664 665func (c *config) PlatformPreviewSdkVersion() string { 666 return String(c.productVariables.Platform_preview_sdk_version) 667} 668 669func (c *config) PlatformMinSupportedTargetSdkVersion() string { 670 return String(c.productVariables.Platform_min_supported_target_sdk_version) 671} 672 673func (c *config) PlatformBaseOS() string { 674 return String(c.productVariables.Platform_base_os) 675} 676 677func (c *config) MinSupportedSdkVersion() ApiLevel { 678 return uncheckedFinalApiLevel(16) 679} 680 681func (c *config) FinalApiLevels() []ApiLevel { 682 var levels []ApiLevel 683 for i := 1; i <= c.PlatformSdkVersion().FinalOrFutureInt(); i++ { 684 levels = append(levels, uncheckedFinalApiLevel(i)) 685 } 686 return levels 687} 688 689func (c *config) PreviewApiLevels() []ApiLevel { 690 var levels []ApiLevel 691 for i, codename := range c.PlatformVersionActiveCodenames() { 692 levels = append(levels, ApiLevel{ 693 value: codename, 694 number: i, 695 isPreview: true, 696 }) 697 } 698 return levels 699} 700 701func (c *config) AllSupportedApiLevels() []ApiLevel { 702 var levels []ApiLevel 703 levels = append(levels, c.FinalApiLevels()...) 704 return append(levels, c.PreviewApiLevels()...) 705} 706 707// DefaultAppTargetSdk returns the API level that platform apps are targeting. 708// This converts a codename to the exact ApiLevel it represents. 709func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { 710 if Bool(c.productVariables.Platform_sdk_final) { 711 return c.PlatformSdkVersion() 712 } 713 codename := c.PlatformSdkCodename() 714 if codename == "" { 715 return NoneApiLevel 716 } 717 if codename == "REL" { 718 panic("Platform_sdk_codename should not be REL when Platform_sdk_final is true") 719 } 720 return ApiLevelOrPanic(ctx, codename) 721} 722 723func (c *config) AppsDefaultVersionName() string { 724 return String(c.productVariables.AppsDefaultVersionName) 725} 726 727// Codenames that are active in the current lunch target. 728func (c *config) PlatformVersionActiveCodenames() []string { 729 return c.productVariables.Platform_version_active_codenames 730} 731 732func (c *config) ProductAAPTConfig() []string { 733 return c.productVariables.AAPTConfig 734} 735 736func (c *config) ProductAAPTPreferredConfig() string { 737 return String(c.productVariables.AAPTPreferredConfig) 738} 739 740func (c *config) ProductAAPTCharacteristics() string { 741 return String(c.productVariables.AAPTCharacteristics) 742} 743 744func (c *config) ProductAAPTPrebuiltDPI() []string { 745 return c.productVariables.AAPTPrebuiltDPI 746} 747 748func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { 749 defaultCert := String(c.productVariables.DefaultAppCertificate) 750 if defaultCert != "" { 751 return PathForSource(ctx, filepath.Dir(defaultCert)) 752 } 753 return PathForSource(ctx, "build/make/target/product/security") 754} 755 756func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { 757 defaultCert := String(c.productVariables.DefaultAppCertificate) 758 if defaultCert != "" { 759 return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") 760 } 761 defaultDir := c.DefaultAppCertificateDir(ctx) 762 return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") 763} 764 765func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { 766 // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE 767 defaultCert := String(c.productVariables.DefaultAppCertificate) 768 if defaultCert == "" || filepath.Dir(defaultCert) == "build/make/target/product/security" { 769 // When defaultCert is unset or is set to the testkeys path, use the APEX keys 770 // that is under the module dir 771 return pathForModuleSrc(ctx) 772 } 773 // If not, APEX keys are under the specified directory 774 return PathForSource(ctx, filepath.Dir(defaultCert)) 775} 776 777// AllowMissingDependencies configures Blueprint/Soong to not fail when modules 778// are configured to depend on non-existent modules. Note that this does not 779// affect missing input dependencies at the Ninja level. 780func (c *config) AllowMissingDependencies() bool { 781 return Bool(c.productVariables.Allow_missing_dependencies) 782} 783 784// Returns true if a full platform source tree cannot be assumed. 785func (c *config) UnbundledBuild() bool { 786 return Bool(c.productVariables.Unbundled_build) 787} 788 789// Returns true if building apps that aren't bundled with the platform. 790// UnbundledBuild() is always true when this is true. 791func (c *config) UnbundledBuildApps() bool { 792 return Bool(c.productVariables.Unbundled_build_apps) 793} 794 795// Returns true if building modules against prebuilt SDKs. 796func (c *config) AlwaysUsePrebuiltSdks() bool { 797 return Bool(c.productVariables.Always_use_prebuilt_sdks) 798} 799 800// Returns true if the boot jars check should be skipped. 801func (c *config) SkipBootJarsCheck() bool { 802 return Bool(c.productVariables.Skip_boot_jars_check) 803} 804 805func (c *config) Fuchsia() bool { 806 return Bool(c.productVariables.Fuchsia) 807} 808 809func (c *config) MinimizeJavaDebugInfo() bool { 810 return Bool(c.productVariables.MinimizeJavaDebugInfo) && !Bool(c.productVariables.Eng) 811} 812 813func (c *config) Debuggable() bool { 814 return Bool(c.productVariables.Debuggable) 815} 816 817func (c *config) Eng() bool { 818 return Bool(c.productVariables.Eng) 819} 820 821func (c *config) DevicePrimaryArchType() ArchType { 822 return c.Targets[Android][0].Arch.ArchType 823} 824 825func (c *config) SanitizeHost() []string { 826 return append([]string(nil), c.productVariables.SanitizeHost...) 827} 828 829func (c *config) SanitizeDevice() []string { 830 return append([]string(nil), c.productVariables.SanitizeDevice...) 831} 832 833func (c *config) SanitizeDeviceDiag() []string { 834 return append([]string(nil), c.productVariables.SanitizeDeviceDiag...) 835} 836 837func (c *config) SanitizeDeviceArch() []string { 838 return append([]string(nil), c.productVariables.SanitizeDeviceArch...) 839} 840 841func (c *config) EnableCFI() bool { 842 if c.productVariables.EnableCFI == nil { 843 return true 844 } 845 return *c.productVariables.EnableCFI 846} 847 848func (c *config) DisableScudo() bool { 849 return Bool(c.productVariables.DisableScudo) 850} 851 852func (c *config) Android64() bool { 853 for _, t := range c.Targets[Android] { 854 if t.Arch.ArchType.Multilib == "lib64" { 855 return true 856 } 857 } 858 859 return false 860} 861 862func (c *config) UseGoma() bool { 863 return Bool(c.productVariables.UseGoma) 864} 865 866func (c *config) UseRBE() bool { 867 return Bool(c.productVariables.UseRBE) 868} 869 870func (c *config) UseRBEJAVAC() bool { 871 return Bool(c.productVariables.UseRBEJAVAC) 872} 873 874func (c *config) UseRBER8() bool { 875 return Bool(c.productVariables.UseRBER8) 876} 877 878func (c *config) UseRBED8() bool { 879 return Bool(c.productVariables.UseRBED8) 880} 881 882func (c *config) UseRemoteBuild() bool { 883 return c.UseGoma() || c.UseRBE() 884} 885 886func (c *config) RunErrorProne() bool { 887 return c.IsEnvTrue("RUN_ERROR_PRONE") 888} 889 890// XrefCorpusName returns the Kythe cross-reference corpus name. 891func (c *config) XrefCorpusName() string { 892 return c.Getenv("XREF_CORPUS") 893} 894 895// XrefCuEncoding returns the compilation unit encoding to use for Kythe code 896// xrefs. Can be 'json' (default), 'proto' or 'all'. 897func (c *config) XrefCuEncoding() string { 898 if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { 899 return enc 900 } 901 return "json" 902} 903 904// XrefCuJavaSourceMax returns the maximum number of the Java source files 905// in a single compilation unit 906const xrefJavaSourceFileMaxDefault = "1000" 907 908func (c Config) XrefCuJavaSourceMax() string { 909 v := c.Getenv("KYTHE_JAVA_SOURCE_BATCH_SIZE") 910 if v == "" { 911 return xrefJavaSourceFileMaxDefault 912 } 913 if _, err := strconv.ParseUint(v, 0, 0); err != nil { 914 fmt.Fprintf(os.Stderr, 915 "bad KYTHE_JAVA_SOURCE_BATCH_SIZE value: %s, will use %s", 916 err, xrefJavaSourceFileMaxDefault) 917 return xrefJavaSourceFileMaxDefault 918 } 919 return v 920 921} 922 923func (c *config) EmitXrefRules() bool { 924 return c.XrefCorpusName() != "" 925} 926 927func (c *config) ClangTidy() bool { 928 return Bool(c.productVariables.ClangTidy) 929} 930 931func (c *config) TidyChecks() string { 932 if c.productVariables.TidyChecks == nil { 933 return "" 934 } 935 return *c.productVariables.TidyChecks 936} 937 938func (c *config) LibartImgHostBaseAddress() string { 939 return "0x60000000" 940} 941 942func (c *config) LibartImgDeviceBaseAddress() string { 943 return "0x70000000" 944} 945 946func (c *config) ArtUseReadBarrier() bool { 947 return Bool(c.productVariables.ArtUseReadBarrier) 948} 949 950// Enforce Runtime Resource Overlays for a module. RROs supersede static RROs, 951// but some modules still depend on it. 952// 953// More info: https://source.android.com/devices/architecture/rros 954func (c *config) EnforceRROForModule(name string) bool { 955 enforceList := c.productVariables.EnforceRROTargets 956 957 if len(enforceList) > 0 { 958 if InList("*", enforceList) { 959 return true 960 } 961 return InList(name, enforceList) 962 } 963 return false 964} 965func (c *config) EnforceRROExcludedOverlay(path string) bool { 966 excluded := c.productVariables.EnforceRROExcludedOverlays 967 if len(excluded) > 0 { 968 return HasAnyPrefix(path, excluded) 969 } 970 return false 971} 972 973func (c *config) ExportedNamespaces() []string { 974 return append([]string(nil), c.productVariables.NamespacesToExport...) 975} 976 977func (c *config) HostStaticBinaries() bool { 978 return Bool(c.productVariables.HostStaticBinaries) 979} 980 981func (c *config) UncompressPrivAppDex() bool { 982 return Bool(c.productVariables.UncompressPrivAppDex) 983} 984 985func (c *config) ModulesLoadedByPrivilegedModules() []string { 986 return c.productVariables.ModulesLoadedByPrivilegedModules 987} 988 989// DexpreoptGlobalConfigPath returns the path to the dexpreopt.config file in 990// the output directory, if it was created during the product configuration 991// phase by Kati. 992func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { 993 if c.productVariables.DexpreoptGlobalConfig == nil { 994 return OptionalPathForPath(nil) 995 } 996 return OptionalPathForPath( 997 pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig)) 998} 999 1000// DexpreoptGlobalConfig returns the raw byte contents of the dexpreopt global 1001// configuration. Since the configuration file was created by Kati during 1002// product configuration (externally of soong_build), it's not tracked, so we 1003// also manually add a Ninja file dependency on the configuration file to the 1004// rule that creates the main build.ninja file. This ensures that build.ninja is 1005// regenerated correctly if dexpreopt.config changes. 1006func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { 1007 path := c.DexpreoptGlobalConfigPath(ctx) 1008 if !path.Valid() { 1009 return nil, nil 1010 } 1011 ctx.AddNinjaFileDeps(path.String()) 1012 return ioutil.ReadFile(absolutePath(path.String())) 1013} 1014 1015func (c *deviceConfig) WithDexpreopt() bool { 1016 return c.config.productVariables.WithDexpreopt 1017} 1018 1019func (c *config) FrameworksBaseDirExists(ctx PathContext) bool { 1020 return ExistentPathForSource(ctx, "frameworks", "base", "Android.bp").Valid() 1021} 1022 1023func (c *config) VndkSnapshotBuildArtifacts() bool { 1024 return Bool(c.productVariables.VndkSnapshotBuildArtifacts) 1025} 1026 1027func (c *config) HasMultilibConflict(arch ArchType) bool { 1028 return c.multilibConflicts[arch] 1029} 1030 1031func (c *config) PrebuiltHiddenApiDir(ctx PathContext) string { 1032 return String(c.productVariables.PrebuiltHiddenApiDir) 1033} 1034 1035func (c *deviceConfig) Arches() []Arch { 1036 var arches []Arch 1037 for _, target := range c.config.Targets[Android] { 1038 arches = append(arches, target.Arch) 1039 } 1040 return arches 1041} 1042 1043func (c *deviceConfig) BinderBitness() string { 1044 is32BitBinder := c.config.productVariables.Binder32bit 1045 if is32BitBinder != nil && *is32BitBinder { 1046 return "32" 1047 } 1048 return "64" 1049} 1050 1051func (c *deviceConfig) VendorPath() string { 1052 if c.config.productVariables.VendorPath != nil { 1053 return *c.config.productVariables.VendorPath 1054 } 1055 return "vendor" 1056} 1057 1058func (c *deviceConfig) VndkVersion() string { 1059 return String(c.config.productVariables.DeviceVndkVersion) 1060} 1061 1062func (c *deviceConfig) RecoverySnapshotVersion() string { 1063 return String(c.config.productVariables.RecoverySnapshotVersion) 1064} 1065 1066func (c *deviceConfig) CurrentApiLevelForVendorModules() string { 1067 return StringDefault(c.config.productVariables.DeviceCurrentApiLevelForVendorModules, "current") 1068} 1069 1070func (c *deviceConfig) PlatformVndkVersion() string { 1071 return String(c.config.productVariables.Platform_vndk_version) 1072} 1073 1074func (c *deviceConfig) ProductVndkVersion() string { 1075 return String(c.config.productVariables.ProductVndkVersion) 1076} 1077 1078func (c *deviceConfig) ExtraVndkVersions() []string { 1079 return c.config.productVariables.ExtraVndkVersions 1080} 1081 1082func (c *deviceConfig) VndkUseCoreVariant() bool { 1083 return Bool(c.config.productVariables.VndkUseCoreVariant) 1084} 1085 1086func (c *deviceConfig) SystemSdkVersions() []string { 1087 return c.config.productVariables.DeviceSystemSdkVersions 1088} 1089 1090func (c *deviceConfig) PlatformSystemSdkVersions() []string { 1091 return c.config.productVariables.Platform_systemsdk_versions 1092} 1093 1094func (c *deviceConfig) OdmPath() string { 1095 if c.config.productVariables.OdmPath != nil { 1096 return *c.config.productVariables.OdmPath 1097 } 1098 return "odm" 1099} 1100 1101func (c *deviceConfig) ProductPath() string { 1102 if c.config.productVariables.ProductPath != nil { 1103 return *c.config.productVariables.ProductPath 1104 } 1105 return "product" 1106} 1107 1108func (c *deviceConfig) SystemExtPath() string { 1109 if c.config.productVariables.SystemExtPath != nil { 1110 return *c.config.productVariables.SystemExtPath 1111 } 1112 return "system_ext" 1113} 1114 1115func (c *deviceConfig) BtConfigIncludeDir() string { 1116 return String(c.config.productVariables.BtConfigIncludeDir) 1117} 1118 1119func (c *deviceConfig) DeviceKernelHeaderDirs() []string { 1120 return c.config.productVariables.DeviceKernelHeaders 1121} 1122 1123func (c *deviceConfig) SamplingPGO() bool { 1124 return Bool(c.config.productVariables.SamplingPGO) 1125} 1126 1127// JavaCoverageEnabledForPath returns whether Java code coverage is enabled for 1128// path. Coverage is enabled by default when the product variable 1129// JavaCoveragePaths is empty. If JavaCoveragePaths is not empty, coverage is 1130// enabled for any path which is part of this variable (and not part of the 1131// JavaCoverageExcludePaths product variable). Value "*" in JavaCoveragePaths 1132// represents any path. 1133func (c *deviceConfig) JavaCoverageEnabledForPath(path string) bool { 1134 coverage := false 1135 if len(c.config.productVariables.JavaCoveragePaths) == 0 || 1136 InList("*", c.config.productVariables.JavaCoveragePaths) || 1137 HasAnyPrefix(path, c.config.productVariables.JavaCoveragePaths) { 1138 coverage = true 1139 } 1140 if coverage && len(c.config.productVariables.JavaCoverageExcludePaths) > 0 { 1141 if HasAnyPrefix(path, c.config.productVariables.JavaCoverageExcludePaths) { 1142 coverage = false 1143 } 1144 } 1145 return coverage 1146} 1147 1148// Returns true if gcov or clang coverage is enabled. 1149func (c *deviceConfig) NativeCoverageEnabled() bool { 1150 return Bool(c.config.productVariables.GcovCoverage) || 1151 Bool(c.config.productVariables.ClangCoverage) 1152} 1153 1154func (c *deviceConfig) ClangCoverageEnabled() bool { 1155 return Bool(c.config.productVariables.ClangCoverage) 1156} 1157 1158func (c *deviceConfig) GcovCoverageEnabled() bool { 1159 return Bool(c.config.productVariables.GcovCoverage) 1160} 1161 1162// NativeCoverageEnabledForPath returns whether (GCOV- or Clang-based) native 1163// code coverage is enabled for path. By default, coverage is not enabled for a 1164// given path unless it is part of the NativeCoveragePaths product variable (and 1165// not part of the NativeCoverageExcludePaths product variable). Value "*" in 1166// NativeCoveragePaths represents any path. 1167func (c *deviceConfig) NativeCoverageEnabledForPath(path string) bool { 1168 coverage := false 1169 if len(c.config.productVariables.NativeCoveragePaths) > 0 { 1170 if InList("*", c.config.productVariables.NativeCoveragePaths) || HasAnyPrefix(path, c.config.productVariables.NativeCoveragePaths) { 1171 coverage = true 1172 } 1173 } 1174 if coverage && len(c.config.productVariables.NativeCoverageExcludePaths) > 0 { 1175 if HasAnyPrefix(path, c.config.productVariables.NativeCoverageExcludePaths) { 1176 coverage = false 1177 } 1178 } 1179 return coverage 1180} 1181 1182func (c *deviceConfig) PgoAdditionalProfileDirs() []string { 1183 return c.config.productVariables.PgoAdditionalProfileDirs 1184} 1185 1186func (c *deviceConfig) VendorSepolicyDirs() []string { 1187 return c.config.productVariables.BoardVendorSepolicyDirs 1188} 1189 1190func (c *deviceConfig) OdmSepolicyDirs() []string { 1191 return c.config.productVariables.BoardOdmSepolicyDirs 1192} 1193 1194func (c *deviceConfig) SystemExtPublicSepolicyDirs() []string { 1195 return c.config.productVariables.SystemExtPublicSepolicyDirs 1196} 1197 1198func (c *deviceConfig) SystemExtPrivateSepolicyDirs() []string { 1199 return c.config.productVariables.SystemExtPrivateSepolicyDirs 1200} 1201 1202func (c *deviceConfig) SepolicyM4Defs() []string { 1203 return c.config.productVariables.BoardSepolicyM4Defs 1204} 1205 1206func (c *deviceConfig) OverrideManifestPackageNameFor(name string) (manifestName string, overridden bool) { 1207 return findOverrideValue(c.config.productVariables.ManifestPackageNameOverrides, name, 1208 "invalid override rule %q in PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES should be <module_name>:<manifest_name>") 1209} 1210 1211func (c *deviceConfig) OverrideCertificateFor(name string) (certificatePath string, overridden bool) { 1212 return findOverrideValue(c.config.productVariables.CertificateOverrides, name, 1213 "invalid override rule %q in PRODUCT_CERTIFICATE_OVERRIDES should be <module_name>:<certificate_module_name>") 1214} 1215 1216func (c *deviceConfig) OverridePackageNameFor(name string) string { 1217 newName, overridden := findOverrideValue( 1218 c.config.productVariables.PackageNameOverrides, 1219 name, 1220 "invalid override rule %q in PRODUCT_PACKAGE_NAME_OVERRIDES should be <module_name>:<package_name>") 1221 if overridden { 1222 return newName 1223 } 1224 return name 1225} 1226 1227func findOverrideValue(overrides []string, name string, errorMsg string) (newValue string, overridden bool) { 1228 if overrides == nil || len(overrides) == 0 { 1229 return "", false 1230 } 1231 for _, o := range overrides { 1232 split := strings.Split(o, ":") 1233 if len(split) != 2 { 1234 // This shouldn't happen as this is first checked in make, but just in case. 1235 panic(fmt.Errorf(errorMsg, o)) 1236 } 1237 if matchPattern(split[0], name) { 1238 return substPattern(split[0], split[1], name), true 1239 } 1240 } 1241 return "", false 1242} 1243 1244func (c *config) IntegerOverflowDisabledForPath(path string) bool { 1245 if len(c.productVariables.IntegerOverflowExcludePaths) == 0 { 1246 return false 1247 } 1248 return HasAnyPrefix(path, c.productVariables.IntegerOverflowExcludePaths) 1249} 1250 1251func (c *config) CFIDisabledForPath(path string) bool { 1252 if len(c.productVariables.CFIExcludePaths) == 0 { 1253 return false 1254 } 1255 return HasAnyPrefix(path, c.productVariables.CFIExcludePaths) 1256} 1257 1258func (c *config) CFIEnabledForPath(path string) bool { 1259 if len(c.productVariables.CFIIncludePaths) == 0 { 1260 return false 1261 } 1262 return HasAnyPrefix(path, c.productVariables.CFIIncludePaths) && !c.CFIDisabledForPath(path) 1263} 1264 1265func (c *config) MemtagHeapDisabledForPath(path string) bool { 1266 if len(c.productVariables.MemtagHeapExcludePaths) == 0 { 1267 return false 1268 } 1269 return HasAnyPrefix(path, c.productVariables.MemtagHeapExcludePaths) 1270} 1271 1272func (c *config) MemtagHeapAsyncEnabledForPath(path string) bool { 1273 if len(c.productVariables.MemtagHeapAsyncIncludePaths) == 0 { 1274 return false 1275 } 1276 return HasAnyPrefix(path, c.productVariables.MemtagHeapAsyncIncludePaths) && !c.MemtagHeapDisabledForPath(path) 1277} 1278 1279func (c *config) MemtagHeapSyncEnabledForPath(path string) bool { 1280 if len(c.productVariables.MemtagHeapSyncIncludePaths) == 0 { 1281 return false 1282 } 1283 return HasAnyPrefix(path, c.productVariables.MemtagHeapSyncIncludePaths) && !c.MemtagHeapDisabledForPath(path) 1284} 1285 1286func (c *config) VendorConfig(name string) VendorConfig { 1287 return soongconfig.Config(c.productVariables.VendorVars[name]) 1288} 1289 1290func (c *config) NdkAbis() bool { 1291 return Bool(c.productVariables.Ndk_abis) 1292} 1293 1294func (c *config) AmlAbis() bool { 1295 return Bool(c.productVariables.Aml_abis) 1296} 1297 1298func (c *config) FlattenApex() bool { 1299 return Bool(c.productVariables.Flatten_apex) 1300} 1301 1302func (c *config) ForceApexSymlinkOptimization() bool { 1303 return Bool(c.productVariables.ForceApexSymlinkOptimization) 1304} 1305 1306func (c *config) CompressedApex() bool { 1307 return Bool(c.productVariables.CompressedApex) 1308} 1309 1310func (c *config) EnforceSystemCertificate() bool { 1311 return Bool(c.productVariables.EnforceSystemCertificate) 1312} 1313 1314func (c *config) EnforceSystemCertificateAllowList() []string { 1315 return c.productVariables.EnforceSystemCertificateAllowList 1316} 1317 1318func (c *config) EnforceProductPartitionInterface() bool { 1319 return Bool(c.productVariables.EnforceProductPartitionInterface) 1320} 1321 1322func (c *config) EnforceInterPartitionJavaSdkLibrary() bool { 1323 return Bool(c.productVariables.EnforceInterPartitionJavaSdkLibrary) 1324} 1325 1326func (c *config) InterPartitionJavaLibraryAllowList() []string { 1327 return c.productVariables.InterPartitionJavaLibraryAllowList 1328} 1329 1330func (c *config) InstallExtraFlattenedApexes() bool { 1331 return Bool(c.productVariables.InstallExtraFlattenedApexes) 1332} 1333 1334func (c *config) ProductHiddenAPIStubs() []string { 1335 return c.productVariables.ProductHiddenAPIStubs 1336} 1337 1338func (c *config) ProductHiddenAPIStubsSystem() []string { 1339 return c.productVariables.ProductHiddenAPIStubsSystem 1340} 1341 1342func (c *config) ProductHiddenAPIStubsTest() []string { 1343 return c.productVariables.ProductHiddenAPIStubsTest 1344} 1345 1346func (c *deviceConfig) TargetFSConfigGen() []string { 1347 return c.config.productVariables.TargetFSConfigGen 1348} 1349 1350func (c *config) ProductPublicSepolicyDirs() []string { 1351 return c.productVariables.ProductPublicSepolicyDirs 1352} 1353 1354func (c *config) ProductPrivateSepolicyDirs() []string { 1355 return c.productVariables.ProductPrivateSepolicyDirs 1356} 1357 1358func (c *config) MissingUsesLibraries() []string { 1359 return c.productVariables.MissingUsesLibraries 1360} 1361 1362func (c *deviceConfig) DeviceArch() string { 1363 return String(c.config.productVariables.DeviceArch) 1364} 1365 1366func (c *deviceConfig) DeviceArchVariant() string { 1367 return String(c.config.productVariables.DeviceArchVariant) 1368} 1369 1370func (c *deviceConfig) DeviceSecondaryArch() string { 1371 return String(c.config.productVariables.DeviceSecondaryArch) 1372} 1373 1374func (c *deviceConfig) DeviceSecondaryArchVariant() string { 1375 return String(c.config.productVariables.DeviceSecondaryArchVariant) 1376} 1377 1378func (c *deviceConfig) BoardUsesRecoveryAsBoot() bool { 1379 return Bool(c.config.productVariables.BoardUsesRecoveryAsBoot) 1380} 1381 1382func (c *deviceConfig) BoardKernelBinaries() []string { 1383 return c.config.productVariables.BoardKernelBinaries 1384} 1385 1386func (c *deviceConfig) BoardKernelModuleInterfaceVersions() []string { 1387 return c.config.productVariables.BoardKernelModuleInterfaceVersions 1388} 1389 1390func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool { 1391 return Bool(c.config.productVariables.BoardMoveRecoveryResourcesToVendorBoot) 1392} 1393 1394func (c *deviceConfig) PlatformSepolicyVersion() string { 1395 return String(c.config.productVariables.PlatformSepolicyVersion) 1396} 1397 1398func (c *deviceConfig) BoardSepolicyVers() string { 1399 if ver := String(c.config.productVariables.BoardSepolicyVers); ver != "" { 1400 return ver 1401 } 1402 return c.PlatformSepolicyVersion() 1403} 1404 1405func (c *deviceConfig) BoardReqdMaskPolicy() []string { 1406 return c.config.productVariables.BoardReqdMaskPolicy 1407} 1408 1409func (c *deviceConfig) DirectedVendorSnapshot() bool { 1410 return c.config.productVariables.DirectedVendorSnapshot 1411} 1412 1413func (c *deviceConfig) VendorSnapshotModules() map[string]bool { 1414 return c.config.productVariables.VendorSnapshotModules 1415} 1416 1417func (c *deviceConfig) DirectedRecoverySnapshot() bool { 1418 return c.config.productVariables.DirectedRecoverySnapshot 1419} 1420 1421func (c *deviceConfig) RecoverySnapshotModules() map[string]bool { 1422 return c.config.productVariables.RecoverySnapshotModules 1423} 1424 1425func createDirsMap(previous map[string]bool, dirs []string) (map[string]bool, error) { 1426 var ret = make(map[string]bool) 1427 for _, dir := range dirs { 1428 clean := filepath.Clean(dir) 1429 if previous[clean] || ret[clean] { 1430 return nil, fmt.Errorf("Duplicate entry %s", dir) 1431 } 1432 ret[clean] = true 1433 } 1434 return ret, nil 1435} 1436 1437func (c *deviceConfig) createDirsMapOnce(onceKey OnceKey, previous map[string]bool, dirs []string) map[string]bool { 1438 dirMap := c.Once(onceKey, func() interface{} { 1439 ret, err := createDirsMap(previous, dirs) 1440 if err != nil { 1441 panic(fmt.Errorf("%s: %w", onceKey.key, err)) 1442 } 1443 return ret 1444 }) 1445 if dirMap == nil { 1446 return nil 1447 } 1448 return dirMap.(map[string]bool) 1449} 1450 1451var vendorSnapshotDirsExcludedKey = NewOnceKey("VendorSnapshotDirsExcludedMap") 1452 1453func (c *deviceConfig) VendorSnapshotDirsExcludedMap() map[string]bool { 1454 return c.createDirsMapOnce(vendorSnapshotDirsExcludedKey, nil, 1455 c.config.productVariables.VendorSnapshotDirsExcluded) 1456} 1457 1458var vendorSnapshotDirsIncludedKey = NewOnceKey("VendorSnapshotDirsIncludedMap") 1459 1460func (c *deviceConfig) VendorSnapshotDirsIncludedMap() map[string]bool { 1461 excludedMap := c.VendorSnapshotDirsExcludedMap() 1462 return c.createDirsMapOnce(vendorSnapshotDirsIncludedKey, excludedMap, 1463 c.config.productVariables.VendorSnapshotDirsIncluded) 1464} 1465 1466var recoverySnapshotDirsExcludedKey = NewOnceKey("RecoverySnapshotDirsExcludedMap") 1467 1468func (c *deviceConfig) RecoverySnapshotDirsExcludedMap() map[string]bool { 1469 return c.createDirsMapOnce(recoverySnapshotDirsExcludedKey, nil, 1470 c.config.productVariables.RecoverySnapshotDirsExcluded) 1471} 1472 1473var recoverySnapshotDirsIncludedKey = NewOnceKey("RecoverySnapshotDirsIncludedMap") 1474 1475func (c *deviceConfig) RecoverySnapshotDirsIncludedMap() map[string]bool { 1476 excludedMap := c.RecoverySnapshotDirsExcludedMap() 1477 return c.createDirsMapOnce(recoverySnapshotDirsIncludedKey, excludedMap, 1478 c.config.productVariables.RecoverySnapshotDirsIncluded) 1479} 1480 1481func (c *deviceConfig) ShippingApiLevel() ApiLevel { 1482 if c.config.productVariables.ShippingApiLevel == nil { 1483 return NoneApiLevel 1484 } 1485 apiLevel, _ := strconv.Atoi(*c.config.productVariables.ShippingApiLevel) 1486 return uncheckedFinalApiLevel(apiLevel) 1487} 1488 1489func (c *deviceConfig) BuildBrokenEnforceSyspropOwner() bool { 1490 return c.config.productVariables.BuildBrokenEnforceSyspropOwner 1491} 1492 1493func (c *deviceConfig) BuildBrokenTrebleSyspropNeverallow() bool { 1494 return c.config.productVariables.BuildBrokenTrebleSyspropNeverallow 1495} 1496 1497func (c *deviceConfig) BuildDebugfsRestrictionsEnabled() bool { 1498 return c.config.productVariables.BuildDebugfsRestrictionsEnabled 1499} 1500 1501func (c *deviceConfig) BuildBrokenVendorPropertyNamespace() bool { 1502 return c.config.productVariables.BuildBrokenVendorPropertyNamespace 1503} 1504 1505func (c *deviceConfig) RequiresInsecureExecmemForSwiftshader() bool { 1506 return c.config.productVariables.RequiresInsecureExecmemForSwiftshader 1507} 1508 1509func (c *config) SelinuxIgnoreNeverallows() bool { 1510 return c.productVariables.SelinuxIgnoreNeverallows 1511} 1512 1513func (c *deviceConfig) SepolicySplit() bool { 1514 return c.config.productVariables.SepolicySplit 1515} 1516 1517// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs. 1518// Such lists are used in the build system for things like bootclasspath jars or system server jars. 1519// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a 1520// module name. The pairs come from Make product variables as a list of colon-separated strings. 1521// 1522// Examples: 1523// - "com.android.art:core-oj" 1524// - "platform:framework" 1525// - "system_ext:foo" 1526// 1527type ConfiguredJarList struct { 1528 // A list of apex components, which can be an apex name, 1529 // or special names like "platform" or "system_ext". 1530 apexes []string 1531 1532 // A list of jar module name components. 1533 jars []string 1534} 1535 1536// Len returns the length of the list of jars. 1537func (l *ConfiguredJarList) Len() int { 1538 return len(l.jars) 1539} 1540 1541// Jar returns the idx-th jar component of (apex, jar) pairs. 1542func (l *ConfiguredJarList) Jar(idx int) string { 1543 return l.jars[idx] 1544} 1545 1546// Apex returns the idx-th apex component of (apex, jar) pairs. 1547func (l *ConfiguredJarList) Apex(idx int) string { 1548 return l.apexes[idx] 1549} 1550 1551// ContainsJar returns true if the (apex, jar) pairs contains a pair with the 1552// given jar module name. 1553func (l *ConfiguredJarList) ContainsJar(jar string) bool { 1554 return InList(jar, l.jars) 1555} 1556 1557// If the list contains the given (apex, jar) pair. 1558func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool { 1559 for i := 0; i < l.Len(); i++ { 1560 if apex == l.apexes[i] && jar == l.jars[i] { 1561 return true 1562 } 1563 } 1564 return false 1565} 1566 1567// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or 1568// an empty string if not found. 1569func (l *ConfiguredJarList) ApexOfJar(jar string) string { 1570 if idx := IndexList(jar, l.jars); idx != -1 { 1571 return l.Apex(IndexList(jar, l.jars)) 1572 } 1573 return "" 1574} 1575 1576// IndexOfJar returns the first pair with the given jar name on the list, or -1 1577// if not found. 1578func (l *ConfiguredJarList) IndexOfJar(jar string) int { 1579 return IndexList(jar, l.jars) 1580} 1581 1582func copyAndAppend(list []string, item string) []string { 1583 // Create the result list to be 1 longer than the input. 1584 result := make([]string, len(list)+1) 1585 1586 // Copy the whole input list into the result. 1587 count := copy(result, list) 1588 1589 // Insert the extra item at the end. 1590 result[count] = item 1591 1592 return result 1593} 1594 1595// Append an (apex, jar) pair to the list. 1596func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList { 1597 // Create a copy of the backing arrays before appending to avoid sharing backing 1598 // arrays that are mutated across instances. 1599 apexes := copyAndAppend(l.apexes, apex) 1600 jars := copyAndAppend(l.jars, jar) 1601 1602 return ConfiguredJarList{apexes, jars} 1603} 1604 1605// RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs. 1606func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList { 1607 apexes := make([]string, 0, l.Len()) 1608 jars := make([]string, 0, l.Len()) 1609 1610 for i, jar := range l.jars { 1611 apex := l.apexes[i] 1612 if !list.containsApexJarPair(apex, jar) { 1613 apexes = append(apexes, apex) 1614 jars = append(jars, jar) 1615 } 1616 } 1617 1618 return ConfiguredJarList{apexes, jars} 1619} 1620 1621// Filter keeps the entries if a jar appears in the given list of jars to keep; returns a new list. 1622func (l *ConfiguredJarList) Filter(jarsToKeep []string) ConfiguredJarList { 1623 var apexes []string 1624 var jars []string 1625 1626 for i, jar := range l.jars { 1627 if InList(jar, jarsToKeep) { 1628 apexes = append(apexes, l.apexes[i]) 1629 jars = append(jars, jar) 1630 } 1631 } 1632 1633 return ConfiguredJarList{apexes, jars} 1634} 1635 1636// CopyOfJars returns a copy of the list of strings containing jar module name 1637// components. 1638func (l *ConfiguredJarList) CopyOfJars() []string { 1639 return CopyOf(l.jars) 1640} 1641 1642// CopyOfApexJarPairs returns a copy of the list of strings with colon-separated 1643// (apex, jar) pairs. 1644func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { 1645 pairs := make([]string, 0, l.Len()) 1646 1647 for i, jar := range l.jars { 1648 apex := l.apexes[i] 1649 pairs = append(pairs, apex+":"+jar) 1650 } 1651 1652 return pairs 1653} 1654 1655// BuildPaths returns a list of build paths based on the given directory prefix. 1656func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths { 1657 paths := make(WritablePaths, l.Len()) 1658 for i, jar := range l.jars { 1659 paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar") 1660 } 1661 return paths 1662} 1663 1664// BuildPathsByModule returns a map from module name to build paths based on the given directory 1665// prefix. 1666func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath { 1667 paths := map[string]WritablePath{} 1668 for _, jar := range l.jars { 1669 paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar") 1670 } 1671 return paths 1672} 1673 1674// UnmarshalJSON converts JSON configuration from raw bytes into a 1675// ConfiguredJarList structure. 1676func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { 1677 // Try and unmarshal into a []string each item of which contains a pair 1678 // <apex>:<jar>. 1679 var list []string 1680 err := json.Unmarshal(b, &list) 1681 if err != nil { 1682 // Did not work so return 1683 return err 1684 } 1685 1686 apexes, jars, err := splitListOfPairsIntoPairOfLists(list) 1687 if err != nil { 1688 return err 1689 } 1690 l.apexes = apexes 1691 l.jars = jars 1692 return nil 1693} 1694 1695func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) { 1696 if len(l.apexes) != len(l.jars) { 1697 return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars)) 1698 } 1699 1700 list := make([]string, 0, len(l.apexes)) 1701 1702 for i := 0; i < len(l.apexes); i++ { 1703 list = append(list, l.apexes[i]+":"+l.jars[i]) 1704 } 1705 1706 return json.Marshal(list) 1707} 1708 1709// ModuleStem hardcodes the stem of framework-minus-apex to return "framework". 1710// 1711// TODO(b/139391334): hard coded until we find a good way to query the stem of a 1712// module before any other mutators are run. 1713func ModuleStem(module string) string { 1714 if module == "framework-minus-apex" { 1715 return "framework" 1716 } 1717 return module 1718} 1719 1720// DevicePaths computes the on-device paths for the list of (apex, jar) pairs, 1721// based on the operating system. 1722func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string { 1723 paths := make([]string, l.Len()) 1724 for i, jar := range l.jars { 1725 apex := l.apexes[i] 1726 name := ModuleStem(jar) + ".jar" 1727 1728 var subdir string 1729 if apex == "platform" { 1730 subdir = "system/framework" 1731 } else if apex == "system_ext" { 1732 subdir = "system_ext/framework" 1733 } else { 1734 subdir = filepath.Join("apex", apex, "javalib") 1735 } 1736 1737 if ostype.Class == Host { 1738 paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name) 1739 } else { 1740 paths[i] = filepath.Join("/", subdir, name) 1741 } 1742 } 1743 return paths 1744} 1745 1746func (l *ConfiguredJarList) String() string { 1747 var pairs []string 1748 for i := 0; i < l.Len(); i++ { 1749 pairs = append(pairs, l.apexes[i]+":"+l.jars[i]) 1750 } 1751 return strings.Join(pairs, ",") 1752} 1753 1754func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) { 1755 // Now we need to populate this list by splitting each item in the slice of 1756 // pairs and appending them to the appropriate list of apexes or jars. 1757 apexes := make([]string, len(list)) 1758 jars := make([]string, len(list)) 1759 1760 for i, apexjar := range list { 1761 apex, jar, err := splitConfiguredJarPair(apexjar) 1762 if err != nil { 1763 return nil, nil, err 1764 } 1765 apexes[i] = apex 1766 jars[i] = jar 1767 } 1768 1769 return apexes, jars, nil 1770} 1771 1772// Expected format for apexJarValue = <apex name>:<jar name> 1773func splitConfiguredJarPair(str string) (string, string, error) { 1774 pair := strings.SplitN(str, ":", 2) 1775 if len(pair) == 2 { 1776 apex := pair[0] 1777 jar := pair[1] 1778 if apex == "" { 1779 return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str) 1780 } 1781 return apex, jar, nil 1782 } else { 1783 return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str) 1784 } 1785} 1786 1787// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests. 1788func CreateTestConfiguredJarList(list []string) ConfiguredJarList { 1789 // Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to 1790 // a json list of strings and then unmarshalling into a ConfiguredJarList instance. 1791 b, err := json.Marshal(list) 1792 if err != nil { 1793 panic(err) 1794 } 1795 1796 var jarList ConfiguredJarList 1797 err = json.Unmarshal(b, &jarList) 1798 if err != nil { 1799 panic(err) 1800 } 1801 1802 return jarList 1803} 1804 1805// EmptyConfiguredJarList returns an empty jar list. 1806func EmptyConfiguredJarList() ConfiguredJarList { 1807 return ConfiguredJarList{} 1808} 1809 1810var earlyBootJarsKey = NewOnceKey("earlyBootJars") 1811 1812func (c *config) BootJars() []string { 1813 return c.Once(earlyBootJarsKey, func() interface{} { 1814 list := c.productVariables.BootJars.CopyOfJars() 1815 return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) 1816 }).([]string) 1817} 1818 1819func (c *config) NonUpdatableBootJars() ConfiguredJarList { 1820 return c.productVariables.BootJars 1821} 1822 1823func (c *config) UpdatableBootJars() ConfiguredJarList { 1824 return c.productVariables.UpdatableBootJars 1825} 1826 1827func (c *config) RBEWrapper() string { 1828 return c.GetenvWithDefault("RBE_WRAPPER", remoteexec.DefaultWrapperPath) 1829} 1830