|
@@ -19,7 +19,6 @@ package android
|
|
|
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
- "errors"
|
|
|
"fmt"
|
|
|
"io/ioutil"
|
|
|
"os"
|
|
@@ -341,123 +340,6 @@ func NullConfig(outDir, soongOutDir string) Config {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-// 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 {
|
|
|
- envCopy[k] = v
|
|
|
- }
|
|
|
-
|
|
|
- // Copy the real PATH value to the test environment, it's needed by
|
|
|
- // NonHermeticHostSystemTool() used in x86_darwin_host.go
|
|
|
- envCopy["PATH"] = os.Getenv("PATH")
|
|
|
-
|
|
|
- config := &config{
|
|
|
- productVariables: productVariables{
|
|
|
- DeviceName: stringPtr("test_device"),
|
|
|
- DeviceProduct: stringPtr("test_product"),
|
|
|
- Platform_sdk_version: intPtr(30),
|
|
|
- Platform_sdk_codename: stringPtr("S"),
|
|
|
- Platform_base_sdk_extension_version: intPtr(1),
|
|
|
- Platform_version_active_codenames: []string{"S", "Tiramisu"},
|
|
|
- DeviceSystemSdkVersions: []string{"14", "15"},
|
|
|
- Platform_systemsdk_versions: []string{"29", "30"},
|
|
|
- AAPTConfig: []string{"normal", "large", "xlarge", "hdpi", "xhdpi", "xxhdpi"},
|
|
|
- AAPTPreferredConfig: stringPtr("xhdpi"),
|
|
|
- AAPTCharacteristics: stringPtr("nosdcard"),
|
|
|
- AAPTPrebuiltDPI: []string{"xhdpi", "xxhdpi"},
|
|
|
- UncompressPrivAppDex: boolPtr(true),
|
|
|
- ShippingApiLevel: stringPtr("30"),
|
|
|
- },
|
|
|
-
|
|
|
- outDir: buildDir,
|
|
|
- soongOutDir: filepath.Join(buildDir, "soong"),
|
|
|
- captureBuild: true,
|
|
|
- env: envCopy,
|
|
|
-
|
|
|
- // Set testAllowNonExistentPaths so that test contexts don't need to specify every path
|
|
|
- // passed to PathForSource or PathForModuleSrc.
|
|
|
- TestAllowNonExistentPaths: true,
|
|
|
-
|
|
|
- BazelContext: noopBazelContext{},
|
|
|
- mixedBuildDisabledModules: make(map[string]struct{}),
|
|
|
- mixedBuildEnabledModules: make(map[string]struct{}),
|
|
|
- }
|
|
|
- config.deviceConfig = &deviceConfig{
|
|
|
- config: config,
|
|
|
- }
|
|
|
- config.TestProductVariables = &config.productVariables
|
|
|
-
|
|
|
- config.mockFileSystem(bp, fs)
|
|
|
-
|
|
|
- determineBuildOS(config)
|
|
|
-
|
|
|
- return Config{config}
|
|
|
-}
|
|
|
-
|
|
|
-func modifyTestConfigToSupportArchMutator(testConfig Config) {
|
|
|
- config := testConfig.config
|
|
|
-
|
|
|
- config.Targets = map[OsType][]Target{
|
|
|
- Android: []Target{
|
|
|
- {Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridgeDisabled, "", "", false},
|
|
|
- {Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Abi: []string{"armeabi-v7a"}}, NativeBridgeDisabled, "", "", false},
|
|
|
- },
|
|
|
- config.BuildOS: []Target{
|
|
|
- {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
|
|
|
- {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
|
|
|
- },
|
|
|
- }
|
|
|
-
|
|
|
- if runtime.GOOS == "darwin" {
|
|
|
- config.Targets[config.BuildOS] = config.Targets[config.BuildOS][:1]
|
|
|
- }
|
|
|
-
|
|
|
- config.BuildOSTarget = config.Targets[config.BuildOS][0]
|
|
|
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
|
|
|
- config.AndroidCommonTarget = getCommonTargets(config.Targets[Android])[0]
|
|
|
- config.AndroidFirstDeviceTarget = FirstTarget(config.Targets[Android], "lib64", "lib32")[0]
|
|
|
- config.TestProductVariables.DeviceArch = proptools.StringPtr("arm64")
|
|
|
- config.TestProductVariables.DeviceArchVariant = proptools.StringPtr("armv8-a")
|
|
|
- config.TestProductVariables.DeviceSecondaryArch = proptools.StringPtr("arm")
|
|
|
- config.TestProductVariables.DeviceSecondaryArchVariant = proptools.StringPtr("armv7-a-neon")
|
|
|
-}
|
|
|
-
|
|
|
-func modifyTestConfigForMusl(config Config) {
|
|
|
- delete(config.Targets, config.BuildOS)
|
|
|
- config.productVariables.HostMusl = boolPtr(true)
|
|
|
- determineBuildOS(config.config)
|
|
|
- config.Targets[config.BuildOS] = []Target{
|
|
|
- {config.BuildOS, Arch{ArchType: X86_64}, NativeBridgeDisabled, "", "", false},
|
|
|
- {config.BuildOS, Arch{ArchType: X86}, NativeBridgeDisabled, "", "", false},
|
|
|
- }
|
|
|
-
|
|
|
- config.BuildOSTarget = config.Targets[config.BuildOS][0]
|
|
|
- config.BuildOSCommonTarget = getCommonTargets(config.Targets[config.BuildOS])[0]
|
|
|
-}
|
|
|
-
|
|
|
-// 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)
|
|
|
- modifyTestConfigToSupportArchMutator(testConfig)
|
|
|
- return testConfig
|
|
|
-}
|
|
|
-
|
|
|
-// 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.moduleListFile, c.runGoTests, c.outDir, c.soongOutDir, c.env)
|
|
|
- if err != nil {
|
|
|
- return Config{}, err
|
|
|
- }
|
|
|
- newConfig.BazelContext = c.BazelContext
|
|
|
- newConfig.envDeps = c.envDeps
|
|
|
- return newConfig, nil
|
|
|
-}
|
|
|
-
|
|
|
// 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(moduleListFile string, runGoTests bool, outDir, soongOutDir string, availableEnv map[string]string) (Config, error) {
|
|
@@ -740,7 +622,8 @@ func (c *config) DeviceName() string {
|
|
|
// these per device type.
|
|
|
//
|
|
|
// NOTE: Do not base conditional logic on this value. It may break product
|
|
|
-// inheritance.
|
|
|
+//
|
|
|
+// inheritance.
|
|
|
func (c *config) DeviceProduct() string {
|
|
|
return *c.productVariables.DeviceProduct
|
|
|
}
|
|
@@ -1729,316 +1612,6 @@ func (c *config) IgnorePrefer32OnDevice() bool {
|
|
|
return c.productVariables.IgnorePrefer32OnDevice
|
|
|
}
|
|
|
|
|
|
-// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
|
|
|
-// Such lists are used in the build system for things like bootclasspath jars or system server jars.
|
|
|
-// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
|
|
|
-// module name. The pairs come from Make product variables as a list of colon-separated strings.
|
|
|
-//
|
|
|
-// Examples:
|
|
|
-// - "com.android.art:core-oj"
|
|
|
-// - "platform:framework"
|
|
|
-// - "system_ext:foo"
|
|
|
-//
|
|
|
-type ConfiguredJarList struct {
|
|
|
- // 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
|
|
|
-}
|
|
|
-
|
|
|
-// Len returns the length of the list of jars.
|
|
|
-func (l *ConfiguredJarList) Len() int {
|
|
|
- return len(l.jars)
|
|
|
-}
|
|
|
-
|
|
|
-// Jar returns the idx-th jar component of (apex, jar) pairs.
|
|
|
-func (l *ConfiguredJarList) Jar(idx int) string {
|
|
|
- return l.jars[idx]
|
|
|
-}
|
|
|
-
|
|
|
-// Apex returns the idx-th apex component of (apex, jar) pairs.
|
|
|
-func (l *ConfiguredJarList) Apex(idx int) string {
|
|
|
- return l.apexes[idx]
|
|
|
-}
|
|
|
-
|
|
|
-// 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)
|
|
|
-}
|
|
|
-
|
|
|
-// If the list contains the given (apex, jar) pair.
|
|
|
-func (l *ConfiguredJarList) containsApexJarPair(apex, jar string) bool {
|
|
|
- for i := 0; i < l.Len(); i++ {
|
|
|
- if apex == l.apexes[i] && jar == l.jars[i] {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
-// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
|
|
|
-// an empty string if not found.
|
|
|
-func (l *ConfiguredJarList) ApexOfJar(jar string) string {
|
|
|
- if idx := IndexList(jar, l.jars); idx != -1 {
|
|
|
- return l.Apex(IndexList(jar, l.jars))
|
|
|
- }
|
|
|
- return ""
|
|
|
-}
|
|
|
-
|
|
|
-// 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)
|
|
|
-}
|
|
|
-
|
|
|
-func copyAndAppend(list []string, item string) []string {
|
|
|
- // Create the result list to be 1 longer than the input.
|
|
|
- result := make([]string, len(list)+1)
|
|
|
-
|
|
|
- // Copy the whole input list into the result.
|
|
|
- count := copy(result, list)
|
|
|
-
|
|
|
- // Insert the extra item at the end.
|
|
|
- result[count] = item
|
|
|
-
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-// Append an (apex, jar) pair to the list.
|
|
|
-func (l *ConfiguredJarList) Append(apex string, jar string) ConfiguredJarList {
|
|
|
- // Create a copy of the backing arrays before appending to avoid sharing backing
|
|
|
- // arrays that are mutated across instances.
|
|
|
- apexes := copyAndAppend(l.apexes, apex)
|
|
|
- jars := copyAndAppend(l.jars, jar)
|
|
|
-
|
|
|
- return ConfiguredJarList{apexes, jars}
|
|
|
-}
|
|
|
-
|
|
|
-// Append a list of (apex, jar) pairs to the list.
|
|
|
-func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
|
|
|
- apexes := make([]string, 0, l.Len()+other.Len())
|
|
|
- jars := make([]string, 0, l.Len()+other.Len())
|
|
|
-
|
|
|
- apexes = append(apexes, l.apexes...)
|
|
|
- jars = append(jars, l.jars...)
|
|
|
-
|
|
|
- apexes = append(apexes, other.apexes...)
|
|
|
- jars = append(jars, other.jars...)
|
|
|
-
|
|
|
- return ConfiguredJarList{apexes, jars}
|
|
|
-}
|
|
|
-
|
|
|
-// 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())
|
|
|
-
|
|
|
- for i, jar := range l.jars {
|
|
|
- apex := l.apexes[i]
|
|
|
- if !list.containsApexJarPair(apex, jar) {
|
|
|
- apexes = append(apexes, apex)
|
|
|
- jars = append(jars, jar)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return ConfiguredJarList{apexes, jars}
|
|
|
-}
|
|
|
-
|
|
|
-// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
|
|
|
-// and any remaining jars that are not on this list.
|
|
|
-func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
|
|
|
- var apexes []string
|
|
|
- var jars []string
|
|
|
-
|
|
|
- for i, jar := range l.jars {
|
|
|
- if InList(jar, jarsToKeep) {
|
|
|
- apexes = append(apexes, l.apexes[i])
|
|
|
- jars = append(jars, jar)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
|
|
|
-}
|
|
|
-
|
|
|
-// CopyOfJars returns a copy of the list of strings containing jar module name
|
|
|
-// components.
|
|
|
-func (l *ConfiguredJarList) CopyOfJars() []string {
|
|
|
- return CopyOf(l.jars)
|
|
|
-}
|
|
|
-
|
|
|
-// 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())
|
|
|
-
|
|
|
- for i, jar := range l.jars {
|
|
|
- apex := l.apexes[i]
|
|
|
- pairs = append(pairs, apex+":"+jar)
|
|
|
- }
|
|
|
-
|
|
|
- return pairs
|
|
|
-}
|
|
|
-
|
|
|
-// 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 {
|
|
|
- paths[i] = dir.Join(ctx, ModuleStem(jar)+".jar")
|
|
|
- }
|
|
|
- return paths
|
|
|
-}
|
|
|
-
|
|
|
-// BuildPathsByModule returns a map from module name to build paths based on the given directory
|
|
|
-// prefix.
|
|
|
-func (l *ConfiguredJarList) BuildPathsByModule(ctx PathContext, dir OutputPath) map[string]WritablePath {
|
|
|
- paths := map[string]WritablePath{}
|
|
|
- for _, jar := range l.jars {
|
|
|
- paths[jar] = dir.Join(ctx, ModuleStem(jar)+".jar")
|
|
|
- }
|
|
|
- return paths
|
|
|
-}
|
|
|
-
|
|
|
-// 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>.
|
|
|
- var list []string
|
|
|
- err := json.Unmarshal(b, &list)
|
|
|
- if err != nil {
|
|
|
- // Did not work so return
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- apexes, jars, err := splitListOfPairsIntoPairOfLists(list)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- l.apexes = apexes
|
|
|
- l.jars = jars
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ConfiguredJarList) MarshalJSON() ([]byte, error) {
|
|
|
- if len(l.apexes) != len(l.jars) {
|
|
|
- return nil, errors.New(fmt.Sprintf("Inconsistent ConfiguredJarList: apexes: %q, jars: %q", l.apexes, l.jars))
|
|
|
- }
|
|
|
-
|
|
|
- list := make([]string, 0, len(l.apexes))
|
|
|
-
|
|
|
- for i := 0; i < len(l.apexes); i++ {
|
|
|
- list = append(list, l.apexes[i]+":"+l.jars[i])
|
|
|
- }
|
|
|
-
|
|
|
- return json.Marshal(list)
|
|
|
-}
|
|
|
-
|
|
|
-// 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 {
|
|
|
- if module == "framework-minus-apex" {
|
|
|
- return "framework"
|
|
|
- }
|
|
|
- return module
|
|
|
-}
|
|
|
-
|
|
|
-// 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 {
|
|
|
- apex := l.apexes[i]
|
|
|
- name := ModuleStem(jar) + ".jar"
|
|
|
-
|
|
|
- var subdir string
|
|
|
- if apex == "platform" {
|
|
|
- subdir = "system/framework"
|
|
|
- } else if apex == "system_ext" {
|
|
|
- subdir = "system_ext/framework"
|
|
|
- } else {
|
|
|
- subdir = filepath.Join("apex", apex, "javalib")
|
|
|
- }
|
|
|
-
|
|
|
- if ostype.Class == Host {
|
|
|
- paths[i] = filepath.Join(cfg.Getenv("OUT_DIR"), "host", cfg.PrebuiltOS(), subdir, name)
|
|
|
- } else {
|
|
|
- paths[i] = filepath.Join("/", subdir, name)
|
|
|
- }
|
|
|
- }
|
|
|
- return paths
|
|
|
-}
|
|
|
-
|
|
|
-func (l *ConfiguredJarList) String() string {
|
|
|
- var pairs []string
|
|
|
- for i := 0; i < l.Len(); i++ {
|
|
|
- pairs = append(pairs, l.apexes[i]+":"+l.jars[i])
|
|
|
- }
|
|
|
- return strings.Join(pairs, ",")
|
|
|
-}
|
|
|
-
|
|
|
-func splitListOfPairsIntoPairOfLists(list []string) ([]string, []string, error) {
|
|
|
- // Now we need to populate this list by splitting each item in the slice of
|
|
|
- // pairs and appending them to the appropriate list of apexes or jars.
|
|
|
- apexes := make([]string, len(list))
|
|
|
- jars := make([]string, len(list))
|
|
|
-
|
|
|
- for i, apexjar := range list {
|
|
|
- apex, jar, err := splitConfiguredJarPair(apexjar)
|
|
|
- if err != nil {
|
|
|
- return nil, nil, err
|
|
|
- }
|
|
|
- apexes[i] = apex
|
|
|
- jars[i] = jar
|
|
|
- }
|
|
|
-
|
|
|
- return apexes, jars, nil
|
|
|
-}
|
|
|
-
|
|
|
-// Expected format for apexJarValue = <apex name>:<jar name>
|
|
|
-func splitConfiguredJarPair(str string) (string, string, error) {
|
|
|
- pair := strings.SplitN(str, ":", 2)
|
|
|
- if len(pair) == 2 {
|
|
|
- apex := pair[0]
|
|
|
- jar := pair[1]
|
|
|
- if apex == "" {
|
|
|
- return apex, jar, fmt.Errorf("invalid apex '%s' in <apex>:<jar> pair '%s', expected format: <apex>:<jar>", apex, str)
|
|
|
- }
|
|
|
- return apex, jar, nil
|
|
|
- } else {
|
|
|
- return "error-apex", "error-jar", fmt.Errorf("malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// CreateTestConfiguredJarList is a function to create ConfiguredJarList for tests.
|
|
|
-func CreateTestConfiguredJarList(list []string) ConfiguredJarList {
|
|
|
- // Create the ConfiguredJarList in as similar way as it is created at runtime by marshalling to
|
|
|
- // a json list of strings and then unmarshalling into a ConfiguredJarList instance.
|
|
|
- b, err := json.Marshal(list)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- var jarList ConfiguredJarList
|
|
|
- err = json.Unmarshal(b, &jarList)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- return jarList
|
|
|
-}
|
|
|
-
|
|
|
-// EmptyConfiguredJarList returns an empty jar list.
|
|
|
-func EmptyConfiguredJarList() ConfiguredJarList {
|
|
|
- return ConfiguredJarList{}
|
|
|
-}
|
|
|
-
|
|
|
-var earlyBootJarsKey = NewOnceKey("earlyBootJars")
|
|
|
-
|
|
|
func (c *config) BootJars() []string {
|
|
|
return c.Once(earlyBootJarsKey, func() interface{} {
|
|
|
list := c.productVariables.BootJars.CopyOfJars()
|