Loading android/config.go +145 −63 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ package android // This is the primary location to write and read all configuration values and // product variables necessary for soong_build's operation. import ( "encoding/json" "fmt" Loading @@ -32,20 +35,31 @@ import ( "android/soong/android/soongconfig" ) // Bool re-exports proptools.Bool for the android package. var Bool = proptools.Bool // String re-exports proptools.String for the android package. var String = proptools.String // StringDefault re-exports proptools.StringDefault for the android package. var StringDefault = proptools.StringDefault // FutureApiLevelInt is a placeholder constant for unreleased API levels. const FutureApiLevelInt = 10000 // FutureApiLevel represents unreleased API levels. var FutureApiLevel = ApiLevel{ value: "current", number: FutureApiLevelInt, 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" // productVariablesFileName contain the product configuration variables from soong_ui for the // soong_build primary builder and Kati. const productVariablesFileName = "soong.variables" // A FileConfigurableOptions contains options which can be configured by the Loading @@ -56,6 +70,8 @@ type FileConfigurableOptions struct { Host_bionic_arm64 *bool `json:",omitempty"` } // SetDefaultConfig resets the receiving FileConfigurableOptions to default // values. func (f *FileConfigurableOptions) SetDefaultConfig() { *f = FileConfigurableOptions{} } Loading @@ -65,29 +81,38 @@ type Config struct { *config } // BuildDir returns the build output directory for the configuration. func (c Config) BuildDir() string { return c.buildDir } // A DeviceConfig object represents the configuration for a particular device being built. For // now there will only be one of these, but in the future there may be multiple devices being // built // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. type DeviceConfig struct { *deviceConfig } // VendorConfig represents the configuration for vendor-specific behavior. 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 { // Options configurable with soong.confg FileConfigurableOptions // Options configurable with soong.variables productVariables productVariables // Only available on configs created by TestConfig TestProductVariables *productVariables // A specialized context object for Bazel/Soong mixed builds and migration // purposes. BazelContext BazelContext PrimaryBuilder string ConfigFileName string ProductVariablesFileName string Loading @@ -97,8 +122,8 @@ type config struct { AndroidCommonTarget Target // the Target for common 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 // multilib value. // multilibConflicts for an ArchType is true if there is earlier configured // device architecture with the same multilib value. multilibConflicts map[ArchType]bool deviceConfig *deviceConfig Loading Loading @@ -128,6 +153,8 @@ type config struct { // in tests when a path doesn't exist. testAllowNonExistentPaths bool // The list of files that when changed, must invalidate soong_build to // regenerate build.ninja. ninjaFileDepsSet sync.Map OncePer Loading @@ -151,7 +178,8 @@ func loadConfig(config *config) error { 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 { // Try to open the file configFileReader, err := os.Open(filename) Loading Loading @@ -191,7 +219,7 @@ func saveToConfigFile(config jsonConfigurable, filename string) error { f, err := ioutil.TempFile(filepath.Dir(filename), "config") 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 f.Close() Loading Loading @@ -223,7 +251,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 { envCopy := make(map[string]string) for k, v := range env { Loading Loading @@ -269,6 +297,9 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string 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 { testConfig := TestArchConfig(buildDir, env, bp, fs) config := testConfig.config Loading @@ -283,6 +314,8 @@ func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp strin 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 { testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config Loading @@ -299,7 +332,8 @@ func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs 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 { testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config Loading Loading @@ -331,10 +365,10 @@ func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[st return testConfig } // Returns a config object which is "reset" for another bootstrap run. // Only per-run data is reset. Data which needs to persist across multiple // runs in the same program execution is carried over (such as Bazel context // or environment deps). // ConfigForAdditionalRun is a config object which is "reset" for another // bootstrap run. Only per-run data is reset. Data which needs to persist across // multiple runs in the same program execution is carried over (such as Bazel // context or environment deps). func ConfigForAdditionalRun(c Config) (Config, error) { newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) if err != nil { Loading @@ -345,10 +379,10 @@ func ConfigForAdditionalRun(c Config) (Config, error) { return newConfig, nil } // New creates a new Config object. The srcDir argument specifies the path to // the root source directory. It also loads the config file, if found. // NewConfig creates a new Config object. The srcDir argument specifies the path // to the root source directory. It also loads the config file, if found. func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { // Make a config with default options // Make a config with default options. config := &config{ ConfigFileName: filepath.Join(buildDir, configFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), Loading Loading @@ -394,6 +428,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { config.katiEnabled = 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) if err != nil { return Config{}, err Loading Loading @@ -427,9 +463,14 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { multilib[target.Arch.ArchType.Multilib] = true } // Map of OS to compilation targets. config.Targets = targets // Compilation targets for host tools. config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] // Compilation targets for Android. if len(config.Targets[Android]) > 0 { config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] Loading @@ -444,13 +485,9 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { Bool(config.productVariables.ClangCoverage)) 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 // filenames to contents stored as a byte slice. Loading Loading @@ -486,12 +523,15 @@ func (c *config) StopBefore() bootstrap.StopBefore { return c.stopBefore } // SetStopBefore configures soong_build to exit earlier at a specific point. func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { c.stopBefore = stopBefore } 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 { return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") } Loading Loading @@ -534,7 +574,7 @@ func (c *config) NonHermeticHostSystemTool(name string) string { "for the full list of allowed host tools on your system.", 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 { switch runtime.GOOS { case "linux": Loading @@ -551,10 +591,14 @@ func (c *config) GoRoot() string { 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 { 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 { switch runtime.GOOS { case "darwin": Loading Loading @@ -602,6 +646,8 @@ func (c *config) IsEnvFalse(key string) bool { 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 { c.envLock.Lock() defer c.envLock.Unlock() Loading @@ -617,11 +663,18 @@ func (c *config) BuildId() string { 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 { 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 func (c *config) DeviceName() string { return *c.productVariables.DeviceName Loading Loading @@ -693,10 +746,12 @@ func (c *config) AllSupportedApiLevels() []ApiLevel { 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 { if Bool(c.productVariables.Platform_sdk_final) { return c.PlatformSdkVersion() } else { } codename := c.PlatformSdkCodename() if codename == "" { return NoneApiLevel Loading @@ -706,7 +761,6 @@ func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { } return ApiLevelOrPanic(ctx, codename) } } func (c *config) AppsDefaultVersionName() string { return String(c.productVariables.AppsDefaultVersionName) Loading Loading @@ -737,20 +791,18 @@ func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { defaultCert := String(c.productVariables.DefaultAppCertificate) if 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) { defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") } else { } defaultDir := c.DefaultAppCertificateDir(ctx) return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") } } func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE Loading @@ -759,12 +811,14 @@ func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // When defaultCert is unset or is set to the testkeys path, use the APEX keys // that is under the module dir return pathForModuleSrc(ctx) } else { } // If not, APEX keys are under the specified directory 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 { return Bool(c.productVariables.Allow_missing_dependencies) } Loading Loading @@ -834,9 +888,8 @@ func (c *config) SanitizeDeviceArch() []string { func (c *config) EnableCFI() bool { if c.productVariables.EnableCFI == nil { return true } else { return *c.productVariables.EnableCFI } return *c.productVariables.EnableCFI } func (c *config) DisableScudo() bool { Loading Loading @@ -881,11 +934,13 @@ func (c *config) RunErrorProne() bool { return c.IsEnvTrue("RUN_ERROR_PRONE") } // XrefCorpusName returns the Kythe cross-reference corpus name. func (c *config) XrefCorpusName() string { 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 { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { return enc Loading Loading @@ -920,6 +975,10 @@ func (c *config) ArtUseReadBarrier() bool { 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 { enforceList := c.productVariables.EnforceRROTargets // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. Loading Loading @@ -966,6 +1025,9 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string { 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 { if c.productVariables.DexpreoptGlobalConfig == nil { return OptionalPathForPath(nil) Loading @@ -974,6 +1036,12 @@ func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { 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) { path := c.DexpreoptGlobalConfigPath(ctx) if !path.Valid() { Loading Loading @@ -1332,26 +1400,31 @@ func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool { // - "system_ext:foo" // type ConfiguredJarList struct { apexes []string // A list of apex components. jars []string // A list of jar components. // A list of apex components, which can be an apex name, // 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 { 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 { 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 { 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 { return InList(jar, l.jars) } Loading @@ -1366,7 +1439,8 @@ func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool { 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 { return IndexList(jar, l.jars) } Loading Loading @@ -1394,7 +1468,7 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList { 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 { apexes := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) Loading @@ -1410,12 +1484,14 @@ func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList 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 { 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 { pairs := make([]string, 0, l.Len()) Loading @@ -1427,7 +1503,7 @@ func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { 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 { paths := make(WritablePaths, l.Len()) for i, jar := range l.jars { Loading @@ -1436,7 +1512,8 @@ func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) Writable 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 { // Try and unmarshal into a []string each item of which contains a pair // <apex>:<jar>. Loading @@ -1456,16 +1533,19 @@ func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { 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 { // 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" { return "framework" } 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 { paths := make([]string, l.Len()) for i, jar := range l.jars { Loading Loading @@ -1526,6 +1606,8 @@ func splitConfiguredJarPair(str string) (string, string, error) { } } // CreateTestConfiguredJarList is a function to create ConfiguredJarList for // tests. func CreateTestConfiguredJarList(list []string) ConfiguredJarList { apexes, jars, err := splitListOfPairsIntoPairOfLists(list) if err != nil { Loading @@ -1535,6 +1617,7 @@ func CreateTestConfiguredJarList(list []string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} } // EmptyConfiguredJarList returns an empty jar list. func EmptyConfiguredJarList() ConfiguredJarList { return ConfiguredJarList{} } Loading @@ -1544,8 +1627,7 @@ var earlyBootJarsKey = NewOnceKey("earlyBootJars") func (c *config) BootJars() []string { return c.Once(earlyBootJarsKey, func() interface{} { list := c.productVariables.BootJars.CopyOfJars() list = append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return list return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) }).([]string) } Loading Loading
android/config.go +145 −63 Original line number Diff line number Diff line Loading @@ -14,6 +14,9 @@ package android // This is the primary location to write and read all configuration values and // product variables necessary for soong_build's operation. import ( "encoding/json" "fmt" Loading @@ -32,20 +35,31 @@ import ( "android/soong/android/soongconfig" ) // Bool re-exports proptools.Bool for the android package. var Bool = proptools.Bool // String re-exports proptools.String for the android package. var String = proptools.String // StringDefault re-exports proptools.StringDefault for the android package. var StringDefault = proptools.StringDefault // FutureApiLevelInt is a placeholder constant for unreleased API levels. const FutureApiLevelInt = 10000 // FutureApiLevel represents unreleased API levels. var FutureApiLevel = ApiLevel{ value: "current", number: FutureApiLevelInt, 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" // productVariablesFileName contain the product configuration variables from soong_ui for the // soong_build primary builder and Kati. const productVariablesFileName = "soong.variables" // A FileConfigurableOptions contains options which can be configured by the Loading @@ -56,6 +70,8 @@ type FileConfigurableOptions struct { Host_bionic_arm64 *bool `json:",omitempty"` } // SetDefaultConfig resets the receiving FileConfigurableOptions to default // values. func (f *FileConfigurableOptions) SetDefaultConfig() { *f = FileConfigurableOptions{} } Loading @@ -65,29 +81,38 @@ type Config struct { *config } // BuildDir returns the build output directory for the configuration. func (c Config) BuildDir() string { return c.buildDir } // A DeviceConfig object represents the configuration for a particular device being built. For // now there will only be one of these, but in the future there may be multiple devices being // built // A DeviceConfig object represents the configuration for a particular device // being built. For now there will only be one of these, but in the future there // may be multiple devices being built. type DeviceConfig struct { *deviceConfig } // VendorConfig represents the configuration for vendor-specific behavior. 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 { // Options configurable with soong.confg FileConfigurableOptions // Options configurable with soong.variables productVariables productVariables // Only available on configs created by TestConfig TestProductVariables *productVariables // A specialized context object for Bazel/Soong mixed builds and migration // purposes. BazelContext BazelContext PrimaryBuilder string ConfigFileName string ProductVariablesFileName string Loading @@ -97,8 +122,8 @@ type config struct { AndroidCommonTarget Target // the Target for common 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 // multilib value. // multilibConflicts for an ArchType is true if there is earlier configured // device architecture with the same multilib value. multilibConflicts map[ArchType]bool deviceConfig *deviceConfig Loading Loading @@ -128,6 +153,8 @@ type config struct { // in tests when a path doesn't exist. testAllowNonExistentPaths bool // The list of files that when changed, must invalidate soong_build to // regenerate build.ninja. ninjaFileDepsSet sync.Map OncePer Loading @@ -151,7 +178,8 @@ func loadConfig(config *config) error { 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 { // Try to open the file configFileReader, err := os.Open(filename) Loading Loading @@ -191,7 +219,7 @@ func saveToConfigFile(config jsonConfigurable, filename string) error { f, err := ioutil.TempFile(filepath.Dir(filename), "config") 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 f.Close() Loading Loading @@ -223,7 +251,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 { envCopy := make(map[string]string) for k, v := range env { Loading Loading @@ -269,6 +297,9 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string 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 { testConfig := TestArchConfig(buildDir, env, bp, fs) config := testConfig.config Loading @@ -283,6 +314,8 @@ func TestArchConfigNativeBridge(buildDir string, env map[string]string, bp strin 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 { testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config Loading @@ -299,7 +332,8 @@ func TestArchConfigFuchsia(buildDir string, env map[string]string, bp string, fs 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 { testConfig := TestConfig(buildDir, env, bp, fs) config := testConfig.config Loading Loading @@ -331,10 +365,10 @@ func TestArchConfig(buildDir string, env map[string]string, bp string, fs map[st return testConfig } // Returns a config object which is "reset" for another bootstrap run. // Only per-run data is reset. Data which needs to persist across multiple // runs in the same program execution is carried over (such as Bazel context // or environment deps). // ConfigForAdditionalRun is a config object which is "reset" for another // bootstrap run. Only per-run data is reset. Data which needs to persist across // multiple runs in the same program execution is carried over (such as Bazel // context or environment deps). func ConfigForAdditionalRun(c Config) (Config, error) { newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile) if err != nil { Loading @@ -345,10 +379,10 @@ func ConfigForAdditionalRun(c Config) (Config, error) { return newConfig, nil } // New creates a new Config object. The srcDir argument specifies the path to // the root source directory. It also loads the config file, if found. // NewConfig creates a new Config object. The srcDir argument specifies the path // to the root source directory. It also loads the config file, if found. func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { // Make a config with default options // Make a config with default options. config := &config{ ConfigFileName: filepath.Join(buildDir, configFileName), ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName), Loading Loading @@ -394,6 +428,8 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { config.katiEnabled = 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) if err != nil { return Config{}, err Loading Loading @@ -427,9 +463,14 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { multilib[target.Arch.ArchType.Multilib] = true } // Map of OS to compilation targets. config.Targets = targets // Compilation targets for host tools. config.BuildOSTarget = config.Targets[BuildOs][0] config.BuildOSCommonTarget = getCommonTargets(config.Targets[BuildOs])[0] // Compilation targets for Android. if len(config.Targets[Android]) > 0 { config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0] config.AndroidFirstDeviceTarget = firstTarget(config.Targets[Android], "lib64", "lib32")[0] Loading @@ -444,13 +485,9 @@ func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) { Bool(config.productVariables.ClangCoverage)) 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 // filenames to contents stored as a byte slice. Loading Loading @@ -486,12 +523,15 @@ func (c *config) StopBefore() bootstrap.StopBefore { return c.stopBefore } // SetStopBefore configures soong_build to exit earlier at a specific point. func (c *config) SetStopBefore(stopBefore bootstrap.StopBefore) { c.stopBefore = stopBefore } 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 { return filepath.Join(c.buildDir, "host", c.PrebuiltOS(), "bin") } Loading Loading @@ -534,7 +574,7 @@ func (c *config) NonHermeticHostSystemTool(name string) string { "for the full list of allowed host tools on your system.", 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 { switch runtime.GOOS { case "linux": Loading @@ -551,10 +591,14 @@ func (c *config) GoRoot() string { 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 { 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 { switch runtime.GOOS { case "darwin": Loading Loading @@ -602,6 +646,8 @@ func (c *config) IsEnvFalse(key string) bool { 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 { c.envLock.Lock() defer c.envLock.Unlock() Loading @@ -617,11 +663,18 @@ func (c *config) BuildId() string { 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 { 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 func (c *config) DeviceName() string { return *c.productVariables.DeviceName Loading Loading @@ -693,10 +746,12 @@ func (c *config) AllSupportedApiLevels() []ApiLevel { 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 { if Bool(c.productVariables.Platform_sdk_final) { return c.PlatformSdkVersion() } else { } codename := c.PlatformSdkCodename() if codename == "" { return NoneApiLevel Loading @@ -706,7 +761,6 @@ func (c *config) DefaultAppTargetSdk(ctx EarlyModuleContext) ApiLevel { } return ApiLevelOrPanic(ctx, codename) } } func (c *config) AppsDefaultVersionName() string { return String(c.productVariables.AppsDefaultVersionName) Loading Loading @@ -737,20 +791,18 @@ func (c *config) DefaultAppCertificateDir(ctx PathContext) SourcePath { defaultCert := String(c.productVariables.DefaultAppCertificate) if 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) { defaultCert := String(c.productVariables.DefaultAppCertificate) if defaultCert != "" { return PathForSource(ctx, defaultCert+".x509.pem"), PathForSource(ctx, defaultCert+".pk8") } else { } defaultDir := c.DefaultAppCertificateDir(ctx) return defaultDir.Join(ctx, "testkey.x509.pem"), defaultDir.Join(ctx, "testkey.pk8") } } func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // TODO(b/121224311): define another variable such as TARGET_APEX_KEY_OVERRIDE Loading @@ -759,12 +811,14 @@ func (c *config) ApexKeyDir(ctx ModuleContext) SourcePath { // When defaultCert is unset or is set to the testkeys path, use the APEX keys // that is under the module dir return pathForModuleSrc(ctx) } else { } // If not, APEX keys are under the specified directory 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 { return Bool(c.productVariables.Allow_missing_dependencies) } Loading Loading @@ -834,9 +888,8 @@ func (c *config) SanitizeDeviceArch() []string { func (c *config) EnableCFI() bool { if c.productVariables.EnableCFI == nil { return true } else { return *c.productVariables.EnableCFI } return *c.productVariables.EnableCFI } func (c *config) DisableScudo() bool { Loading Loading @@ -881,11 +934,13 @@ func (c *config) RunErrorProne() bool { return c.IsEnvTrue("RUN_ERROR_PRONE") } // XrefCorpusName returns the Kythe cross-reference corpus name. func (c *config) XrefCorpusName() string { 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 { if enc := c.Getenv("KYTHE_KZIP_ENCODING"); enc != "" { return enc Loading Loading @@ -920,6 +975,10 @@ func (c *config) ArtUseReadBarrier() bool { 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 { enforceList := c.productVariables.EnforceRROTargets // TODO(b/150820813) Some modules depend on static overlay, remove this after eliminating the dependency. Loading Loading @@ -966,6 +1025,9 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string { 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 { if c.productVariables.DexpreoptGlobalConfig == nil { return OptionalPathForPath(nil) Loading @@ -974,6 +1036,12 @@ func (c *config) DexpreoptGlobalConfigPath(ctx PathContext) OptionalPath { 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) { path := c.DexpreoptGlobalConfigPath(ctx) if !path.Valid() { Loading Loading @@ -1332,26 +1400,31 @@ func (c *deviceConfig) BoardMoveRecoveryResourcesToVendorBoot() bool { // - "system_ext:foo" // type ConfiguredJarList struct { apexes []string // A list of apex components. jars []string // A list of jar components. // A list of apex components, which can be an apex name, // 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 { 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 { 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 { 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 { return InList(jar, l.jars) } Loading @@ -1366,7 +1439,8 @@ func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool { 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 { return IndexList(jar, l.jars) } Loading Loading @@ -1394,7 +1468,7 @@ func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList { 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 { apexes := make([]string, 0, l.Len()) jars := make([]string, 0, l.Len()) Loading @@ -1410,12 +1484,14 @@ func (l *ConfiguredJarList) RemoveList(list ConfiguredJarList) ConfiguredJarList 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 { 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 { pairs := make([]string, 0, l.Len()) Loading @@ -1427,7 +1503,7 @@ func (l *ConfiguredJarList) CopyOfApexJarPairs() []string { 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 { paths := make(WritablePaths, l.Len()) for i, jar := range l.jars { Loading @@ -1436,7 +1512,8 @@ func (l *ConfiguredJarList) BuildPaths(ctx PathContext, dir OutputPath) Writable 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 { // Try and unmarshal into a []string each item of which contains a pair // <apex>:<jar>. Loading @@ -1456,16 +1533,19 @@ func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { 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 { // 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" { return "framework" } 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 { paths := make([]string, l.Len()) for i, jar := range l.jars { Loading Loading @@ -1526,6 +1606,8 @@ func splitConfiguredJarPair(str string) (string, string, error) { } } // CreateTestConfiguredJarList is a function to create ConfiguredJarList for // tests. func CreateTestConfiguredJarList(list []string) ConfiguredJarList { apexes, jars, err := splitListOfPairsIntoPairOfLists(list) if err != nil { Loading @@ -1535,6 +1617,7 @@ func CreateTestConfiguredJarList(list []string) ConfiguredJarList { return ConfiguredJarList{apexes, jars} } // EmptyConfiguredJarList returns an empty jar list. func EmptyConfiguredJarList() ConfiguredJarList { return ConfiguredJarList{} } Loading @@ -1544,8 +1627,7 @@ var earlyBootJarsKey = NewOnceKey("earlyBootJars") func (c *config) BootJars() []string { return c.Once(earlyBootJarsKey, func() interface{} { list := c.productVariables.BootJars.CopyOfJars() list = append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) return list return append(list, c.productVariables.UpdatableBootJars.CopyOfJars()...) }).([]string) } Loading