Loading android/config.go +145 −63 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,9 @@ package android package android // This is the primary location to write and read all configuration values and // product variables necessary for soong_build's operation. import ( import ( "encoding/json" "encoding/json" "fmt" "fmt" Loading @@ -32,20 +35,31 @@ import ( "android/soong/android/soongconfig" "android/soong/android/soongconfig" ) ) // Bool re-exports proptools.Bool for the android package. var Bool = proptools.Bool var Bool = proptools.Bool // String re-exports proptools.String for the android package. var String = proptools.String var String = proptools.String // StringDefault re-exports proptools.StringDefault for the android package. var StringDefault = proptools.StringDefault var StringDefault = proptools.StringDefault // FutureApiLevelInt is a placeholder constant for unreleased API levels. const FutureApiLevelInt = 10000 const FutureApiLevelInt = 10000 // FutureApiLevel represents unreleased API levels. var FutureApiLevel = ApiLevel{ var FutureApiLevel = ApiLevel{ value: "current", value: "current", number: FutureApiLevelInt, number: FutureApiLevelInt, isPreview: true, isPreview: true, } } // The configuration file name // configFileName is the name the file containing FileConfigurableOptions from // soong_ui for the soong_build primary builder. const configFileName = "soong.config" const configFileName = "soong.config" // productVariablesFileName contain the product configuration variables from soong_ui for the // soong_build primary builder and Kati. const productVariablesFileName = "soong.variables" const productVariablesFileName = "soong.variables" // A FileConfigurableOptions contains options which can be configured by the // A FileConfigurableOptions contains options which can be configured by the Loading @@ -56,6 +70,8 @@ type FileConfigurableOptions struct { Host_bionic_arm64 *bool `json:",omitempty"` Host_bionic_arm64 *bool `json:",omitempty"` } } // SetDefaultConfig resets the receiving FileConfigurableOptions to default // values. func (f *FileConfigurableOptions) SetDefaultConfig() { func (f *FileConfigurableOptions) SetDefaultConfig() { *f = FileConfigurableOptions{} *f = FileConfigurableOptions{} } } Loading @@ -65,29 +81,38 @@ type Config struct { *config *config } } // BuildDir returns the build output directory for the configuration. func (c Config) BuildDir() string { func (c Config) BuildDir() string { return c.buildDir return c.buildDir } } // A DeviceConfig object represents the configuration for a particular device being built. For // A DeviceConfig object represents the configuration for a particular device // now there will only be one of these, but in the future there may be multiple devices being // being built. For now there will only be one of these, but in the future there // built // may be multiple devices being built. type DeviceConfig struct { type DeviceConfig struct { *deviceConfig *deviceConfig } } // VendorConfig represents the configuration for vendor-specific behavior. type VendorConfig soongconfig.SoongConfig type VendorConfig soongconfig.SoongConfig // Definition of general build configuration for soong_build. Some of these // configuration values are generated from soong_ui for soong_build, // communicated over JSON files like soong.config or soong.variables. type config struct { type config struct { // Options configurable with soong.confg FileConfigurableOptions FileConfigurableOptions // Options configurable with soong.variables productVariables productVariables productVariables productVariables // Only available on configs created by TestConfig // Only available on configs created by TestConfig TestProductVariables *productVariables TestProductVariables *productVariables // A specialized context object for Bazel/Soong mixed builds and migration // purposes. BazelContext BazelContext BazelContext BazelContext PrimaryBuilder string ConfigFileName string ConfigFileName string ProductVariablesFileName string ProductVariablesFileName string Loading @@ -97,8 +122,8 @@ type config struct { AndroidCommonTarget Target // the Target for common modules for the Android device AndroidCommonTarget Target // the Target for common modules for the Android device AndroidFirstDeviceTarget Target // the first Target for modules for the Android device AndroidFirstDeviceTarget Target // the first Target for modules for the Android device // multilibConflicts for an ArchType is true if there is earlier configured device architecture with the same // multilibConflicts for an ArchType is true if there is earlier configured // multilib value. // device architecture with the same multilib value. multilibConflicts map[ArchType]bool multilibConflicts map[ArchType]bool deviceConfig *deviceConfig deviceConfig *deviceConfig Loading Loading @@ -126,6 +151,8 @@ type config struct { // in tests when a path doesn't exist. // in tests when a path doesn't exist. testAllowNonExistentPaths bool testAllowNonExistentPaths bool // The list of files that when changed, must invalidate soong_build to // regenerate build.ninja. ninjaFileDepsSet sync.Map ninjaFileDepsSet sync.Map OncePer OncePer Loading @@ -149,7 +176,8 @@ func loadConfig(config *config) error { return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) } } // loads configuration options from a JSON file in the cwd. // loadFromConfigFile loads and decodes configuration options from a JSON file // in the current working directory. func loadFromConfigFile(configurable jsonConfigurable, filename string) error { func loadFromConfigFile(configurable jsonConfigurable, filename string) error { // Try to open the file // Try to open the file configFileReader, err := os.Open(filename) configFileReader, err := os.Open(filename) Loading Loading @@ -189,7 +217,7 @@ func saveToConfigFile(config jsonConfigurable, filename string) error { f, err := ioutil.TempFile(filepath.Dir(filename), "config") f, err := ioutil.TempFile(filepath.Dir(filename), "config") if err != nil { if err != nil { return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error()) return fmt.Errorf("cannot create empty config file %s: %s", filename, err.Error()) } } defer os.Remove(f.Name()) defer os.Remove(f.Name()) defer f.Close() defer f.Close() Loading Loading @@ -221,7 +249,7 @@ func NullConfig(buildDir string) Config { } } } } // TestConfig returns a Config object suitable for using for tests // TestConfig returns a Config object for testing. func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { envCopy := make(map[string]string) envCopy := make(map[string]string) for k, v := range env { for k, v := range env { Loading Loading @@ -266,6 +294,9 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string return Config{config} return Config{config} } } // TestArchConfigNativeBridge returns a Config object suitable for using // for tests that need to run the arch mutator for native bridge supported // archs. func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestArchConfig(buildDir, env, bp, fs) testConfig := TestArchConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading @@ -280,6 +311,8 @@ func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp strin return testConfig return testConfig } } // TestArchConfigFuchsia returns a Config object suitable for using for // tests that need to run the arch mutator for the Fuchsia arch. func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestConfig(buildDir, env, bp, fs) testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading @@ -296,7 +329,8 @@ func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs return testConfig return testConfig } } // TestConfig returns a Config object suitable for using for tests that need to run the arch mutator // TestArchConfig returns a Config object suitable for using for tests that // need to run the arch mutator. func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestConfig(buildDir, env, bp, fs) testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading Loading @@ -328,10 +362,10 @@ func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[st return testConfig return testConfig } } // Returns a config object which is "reset" for another bootstrap run. // ConfigForAdditionalRun is a config object which is "reset" for another // Only per-run data is reset. Data which needs to persist across multiple // bootstrap run. Only per-run data is reset. Data which needs to persist across // runs in the same program execution is carried over (such as Bazel context // multiple runs in the same program execution is carried over (such as Bazel // or environment deps). // context or environment deps). func ConfigForAdditionalRun(c Config) (Config, error) { func ConfigForAdditionalRun(c Config) (Config, error) { newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) if err != nil { if err != nil { Loading @@ -342,10 +376,10 @@ func ConfigForAdditionalRun(c Config) (Config, error) { return newConfig, nil return newConfig, nil } } // New creates a new Config object. The srcDir argument specifies the path to // NewConfig creates a new Config object. The srcDir argument specifies the path // the root source directory. It also loads the config file, if found. // to the root source directory. It also loads the config file, if found. func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { // Make a config with default options // Make a config with default options. config := &config{ config := &config{ ConfigFileName: filepath.Join(buildDir, configFileName), ConfigFileName: filepath.Join(buildDir, configFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), Loading Loading @@ -391,6 +425,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { config.inMake = true config.inMake = true } } // Sets up the map of target OSes to the finer grained compilation targets // that are configured from the product variables. targets, err := decodeTargetProductVariables(config) targets, err := decodeTargetProductVariables(config) if err != nil { if err != nil { return Config{}, err return Config{}, err Loading Loading @@ -424,9 +460,14 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { multilib[target.Arch.ArchType.Multilib] = true multilib[target.Arch.ArchType.Multilib] = true } } // Map of OS to compilation targets. config.Targets = targets config.Targets = targets // Compilation targets for host tools. config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] // Compilation targets for Android. if len(config.Targets[Android]) > 0 { if len(config.Targets[Android]) > 0 { config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] Loading @@ -441,13 +482,9 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { Bool(config.productVariables.ClangCoverage)) Bool(config.productVariables.ClangCoverage)) config.BazelContext, err = NewBazelContext(config) config.BazelContext, err = NewBazelContext(config) if err != nil { return Config{}, err } return Config{config}, nil } var TestConfigOsFs = map[string][]byte{} return Config{config}, err } // mockFileSystem replaces all reads with accesses to the provided map of // mockFileSystem replaces all reads with accesses to the provided map of // filenames to contents stored as a byte slice. // filenames to contents stored as a byte slice. Loading Loading @@ -483,12 +520,15 @@ func (c *config) StopBefore() bootstrap.StopBefore { return c.stopBefore return c.stopBefore } } // SetStopBefore configures soong_build to exit earlier at a specific point. func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { c.stopBefore = stopBefore c.stopBefore = stopBefore } } var _ bootstrap.ConfigStopBefore = (*config)(nil) var _ bootstrap.ConfigStopBefore = (*config)(nil) // BlueprintToolLocation returns the directory containing build system tools // from Blueprint, like soong_zip and merge_zips. func (c *config) BlueprintToolLocation() string { func (c *config) BlueprintToolLocation() string { return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") } } Loading Loading @@ -525,7 +565,7 @@ func (c *config) HostSystemTool(name string) string { return name return name } } // PrebuiltOS returns the name of the host OS used in prebuilts directories // PrebuiltOS returns the name of the host OS used in prebuilts directories. func (c *config) PrebuiltOS() string { func (c *config) PrebuiltOS() string { switch runtime.GOOS { switch runtime.GOOS { case "linux": case "linux": Loading @@ -542,10 +582,14 @@ func (c *config) GoRoot() string { return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) } } // PrebuiltBuildTool returns the path to a tool in the prebuilts directory containing // checked-in tools, like Kati, Ninja or Toybox, for the current host OS. func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) } } // CpPreserveSymlinksFlags returns the host-specific flag for the cp(1) command // to preserve symlinks. func (c *config) CpPreserveSymlinksFlags() string { func (c *config) CpPreserveSymlinksFlags() string { switch runtime.GOOS { switch runtime.GOOS { case "darwin": case "darwin": Loading Loading @@ -593,6 +637,8 @@ func (c *config) IsEnvFalse(key string) bool { return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" } } // EnvDeps returns the environment variables this build depends on. The first // call to this function blocks future reads from the environment. func (c *config) EnvDeps() map[string]string { func (c *config) EnvDeps() map[string]string { c.envLock.Lock() c.envLock.Lock() defer c.envLock.Unlock() defer c.envLock.Unlock() Loading @@ -608,11 +654,18 @@ func (c *config) BuildId() string { return String(c.productVariables.BuildId) return String(c.productVariables.BuildId) } } // BuildNumberFile returns the path to a text file containing metadata // representing the current build's number. // // Rules that want to reference the build number should read from this file // without depending on it. They will run whenever their other dependencies // require them to run and get the current build number. This ensures they don't // rebuild on every incremental build when the build number changes. func (c *config) BuildNumberFile(ctx PathContext) Path { func (c *config) BuildNumberFile(ctx PathContext) Path { return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) } } // DeviceName returns the name of the current device target // DeviceName returns the name of the current device target. // TODO: take an AndroidModuleContext to select the device name for multi-device builds // TODO: take an AndroidModuleContext to select the device name for multi-device builds func (c *config) DeviceName() string { func (c *config) DeviceName() string { return *c.productVariables.DeviceName return *c.productVariables.DeviceName Loading Loading @@ -684,10 +737,12 @@ func (c *config) AllSupportedApiLevels() []ApiLevel { return append(levels, c.PreviewApiLevels()...) return append(levels, c.PreviewApiLevels()...) } } // DefaultAppTargetSdk returns the API level that platform apps are targeting. // This converts a codename to the exact ApiLevel it represents. func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { if Bool(c.productVariables.Platform_sdk_final) { if Bool(c.productVariables.Platform_sdk_final) { return c.PlatformSdkVersion() return c.PlatformSdkVersion() } else { } codename := c.PlatformSdkCodename() codename := c.PlatformSdkCodename() if codename == "" { if codename == "" { return NoneApiLevel return NoneApiLevel Loading @@ -697,7 +752,6 @@ func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { } } return ApiLevelOrPanic(ctx, codename) return ApiLevelOrPanic(ctx, codename) } } } func (c *config) AppsDefaultVersionName() string { func (c *config) AppsDefaultVersionName() string { return String(c.productVariables.AppsDefaultVersionName) return String(c.productVariables.AppsDefaultVersionName) Loading Loading @@ -728,20 +782,18 @@ func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { defaultCert := String(c.productVariables.DefaultAppCertificate) defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { if defaultCert != "" { return PathForSource(ctx, filepath.Dir(defaultCert)) return PathForSource(ctx, filepath.Dir(defaultCert)) } else { return PathForSource(ctx, "build/make/target/product/security") } } return PathForSource(ctx, "build/make/target/product/security") } } func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { defaultCert := String(c.productVariables.DefaultAppCertificate) defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { if defaultCert != "" { return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") } else { } defaultDir := c.DefaultAppCertificateDir(ctx) defaultDir := c.DefaultAppCertificateDir(ctx) return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") } } } func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE Loading @@ -750,12 +802,14 @@ func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // When defaultCert is unset or is set to the testkeys path, use the APEX keys // When defaultCert is unset or is set to the testkeys path, use the APEX keys // that is under the module dir // that is under the module dir return pathForModuleSrc(ctx) return pathForModuleSrc(ctx) } else { } // If not, APEX keys are under the specified directory // If not, APEX keys are under the specified directory return PathForSource(ctx, filepath.Dir(defaultCert)) return PathForSource(ctx, filepath.Dir(defaultCert)) } } } // AllowMissingDependencies configures Blueprint/Soong to not fail when modules // are configured to depend on non-existent modules. Note that this does not // affect missing input dependencies at the Ninja level. func (c *config) AllowMissingDependencies() bool { func (c *config) AllowMissingDependencies() bool { return Bool(c.productVariables.Allow_missing_dependencies) return Bool(c.productVariables.Allow_missing_dependencies) } } Loading Loading @@ -825,9 +879,8 @@ func (c *config) SanitizeDeviceArch() []string { func (c *config) EnableCFI() bool { func (c *config) EnableCFI() bool { if c.productVariables.EnableCFI == nil { if c.productVariables.EnableCFI == nil { return true return true } else { return *c.productVariables.EnableCFI } } return *c.productVariables.EnableCFI } } func (c *config) DisableScudo() bool { func (c *config) DisableScudo() bool { Loading Loading @@ -872,11 +925,13 @@ func (c *config) RunErrorProne() bool { return c.IsEnvTrue("RUN_ERROR_PRONE") return c.IsEnvTrue("RUN_ERROR_PRONE") } } // XrefCorpusName returns the Kythe cross-reference corpus name. func (c *config) XrefCorpusName() string { func (c *config) XrefCorpusName() string { return c.Getenv("XREF_CORPUS") return c.Getenv("XREF_CORPUS") } } // Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'. // XrefCuEncoding returns the compilation unit encoding to use for Kythe code // xrefs. Can be 'json' (default), 'proto' or 'all'. func (c *config) XrefCuEncoding() string { func (c *config) XrefCuEncoding() string { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { return enc return enc Loading Loading @@ -911,6 +966,10 @@ func (c *config) ArtUseReadBarrier() bool { return Bool(c.productVariables.ArtUseReadBarrier) return Bool(c.productVariables.ArtUseReadBarrier) } } // Enforce Runtime Resource Overlays for a module. RROs supersede static RROs, // but some modules still depend on it. // // More info: https://source.android.com/devices/architecture/rros func (c *config) EnforceRROForModule(name string) bool { func (c *config) EnforceRROForModule(name string) bool { enforceList := c.productVariables.EnforceRROTargets enforceList := c.productVariables.EnforceRROTargets // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. Loading Loading @@ -957,6 +1016,9 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string { return c.productVariables.ModulesLoadedByPrivilegedModules return c.productVariables.ModulesLoadedByPrivilegedModules } } // DexpreoptGlobalConfigPath returns the path to the dexpreopt.config file in // the output directory, if it was created during the product configuration // phase by Kati. func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { if c.productVariables.DexpreoptGlobalConfig == nil { if c.productVariables.DexpreoptGlobalConfig == nil { return OptionalPathForPath(nil) return OptionalPathForPath(nil) Loading @@ -965,6 +1027,12 @@ func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig)) pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig)) } } // DexpreoptGlobalConfig returns the raw byte contents of the dexpreopt global // configuration. Since the configuration file was created by Kati during // product configuration (externally of soong_build), it's not tracked, so we // also manually add a Ninja file dependency on the configuration file to the // rule that creates the main build.ninja file. This ensures that build.ninja is // regenerated correctly if dexpreopt.config changes. func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { path := c.DexpreoptGlobalConfigPath(ctx) path := c.DexpreoptGlobalConfigPath(ctx) if !path.Valid() { if !path.Valid() { Loading Loading @@ -1323,26 +1391,31 @@ func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool { // - "system_ext:foo" // - "system_ext:foo" // // type ConfiguredJarList struct { type ConfiguredJarList struct { apexes []string // A list of apex components. // A list of apex components, which can be an apex name, jars []string // A list of jar components. // or special names like "platform" or "system_ext". apexes []string // A list of jar module name components. jars []string } } // The length of the list. // Len returns the length of the list of jars. func (l *ConfiguredJarList) Len() int { func (l *ConfiguredJarList) Len() int { return len(l.jars) return len(l.jars) } } // Jar component of idx-th pair on the list. // Jar returns the idx-th jar component of (apex, jar) pairs. func (l *ConfiguredJarList) Jar(idx int) string { func (l *ConfiguredJarList) Jar(idx int) string { return l.jars[idx] return l.jars[idx] } } // Apex component of idx-th pair on the list. // Apex returns the idx-th apex component of (apex, jar) pairs. func (l *ConfiguredJarList) Apex(idx int) string { func (l *ConfiguredJarList) Apex(idx int) string { return l.apexes[idx] return l.apexes[idx] } } // If the list contains a pair with the given jar. // ContainsJar returns true if the (apex, jar) pairs contains a pair with the // given jar module name. func (l *ConfiguredJarList) ContainsJar(jar string) bool { func (l *ConfiguredJarList) ContainsJar(jar string) bool { return InList(jar, l.jars) return InList(jar, l.jars) } } Loading @@ -1357,7 +1430,8 @@ func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool { return false return false } } // Index of the first pair with the given jar on the list, or -1 if none. // IndexOfJar returns the first pair with the given jar name on the list, or -1 // if not found. func (l *ConfiguredJarList) IndexOfJar(jar string) int { func (l *ConfiguredJarList) IndexOfJar(jar string) int { return IndexList(jar, l.jars) return IndexList(jar, l.jars) } } Loading Loading @@ -1385,7 +1459,7 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // Filter out sublist. // RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs. func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList { func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList { apexes := make([]string, 0, l.Len()) apexes := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) Loading @@ -1401,12 +1475,14 @@ func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // A copy of the list of strings containing jar components. // CopyOfJars returns a copy of the list of strings containing jar module name // components. func (l *ConfiguredJarList) CopyOfJars() []string { func (l *ConfiguredJarList) CopyOfJars() []string { return CopyOf(l.jars) return CopyOf(l.jars) } } // A copy of the list of strings with colon-separated (apex, jar) pairs. // CopyOfApexJarPairs returns a copy of the list of strings with colon-separated // (apex, jar) pairs. func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { pairs := make([]string, 0, l.Len()) pairs := make([]string, 0, l.Len()) Loading @@ -1418,7 +1494,7 @@ func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { return pairs return pairs } } // A list of build paths based on the given directory prefix. // BuildPaths returns a list of build paths based on the given directory prefix. func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths { func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths { paths := make(WritablePaths, l.Len()) paths := make(WritablePaths, l.Len()) for i, jar := range l.jars { for i, jar := range l.jars { Loading @@ -1427,7 +1503,8 @@ func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) Writable return paths return paths } } // Called when loading configuration from JSON into a configuration structure. // UnmarshalJSON converts JSON configuration from raw bytes into a // ConfiguredJarList structure. func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { // Try and unmarshal into a []string each item of which contains a pair // Try and unmarshal into a []string each item of which contains a pair // <apex>:<jar>. // <apex>:<jar>. Loading @@ -1447,16 +1524,19 @@ func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { return nil return nil } } // ModuleStem hardcodes the stem of framework-minus-apex to return "framework". // // TODO(b/139391334): hard coded until we find a good way to query the stem of a // module before any other mutators are run. func ModuleStem(module string) string { func ModuleStem(module string) string { // b/139391334: the stem of framework-minus-apex is framework. This is hard coded here until we // find a good way to query the stem of a module before any other mutators are run. if module == "framework-minus-apex" { if module == "framework-minus-apex" { return "framework" return "framework" } } return module return module } } // A list of on-device paths. // DevicePaths computes the on-device paths for the list of (apex, jar) pairs, // based on the operating system. func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string { func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string { paths := make([]string, l.Len()) paths := make([]string, l.Len()) for i, jar := range l.jars { for i, jar := range l.jars { Loading Loading @@ -1517,6 +1597,8 @@ func splitConfiguredJarPair(str string) (string, string, error) { } } } } // CreateTestConfiguredJarList is a function to create ConfiguredJarList for // tests. func CreateTestConfiguredJarList(list []string) ConfiguredJarList { func CreateTestConfiguredJarList(list []string) ConfiguredJarList { apexes, jars, err := splitListOfPairsIntoPairOfLists(list) apexes, jars, err := splitListOfPairsIntoPairOfLists(list) if err != nil { if err != nil { Loading @@ -1526,6 +1608,7 @@ func CreateTestConfiguredJarList(list []string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // EmptyConfiguredJarList returns an empty jar list. func EmptyConfiguredJarList() ConfiguredJarList { func EmptyConfiguredJarList() ConfiguredJarList { return ConfiguredJarList{} return ConfiguredJarList{} } } Loading @@ -1535,8 +1618,7 @@ var earlyBootJarsKey = NewOnceKey("earlyBootJars") func (c *config) BootJars() []string { func (c *config) BootJars() []string { return c.Once(earlyBootJarsKey, func() interface{} { return c.Once(earlyBootJarsKey, func() interface{} { list := c.productVariables.BootJars.CopyOfJars() list := c.productVariables.BootJars.CopyOfJars() list = append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return list }).([]string) }).([]string) } } Loading Loading
android/config.go +145 −63 Original line number Original line Diff line number Diff line Loading @@ -14,6 +14,9 @@ package android package android // This is the primary location to write and read all configuration values and // product variables necessary for soong_build's operation. import ( import ( "encoding/json" "encoding/json" "fmt" "fmt" Loading @@ -32,20 +35,31 @@ import ( "android/soong/android/soongconfig" "android/soong/android/soongconfig" ) ) // Bool re-exports proptools.Bool for the android package. var Bool = proptools.Bool var Bool = proptools.Bool // String re-exports proptools.String for the android package. var String = proptools.String var String = proptools.String // StringDefault re-exports proptools.StringDefault for the android package. var StringDefault = proptools.StringDefault var StringDefault = proptools.StringDefault // FutureApiLevelInt is a placeholder constant for unreleased API levels. const FutureApiLevelInt = 10000 const FutureApiLevelInt = 10000 // FutureApiLevel represents unreleased API levels. var FutureApiLevel = ApiLevel{ var FutureApiLevel = ApiLevel{ value: "current", value: "current", number: FutureApiLevelInt, number: FutureApiLevelInt, isPreview: true, isPreview: true, } } // The configuration file name // configFileName is the name the file containing FileConfigurableOptions from // soong_ui for the soong_build primary builder. const configFileName = "soong.config" const configFileName = "soong.config" // productVariablesFileName contain the product configuration variables from soong_ui for the // soong_build primary builder and Kati. const productVariablesFileName = "soong.variables" const productVariablesFileName = "soong.variables" // A FileConfigurableOptions contains options which can be configured by the // A FileConfigurableOptions contains options which can be configured by the Loading @@ -56,6 +70,8 @@ type FileConfigurableOptions struct { Host_bionic_arm64 *bool `json:",omitempty"` Host_bionic_arm64 *bool `json:",omitempty"` } } // SetDefaultConfig resets the receiving FileConfigurableOptions to default // values. func (f *FileConfigurableOptions) SetDefaultConfig() { func (f *FileConfigurableOptions) SetDefaultConfig() { *f = FileConfigurableOptions{} *f = FileConfigurableOptions{} } } Loading @@ -65,29 +81,38 @@ type Config struct { *config *config } } // BuildDir returns the build output directory for the configuration. func (c Config) BuildDir() string { func (c Config) BuildDir() string { return c.buildDir return c.buildDir } } // A DeviceConfig object represents the configuration for a particular device being built. For // A DeviceConfig object represents the configuration for a particular device // now there will only be one of these, but in the future there may be multiple devices being // being built. For now there will only be one of these, but in the future there // built // may be multiple devices being built. type DeviceConfig struct { type DeviceConfig struct { *deviceConfig *deviceConfig } } // VendorConfig represents the configuration for vendor-specific behavior. type VendorConfig soongconfig.SoongConfig type VendorConfig soongconfig.SoongConfig // Definition of general build configuration for soong_build. Some of these // configuration values are generated from soong_ui for soong_build, // communicated over JSON files like soong.config or soong.variables. type config struct { type config struct { // Options configurable with soong.confg FileConfigurableOptions FileConfigurableOptions // Options configurable with soong.variables productVariables productVariables productVariables productVariables // Only available on configs created by TestConfig // Only available on configs created by TestConfig TestProductVariables *productVariables TestProductVariables *productVariables // A specialized context object for Bazel/Soong mixed builds and migration // purposes. BazelContext BazelContext BazelContext BazelContext PrimaryBuilder string ConfigFileName string ConfigFileName string ProductVariablesFileName string ProductVariablesFileName string Loading @@ -97,8 +122,8 @@ type config struct { AndroidCommonTarget Target // the Target for common modules for the Android device AndroidCommonTarget Target // the Target for common modules for the Android device AndroidFirstDeviceTarget Target // the first Target for modules for the Android device AndroidFirstDeviceTarget Target // the first Target for modules for the Android device // multilibConflicts for an ArchType is true if there is earlier configured device architecture with the same // multilibConflicts for an ArchType is true if there is earlier configured // multilib value. // device architecture with the same multilib value. multilibConflicts map[ArchType]bool multilibConflicts map[ArchType]bool deviceConfig *deviceConfig deviceConfig *deviceConfig Loading Loading @@ -126,6 +151,8 @@ type config struct { // in tests when a path doesn't exist. // in tests when a path doesn't exist. testAllowNonExistentPaths bool testAllowNonExistentPaths bool // The list of files that when changed, must invalidate soong_build to // regenerate build.ninja. ninjaFileDepsSet sync.Map ninjaFileDepsSet sync.Map OncePer OncePer Loading @@ -149,7 +176,8 @@ func loadConfig(config *config) error { return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) return loadFromConfigFile(&config.productVariables, absolutePath(config.ProductVariablesFileName)) } } // loads configuration options from a JSON file in the cwd. // loadFromConfigFile loads and decodes configuration options from a JSON file // in the current working directory. func loadFromConfigFile(configurable jsonConfigurable, filename string) error { func loadFromConfigFile(configurable jsonConfigurable, filename string) error { // Try to open the file // Try to open the file configFileReader, err := os.Open(filename) configFileReader, err := os.Open(filename) Loading Loading @@ -189,7 +217,7 @@ func saveToConfigFile(config jsonConfigurable, filename string) error { f, err := ioutil.TempFile(filepath.Dir(filename), "config") f, err := ioutil.TempFile(filepath.Dir(filename), "config") if err != nil { if err != nil { return fmt.Errorf("cannot create empty config file %s: %s\n", filename, err.Error()) return fmt.Errorf("cannot create empty config file %s: %s", filename, err.Error()) } } defer os.Remove(f.Name()) defer os.Remove(f.Name()) defer f.Close() defer f.Close() Loading Loading @@ -221,7 +249,7 @@ func NullConfig(buildDir string) Config { } } } } // TestConfig returns a Config object suitable for using for tests // TestConfig returns a Config object for testing. func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { envCopy := make(map[string]string) envCopy := make(map[string]string) for k, v := range env { for k, v := range env { Loading Loading @@ -266,6 +294,9 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string return Config{config} return Config{config} } } // TestArchConfigNativeBridge returns a Config object suitable for using // for tests that need to run the arch mutator for native bridge supported // archs. func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestArchConfig(buildDir, env, bp, fs) testConfig := TestArchConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading @@ -280,6 +311,8 @@ func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp strin return testConfig return testConfig } } // TestArchConfigFuchsia returns a Config object suitable for using for // tests that need to run the arch mutator for the Fuchsia arch. func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestConfig(buildDir, env, bp, fs) testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading @@ -296,7 +329,8 @@ func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs return testConfig return testConfig } } // TestConfig returns a Config object suitable for using for tests that need to run the arch mutator // TestArchConfig returns a Config object suitable for using for tests that // need to run the arch mutator. func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) Config { testConfig := TestConfig(buildDir, env, bp, fs) testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config config := testConfig.config Loading Loading @@ -328,10 +362,10 @@ func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[st return testConfig return testConfig } } // Returns a config object which is "reset" for another bootstrap run. // ConfigForAdditionalRun is a config object which is "reset" for another // Only per-run data is reset. Data which needs to persist across multiple // bootstrap run. Only per-run data is reset. Data which needs to persist across // runs in the same program execution is carried over (such as Bazel context // multiple runs in the same program execution is carried over (such as Bazel // or environment deps). // context or environment deps). func ConfigForAdditionalRun(c Config) (Config, error) { func ConfigForAdditionalRun(c Config) (Config, error) { newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) if err != nil { if err != nil { Loading @@ -342,10 +376,10 @@ func ConfigForAdditionalRun(c Config) (Config, error) { return newConfig, nil return newConfig, nil } } // New creates a new Config object. The srcDir argument specifies the path to // NewConfig creates a new Config object. The srcDir argument specifies the path // the root source directory. It also loads the config file, if found. // to the root source directory. It also loads the config file, if found. func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { // Make a config with default options // Make a config with default options. config := &config{ config := &config{ ConfigFileName: filepath.Join(buildDir, configFileName), ConfigFileName: filepath.Join(buildDir, configFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), Loading Loading @@ -391,6 +425,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { config.inMake = true config.inMake = true } } // Sets up the map of target OSes to the finer grained compilation targets // that are configured from the product variables. targets, err := decodeTargetProductVariables(config) targets, err := decodeTargetProductVariables(config) if err != nil { if err != nil { return Config{}, err return Config{}, err Loading Loading @@ -424,9 +460,14 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { multilib[target.Arch.ArchType.Multilib] = true multilib[target.Arch.ArchType.Multilib] = true } } // Map of OS to compilation targets. config.Targets = targets config.Targets = targets // Compilation targets for host tools. config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] // Compilation targets for Android. if len(config.Targets[Android]) > 0 { if len(config.Targets[Android]) > 0 { config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] Loading @@ -441,13 +482,9 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { Bool(config.productVariables.ClangCoverage)) Bool(config.productVariables.ClangCoverage)) config.BazelContext, err = NewBazelContext(config) config.BazelContext, err = NewBazelContext(config) if err != nil { return Config{}, err } return Config{config}, nil } var TestConfigOsFs = map[string][]byte{} return Config{config}, err } // mockFileSystem replaces all reads with accesses to the provided map of // mockFileSystem replaces all reads with accesses to the provided map of // filenames to contents stored as a byte slice. // filenames to contents stored as a byte slice. Loading Loading @@ -483,12 +520,15 @@ func (c *config) StopBefore() bootstrap.StopBefore { return c.stopBefore return c.stopBefore } } // SetStopBefore configures soong_build to exit earlier at a specific point. func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { c.stopBefore = stopBefore c.stopBefore = stopBefore } } var _ bootstrap.ConfigStopBefore = (*config)(nil) var _ bootstrap.ConfigStopBefore = (*config)(nil) // BlueprintToolLocation returns the directory containing build system tools // from Blueprint, like soong_zip and merge_zips. func (c *config) BlueprintToolLocation() string { func (c *config) BlueprintToolLocation() string { return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") } } Loading Loading @@ -525,7 +565,7 @@ func (c *config) HostSystemTool(name string) string { return name return name } } // PrebuiltOS returns the name of the host OS used in prebuilts directories // PrebuiltOS returns the name of the host OS used in prebuilts directories. func (c *config) PrebuiltOS() string { func (c *config) PrebuiltOS() string { switch runtime.GOOS { switch runtime.GOOS { case "linux": case "linux": Loading @@ -542,10 +582,14 @@ func (c *config) GoRoot() string { return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) return fmt.Sprintf("%s/prebuilts/go/%s", c.srcDir, c.PrebuiltOS()) } } // PrebuiltBuildTool returns the path to a tool in the prebuilts directory containing // checked-in tools, like Kati, Ninja or Toybox, for the current host OS. func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { func (c *config) PrebuiltBuildTool(ctx PathContext, tool string) Path { return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) return PathForSource(ctx, "prebuilts/build-tools", c.PrebuiltOS(), "bin", tool) } } // CpPreserveSymlinksFlags returns the host-specific flag for the cp(1) command // to preserve symlinks. func (c *config) CpPreserveSymlinksFlags() string { func (c *config) CpPreserveSymlinksFlags() string { switch runtime.GOOS { switch runtime.GOOS { case "darwin": case "darwin": Loading Loading @@ -593,6 +637,8 @@ func (c *config) IsEnvFalse(key string) bool { return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" } } // EnvDeps returns the environment variables this build depends on. The first // call to this function blocks future reads from the environment. func (c *config) EnvDeps() map[string]string { func (c *config) EnvDeps() map[string]string { c.envLock.Lock() c.envLock.Lock() defer c.envLock.Unlock() defer c.envLock.Unlock() Loading @@ -608,11 +654,18 @@ func (c *config) BuildId() string { return String(c.productVariables.BuildId) return String(c.productVariables.BuildId) } } // BuildNumberFile returns the path to a text file containing metadata // representing the current build's number. // // Rules that want to reference the build number should read from this file // without depending on it. They will run whenever their other dependencies // require them to run and get the current build number. This ensures they don't // rebuild on every incremental build when the build number changes. func (c *config) BuildNumberFile(ctx PathContext) Path { func (c *config) BuildNumberFile(ctx PathContext) Path { return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) return PathForOutput(ctx, String(c.productVariables.BuildNumberFile)) } } // DeviceName returns the name of the current device target // DeviceName returns the name of the current device target. // TODO: take an AndroidModuleContext to select the device name for multi-device builds // TODO: take an AndroidModuleContext to select the device name for multi-device builds func (c *config) DeviceName() string { func (c *config) DeviceName() string { return *c.productVariables.DeviceName return *c.productVariables.DeviceName Loading Loading @@ -684,10 +737,12 @@ func (c *config) AllSupportedApiLevels() []ApiLevel { return append(levels, c.PreviewApiLevels()...) return append(levels, c.PreviewApiLevels()...) } } // DefaultAppTargetSdk returns the API level that platform apps are targeting. // This converts a codename to the exact ApiLevel it represents. func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { if Bool(c.productVariables.Platform_sdk_final) { if Bool(c.productVariables.Platform_sdk_final) { return c.PlatformSdkVersion() return c.PlatformSdkVersion() } else { } codename := c.PlatformSdkCodename() codename := c.PlatformSdkCodename() if codename == "" { if codename == "" { return NoneApiLevel return NoneApiLevel Loading @@ -697,7 +752,6 @@ func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { } } return ApiLevelOrPanic(ctx, codename) return ApiLevelOrPanic(ctx, codename) } } } func (c *config) AppsDefaultVersionName() string { func (c *config) AppsDefaultVersionName() string { return String(c.productVariables.AppsDefaultVersionName) return String(c.productVariables.AppsDefaultVersionName) Loading Loading @@ -728,20 +782,18 @@ func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { defaultCert := String(c.productVariables.DefaultAppCertificate) defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { if defaultCert != "" { return PathForSource(ctx, filepath.Dir(defaultCert)) return PathForSource(ctx, filepath.Dir(defaultCert)) } else { return PathForSource(ctx, "build/make/target/product/security") } } return PathForSource(ctx, "build/make/target/product/security") } } func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { func (c *config) DefaultAppCertificate(ctx PathContext) (pem, key SourcePath) { defaultCert := String(c.productVariables.DefaultAppCertificate) defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { if defaultCert != "" { return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") } else { } defaultDir := c.DefaultAppCertificateDir(ctx) defaultDir := c.DefaultAppCertificateDir(ctx) return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") } } } func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE Loading @@ -750,12 +802,14 @@ func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // When defaultCert is unset or is set to the testkeys path, use the APEX keys // When defaultCert is unset or is set to the testkeys path, use the APEX keys // that is under the module dir // that is under the module dir return pathForModuleSrc(ctx) return pathForModuleSrc(ctx) } else { } // If not, APEX keys are under the specified directory // If not, APEX keys are under the specified directory return PathForSource(ctx, filepath.Dir(defaultCert)) return PathForSource(ctx, filepath.Dir(defaultCert)) } } } // AllowMissingDependencies configures Blueprint/Soong to not fail when modules // are configured to depend on non-existent modules. Note that this does not // affect missing input dependencies at the Ninja level. func (c *config) AllowMissingDependencies() bool { func (c *config) AllowMissingDependencies() bool { return Bool(c.productVariables.Allow_missing_dependencies) return Bool(c.productVariables.Allow_missing_dependencies) } } Loading Loading @@ -825,9 +879,8 @@ func (c *config) SanitizeDeviceArch() []string { func (c *config) EnableCFI() bool { func (c *config) EnableCFI() bool { if c.productVariables.EnableCFI == nil { if c.productVariables.EnableCFI == nil { return true return true } else { return *c.productVariables.EnableCFI } } return *c.productVariables.EnableCFI } } func (c *config) DisableScudo() bool { func (c *config) DisableScudo() bool { Loading Loading @@ -872,11 +925,13 @@ func (c *config) RunErrorProne() bool { return c.IsEnvTrue("RUN_ERROR_PRONE") return c.IsEnvTrue("RUN_ERROR_PRONE") } } // XrefCorpusName returns the Kythe cross-reference corpus name. func (c *config) XrefCorpusName() string { func (c *config) XrefCorpusName() string { return c.Getenv("XREF_CORPUS") return c.Getenv("XREF_CORPUS") } } // Returns Compilation Unit encoding to use. Can be 'json' (default), 'proto' or 'all'. // XrefCuEncoding returns the compilation unit encoding to use for Kythe code // xrefs. Can be 'json' (default), 'proto' or 'all'. func (c *config) XrefCuEncoding() string { func (c *config) XrefCuEncoding() string { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { return enc return enc Loading Loading @@ -911,6 +966,10 @@ func (c *config) ArtUseReadBarrier() bool { return Bool(c.productVariables.ArtUseReadBarrier) return Bool(c.productVariables.ArtUseReadBarrier) } } // Enforce Runtime Resource Overlays for a module. RROs supersede static RROs, // but some modules still depend on it. // // More info: https://source.android.com/devices/architecture/rros func (c *config) EnforceRROForModule(name string) bool { func (c *config) EnforceRROForModule(name string) bool { enforceList := c.productVariables.EnforceRROTargets enforceList := c.productVariables.EnforceRROTargets // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. Loading Loading @@ -957,6 +1016,9 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string { return c.productVariables.ModulesLoadedByPrivilegedModules return c.productVariables.ModulesLoadedByPrivilegedModules } } // DexpreoptGlobalConfigPath returns the path to the dexpreopt.config file in // the output directory, if it was created during the product configuration // phase by Kati. func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { if c.productVariables.DexpreoptGlobalConfig == nil { if c.productVariables.DexpreoptGlobalConfig == nil { return OptionalPathForPath(nil) return OptionalPathForPath(nil) Loading @@ -965,6 +1027,12 @@ func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig)) pathForBuildToolDep(ctx, *c.productVariables.DexpreoptGlobalConfig)) } } // DexpreoptGlobalConfig returns the raw byte contents of the dexpreopt global // configuration. Since the configuration file was created by Kati during // product configuration (externally of soong_build), it's not tracked, so we // also manually add a Ninja file dependency on the configuration file to the // rule that creates the main build.ninja file. This ensures that build.ninja is // regenerated correctly if dexpreopt.config changes. func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { path := c.DexpreoptGlobalConfigPath(ctx) path := c.DexpreoptGlobalConfigPath(ctx) if !path.Valid() { if !path.Valid() { Loading Loading @@ -1323,26 +1391,31 @@ func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool { // - "system_ext:foo" // - "system_ext:foo" // // type ConfiguredJarList struct { type ConfiguredJarList struct { apexes []string // A list of apex components. // A list of apex components, which can be an apex name, jars []string // A list of jar components. // or special names like "platform" or "system_ext". apexes []string // A list of jar module name components. jars []string } } // The length of the list. // Len returns the length of the list of jars. func (l *ConfiguredJarList) Len() int { func (l *ConfiguredJarList) Len() int { return len(l.jars) return len(l.jars) } } // Jar component of idx-th pair on the list. // Jar returns the idx-th jar component of (apex, jar) pairs. func (l *ConfiguredJarList) Jar(idx int) string { func (l *ConfiguredJarList) Jar(idx int) string { return l.jars[idx] return l.jars[idx] } } // Apex component of idx-th pair on the list. // Apex returns the idx-th apex component of (apex, jar) pairs. func (l *ConfiguredJarList) Apex(idx int) string { func (l *ConfiguredJarList) Apex(idx int) string { return l.apexes[idx] return l.apexes[idx] } } // If the list contains a pair with the given jar. // ContainsJar returns true if the (apex, jar) pairs contains a pair with the // given jar module name. func (l *ConfiguredJarList) ContainsJar(jar string) bool { func (l *ConfiguredJarList) ContainsJar(jar string) bool { return InList(jar, l.jars) return InList(jar, l.jars) } } Loading @@ -1357,7 +1430,8 @@ func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool { return false return false } } // Index of the first pair with the given jar on the list, or -1 if none. // IndexOfJar returns the first pair with the given jar name on the list, or -1 // if not found. func (l *ConfiguredJarList) IndexOfJar(jar string) int { func (l *ConfiguredJarList) IndexOfJar(jar string) int { return IndexList(jar, l.jars) return IndexList(jar, l.jars) } } Loading Loading @@ -1385,7 +1459,7 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // Filter out sublist. // RemoveList filters out a list of (apex, jar) pairs from the receiving list of pairs. func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList { func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList { apexes := make([]string, 0, l.Len()) apexes := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) Loading @@ -1401,12 +1475,14 @@ func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // A copy of the list of strings containing jar components. // CopyOfJars returns a copy of the list of strings containing jar module name // components. func (l *ConfiguredJarList) CopyOfJars() []string { func (l *ConfiguredJarList) CopyOfJars() []string { return CopyOf(l.jars) return CopyOf(l.jars) } } // A copy of the list of strings with colon-separated (apex, jar) pairs. // CopyOfApexJarPairs returns a copy of the list of strings with colon-separated // (apex, jar) pairs. func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { pairs := make([]string, 0, l.Len()) pairs := make([]string, 0, l.Len()) Loading @@ -1418,7 +1494,7 @@ func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { return pairs return pairs } } // A list of build paths based on the given directory prefix. // BuildPaths returns a list of build paths based on the given directory prefix. func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths { func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) WritablePaths { paths := make(WritablePaths, l.Len()) paths := make(WritablePaths, l.Len()) for i, jar := range l.jars { for i, jar := range l.jars { Loading @@ -1427,7 +1503,8 @@ func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) Writable return paths return paths } } // Called when loading configuration from JSON into a configuration structure. // UnmarshalJSON converts JSON configuration from raw bytes into a // ConfiguredJarList structure. func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { // Try and unmarshal into a []string each item of which contains a pair // Try and unmarshal into a []string each item of which contains a pair // <apex>:<jar>. // <apex>:<jar>. Loading @@ -1447,16 +1524,19 @@ func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { return nil return nil } } // ModuleStem hardcodes the stem of framework-minus-apex to return "framework". // // TODO(b/139391334): hard coded until we find a good way to query the stem of a // module before any other mutators are run. func ModuleStem(module string) string { func ModuleStem(module string) string { // b/139391334: the stem of framework-minus-apex is framework. This is hard coded here until we // find a good way to query the stem of a module before any other mutators are run. if module == "framework-minus-apex" { if module == "framework-minus-apex" { return "framework" return "framework" } } return module return module } } // A list of on-device paths. // DevicePaths computes the on-device paths for the list of (apex, jar) pairs, // based on the operating system. func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string { func (l *ConfiguredJarList) DevicePaths(cfg Config, ostype OsType) []string { paths := make([]string, l.Len()) paths := make([]string, l.Len()) for i, jar := range l.jars { for i, jar := range l.jars { Loading Loading @@ -1517,6 +1597,8 @@ func splitConfiguredJarPair(str string) (string, string, error) { } } } } // CreateTestConfiguredJarList is a function to create ConfiguredJarList for // tests. func CreateTestConfiguredJarList(list []string) ConfiguredJarList { func CreateTestConfiguredJarList(list []string) ConfiguredJarList { apexes, jars, err := splitListOfPairsIntoPairOfLists(list) apexes, jars, err := splitListOfPairsIntoPairOfLists(list) if err != nil { if err != nil { Loading @@ -1526,6 +1608,7 @@ func CreateTestConfiguredJarList(list []string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} return ConfiguredJarList{apexes, jars} } } // EmptyConfiguredJarList returns an empty jar list. func EmptyConfiguredJarList() ConfiguredJarList { func EmptyConfiguredJarList() ConfiguredJarList { return ConfiguredJarList{} return ConfiguredJarList{} } } Loading @@ -1535,8 +1618,7 @@ var earlyBootJarsKey = NewOnceKey("earlyBootJars") func (c *config) BootJars() []string { func (c *config) BootJars() []string { return c.Once(earlyBootJarsKey, func() interface{} { return c.Once(earlyBootJarsKey, func() interface{} { list := c.productVariables.BootJars.CopyOfJars() list := c.productVariables.BootJars.CopyOfJars() list = append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return list }).([]string) }).([]string) } } Loading