diff options
-rw-r--r-- | android/config.go | 15 | ||||
-rw-r--r-- | android/config_test.go | 32 | ||||
-rw-r--r-- | android/test_asserts.go | 9 | ||||
-rw-r--r-- | android/variable.go | 3 | ||||
-rw-r--r-- | apex/apex.go | 45 | ||||
-rwxr-xr-x | bootstrap_test.sh | 59 | ||||
-rw-r--r-- | filesystem/Android.bp | 1 | ||||
-rw-r--r-- | filesystem/bootimg.go | 48 | ||||
-rw-r--r-- | filesystem/filesystem.go | 17 | ||||
-rw-r--r-- | filesystem/logical_partition.go | 4 | ||||
-rw-r--r-- | filesystem/vbmeta.go | 265 | ||||
-rw-r--r-- | java/Android.bp | 1 | ||||
-rw-r--r-- | java/app_test.go | 180 | ||||
-rw-r--r-- | java/java_test.go | 5 | ||||
-rw-r--r-- | java/platform_compat_config.go | 96 | ||||
-rw-r--r-- | java/platform_compat_config_test.go | 53 | ||||
-rw-r--r-- | python/Android.bp | 1 | ||||
-rw-r--r-- | python/binary.go | 6 | ||||
-rw-r--r-- | python/library.go | 8 | ||||
-rw-r--r-- | python/python.go | 6 | ||||
-rw-r--r-- | python/python_test.go | 18 | ||||
-rw-r--r-- | python/test.go | 8 | ||||
-rw-r--r-- | python/testing.go | 24 | ||||
-rw-r--r-- | rust/bindgen.go | 2 |
24 files changed, 670 insertions, 236 deletions
diff --git a/android/config.go b/android/config.go index d7c82a099..c880aebc2 100644 --- a/android/config.go +++ b/android/config.go @@ -19,6 +19,7 @@ package android import ( "encoding/json" + "errors" "fmt" "io/ioutil" "os" @@ -1618,6 +1619,20 @@ func (l *ConfiguredJarList) UnmarshalJSON(b []byte) error { 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 diff --git a/android/config_test.go b/android/config_test.go index a11115d9d..9df5288a1 100644 --- a/android/config_test.go +++ b/android/config_test.go @@ -16,6 +16,7 @@ package android import ( "fmt" + "path/filepath" "reflect" "strings" "testing" @@ -87,6 +88,37 @@ func TestMissingVendorConfig(t *testing.T) { } } +func verifyProductVariableMarshaling(t *testing.T, v productVariables) { + dir := t.TempDir() + path := filepath.Join(dir, "test.variables") + err := saveToConfigFile(&v, path) + if err != nil { + t.Errorf("Couldn't save default product config: %q", err) + } + + var v2 productVariables + err = loadFromConfigFile(&v2, path) + if err != nil { + t.Errorf("Couldn't load default product config: %q", err) + } +} +func TestDefaultProductVariableMarshaling(t *testing.T) { + v := productVariables{} + v.SetDefaultConfig() + verifyProductVariableMarshaling(t, v) +} + +func TestBootJarsMarshaling(t *testing.T) { + v := productVariables{} + v.SetDefaultConfig() + v.BootJars = ConfiguredJarList{ + apexes: []string{"apex"}, + jars: []string{"jar"}, + } + + verifyProductVariableMarshaling(t, v) +} + func assertStringEquals(t *testing.T, expected, actual string) { if actual != expected { t.Errorf("expected %q found %q", expected, actual) diff --git a/android/test_asserts.go b/android/test_asserts.go index 977e1af9f..4b5e9343e 100644 --- a/android/test_asserts.go +++ b/android/test_asserts.go @@ -40,6 +40,15 @@ func AssertBoolEquals(t *testing.T, message string, expected bool, actual bool) } } +// AssertIntEquals checks if the expected and actual values are equal and if they are not then it +// reports an error prefixed with the supplied message and including a reason for why it failed. +func AssertIntEquals(t *testing.T, message string, expected int, actual int) { + t.Helper() + if actual != expected { + t.Errorf("%s: expected %d, actual %d", message, expected, actual) + } +} + // AssertStringEquals checks if the expected and actual values are equal and if they are not then // it reports an error prefixed with the supplied message and including a reason for why it failed. func AssertStringEquals(t *testing.T, message string, expected string, actual string) { diff --git a/android/variable.go b/android/variable.go index a5e9ab4dd..08fa12ca4 100644 --- a/android/variable.go +++ b/android/variable.go @@ -426,6 +426,9 @@ func (v *productVariables) SetDefaultConfig() { Malloc_zero_contents: boolPtr(true), Malloc_pattern_fill_contents: boolPtr(false), Safestack: boolPtr(false), + + BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}}, + UpdatableBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}}, } if runtime.GOOS == "linux" { diff --git a/apex/apex.go b/apex/apex.go index 3db20f465..119345aa4 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -549,24 +549,35 @@ type dependencyTag struct { // Determines if the dependent will be part of the APEX payload. Can be false for the // dependencies to the signing key module, etc. payload bool + + // True if the dependent can only be a source module, false if a prebuilt module is a suitable + // replacement. This is needed because some prebuilt modules do not provide all the information + // needed by the apex. + sourceOnly bool +} + +func (d dependencyTag) ReplaceSourceWithPrebuilt() bool { + return !d.sourceOnly } +var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{} + var ( - androidAppTag = dependencyTag{name: "androidApp", payload: true} - bpfTag = dependencyTag{name: "bpf", payload: true} - certificateTag = dependencyTag{name: "certificate"} - executableTag = dependencyTag{name: "executable", payload: true} - fsTag = dependencyTag{name: "filesystem", payload: true} - bootImageTag = dependencyTag{name: "bootImage", payload: true} - compatConfigsTag = dependencyTag{name: "compatConfig", payload: true} - javaLibTag = dependencyTag{name: "javaLib", payload: true} - jniLibTag = dependencyTag{name: "jniLib", payload: true} - keyTag = dependencyTag{name: "key"} - prebuiltTag = dependencyTag{name: "prebuilt", payload: true} - rroTag = dependencyTag{name: "rro", payload: true} - sharedLibTag = dependencyTag{name: "sharedLib", payload: true} - testForTag = dependencyTag{name: "test for"} - testTag = dependencyTag{name: "test", payload: true} + androidAppTag = dependencyTag{name: "androidApp", payload: true} + bpfTag = dependencyTag{name: "bpf", payload: true} + certificateTag = dependencyTag{name: "certificate"} + executableTag = dependencyTag{name: "executable", payload: true} + fsTag = dependencyTag{name: "filesystem", payload: true} + bootImageTag = dependencyTag{name: "bootImage", payload: true} + compatConfigTag = dependencyTag{name: "compatConfig", payload: true} + javaLibTag = dependencyTag{name: "javaLib", payload: true} + jniLibTag = dependencyTag{name: "jniLib", payload: true} + keyTag = dependencyTag{name: "key"} + prebuiltTag = dependencyTag{name: "prebuilt", payload: true} + rroTag = dependencyTag{name: "rro", payload: true} + sharedLibTag = dependencyTag{name: "sharedLib", payload: true} + testForTag = dependencyTag{name: "test for"} + testTag = dependencyTag{name: "test", payload: true} ) // TODO(jiyong): shorten this function signature @@ -741,7 +752,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...) ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...) ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...) - ctx.AddFarVariationDependencies(commonVariation, compatConfigsTag, a.properties.Compat_configs...) + ctx.AddFarVariationDependencies(commonVariation, compatConfigTag, a.properties.Compat_configs...) if a.artApex { // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library. @@ -1743,7 +1754,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } else { ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName) } - case compatConfigsTag: + case compatConfigTag: if compatConfig, ok := child.(java.PlatformCompatConfigIntf); ok { filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, compatConfig, depName)) } else { diff --git a/bootstrap_test.sh b/bootstrap_test.sh index 68067ee87..87f5e31fc 100755 --- a/bootstrap_test.sh +++ b/bootstrap_test.sh @@ -4,7 +4,7 @@ # in a source tree that only contains enough files for Bazel and Soong to work. HARDWIRED_MOCK_TOP= -# Uncomment this for to be able to view the source tree after a test is run +# Uncomment this to be able to view the source tree after a test is run # HARDWIRED_MOCK_TOP=/tmp/td REAL_TOP="$(readlink -f "$(dirname "$0")"/../..)" @@ -85,63 +85,6 @@ function setup() { export ALLOW_MISSING_DEPENDENCIES=true mkdir -p out/soong - # This is necessary because the empty soong.variables file written to satisfy - # Ninja would contain "BootJars: {}" instead of "BootJars: []" which cannot - # be parsed back - # TODO(b/182965747): Fix this. - cat > out/soong/soong.variables <<'EOF' -{ - "BuildNumberFile": "build_number.txt", - "Platform_version_name": "S", - "Platform_sdk_version": 30, - "Platform_sdk_codename": "S", - "Platform_sdk_final": false, - "Platform_version_active_codenames": [ - "S" - ], - "Platform_vndk_version": "S", - "DeviceName": "generic_arm64", - "DeviceArch": "arm64", - "DeviceArchVariant": "armv8-a", - "DeviceCpuVariant": "generic", - "DeviceAbi": [ - "arm64-v8a" - ], - "DeviceSecondaryArch": "arm", - "DeviceSecondaryArchVariant": "armv8-a", - "DeviceSecondaryCpuVariant": "generic", - "DeviceSecondaryAbi": [ - "armeabi-v7a", - "armeabi" - ], - "HostArch": "x86_64", - "HostSecondaryArch": "x86", - "CrossHost": "windows", - "CrossHostArch": "x86", - "CrossHostSecondaryArch": "x86_64", - "AAPTCharacteristics": "nosdcard", - "AAPTConfig": [ - "normal", - "large", - "xlarge", - "hdpi", - "xhdpi", - "xxhdpi" - ], - "AAPTPreferredConfig": "xhdpi", - "AAPTPrebuiltDPI": [ - "xhdpi", - "xxhdpi" - ], - "Malloc_not_svelte": true, - "Malloc_zero_contents": true, - "Malloc_pattern_fill_contents": false, - "Safestack": false, - "BootJars": [], - "UpdatableBootJars": [], - "Native_coverage": null -} -EOF } function run_soong() { diff --git a/filesystem/Android.bp b/filesystem/Android.bp index dcdbdcf43..791019ddb 100644 --- a/filesystem/Android.bp +++ b/filesystem/Android.bp @@ -14,6 +14,7 @@ bootstrap_go_package { "bootimg.go", "filesystem.go", "logical_partition.go", + "vbmeta.go", ], testSrcs: [ ], diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go index 372a610e0..3dcc4165c 100644 --- a/filesystem/bootimg.go +++ b/filesystem/bootimg.go @@ -17,6 +17,7 @@ package filesystem import ( "fmt" "strconv" + "strings" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -217,22 +218,46 @@ func (b *bootimg) buildBootImage(ctx android.ModuleContext, vendor bool) android } func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.OutputPath) android.OutputPath { - output := android.PathForModuleOut(ctx, b.installFileName()).OutputPath - key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)) + propFile, toolDeps := b.buildPropFile(ctx) + output := android.PathForModuleOut(ctx, b.installFileName()).OutputPath builder := android.NewRuleBuilder(pctx, ctx) builder.Command().Text("cp").Input(unsignedImage).Output(output) - builder.Command(). - BuiltTool("avbtool"). - Flag("add_hash_footer"). - FlagWithArg("--partition_name ", b.partitionName()). - FlagWithInput("--key ", key). - FlagWithOutput("--image ", output) + builder.Command().BuiltTool("verity_utils"). + Input(propFile). + Implicits(toolDeps). + Output(output) builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName())) return output } +func (b *bootimg) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) { + var sb strings.Builder + var deps android.Paths + addStr := func(name string, value string) { + fmt.Fprintf(&sb, "%s=%s\n", name, value) + } + addPath := func(name string, path android.Path) { + addStr(name, path.String()) + deps = append(deps, path) + } + + addStr("avb_hash_enable", "true") + addPath("avb_avbtool", ctx.Config().HostToolPath(ctx, "avbtool")) + algorithm := proptools.StringDefault(b.properties.Avb_algorithm, "SHA256_RSA4096") + addStr("avb_algorithm", algorithm) + key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)) + addPath("avb_key_path", key) + addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index + partitionName := proptools.StringDefault(b.properties.Partition_name, b.Name()) + addStr("partition_name", partitionName) + + propFile = android.PathForModuleOut(ctx, "prop").OutputPath + android.WriteFileRule(ctx, propFile, sb.String()) + return propFile, deps +} + var _ android.AndroidMkEntriesProvider = (*bootimg)(nil) // Implements android.AndroidMkEntriesProvider @@ -255,6 +280,13 @@ func (b *bootimg) OutputPath() android.Path { return b.output } +func (b *bootimg) SignedOutputPath() android.Path { + if proptools.Bool(b.properties.Use_avb) { + return b.OutputPath() + } + return nil +} + var _ android.OutputFileProducer = (*bootimg)(nil) // Implements android.OutputFileProducer diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 3b0a7ae5a..8974eba4f 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -55,6 +55,9 @@ type filesystemProperties struct { // Hash and signing algorithm for avbtool. Default is SHA256_RSA4096. Avb_algorithm *string + // Name of the partition stored in vbmeta desc. Defaults to the name of this module. + Partition_name *string + // Type of the filesystem. Currently, ext4, cpio, and compressed_cpio are supported. Default // is ext4. Type *string @@ -279,7 +282,8 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android. key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key)) addPath("avb_key_path", key) addStr("avb_add_hashtree_footer_args", "--do_not_generate_fec") - addStr("partition_name", f.Name()) + partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name()) + addStr("partition_name", partitionName) } if proptools.String(f.properties.File_contexts) != "" { @@ -381,6 +385,10 @@ func (f *filesystem) OutputFiles(tag string) (android.Paths, error) { type Filesystem interface { android.Module OutputPath() android.Path + + // Returns the output file that is signed by avbtool. If this module is not signed, returns + // nil. + SignedOutputPath() android.Path } var _ Filesystem = (*filesystem)(nil) @@ -388,3 +396,10 @@ var _ Filesystem = (*filesystem)(nil) func (f *filesystem) OutputPath() android.Path { return f.output } + +func (f *filesystem) SignedOutputPath() android.Path { + if proptools.Bool(f.properties.Use_avb) { + return f.OutputPath() + } + return nil +} diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go index 16b6037cf..20d9622dc 100644 --- a/filesystem/logical_partition.go +++ b/filesystem/logical_partition.go @@ -209,6 +209,10 @@ func (l *logicalPartition) OutputPath() android.Path { return l.output } +func (l *logicalPartition) SignedOutputPath() android.Path { + return nil // logical partition is not signed by itself +} + var _ android.OutputFileProducer = (*logicalPartition)(nil) // Implements android.OutputFileProducer diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go new file mode 100644 index 000000000..f823387b0 --- /dev/null +++ b/filesystem/vbmeta.go @@ -0,0 +1,265 @@ +// Copyright (C) 2021 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package filesystem + +import ( + "fmt" + "strconv" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" + + "android/soong/android" +) + +func init() { + android.RegisterModuleType("vbmeta", vbmetaFactory) +} + +type vbmeta struct { + android.ModuleBase + + properties vbmetaProperties + + output android.OutputPath + installDir android.InstallPath +} + +type vbmetaProperties struct { + // Name of the partition stored in vbmeta desc. Defaults to the name of this module. + Partition_name *string + + // Set the name of the output. Defaults to <module_name>.img. + Stem *string + + // Path to the private key that avbtool will use to sign this vbmeta image. + Private_key *string `android:"path"` + + // Algorithm that avbtool will use to sign this vbmeta image. Default is SHA256_RSA4096. + Algorithm *string + + // File whose content will provide the rollback index. If unspecified, the rollback index + // is from PLATFORM_SECURITY_PATCH + Rollback_index_file *string `android:"path"` + + // Rollback index location of this vbmeta image. Must be 0, 1, 2, etc. Default is 0. + Rollback_index_location *int64 + + // List of filesystem modules that this vbmeta has descriptors for. The filesystem modules + // have to be signed (use_avb: true). + Partitions []string + + // List of chained partitions that this vbmeta deletages the verification. + Chained_partitions []chainedPartitionProperties +} + +type chainedPartitionProperties struct { + // Name of the chained partition + Name *string + + // Rollback index location of the chained partition. Must be 0, 1, 2, etc. Default is the + // index of this partition in the list + 1. + Rollback_index_location *int64 + + // Path to the public key that the chained partition is signed with. If this is specified, + // private_key is ignored. + Public_key *string `android:"path"` + + // Path to the private key that the chained partition is signed with. If this is specified, + // and public_key is not specified, a public key is extracted from this private key and + // the extracted public key is embedded in the vbmeta image. + Private_key *string `android:"path"` +} + +// vbmeta is the partition image that has the verification information for other partitions. +func vbmetaFactory() android.Module { + module := &vbmeta{} + module.AddProperties(&module.properties) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + return module +} + +type vbmetaDep struct { + blueprint.BaseDependencyTag + kind string +} + +var vbmetaPartitionDep = vbmetaDep{kind: "partition"} + +func (v *vbmeta) DepsMutator(ctx android.BottomUpMutatorContext) { + ctx.AddDependency(ctx.Module(), vbmetaPartitionDep, v.properties.Partitions...) +} + +func (v *vbmeta) installFileName() string { + return proptools.StringDefault(v.properties.Stem, v.BaseModuleName()+".img") +} + +func (v *vbmeta) partitionName() string { + return proptools.StringDefault(v.properties.Partition_name, v.BaseModuleName()) +} + +func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) { + extractedPublicKeys := v.extractPublicKeys(ctx) + + v.output = android.PathForModuleOut(ctx, v.installFileName()).OutputPath + + builder := android.NewRuleBuilder(pctx, ctx) + cmd := builder.Command().BuiltTool("avbtool").Text("make_vbmeta_image") + + key := android.PathForModuleSrc(ctx, proptools.String(v.properties.Private_key)) + cmd.FlagWithInput("--key ", key) + + algorithm := proptools.StringDefault(v.properties.Algorithm, "SHA256_RSA4096") + cmd.FlagWithArg("--algorithm ", algorithm) + + cmd.FlagWithArg("--rollback_index ", v.rollbackIndexCommand(ctx)) + ril := proptools.IntDefault(v.properties.Rollback_index_location, 0) + if ril < 0 { + ctx.PropertyErrorf("rollback_index_location", "must be 0, 1, 2, ...") + return + } + cmd.FlagWithArg("--rollback_index_location ", strconv.Itoa(ril)) + + for _, p := range ctx.GetDirectDepsWithTag(vbmetaPartitionDep) { + f, ok := p.(Filesystem) + if !ok { + ctx.PropertyErrorf("partitions", "%q(type: %s) is not supported", + p.Name(), ctx.OtherModuleType(p)) + continue + } + signedImage := f.SignedOutputPath() + if signedImage == nil { + ctx.PropertyErrorf("partitions", "%q(type: %s) is not signed. Use `use_avb: true`", + p.Name(), ctx.OtherModuleType(p)) + continue + } + cmd.FlagWithInput("--include_descriptors_from_image ", signedImage) + } + + for i, cp := range v.properties.Chained_partitions { + name := proptools.String(cp.Name) + if name == "" { + ctx.PropertyErrorf("chained_partitions", "name must be specified") + continue + } + + ril := proptools.IntDefault(cp.Rollback_index_location, i+1) + if ril < 0 { + ctx.PropertyErrorf("chained_partitions", "must be 0, 1, 2, ...") + continue + } + + var publicKey android.Path + if cp.Public_key != nil { + publicKey = android.PathForModuleSrc(ctx, proptools.String(cp.Public_key)) + } else { + publicKey = extractedPublicKeys[name] + } + cmd.FlagWithArg("--chain_partition ", fmt.Sprintf("%s:%d:%s", name, ril, publicKey.String())) + cmd.Implicit(publicKey) + } + + cmd.FlagWithOutput("--output ", v.output) + builder.Build("vbmeta", fmt.Sprintf("vbmeta %s", ctx.ModuleName())) + + v.installDir = android.PathForModuleInstall(ctx, "etc") + ctx.InstallFile(v.installDir, v.installFileName(), v.output) +} + +// Returns the embedded shell command that prints the rollback index +func (v *vbmeta) rollbackIndexCommand(ctx android.ModuleContext) string { + var cmd string + if v.properties.Rollback_index_file != nil { + f := android.PathForModuleSrc(ctx, proptools.String(v.properties.Rollback_index_file)) + cmd = "cat " + f.String() + } else { + cmd = "date -d 'TZ=\"GMT\" " + ctx.Config().PlatformSecurityPatch() + "' +%s" + } + // Take the first line and remove the newline char + return "$(" + cmd + " | head -1 | tr -d '\n'" + ")" +} + +// Extract public keys from chained_partitions.private_key. The keys are indexed with the partition +// name. +func (v *vbmeta) extractPublicKeys(ctx android.ModuleContext) map[string]android.OutputPath { + result := make(map[string]android.OutputPath) + + builder := android.NewRuleBuilder(pctx, ctx) + for _, cp := range v.properties.Chained_partitions { + if cp.Private_key == nil { + continue + } + + name := proptools.String(cp.Name) + if name == "" { + ctx.PropertyErrorf("chained_partitions", "name must be specified") + continue + } + + if _, ok := result[name]; ok { + ctx.PropertyErrorf("chained_partitions", "name %q is duplicated", name) + continue + } + + privateKeyFile := android.PathForModuleSrc(ctx, proptools.String(cp.Private_key)) + publicKeyFile := android.PathForModuleOut(ctx, name+".avbpubkey").OutputPath + + builder.Command(). + BuiltTool("avbtool"). + Text("extract_public_key"). + FlagWithInput("--key ", privateKeyFile). + FlagWithOutput("--output ", publicKeyFile) + + result[name] = publicKeyFile + } + builder.Build("vbmeta_extract_public_key", fmt.Sprintf("Extract public keys for %s", ctx.ModuleName())) + return result +} + +var _ android.AndroidMkEntriesProvider = (*vbmeta)(nil) + +// Implements android.AndroidMkEntriesProvider +func (v *vbmeta) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{android.AndroidMkEntries{ + Class: "ETC", + OutputFile: android.OptionalPathForPath(v.output), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_PATH", v.installDir.ToMakePath().String()) + entries.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName()) + }, + }, + }} +} + +var _ Filesystem = (*vbmeta)(nil) + +func (v *vbmeta) OutputPath() android.Path { + return v.output +} + +func (v *vbmeta) SignedOutputPath() android.Path { + return v.OutputPath() // vbmeta is always signed +} + +var _ android.OutputFileProducer = (*vbmeta)(nil) + +// Implements android.OutputFileProducer +func (v *vbmeta) OutputFiles(tag string) (android.Paths, error) { + if tag == "" { + return []android.Path{v.output}, nil + } + return nil, fmt.Errorf("unsupported module reference tag %q", tag) +} diff --git a/java/Android.bp b/java/Android.bp index 9e2db8314..56cc40129 100644 --- a/java/Android.bp +++ b/java/Android.bp @@ -75,6 +75,7 @@ bootstrap_go_package { "java_test.go", "jdeps_test.go", "kotlin_test.go", + "platform_compat_config_test.go", "plugin_test.go", "rro_test.go", "sdk_test.go", diff --git a/java/app_test.go b/java/app_test.go index c189ee5d3..7168a9645 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -370,11 +370,15 @@ func TestUpdatableApps(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - if test.expectedError == "" { - testJava(t, test.bp) - } else { - testJavaError(t, test.expectedError, test.bp) + errorHandler := android.FixtureExpectsNoErrors + if test.expectedError != "" { + errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(test.expectedError) } + javaFixtureFactory. + Extend(FixtureWithPrebuiltApis(map[string][]string{ + "29": {"foo"}, + })). + ExtendWithErrorHandler(errorHandler).RunTestWithBp(t, test.bp) }) } } @@ -984,12 +988,8 @@ func TestAndroidResources(t *testing.T) { } } -func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion string) { - ctx := testContext(config) - - run(t, ctx, config) - - foo := ctx.ModuleForTests("foo", "android_common") +func checkSdkVersion(t *testing.T, result *android.TestResult, expectedSdkVersion string) { + foo := result.ModuleForTests("foo", "android_common") link := foo.Output("package-res.apk") linkFlags := strings.Split(link.Args["flags"], " ") min := android.IndexList("--min-sdk-version", linkFlags) @@ -1002,15 +1002,9 @@ func checkSdkVersion(t *testing.T, config android.Config, expectedSdkVersion str gotMinSdkVersion := linkFlags[min+1] gotTargetSdkVersion := linkFlags[target+1] - if gotMinSdkVersion != expectedSdkVersion { - t.Errorf("incorrect --min-sdk-version, expected %q got %q", - expectedSdkVersion, gotMinSdkVersion) - } + android.AssertStringEquals(t, "incorrect --min-sdk-version", expectedSdkVersion, gotMinSdkVersion) - if gotTargetSdkVersion != expectedSdkVersion { - t.Errorf("incorrect --target-sdk-version, expected %q got %q", - expectedSdkVersion, gotTargetSdkVersion) - } + android.AssertStringEquals(t, "incorrect --target-sdk-version", expectedSdkVersion, gotTargetSdkVersion) } func TestAppSdkVersion(t *testing.T) { @@ -1083,13 +1077,19 @@ func TestAppSdkVersion(t *testing.T) { %s }`, moduleType, test.sdkVersion, platformApiProp) - config := testAppConfig(nil, bp, nil) - config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt - config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename - config.TestProductVariables.Platform_version_active_codenames = test.activeCodenames - config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal - checkSdkVersion(t, config, test.expectedMinSdkVersion) - + result := javaFixtureFactory.Extend( + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_version = &test.platformSdkInt + variables.Platform_sdk_codename = &test.platformSdkCodename + variables.Platform_version_active_codenames = test.activeCodenames + variables.Platform_sdk_final = &test.platformSdkFinal + }), + FixtureWithPrebuiltApis(map[string][]string{ + "14": {"foo"}, + }), + ).RunTestWithBp(t, bp) + + checkSdkVersion(t, result, test.expectedMinSdkVersion) }) } } @@ -1145,13 +1145,22 @@ func TestVendorAppSdkVersion(t *testing.T) { vendor: true, }`, moduleType, sdkKind, test.sdkVersion) - config := testAppConfig(nil, bp, nil) - config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt - config.TestProductVariables.Platform_sdk_codename = &test.platformSdkCodename - config.TestProductVariables.Platform_sdk_final = &test.platformSdkFinal - config.TestProductVariables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules - config.TestProductVariables.DeviceSystemSdkVersions = []string{"28", "29"} - checkSdkVersion(t, config, test.expectedMinSdkVersion) + result := javaFixtureFactory.Extend( + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.Platform_sdk_version = &test.platformSdkInt + variables.Platform_sdk_codename = &test.platformSdkCodename + variables.Platform_sdk_final = &test.platformSdkFinal + variables.DeviceCurrentApiLevelForVendorModules = &test.deviceCurrentApiLevelForVendorModules + variables.DeviceSystemSdkVersions = []string{"28", "29"} + }), + FixtureWithPrebuiltApis(map[string][]string{ + "28": {"foo"}, + "29": {"foo"}, + "current": {"foo"}, + }), + ).RunTestWithBp(t, bp) + + checkSdkVersion(t, result, test.expectedMinSdkVersion) }) } } @@ -2360,15 +2369,16 @@ func TestUsesLibraries(t *testing.T) { } ` - config := testAppConfig(nil, bp, nil) - config.TestProductVariables.MissingUsesLibraries = []string{"baz"} + result := javaFixtureFactory.Extend( + PrepareForTestWithJavaSdkLibraryFiles, + FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.MissingUsesLibraries = []string{"baz"} + }), + ).RunTestWithBp(t, bp) - ctx := testContext(config) - - run(t, ctx, config) - - app := ctx.ModuleForTests("app", "android_common") - prebuilt := ctx.ModuleForTests("prebuilt", "android_common") + app := result.ModuleForTests("app", "android_common") + prebuilt := result.ModuleForTests("prebuilt", "android_common") // Test that implicit dependencies on java_sdk_library instances are passed to the manifest. // This should not include explicit `uses_libs`/`optional_uses_libs` entries. @@ -2380,10 +2390,7 @@ func TestUsesLibraries(t *testing.T) { `--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer `--uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer `--uses-library runtime-library` - if actualManifestFixerArgs != expectManifestFixerArgs { - t.Errorf("unexpected manifest_fixer args:\n\texpect: %q\n\tactual: %q", - expectManifestFixerArgs, actualManifestFixerArgs) - } + android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs) // Test that all libraries are verified (library order matters). verifyCmd := app.Rule("verify_uses_libraries").RuleParams.Command @@ -2394,9 +2401,7 @@ func TestUsesLibraries(t *testing.T) { `--uses-library runtime-library ` + `--optional-uses-library bar ` + `--optional-uses-library baz ` - if !strings.Contains(verifyCmd, verifyArgs) { - t.Errorf("wanted %q in %q", verifyArgs, verifyCmd) - } + android.AssertStringDoesContain(t, "verify cmd args", verifyCmd, verifyArgs) // Test that all libraries are verified for an APK (library order matters). verifyApkCmd := prebuilt.Rule("verify_uses_libraries").RuleParams.Command @@ -2405,9 +2410,7 @@ func TestUsesLibraries(t *testing.T) { `--uses-library android.test.runner ` + `--optional-uses-library bar ` + `--optional-uses-library baz ` - if !strings.Contains(verifyApkCmd, verifyApkArgs) { - t.Errorf("wanted %q in %q", verifyApkArgs, verifyApkCmd) - } + android.AssertStringDoesContain(t, "verify apk cmd args", verifyApkCmd, verifyApkArgs) // Test that all present libraries are preopted, including implicit SDK dependencies, possibly stubs cmd := app.Rule("dexpreopt").RuleParams.Command @@ -2418,46 +2421,39 @@ func TestUsesLibraries(t *testing.T) { `PCL[/system/framework/non-sdk-lib.jar]#` + `PCL[/system/framework/bar.jar]#` + `PCL[/system/framework/runtime-library.jar]` - if !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt app cmd args", cmd, w) // Test conditional context for target SDK version 28. - if w := `--target-context-for-sdk 28` + - ` PCL[/system/framework/org.apache.http.legacy.jar] `; !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt app cmd 28", cmd, + `--target-context-for-sdk 28`+ + ` PCL[/system/framework/org.apache.http.legacy.jar] `) // Test conditional context for target SDK version 29. - if w := `--target-context-for-sdk 29` + - ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]` + - `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `; !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt app cmd 29", cmd, + `--target-context-for-sdk 29`+ + ` PCL[/system/framework/android.hidl.manager-V1.0-java.jar]`+ + `#PCL[/system/framework/android.hidl.base-V1.0-java.jar] `) // Test conditional context for target SDK version 30. // "android.test.mock" is absent because "android.test.runner" is not used. - if w := `--target-context-for-sdk 30` + - ` PCL[/system/framework/android.test.base.jar] `; !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt app cmd 30", cmd, + `--target-context-for-sdk 30`+ + ` PCL[/system/framework/android.test.base.jar] `) cmd = prebuilt.Rule("dexpreopt").RuleParams.Command - if w := `--target-context-for-sdk any` + - ` PCL[/system/framework/foo.jar]` + - `#PCL[/system/framework/non-sdk-lib.jar]` + - `#PCL[/system/framework/android.test.runner.jar]` + - `#PCL[/system/framework/bar.jar] `; !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd", cmd, + `--target-context-for-sdk any`+ + ` PCL[/system/framework/foo.jar]`+ + `#PCL[/system/framework/non-sdk-lib.jar]`+ + `#PCL[/system/framework/android.test.runner.jar]`+ + `#PCL[/system/framework/bar.jar] `) // Test conditional context for target SDK version 30. // "android.test.mock" is present because "android.test.runner" is used. - if w := `--target-context-for-sdk 30` + - ` PCL[/system/framework/android.test.base.jar]` + - `#PCL[/system/framework/android.test.mock.jar] `; !strings.Contains(cmd, w) { - t.Errorf("wanted %q in %q", w, cmd) - } + android.AssertStringDoesContain(t, "dexpreopt prebuilt cmd 30", cmd, + `--target-context-for-sdk 30`+ + ` PCL[/system/framework/android.test.base.jar]`+ + `#PCL[/system/framework/android.test.mock.jar] `) } func TestCodelessApp(t *testing.T) { @@ -2722,28 +2718,24 @@ func TestUncompressDex(t *testing.T) { test := func(t *testing.T, bp string, want bool, unbundled bool) { t.Helper() - config := testAppConfig(nil, bp, nil) - if unbundled { - config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true) - config.TestProductVariables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) - } - - ctx := testContext(config) - - run(t, ctx, config) + result := javaFixtureFactory.Extend( + PrepareForTestWithPrebuiltsOfCurrentApi, + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + if unbundled { + variables.Unbundled_build = proptools.BoolPtr(true) + variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) + } + }), + ).RunTestWithBp(t, bp) - foo := ctx.ModuleForTests("foo", "android_common") + foo := result.ModuleForTests("foo", "android_common") dex := foo.Rule("r8") uncompressedInDexJar := strings.Contains(dex.Args["zipFlags"], "-L 0") aligned := foo.MaybeRule("zipalign").Rule != nil - if uncompressedInDexJar != want { - t.Errorf("want uncompressed in dex %v, got %v", want, uncompressedInDexJar) - } + android.AssertBoolEquals(t, "uncompressed in dex", want, uncompressedInDexJar) - if aligned != want { - t.Errorf("want aligned %v, got %v", want, aligned) - } + android.AssertBoolEquals(t, "aligne", want, aligned) } for _, tt := range testCases { diff --git a/java/java_test.go b/java/java_test.go index 2eb724185..990e0102e 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -48,9 +48,10 @@ func tearDown() { os.RemoveAll(buildDir) } +var emptyFixtureFactory = android.NewFixtureFactory(&buildDir) + // Factory to use to create fixtures for tests in this package. -var javaFixtureFactory = android.NewFixtureFactory( - &buildDir, +var javaFixtureFactory = emptyFixtureFactory.Extend( genrule.PrepareForTestWithGenRuleBuildComponents, // Get the CC build components but not default modules. cc.PrepareForTestWithCcBuildComponents, diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go index 4bfd4e2f9..4c3143a48 100644 --- a/java/platform_compat_config.go +++ b/java/platform_compat_config.go @@ -35,10 +35,6 @@ func platformCompatConfigPath(ctx android.PathContext) android.OutputPath { return android.PathForOutput(ctx, "compat_config", "merged_compat_config.xml") } -type platformCompatConfigSingleton struct { - metadata android.Path -} - type platformCompatConfigProperties struct { Src *string `android:"path"` } @@ -52,7 +48,7 @@ type platformCompatConfig struct { metadataFile android.OutputPath } -func (p *platformCompatConfig) compatConfigMetadata() android.OutputPath { +func (p *platformCompatConfig) compatConfigMetadata() android.Path { return p.metadataFile } @@ -64,52 +60,20 @@ func (p *platformCompatConfig) SubDir() string { return "compatconfig" } +type platformCompatConfigMetadataProvider interface { + compatConfigMetadata() android.Path +} + type PlatformCompatConfigIntf interface { android.Module - compatConfigMetadata() android.OutputPath CompatConfig() android.OutputPath // Sub dir under etc dir. SubDir() string } var _ PlatformCompatConfigIntf = (*platformCompatConfig)(nil) - -// compat singleton rules -func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) { - - var compatConfigMetadata android.Paths - - ctx.VisitAllModules(func(module android.Module) { - if c, ok := module.(PlatformCompatConfigIntf); ok { - metadata := c.compatConfigMetadata() - compatConfigMetadata = append(compatConfigMetadata, metadata) - } - }) - - if compatConfigMetadata == nil { - // nothing to do. - return - } - - rule := android.NewRuleBuilder(pctx, ctx) - outputPath := platformCompatConfigPath(ctx) - - rule.Command(). - BuiltTool("process-compat-config"). - FlagForEachInput("--xml ", compatConfigMetadata). - FlagWithOutput("--merged-config ", outputPath) - - rule.Build("merged-compat-config", "Merge compat config") - - p.metadata = outputPath -} - -func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) { - if p.metadata != nil { - ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String()) - } -} +var _ platformCompatConfigMetadataProvider = (*platformCompatConfig)(nil) func (p *platformCompatConfig) GenerateAndroidBuildActions(ctx android.ModuleContext) { rule := android.NewRuleBuilder(pctx, ctx) @@ -145,10 +109,6 @@ func (p *platformCompatConfig) AndroidMkEntries() []android.AndroidMkEntries { }} } -func platformCompatConfigSingletonFactory() android.Singleton { - return &platformCompatConfigSingleton{} -} - func PlatformCompatConfigFactory() android.Module { module := &platformCompatConfig{} module.AddProperties(&module.properties) @@ -156,6 +116,50 @@ func PlatformCompatConfigFactory() android.Module { return module } +// compat singleton rules +type platformCompatConfigSingleton struct { + metadata android.Path +} + +func (p *platformCompatConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) { + + var compatConfigMetadata android.Paths + + ctx.VisitAllModules(func(module android.Module) { + if c, ok := module.(platformCompatConfigMetadataProvider); ok { + metadata := c.compatConfigMetadata() + compatConfigMetadata = append(compatConfigMetadata, metadata) + } + }) + + if compatConfigMetadata == nil { + // nothing to do. + return + } + + rule := android.NewRuleBuilder(pctx, ctx) + outputPath := platformCompatConfigPath(ctx) + + rule.Command(). + BuiltTool("process-compat-config"). + FlagForEachInput("--xml ", compatConfigMetadata). + FlagWithOutput("--merged-config ", outputPath) + + rule.Build("merged-compat-config", "Merge compat config") + + p.metadata = outputPath +} + +func (p *platformCompatConfigSingleton) MakeVars(ctx android.MakeVarsContext) { + if p.metadata != nil { + ctx.Strict("INTERNAL_PLATFORM_MERGED_COMPAT_CONFIG", p.metadata.String()) + } +} + +func platformCompatConfigSingletonFactory() android.Singleton { + return &platformCompatConfigSingleton{} +} + //============== merged_compat_config ================= type globalCompatConfigProperties struct { // name of the file into which the metadata will be copied. diff --git a/java/platform_compat_config_test.go b/java/platform_compat_config_test.go new file mode 100644 index 000000000..0c5d001ac --- /dev/null +++ b/java/platform_compat_config_test.go @@ -0,0 +1,53 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package java + +import ( + "testing" + + "android/soong/android" +) + +func TestPlatformCompatConfig(t *testing.T) { + result := emptyFixtureFactory.RunTest(t, + PrepareForTestWithPlatformCompatConfig, + android.FixtureWithRootAndroidBp(` + platform_compat_config { + name: "myconfig2", + } + platform_compat_config { + name: "myconfig1", + } + platform_compat_config { + name: "myconfig3", + } + `), + ) + + checkMergedCompatConfigInputs(t, result, "myconfig", + "out/soong/.intermediates/myconfig1/myconfig1_meta.xml", + "out/soong/.intermediates/myconfig2/myconfig2_meta.xml", + "out/soong/.intermediates/myconfig3/myconfig3_meta.xml", + ) +} + +// Check that the merged file create by platform_compat_config_singleton has the correct inputs. +func checkMergedCompatConfigInputs(t *testing.T, result *android.TestResult, message string, expectedPaths ...string) { + sourceGlobalCompatConfig := result.SingletonForTests("platform_compat_config_singleton") + allOutputs := sourceGlobalCompatConfig.AllOutputs() + android.AssertIntEquals(t, message+": output len", 1, len(allOutputs)) + output := sourceGlobalCompatConfig.Output(allOutputs[0]) + android.AssertPathsRelativeToTopEquals(t, message+": inputs", expectedPaths, output.Implicits) +} diff --git a/python/Android.bp b/python/Android.bp index b633f1e3f..e49fa6a3c 100644 --- a/python/Android.bp +++ b/python/Android.bp @@ -20,6 +20,7 @@ bootstrap_go_package { "proto.go", "python.go", "test.go", + "testing.go", ], testSrcs: [ "python_test.go", diff --git a/python/binary.go b/python/binary.go index 372b8a8c1..6061ad4f7 100644 --- a/python/binary.go +++ b/python/binary.go @@ -26,10 +26,14 @@ import ( ) func init() { - android.RegisterModuleType("python_binary_host", PythonBinaryHostFactory) + registerPythonBinaryComponents(android.InitRegistrationContext) android.RegisterBp2BuildMutator("python_binary_host", PythonBinaryBp2Build) } +func registerPythonBinaryComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("python_binary_host", PythonBinaryHostFactory) +} + type bazelPythonBinaryAttributes struct { Main string Srcs bazel.LabelList diff --git a/python/library.go b/python/library.go index b724d2b9f..9663b3c75 100644 --- a/python/library.go +++ b/python/library.go @@ -21,8 +21,12 @@ import ( ) func init() { - android.RegisterModuleType("python_library_host", PythonLibraryHostFactory) - android.RegisterModuleType("python_library", PythonLibraryFactory) + registerPythonLibraryComponents(android.InitRegistrationContext) +} + +func registerPythonLibraryComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("python_library_host", PythonLibraryHostFactory) + ctx.RegisterModuleType("python_library", PythonLibraryFactory) } func PythonLibraryHostFactory() android.Module { diff --git a/python/python.go b/python/python.go index a078c0b58..4444a70e6 100644 --- a/python/python.go +++ b/python/python.go @@ -29,7 +29,11 @@ import ( ) func init() { - android.PreDepsMutators(RegisterPythonPreDepsMutators) + registerPythonMutators(android.InitRegistrationContext) +} + +func registerPythonMutators(ctx android.RegistrationContext) { + ctx.PreDepsMutators(RegisterPythonPreDepsMutators) } // Exported to support other packages using Python modules in tests. diff --git a/python/python_test.go b/python/python_test.go index 5c4efa763..14d78b2b6 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -207,14 +207,26 @@ var ( "lib1", ], } + + python_binary_host { + name: "bin", + pkg_path: "e/", + srcs: [ + "bin.py", + ], + libs: [ + "lib2", + ], + } `, ), "dir/c/file1.py": nil, "dir/file1.py": nil, + "dir/bin.py": nil, }, errors: []string{ - fmt.Sprintf(dupRunfileErrTemplate, "dir/Android.bp:9:6", - "lib2", "PY3", "a/b/c/file1.py", "lib2", "dir/file1.py", + fmt.Sprintf(dupRunfileErrTemplate, "dir/Android.bp:20:6", + "bin", "PY3", "a/b/c/file1.py", "bin", "dir/file1.py", "lib1", "dir/c/file1.py"), }, }, @@ -339,7 +351,7 @@ func TestPythonModule(t *testing.T) { _, testErrs := ctx.ParseBlueprintsFiles(bpFile) android.FailIfErrored(t, testErrs) _, actErrs := ctx.PrepareBuildActions(config) - if len(actErrs) > 0 { + if len(actErrs) > 0 || len(d.errors) > 0 { testErrs = append(testErrs, expectErrors(t, actErrs, d.errors)...) } else { for _, e := range d.expectedBinaries { diff --git a/python/test.go b/python/test.go index b7cd4756a..6713189fd 100644 --- a/python/test.go +++ b/python/test.go @@ -22,8 +22,12 @@ import ( // This file contains the module types for building Python test. func init() { - android.RegisterModuleType("python_test_host", PythonTestHostFactory) - android.RegisterModuleType("python_test", PythonTestFactory) + registerPythonTestComponents(android.InitRegistrationContext) +} + +func registerPythonTestComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("python_test_host", PythonTestHostFactory) + ctx.RegisterModuleType("python_test", PythonTestFactory) } // Test option struct. diff --git a/python/testing.go b/python/testing.go new file mode 100644 index 000000000..ce1a5ab27 --- /dev/null +++ b/python/testing.go @@ -0,0 +1,24 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package python + +import "android/soong/android" + +var PrepareForTestWithPythonBuildComponents = android.GroupFixturePreparers( + android.FixtureRegisterWithContext(registerPythonBinaryComponents), + android.FixtureRegisterWithContext(registerPythonLibraryComponents), + android.FixtureRegisterWithContext(registerPythonTestComponents), + android.FixtureRegisterWithContext(registerPythonMutators), +) diff --git a/rust/bindgen.go b/rust/bindgen.go index 56d660eca..db69e2337 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -29,7 +29,7 @@ var ( defaultBindgenFlags = []string{""} // bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures. - bindgenClangVersion = "clang-r399163b" + bindgenClangVersion = "clang-r412851" _ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string { if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" { |