diff options
45 files changed, 930 insertions, 370 deletions
diff --git a/Android.bp b/Android.bp index 0e8d86d3b..7c5004735 100644 --- a/Android.bp +++ b/Android.bp @@ -46,25 +46,6 @@ cc_defaults { // C static libraries extracted from the gcc toolchain // -toolchain_library { - name: "libwinpthread", - host_supported: true, - enabled: false, - target: { - windows: { - enabled: true, - }, - windows_x86: { - src: "prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib32/libwinpthread.a", - }, - windows_x86_64: { - src: "prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib/libwinpthread.a", - }, - }, - notice: ":mingw-libwinpthread-notice", - licenses: ["winpthreads_license"], -} - kernel_headers { name: "device_kernel_headers", vendor: true, diff --git a/android/config.go b/android/config.go index afc138b1f..10e074cb1 100644 --- a/android/config.go +++ b/android/config.go @@ -24,6 +24,7 @@ import ( "io/ioutil" "os" "path/filepath" + "reflect" "runtime" "strconv" "strings" @@ -273,15 +274,45 @@ func saveToBazelConfigFile(config *productVariables, outDir string) error { return fmt.Errorf("Could not create dir %s: %s", dir, err) } - data, err := json.MarshalIndent(&config, "", " ") + nonArchVariantProductVariables := []string{} + archVariantProductVariables := []string{} + p := variableProperties{} + t := reflect.TypeOf(p.Product_variables) + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + nonArchVariantProductVariables = append(nonArchVariantProductVariables, strings.ToLower(f.Name)) + if proptools.HasTag(f, "android", "arch_variant") { + archVariantProductVariables = append(archVariantProductVariables, strings.ToLower(f.Name)) + } + } + + //TODO(b/216168792) should use common function to print Starlark code + nonArchVariantProductVariablesJson, err := json.MarshalIndent(&nonArchVariantProductVariables, "", " ") + if err != nil { + return fmt.Errorf("cannot marshal product variable data: %s", err.Error()) + } + + //TODO(b/216168792) should use common function to print Starlark code + archVariantProductVariablesJson, err := json.MarshalIndent(&archVariantProductVariables, "", " ") + if err != nil { + return fmt.Errorf("cannot marshal arch variant product variable data: %s", err.Error()) + } + + configJson, err := json.MarshalIndent(&config, "", " ") if err != nil { return fmt.Errorf("cannot marshal config data: %s", err.Error()) } bzl := []string{ bazel.GeneratedBazelFileWarning, - fmt.Sprintf(`_product_vars = json.decode("""%s""")`, data), - "product_vars = _product_vars\n", + fmt.Sprintf(`_product_vars = json.decode("""%s""")`, configJson), + fmt.Sprintf(`_product_var_constraints = %s`, nonArchVariantProductVariablesJson), + fmt.Sprintf(`_arch_variant_product_var_constraints = %s`, archVariantProductVariablesJson), + "\n", ` +product_vars = _product_vars +product_var_constraints = _product_var_constraints +arch_variant_product_var_constraints = _arch_variant_product_var_constraints +`, } err = ioutil.WriteFile(filepath.Join(dir, "product_variables.bzl"), []byte(strings.Join(bzl, "\n")), 0644) if err != nil { @@ -658,10 +689,6 @@ func (c *config) IsEnvFalse(key string) bool { return value == "0" || value == "n" || value == "no" || value == "off" || value == "false" } -func (c *config) TargetsJava11() bool { - return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") -} - // 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 { diff --git a/android/module.go b/android/module.go index 3c8c7770f..2d0813c0f 100644 --- a/android/module.go +++ b/android/module.go @@ -2620,7 +2620,7 @@ func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag b } if aModule == nil { - b.ModuleErrorf("module %q not an android module", b.OtherModuleName(module)) + b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag) return nil } @@ -2742,8 +2742,8 @@ func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) { func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { b.bp.VisitDirectDeps(func(module blueprint.Module) { - if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { - if b.bp.OtherModuleDependencyTag(aModule) == tag { + if b.bp.OtherModuleDependencyTag(module) == tag { + if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps); aModule != nil { visit(aModule) } } diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go index ea537056d..abdbf5373 100644 --- a/androidmk/androidmk/androidmk_test.go +++ b/androidmk/androidmk/androidmk_test.go @@ -699,7 +699,7 @@ include $(call all-makefiles-under,$(LOCAL_PATH)) expected: ` android_library { srcs: ["test.java"], - resource_dirs: ["res"], + jacoco: { include_filter: ["foo.*"], }, @@ -1121,6 +1121,25 @@ prebuilt_usr_share_host { `, }, { + desc: "prebuilt_root_host", + in: ` +include $(CLEAR_VARS) +LOCAL_MODULE := foo +LOCAL_MODULE_CLASS := ETC +LOCAL_MODULE_PATH := $(HOST_OUT)/subdir +LOCAL_SRC_FILES := foo.txt +include $(BUILD_PREBUILT) +`, + expected: ` +prebuilt_root_host { + name: "foo", + + src: "foo.txt", + relative_install_path: "subdir", +} +`, + }, + { desc: "prebuilt_font", in: ` include $(CLEAR_VARS) @@ -1439,7 +1458,7 @@ include $(BUILD_RRO_PACKAGE) runtime_resource_overlay { name: "foo", product_specific: true, - resource_dirs: ["res"], + sdk_version: "current", theme: "FooTheme", @@ -1585,6 +1604,22 @@ cc_prebuilt_library_shared { } `, }, + { + desc: "Drop default resource and asset dirs from bp", + in: ` +include $(CLEAR_VARS) +LOCAL_MODULE := foo +LOCAL_ASSET_DIR := $(LOCAL_PATH)/assets +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res +include $(BUILD_PACKAGE) +`, + expected: ` +android_app { + name: "foo", + +} +`, + }, } func TestEndToEnd(t *testing.T) { diff --git a/apex/apex.go b/apex/apex.go index 30515535a..0ac6eaa89 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -151,12 +151,6 @@ type apexBundleProperties struct { // Default: true. Installable *bool - // Whether this APEX can be compressed or not. Setting this property to false means this - // APEX will never be compressed. When set to true, APEX will be compressed if other - // conditions, e.g, target device needs to support APEX compression, are also fulfilled. - // Default: true. - Compressible *bool - // If set true, VNDK libs are considered as stable libs and are not included in this APEX. // Should be only used in non-system apexes (e.g. vendor: true). Default is false. Use_vndk_as_stable *bool @@ -347,6 +341,12 @@ type overridableProperties struct { // certificate and the private key are provided from the android_app_certificate module // named "module". Certificate *string + + // Whether this APEX can be compressed or not. Setting this property to false means this + // APEX will never be compressed. When set to true, APEX will be compressed if other + // conditions, e.g., target device needs to support APEX compression, are also fulfilled. + // Default: false. + Compressible *bool } type apexBundle struct { @@ -1310,7 +1310,7 @@ func (a *apexBundle) EnableCoverageIfNeeded() {} var _ android.ApexBundleDepsInfoIntf = (*apexBundle)(nil) -// Implements android.ApexBudleDepsInfoIntf +// Implements android.ApexBundleDepsInfoIntf func (a *apexBundle) Updatable() bool { return proptools.BoolDefault(a.properties.Updatable, true) } @@ -3289,6 +3289,7 @@ type bazelApexBundleAttributes struct { Prebuilts bazel.LabelListAttribute Native_shared_libs_32 bazel.LabelListAttribute Native_shared_libs_64 bazel.LabelListAttribute + Compressible bazel.BoolAttribute } type convertedNativeSharedLibs struct { @@ -3366,6 +3367,11 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { installableAttribute.Value = a.properties.Installable } + var compressibleAttribute bazel.BoolAttribute + if a.overridableProperties.Compressible != nil { + compressibleAttribute.Value = a.overridableProperties.Compressible + } + attrs := &bazelApexBundleAttributes{ Manifest: manifestLabelAttribute, Android_manifest: androidManifestLabelAttribute, @@ -3379,6 +3385,7 @@ func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) { Native_shared_libs_64: nativeSharedLibs.Native_shared_libs_64, Binaries: binariesLabelListAttribute, Prebuilts: prebuiltsLabelListAttribute, + Compressible: compressibleAttribute, } props := bazel.BazelTargetModuleProperties{ diff --git a/apex/builder.go b/apex/builder.go index ea25537ca..a66e1e0fc 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -567,8 +567,8 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { outHostBinDir := ctx.Config().HostToolPath(ctx, "").String() prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin") - // Figure out if need to compress apex. - compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.properties.Compressible, false) && !a.testApex && !ctx.Config().UnbundledBuildApps() + // Figure out if we need to compress the apex. + compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.overridableProperties.Compressible, false) && !a.testApex && !ctx.Config().UnbundledBuildApps() if apexType == imageApex { //////////////////////////////////////////////////////////////////////////////////// diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index 4b141c954..90571893c 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -104,6 +104,7 @@ apex { certificate: "com.android.apogee.certificate", updatable: false, installable: false, + compressible: false, native_shared_libs: [ "native_shared_lib_1", "native_shared_lib_2", @@ -150,7 +151,8 @@ apex { ":pretend_prebuilt_1", ":pretend_prebuilt_2", ]`, - "updatable": "False", + "updatable": "False", + "compressible": "False", }), }}) } diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index de4f437b6..ee1978320 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -27,17 +27,6 @@ const ( soongCcLibraryPreamble = ` cc_defaults { name: "linux_bionic_supported", -} - -toolchain_library { - name: "libclang_rt.builtins-x86_64-android", - defaults: ["linux_bionic_supported"], - vendor_available: true, - vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, - native_bridge_supported: true, - src: "", }` soongCcProtoLibraries = ` @@ -64,7 +53,6 @@ func registerCcLibraryModuleTypes(ctx android.RegistrationContext) { ctx.RegisterModuleType("filegroup", android.FileGroupFactory) ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory) - ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) } @@ -1264,7 +1252,7 @@ cc_library { include_build_directory: false, } `, - expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo-lib\": nocrt is not supported for arch variants"), + expectedErr: fmt.Errorf("module \"foo-lib\": nocrt is not supported for arch variants"), }) } diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go index 594c05009..e4cfa358b 100644 --- a/bp2build/cc_library_headers_conversion_test.go +++ b/bp2build/cc_library_headers_conversion_test.go @@ -26,17 +26,6 @@ const ( soongCcLibraryHeadersPreamble = ` cc_defaults { name: "linux_bionic_supported", -} - -toolchain_library { - name: "libclang_rt.builtins-x86_64-android", - defaults: ["linux_bionic_supported"], - vendor_available: true, - vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, - native_bridge_supported: true, - src: "", }` ) @@ -68,7 +57,6 @@ func TestCcLibraryHeadersLoadStatement(t *testing.T) { func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) - ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) } func runCcLibraryHeadersTestCase(t *testing.T, tc bp2buildTestCase) { diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 0f6765320..e8ba573c0 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -30,7 +30,6 @@ const ( func registerCcLibrarySharedModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) - ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) ctx.RegisterModuleType("cc_library", cc.LibraryFactory) @@ -422,7 +421,7 @@ cc_library_shared { include_build_directory: false, } `, - expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo_shared\": nocrt is not supported for arch variants"), + expectedErr: fmt.Errorf("module \"foo_shared\": nocrt is not supported for arch variants"), }) } diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index fac741cf8..f1684c462 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -27,17 +27,6 @@ const ( soongCcLibraryStaticPreamble = ` cc_defaults { name: "linux_bionic_supported", -} - -toolchain_library { - name: "libclang_rt.builtins-x86_64-android", - defaults: ["linux_bionic_supported"], - vendor_available: true, - vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, - native_bridge_supported: true, - src: "", }` ) @@ -69,7 +58,6 @@ func TestCcLibraryStaticLoadStatement(t *testing.T) { func registerCcLibraryStaticModuleTypes(ctx android.RegistrationContext) { cc.RegisterCCBuildComponents(ctx) - ctx.RegisterModuleType("toolchain_library", cc.ToolchainLibraryFactory) ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory) ctx.RegisterModuleType("genrule", genrule.GenRuleFactory) // Required for system_shared_libs dependencies. diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go index b6834721a..4f7d88ce6 100644 --- a/bpfix/bpfix/bpfix.go +++ b/bpfix/bpfix/bpfix.go @@ -158,6 +158,10 @@ var fixSteps = []FixStep{ Name: "formatFlagProperties", Fix: runPatchListMod(formatFlagProperties), }, + { + Name: "removeResourcesAndAssetsIfDefault", + Fix: removeResourceAndAssetsIfDefault, + }, } // for fix that only need to run once @@ -610,7 +614,11 @@ func (f etcPrebuiltModuleUpdate) update(m *parser.Module, path string) bool { } var localModuleUpdate = map[string][]etcPrebuiltModuleUpdate{ - "HOST_OUT": {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}}, + "HOST_OUT": { + {prefix: "/etc", modType: "prebuilt_etc_host"}, + {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}, + {prefix: "", modType: "prebuilt_root_host"}, + }, "PRODUCT_OUT": {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}}, "TARGET_OUT": {{prefix: "/usr/share", modType: "prebuilt_usr_share"}, {prefix: "/fonts", modType: "prebuilt_font"}, {prefix: "/etc/firmware", modType: "prebuilt_firmware"}, {prefix: "/vendor/firmware", modType: "prebuilt_firmware", flags: []string{"proprietary"}}, @@ -882,6 +890,24 @@ func removeSoongConfigBoolVariable(f *Fixer) error { return nil } +func removeResourceAndAssetsIfDefault(f *Fixer) error { + for _, def := range f.tree.Defs { + mod, ok := def.(*parser.Module) + if !ok { + continue + } + resourceDirList, resourceDirFound := getLiteralListPropertyValue(mod, "resource_dirs") + if resourceDirFound && len(resourceDirList) == 1 && resourceDirList[0] == "res" { + removeProperty(mod, "resource_dirs") + } + assetDirList, assetDirFound := getLiteralListPropertyValue(mod, "asset_dirs") + if assetDirFound && len(assetDirList) == 1 && assetDirList[0] == "assets" { + removeProperty(mod, "asset_dirs") + } + } + return nil +} + // Converts the default source list property, 'srcs', to a single source property with a given name. // "LOCAL_MODULE" reference is also resolved during the conversion process. func convertToSingleSource(mod *parser.Module, srcPropertyName string) { diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go index 69f596752..17b3c2444 100644 --- a/bpfix/bpfix/bpfix_test.go +++ b/bpfix/bpfix/bpfix_test.go @@ -19,11 +19,10 @@ package bpfix import ( "bytes" "fmt" + "reflect" "strings" "testing" - "reflect" - "github.com/google/blueprint/parser" "github.com/google/blueprint/pathtools" ) @@ -828,6 +827,46 @@ func TestRewritePrebuiltEtc(t *testing.T) { } `, }, + { + name: "prebuilt_etc sub_dir", + in: ` + prebuilt_etc_host { + name: "foo", + src: "bar", + local_module_path: { + var: "HOST_OUT", + fixed: "/etc/baz", + }, + } + `, + out: `prebuilt_etc_host { + name: "foo", + src: "bar", + relative_install_path: "baz", + + } + `, + }, + { + name: "prebuilt_etc sub_dir", + in: ` + prebuilt_etc_host { + name: "foo", + src: "bar", + local_module_path: { + var: "HOST_OUT", + fixed: "/baz/sub", + }, + } + `, + out: `prebuilt_root_host { + name: "foo", + src: "bar", + relative_install_path: "baz/sub", + + } + `, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { @@ -2023,3 +2062,124 @@ func TestHaveSameLicense(t *testing.T) { }) } } + +func TestRemoveResourceAndAssetsIfDefault(t *testing.T) { + tests := []struct { + name string + in string + out string + }{ + { + name: "resource_dirs default", + in: ` + android_app { + name: "foo", + resource_dirs: ["res"], + } + `, + out: ` + android_app { + name: "foo", + + } + `, + }, + { + name: "resource_dirs not default", + in: ` + android_app { + name: "foo", + resource_dirs: ["reso"], + } + `, + out: ` + android_app { + name: "foo", + resource_dirs: ["reso"], + } + `, + }, + { + name: "resource_dirs includes not default", + in: ` + android_app { + name: "foo", + resource_dirs: ["res", "reso"], + } + `, + out: ` + android_app { + name: "foo", + resource_dirs: ["res", "reso"], + } + `, + }, { + name: "asset_dirs default", + in: ` + android_app { + name: "foo", + asset_dirs: ["assets"], + } + `, + out: ` + android_app { + name: "foo", + + } + `, + }, + { + name: "asset_dirs not default", + in: ` + android_app { + name: "foo", + asset_dirs: ["assety"], + } + `, + out: ` + android_app { + name: "foo", + asset_dirs: ["assety"], + } + `, + }, + { + name: "asset_dirs includes not default", + in: ` + android_app { + name: "foo", + asset_dirs: ["assets", "assety"], + } + `, + out: ` + android_app { + name: "foo", + asset_dirs: ["assets", "assety"], + } + `, + }, + { + name: "resource_dirs and asset_dirs both default", + in: ` + android_app { + name: "foo", + asset_dirs: ["assets"], + resource_dirs: ["res"], + } + `, + out: ` + android_app { + name: "foo", + + } + `, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + runPassOnce(t, test.in, test.out, func(fixer *Fixer) error { + return removeResourceAndAssetsIfDefault(fixer) + }) + }) + } +} diff --git a/cc/Android.bp b/cc/Android.bp index 0bf0045d3..9103a48b4 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -68,7 +68,6 @@ bootstrap_go_package { "native_bridge_sdk_trait.go", "object.go", "test.go", - "toolchain_library.go", "ndk_abi.go", "ndk_headers.go", @@ -89,6 +88,7 @@ bootstrap_go_package { "stub_library.go", ], testSrcs: [ + "afdo_test.go", "cc_test.go", "compiler_test.go", "gen_test.go", @@ -1,4 +1,4 @@ per-file ndk_*.go = danalbert@google.com per-file tidy.go = srhines@google.com, chh@google.com -per-file lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com +per-file afdo.go,afdo_test.go,lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com diff --git a/cc/afdo.go b/cc/afdo.go index 022f2833b..d7cce77dd 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -40,7 +40,7 @@ func getAfdoProfileProjects(config android.DeviceConfig) []string { }) } -func recordMissingAfdoProfileFile(ctx BaseModuleContext, missing string) { +func recordMissingAfdoProfileFile(ctx android.BaseModuleContext, missing string) { getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true) } @@ -67,14 +67,14 @@ func (afdo *afdo) AfdoEnabled() bool { // 1. libfoo_arm64.afdo // 2. libfoo.afdo // Add more specialisation as needed. -func getProfileFiles(ctx BaseModuleContext, moduleName string) []string { +func getProfileFiles(ctx android.BaseModuleContext, moduleName string) []string { var files []string files = append(files, moduleName+"_"+ctx.Arch().ArchType.String()+".afdo") files = append(files, moduleName+".afdo") return files } -func (props *AfdoProperties) getAfdoProfileFile(ctx BaseModuleContext, module string) android.OptionalPath { +func (props *AfdoProperties) GetAfdoProfileFile(ctx android.BaseModuleContext, module string) android.OptionalPath { // Test if the profile_file is present in any of the Afdo profile projects for _, profileFile := range getProfileFiles(ctx, module) { for _, profileProject := range getAfdoProfileProjects(ctx.DeviceConfig()) { @@ -93,9 +93,15 @@ func (props *AfdoProperties) getAfdoProfileFile(ctx BaseModuleContext, module st } func (afdo *afdo) begin(ctx BaseModuleContext) { - if afdo.Properties.Afdo && !ctx.static() && !ctx.Host() { + if ctx.Host() { + return + } + if ctx.static() && !ctx.staticBinary() { + return + } + if afdo.Properties.Afdo { module := ctx.ModuleName() - if afdo.Properties.getAfdoProfileFile(ctx, module).Valid() { + if afdo.Properties.GetAfdoProfileFile(ctx, module).Valid() { afdo.Properties.AfdoTarget = proptools.StringPtr(module) } } @@ -103,7 +109,7 @@ func (afdo *afdo) begin(ctx BaseModuleContext) { func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags { if profile := afdo.Properties.AfdoTarget; profile != nil { - if profileFile := afdo.Properties.getAfdoProfileFile(ctx, *profile); profileFile.Valid() { + if profileFile := afdo.Properties.GetAfdoProfileFile(ctx, *profile); profileFile.Valid() { profileFilePath := profileFile.Path() profileUseFlag := fmt.Sprintf(afdoCFlagsFormat, profileFile) diff --git a/cc/afdo_test.go b/cc/afdo_test.go new file mode 100644 index 000000000..551546424 --- /dev/null +++ b/cc/afdo_test.go @@ -0,0 +1,70 @@ +// Copyright 2022 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 cc + +import ( + "testing" + + "android/soong/android" + "github.com/google/blueprint" +) + +func TestAfdoDeps(t *testing.T) { + bp := ` + cc_library { + name: "libTest", + srcs: ["foo.c"], + static_libs: ["libFoo"], + afdo: true, + } + + cc_library { + name: "libFoo", + static_libs: ["libBar"], + } + + cc_library { + name: "libBar", + } + ` + prepareForAfdoTest := android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libTest.afdo", "TEST") + + result := android.GroupFixturePreparers( + prepareForCcTest, + prepareForAfdoTest, + ).RunTestWithBp(t, bp) + + libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module() + libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest").Module() + libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest").Module() + + hasDep := func(m android.Module, wantDep android.Module) bool { + var found bool + result.VisitDirectDeps(m, func(dep blueprint.Module) { + if dep == wantDep { + found = true + } + }) + return found + } + + if !hasDep(libTest, libFoo) { + t.Errorf("libTest missing dependency on afdo variant of libFoo") + } + + if !hasDep(libFoo, libBar) { + t.Errorf("libTest missing dependency on afdo variant of libBar") + } +} diff --git a/cc/androidmk.go b/cc/androidmk.go index f6fe6f7bd..b56d689d6 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -15,6 +15,8 @@ package cc import ( + "github.com/google/blueprint/proptools" + "fmt" "io" "path/filepath" @@ -439,14 +441,6 @@ func (test *testLibrary) AndroidMkEntries(ctx AndroidMkContext, entries *android ctx.subAndroidMk(entries, test.libraryDecorator) } -func (library *toolchainLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { - entries.Class = "STATIC_LIBRARIES" - entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - _, suffix, _ := android.SplitFileExt(entries.OutputFile.Path().Base()) - entries.SetString("LOCAL_MODULE_SUFFIX", suffix) - }) -} - func (installer *baseInstaller) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { if installer.path == (android.InstallPath{}) { return @@ -532,7 +526,13 @@ func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entrie c.libraryDecorator.androidMkWriteExportedFlags(entries) if c.shared() || c.static() { - path, file := filepath.Split(c.path.String()) + src := c.path.String() + // For static libraries which aren't installed, directly use Src to extract filename. + // This is safe: generated snapshot modules have a real path as Src, not a module + if c.static() { + src = proptools.String(c.properties.Src) + } + path, file := filepath.Split(src) stem, suffix, ext := android.SplitFileExt(file) entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext) entries.SetString("LOCAL_MODULE_SUFFIX", suffix) diff --git a/cc/builder.go b/cc/builder.go index 512f83885..a5e540685 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -744,7 +744,7 @@ func transformObjToStaticLib(ctx android.ModuleContext, arCmd := "${config.ClangBin}/llvm-ar" arFlags := "" if !ctx.Darwin() { - arFlags += " -format=gnu" + arFlags += " --format=gnu" } if len(wholeStaticLibs) == 0 { @@ -548,8 +548,7 @@ type feature interface { } // compiler is the interface for a compiler helper object. Different module decorators may implement -// this helper differently. For example, compiling a `cc_library` may use a different build -// statement than building a `toolchain_library`. +// this helper differently. type compiler interface { compilerInit(ctx BaseModuleContext) compilerDeps(ctx DepsContext, deps Deps) Deps @@ -979,13 +978,6 @@ func (c *Module) SelectedStl() string { return "" } -func (c *Module) ToolchainLibrary() bool { - if _, ok := c.linker.(*toolchainLibraryDecorator); ok { - return true - } - return false -} - func (c *Module) NdkPrebuiltStl() bool { if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok { return true @@ -2450,10 +2442,6 @@ func checkLinkType(ctx android.BaseModuleContext, from LinkableInterface, to Lin return } if c, ok := to.(*Module); ok { - if c.ToolchainLibrary() { - // These are always allowed - return - } if c.NdkPrebuiltStl() { // These are allowed, but they don't set sdk_version return @@ -3439,10 +3427,6 @@ func (c *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, if strings.HasPrefix(ctx.OtherModuleName(c), "libclang_rt") { return nil } - // b/154569636: set min_sdk_version correctly for toolchain_libraries - if c.ToolchainLibrary() { - return nil - } // We don't check for prebuilt modules if _, ok := c.linker.(prebuiltLinkerInterface); ok { return nil diff --git a/cc/config/global.go b/cc/config/global.go index e46ac9616..5acc7f52c 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -46,6 +46,7 @@ var ( "-O2", "-g", + "-fdebug-default-version=5", "-fno-strict-aliasing", diff --git a/cc/linker.go b/cc/linker.go index aaaca7ad4..bea65d441 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -427,7 +427,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) - if ctx.Windows() { + if ctx.Windows() && ctx.ModuleName() != "libwinpthread" { deps.LateStaticLibs = append(deps.LateStaticLibs, "libwinpthread") } @@ -208,6 +208,10 @@ func (props *PgoProperties) isPGO(ctx BaseModuleContext) bool { ctx.ModuleErrorf("Instrumentation PGO specification is missing benchmark property") } + if isSampling { + ctx.ModuleErrorf("Sampling PGO is deprecated, use AFDO instead") + } + if isSampling && isInstrumentation { ctx.PropertyErrorf("pgo", "Exactly one of \"instrumentation\" and \"sampling\" properties must be set") } diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index 253a11bb6..753d74c75 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -506,7 +506,7 @@ func (p *snapshotLibraryDecorator) link(ctx ModuleContext, flags Flags, deps Pat } func (p *snapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) { - if p.MatchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) { + if p.MatchesWithDevice(ctx.DeviceConfig()) && p.shared() { p.baseInstaller.install(ctx, file) } } diff --git a/cc/testing.go b/cc/testing.go index 3bf936d43..3d0c10a88 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -30,7 +30,6 @@ func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterLibraryBuildComponents(ctx) RegisterLibraryHeadersBuildComponents(ctx) - ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory) ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory) ctx.RegisterModuleType("cc_object", ObjectFactory) ctx.RegisterModuleType("cc_genrule", GenRuleFactory) @@ -63,131 +62,110 @@ func GatherRequiredDepsForTest(oses ...android.OsType) string { func commonDefaultModules() string { return ` - toolchain_library { - name: "libcompiler_rt-extras", + cc_defaults { + name: "toolchain_libs_defaults", vendor_available: true, - vendor_ramdisk_available: true, product_available: true, recovery_available: true, - src: "", + no_libcrt: true, + sdk_version: "minimum", + nocrt: true, + system_shared_libs: [], + stl: "none", + srcs: [""], + check_elf_files: false, + sanitize: { + never: true, + }, } - toolchain_library { - name: "libclang_rt.builtins-arm-android", - vendor_available: true, + cc_prebuilt_library_static { + name: "libcompiler_rt-extras", + defaults: ["toolchain_libs_defaults"], vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, + } + + cc_prebuilt_library_static { + name: "libclang_rt.builtins-arm-android", + defaults: ["toolchain_libs_defaults"], native_bridge_supported: true, - src: "", + vendor_ramdisk_available: true, } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.builtins-aarch64-android", - vendor_available: true, - vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, + defaults: ["toolchain_libs_defaults"], native_bridge_supported: true, - src: "", + vendor_ramdisk_available: true, } cc_prebuilt_library_shared { name: "libclang_rt.hwasan-aarch64-android", - nocrt: true, - vendor_available: true, - product_available: true, - recovery_available: true, - system_shared_libs: [], - stl: "none", - srcs: [""], - check_elf_files: false, - sanitize: { - never: true, - }, + defaults: ["toolchain_libs_defaults"], } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.builtins-i686-android", - vendor_available: true, + defaults: ["toolchain_libs_defaults"], vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, native_bridge_supported: true, - src: "", } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.builtins-x86_64-android", - defaults: ["linux_bionic_supported"], - vendor_available: true, - vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, + defaults: [ + "linux_bionic_supported", + "toolchain_libs_defaults", + ], native_bridge_supported: true, - src: "", + vendor_ramdisk_available: true, } - toolchain_library { + cc_prebuilt_library_static { name: "libunwind", - defaults: ["linux_bionic_supported"], - vendor_available: true, + defaults: [ + "linux_bionic_supported", + "toolchain_libs_defaults", + ], vendor_ramdisk_available: true, - product_available: true, - recovery_available: true, native_bridge_supported: true, - src: "", } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.fuzzer-arm-android", - vendor_available: true, - product_available: true, - recovery_available: true, - src: "", + defaults: ["toolchain_libs_defaults"], } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.fuzzer-aarch64-android", - vendor_available: true, - product_available: true, - recovery_available: true, - src: "", + defaults: ["toolchain_libs_defaults"], } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.fuzzer-i686-android", - vendor_available: true, - product_available: true, - recovery_available: true, - src: "", + defaults: ["toolchain_libs_defaults"], } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.fuzzer-x86_64-android", - defaults: ["linux_bionic_supported"], - vendor_available: true, - product_available: true, - recovery_available: true, - src: "", + defaults: [ + "linux_bionic_supported", + "toolchain_libs_defaults", + ], } - toolchain_library { + cc_prebuilt_library_static { name: "libclang_rt.fuzzer-x86_64", - vendor_available: true, - product_available: true, - recovery_available: true, - src: "", + defaults: [ + "linux_bionic_supported", + "toolchain_libs_defaults", + ], } // Needed for sanitizer cc_prebuilt_library_shared { name: "libclang_rt.ubsan_standalone-aarch64-android", - vendor_available: true, - product_available: true, - recovery_available: true, - system_shared_libs: [], - srcs: [""], + defaults: ["toolchain_libs_defaults"], } cc_library { @@ -480,7 +458,7 @@ func commonDefaultModules() string { func withWindowsModules() string { return ` - toolchain_library { + cc_prebuilt_library_static { name: "libwinpthread", host_supported: true, enabled: false, @@ -489,7 +467,8 @@ func withWindowsModules() string { enabled: true, }, }, - src: "", + stl: "none", + srcs:[""], } ` } diff --git a/cc/tidy.go b/cc/tidy.go index 97418fe17..1f5f56d5b 100644 --- a/cc/tidy.go +++ b/cc/tidy.go @@ -156,6 +156,9 @@ func (tidy *tidyFeature) flags(ctx ModuleContext, flags Flags) Flags { // Too many existing functions trigger this rule, and fixing it requires large code // refactoring. The cost of maintaining this tidy rule outweighs the benefit it brings. tidyChecks = tidyChecks + ",-bugprone-easily-swappable-parameters" + // http://b/216364337 - TODO: Follow-up after compiler update to + // disable or fix individual instances. + tidyChecks = tidyChecks + ",-cert-err33-c" flags.TidyFlags = append(flags.TidyFlags, tidyChecks) if ctx.Config().IsEnvTrue("WITH_TIDY") { diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go deleted file mode 100644 index bda73eabf..000000000 --- a/cc/toolchain_library.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2016 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 cc - -import ( - "android/soong/android" -) - -// -// Device libraries shipped with gcc -// - -func init() { - android.RegisterModuleType("toolchain_library", ToolchainLibraryFactory) -} - -type toolchainLibraryProperties struct { - // the prebuilt toolchain library, as a path from the top of the source tree - Src *string `android:"arch_variant"` - - // Repack the archive with only the selected objects. - Repack_objects_to_keep []string `android:"arch_variant"` -} - -type toolchainLibraryDecorator struct { - *libraryDecorator - stripper Stripper - - Properties toolchainLibraryProperties -} - -func (*toolchainLibraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { - // toolchain libraries can't have any dependencies - return deps -} - -func (library *toolchainLibraryDecorator) linkerProps() []interface{} { - var props []interface{} - props = append(props, library.libraryDecorator.linkerProps()...) - return append(props, &library.Properties, &library.stripper.StripProperties) -} - -// toolchain_library is used internally by the build tool to link the specified -// static library in src property to the device libraries that are shipped with -// gcc. -func ToolchainLibraryFactory() android.Module { - module, library := NewLibrary(android.HostAndDeviceSupported) - library.BuildOnlyStatic() - toolchainLibrary := &toolchainLibraryDecorator{ - libraryDecorator: library, - } - module.compiler = toolchainLibrary - module.linker = toolchainLibrary - module.stl = nil - module.sanitize = nil - module.installer = nil - module.library = toolchainLibrary - module.Properties.Sdk_version = StringPtr("current") - return module.Init() -} - -func (library *toolchainLibraryDecorator) compile(ctx ModuleContext, flags Flags, - deps PathDeps) Objects { - return Objects{} -} - -func (library *toolchainLibraryDecorator) link(ctx ModuleContext, - flags Flags, deps PathDeps, objs Objects) android.Path { - - if library.Properties.Src == nil { - ctx.PropertyErrorf("src", "No library source specified") - return android.PathForSource(ctx, "") - } - - srcPath := android.PathForSource(ctx, *library.Properties.Src) - outputFile := android.Path(srcPath) - - if library.Properties.Repack_objects_to_keep != nil { - fileName := ctx.ModuleName() + staticLibraryExtension - repackedPath := android.PathForModuleOut(ctx, fileName) - transformArchiveRepack(ctx, outputFile, repackedPath, library.Properties.Repack_objects_to_keep) - outputFile = repackedPath - } - - if library.stripper.StripProperties.Strip.Keep_symbols_list != nil { - fileName := ctx.ModuleName() + staticLibraryExtension - strippedPath := android.PathForModuleOut(ctx, fileName) - stripFlags := flagsToStripFlags(flags) - library.stripper.StripStaticLib(ctx, outputFile, strippedPath, stripFlags) - outputFile = strippedPath - } - - depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputFile).Build() - ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ - StaticLibrary: outputFile, - - TransitiveStaticLibrariesForOrdering: depSet, - }) - - return outputFile -} - -func (library *toolchainLibraryDecorator) nativeCoverage() bool { - return false -} diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go index b5022c8d2..645b2ccf6 100644 --- a/cc/vendor_snapshot_test.go +++ b/cc/vendor_snapshot_test.go @@ -65,10 +65,13 @@ func TestVendorSnapshotCapture(t *testing.T) { nocrt: true, } - toolchain_library { + cc_prebuilt_library_static { name: "libb", vendor_available: true, - src: "libb.a", + srcs: ["libb.a"], + nocrt: true, + no_libcrt: true, + stl: "none", } cc_object { @@ -1222,10 +1225,13 @@ func TestRecoverySnapshotCapture(t *testing.T) { nocrt: true, } - toolchain_library { + cc_prebuilt_library_static { name: "libb", recovery_available: true, - src: "libb.a", + srcs: ["libb.a"], + nocrt: true, + no_libcrt: true, + stl: "none", } cc_object { diff --git a/docs/OWNERS b/docs/OWNERS index d1433171d..45ec5232c 100644 --- a/docs/OWNERS +++ b/docs/OWNERS @@ -1 +1,2 @@ per-file map_files.md = danalbert@google.com, enh@google.com, jiyong@google.com +per-file native_code_coverage.md = pirama@google.com, srhines@google.com, allenhair@google.com diff --git a/docs/native_code_coverage.md b/docs/native_code_coverage.md new file mode 100644 index 000000000..fabbfa013 --- /dev/null +++ b/docs/native_code_coverage.md @@ -0,0 +1,241 @@ +## Native Code Coverage for Android + +## Scope + +These instructions are for Android developers to collect and inspect code +coverage for C++ and Rust code on the Android platform. + +## Building with Native Code Coverage Instrumentation + +Identify the paths where native code-coverage instrumentation should be enabled +and set up the following environment variables. + +``` + export CLANG_COVERAGE=true + export NATIVE_COVERAGE_PATHS="<paths-to-instrument-for-coverage>" +``` + +`NATIVE_COVERAGE_PATHS` should be a list of paths. Any Android.bp module defined +under these paths is instrumented for code-coverage. E.g: + +``` +export NATIVE_COVERAGE_PATHS="external/libcxx system/core/adb" +``` + +### Additional Notes + +- Native Code coverage is not supported for host modules or `Android.mk` + modules. +- `NATIVE_COVERAGE_PATHS="*"` enables coverage instrumentation for all paths. +- Set `native_coverage: false` blueprint property to always disable code + coverage instrumentation for a module. This is useful if this module has + issues when building or running with coverage. +- `NATIVE_COVERAGE_EXCLUDE_PATHS` can be set to exclude subdirs under + `NATIVE_COVERAGE_PATHS` from coverage instrumentation. E.g. + `NATIVE_COVERAGE_PATHS=frameworks/native + NATIVE_COVERAGE_PATHS=frameworks/native/vulkan` will instrument all native + code under `frameworks/native` except`frameworks/native/vulkan`. + +## Running Tests + +### Collecting Profiles + +When an instrumented program is run, the profiles are stored to the path and +name specified in the `LLVM_PROFILE_FILE` environment variable. On Android +coverage builds it is set to `/data/misc/trace/clang-%p-%20m.profraw`. + +* `%`p is replaced by the pid of the process +* `%m` by the hash of the library/binary +* The `20` in`%20m` creates a pool of 20 profraw files and "online" profile + merging is used to merge coverage to profiles onto this pool. + +Reference:`LLVM_PROFILE_FILE` can include additional specifiers as described +[here](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program). + +For this and following steps, use the `acov-llvm.py` script: +`$ANDROID_BUILD_TOP/development/scripts/acov-llvm.py`. + +There may be profiles in `/data/misc/trace` collected before the test is run. +Clear this data before running the test. + +``` + # Clear any coverage that's already written to /data/misc/trace + # and reset coverage for all daemons. + <host>$ acov-llvm.py clean-device + + # Run the test. The exact command depends on the nature of the test. + <device>$ /data/local/tmp/$MY_TEST +``` + +For tests that exercise a daemon/service running in another process, write out +the coverage for those processes as well. + +``` + # Flush coverage of all daemons/processes running on the device. + <host>$ acov-llvm.py flush + + # Flush coverage for a particular daemon, say adbd. + <host>$ acov-llvm.py flush adbd +``` + +## Viewing Coverage Data (acov-llvm.py) + +To post-process and view coverage information we use the `acov-llvm.py report` +command. It invokes two LLVM utilities `llvm-profdata` and `llvm-cov`. An +advanced user can manually invoke these utilities for fine-grained control. This +is discussed [below](#viewing-coverage-data-manual). + +To generate coverage report need the following parameters. These are dependent +on the test/module: + +1. One or more binaries and shared libraries from which coverage was collected. + E.g.: + + 1. ART mainline module contains a few libraries such as `libart.so`, + `libart-compiler.so`. + 2. Bionic tests exercise code in `libc.so` and `libm.so`. + + We need the *unstripped* copies of these binaries. Source information + included in the debuginfo is used to process the coverage data. + +2. One or more source directories under `$ANDROID_BUILD_TOP` for which coverage + needs to be reported. + +Invoke the report subcommand of acov-llvm.py to produce a html coverage summary: + +``` + $ acov-llvm.py report \ + -s <one-or-more-source-paths-in-$ANDROID_BUILD_TOP \ + -b <one-or-more-(unstripped)-binaries-in-$OUT> +``` + +E.g.: + +``` + $ acov-llvm.py report \ + -s bionic \ + -b \ + $OUT/symbols/apex/com.android.runtime/lib/bionic/libc.so \ + $OUT/symbols/apex/com.android.runtime/lib/bionic/libm.so +``` + +The script will produce a report in a temporary directory under +`$ANDROID_BUILD_TOP`. It'll produce a log as below: + +``` + generating coverage report in covreport-xxxxxx +``` + +A html report would be generated under `covreport-xxxxxx/html`. + +## Viewing Coverage Data (manual) + +`acov-llvm.py report` does a few operations under the hood which we can also +manually invoke for flexibility. + +### Post-processing Coverage Files + +Fetch coverage files from the device and post-process them to a `.profdata` file +as follows: + +``` + # Fetch the coverage data from the device. + <host>$ cd coverage_data + <host>$ adb pull /data/misc/trace/ $TRACE_DIR_HOST + + # Convert from .profraw format to the .profdata format. + <host>$ llvm-profdata merge --output=$MY_TEST.profdata \ + $TRACE_DIR_HOST/clang-*.profraw +``` + +For added specificity, restrict the above command to just the <PID>s of the +daemon or test processes of interest. + +``` + <host>$ llvm-profdata merge --output=$MY_TEST.profdata \ + $MY_TEST.profraw \ + trace/clang-<pid1>.profraw trace/clang-<pid2>.profraw ... +``` + +### Generating Coverage report + +Documentation on Clang source-instrumentation-based coverage is available +[here](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#creating-coverage-reports). +The `llvm-cov` utility is used to show coverage from a `.profdata` file. The +documentation for commonly used `llvm-cov` command-line arguments is available +[here](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report). (Try +`llvm-cov show --help` for a complete list). + +#### `show` subcommand + +The `show` command displays the function and line coverage for each source file +in the binary. + +``` + <host>$ llvm-cov show \ + --show-region-summary=false + --format=html --output-dir=coverage-html \ + --instr-profile=$MY_TEST.profdata \ + $MY_BIN \ +``` + +* In the above command, `$MY_BIN` should be the unstripped binary (i.e. with + debuginfo) since `llvm-cov` reads some debuginfo to process the coverage + data. + + E.g.: + + ~~~ + ``` + <host>$ llvm-cov report \ + --instr-profile=adbd.profdata \ + $LOCATION_OF_UNSTRIPPED_ADBD/adbd \ + --show-region-summary=false + ``` + ~~~ + +* The `-ignore-filename-regex=<regex>` option can be used to ignore files that + are not of interest. E.g: `-ignore-filename-regex="external/*"` + +* Use the `--object=<BIN>` argument to specify additional binaries and shared + libraries whose coverage is included in this profdata. See the earlier + [section](#viewing-coverage-data-acov-llvm-py) for examples where more than + one binary may need to be used. + + E.g., the following command is used for `bionic-unit-tests`, which tests + both `libc.so` and `libm.so`: + + ~~~ + ``` + <host>$ llvm-cov report \ + --instr-profile=bionic.profdata \ + $OUT/.../libc.so \ + --object=$OUT/.../libm.so + ``` + ~~~ + +* `llvm-cov` also takes positional SOURCES argument to consider/display only + particular paths of interest. E.g: + + ~~~ + ``` + <host>$ llvm-cov report \ + --instr-profile=adbd.profdata \ + $LOCATION_OF_ADBD/adbd \ + --show-region-summary=false \ + /proc/self/cwd/system/core/adb + ``` + ~~~ + +Note that the paths for the sources need to be prepended with +'`/proc/self/cwd/`'. This is because Android C/C++ compilations run with +`PWD=/proc/self/cwd` and consequently the source names are recorded with that +prefix. Alternatively, the +[`--path-equivalence`](https://llvm.org/docs/CommandGuide/llvm-cov.html#cmdoption-llvm-cov-show-path-equivalence) +option to `llvm-cov` can be used. + +#### `report` subcommand + +The [`report`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-report) +subcommand summarizes the percentage of covered lines to the console. It takes +options similar to the `show` subcommand. diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go index 377a56651..a142833dd 100644 --- a/etc/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -54,6 +54,7 @@ func RegisterPrebuiltEtcBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) ctx.RegisterModuleType("prebuilt_root", PrebuiltRootFactory) + ctx.RegisterModuleType("prebuilt_root_host", PrebuiltRootHostFactory) ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) ctx.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) ctx.RegisterModuleType("prebuilt_font", PrebuiltFontFactory) @@ -454,6 +455,17 @@ func PrebuiltRootFactory() android.Module { return module } +// prebuilt_root_host is for a host prebuilt artifact that is installed in $(HOST_OUT)/<sub_dir> +// directory. +func PrebuiltRootHostFactory() android.Module { + module := &PrebuiltEtc{} + InitPrebuiltEtcModule(module, ".") + // This module is host-only + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) + android.InitDefaultableModule(module) + return module +} + // prebuilt_usr_share is for a prebuilt artifact that is installed in // <partition>/usr/share/<sub_dir> directory. func PrebuiltUserShareFactory() android.Module { diff --git a/java/base.go b/java/base.go index 63328c89d..a3eb8de21 100644 --- a/java/base.go +++ b/java/base.go @@ -122,14 +122,6 @@ type CommonProperties struct { Javacflags []string } - Openjdk11 struct { - // List of source files that should only be used when passing -source 1.9 or higher - Srcs []string `android:"path"` - - // List of javac flags that should only be used when passing -source 1.9 or higher - Javacflags []string - } - // When compiling language level 9+ .java code in packages that are part of // a system module, patch_module names the module that your sources and // dependencies should be patched into. The Android runtime currently @@ -976,9 +968,6 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { if flags.javaVersion.usesJavaModules() { j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) } - if ctx.Config().TargetsJava11() { - j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk11.Srcs...) - } srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) if hasSrcExt(srcFiles.Strings(), ".proto") { diff --git a/java/java.go b/java/java.go index bb7c32be8..171415207 100644 --- a/java/java.go +++ b/java/java.go @@ -325,6 +325,7 @@ func IsJniDepTag(depTag blueprint.DependencyTag) bool { var ( dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} + dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} staticLibTag = dependencyTag{name: "staticlib"} libTag = dependencyTag{name: "javalib", runtimeLinked: true} java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} @@ -450,14 +451,8 @@ func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext an return normalizeJavaVersion(ctx, javaVersion) } else if ctx.Device() { return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) - } else if ctx.Config().TargetsJava11() { - // Temporary experimental flag to be able to try and build with - // java version 11 options. The flag, if used, just sets Java - // 11 as the default version, leaving any components that - // target an older version intact. - return JAVA_VERSION_11 } else { - return JAVA_VERSION_9 + return JAVA_VERSION_11 } } @@ -837,6 +832,9 @@ type testProperties struct { type hostTestProperties struct { // list of native binary modules that should be installed alongside the test Data_native_bins []string `android:"arch_variant"` + + // list of device binary modules that should be installed alongside the test + Data_device_bins []string `android:"arch_variant"` } type testHelperLibraryProperties struct { @@ -910,6 +908,11 @@ func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { } } + if len(j.testHostProperties.Data_device_bins) > 0 { + deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() + ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins...) + } + if len(j.testProperties.Jni_libs) > 0 { for _, target := range ctx.MultiTargets() { sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) @@ -924,14 +927,35 @@ func (j *TestHost) AddExtraResource(p android.Path) { j.extraResources = append(j.extraResources, p) } +func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { + var configs []tradefed.Config + if len(j.testHostProperties.Data_device_bins) > 0 { + // add Tradefed configuration to push device bins to device for testing + remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) + options := []tradefed.Option{{Name: "cleanup", Value: "true"}} + for _, bin := range j.testHostProperties.Data_device_bins { + fullPath := filepath.Join(remoteDir, bin) + options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) + } + configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.PushFilePreparer", options}) + } + + j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) +} + func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { + j.generateAndroidBuildActionsWithConfig(ctx, nil) +} + +func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest) } + j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, - j.testProperties.Test_suites, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test) + j.testProperties.Test_suites, configs, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test) j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) @@ -941,6 +965,10 @@ func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) }) + ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) { + j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) + }) + ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo) if sharedLibInfo.SharedLibrary != nil { @@ -973,7 +1001,7 @@ func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContex func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil, - j.prebuiltTestProperties.Test_suites, nil, nil) + j.prebuiltTestProperties.Test_suites, nil, nil, nil) j.Import.GenerateAndroidBuildActions(ctx) } diff --git a/java/java_test.go b/java/java_test.go index 3a51981e6..21c76b6c1 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1460,3 +1460,64 @@ func TestErrorproneEnabledOnlyByEnvironmentVariable(t *testing.T) { t.Errorf("expected errorprone to contain %q, got %q", expectedSubstring, javac.Args["javacFlags"]) } } + +func TestDataDeviceBinsBuildsDeviceBinary(t *testing.T) { + bp := ` + java_test_host { + name: "foo", + srcs: ["test.java"], + data_device_bins: ["bar"], + } + + cc_binary { + name: "bar", + } + ` + + ctx := android.GroupFixturePreparers( + PrepareForIntegrationTestWithJava, + ).RunTestWithBp(t, bp) + + buildOS := ctx.Config.BuildOS.String() + fooVariant := ctx.ModuleForTests("foo", buildOS+"_common") + barVariant := ctx.ModuleForTests("bar", "android_arm64_armv8-a") + fooMod := fooVariant.Module().(*TestHost) + + relocated := barVariant.Output("bar") + expectedInput := "out/soong/.intermediates/bar/android_arm64_armv8-a/unstripped/bar" + android.AssertPathRelativeToTopEquals(t, "relocation input", expectedInput, relocated.Input) + + entries := android.AndroidMkEntriesForTest(t, ctx.TestContext, fooMod)[0] + expectedData := []string{ + "out/soong/.intermediates/bar/android_arm64_armv8-a/bar:bar", + } + actualData := entries.EntryMap["LOCAL_COMPATIBILITY_SUPPORT_FILES"] + android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", ctx.Config, expectedData, actualData) +} + +func TestDataDeviceBinsAutogenTradefedConfig(t *testing.T) { + bp := ` + java_test_host { + name: "foo", + srcs: ["test.java"], + data_device_bins: ["bar"], + } + + cc_binary { + name: "bar", + } + ` + + ctx := android.GroupFixturePreparers( + PrepareForIntegrationTestWithJava, + ).RunTestWithBp(t, bp) + + buildOS := ctx.Config.BuildOS.String() + fooModule := ctx.ModuleForTests("foo", buildOS+"_common") + expectedAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` + + autogen := fooModule.Rule("autogen") + if !strings.Contains(autogen.Args["extraConfigs"], expectedAutogenConfig) { + t.Errorf("foo extraConfigs %v does not contain %q", autogen.Args["extraConfigs"], expectedAutogenConfig) + } +} diff --git a/java/sdk.go b/java/sdk.go index 756a24deb..0dddd40aa 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -55,14 +55,10 @@ func defaultJavaLanguageVersion(ctx android.EarlyModuleContext, s android.SdkSpe return JAVA_VERSION_7 } else if sdk.FinalOrFutureInt() <= 29 { return JAVA_VERSION_8 - } else if ctx.Config().TargetsJava11() { - // Temporary experimental flag to be able to try and build with - // java version 11 options. The flag, if used, just sets Java - // 11 as the default version, leaving any components that - // target an older version intact. - return JAVA_VERSION_11 - } else { + } else if sdk.FinalOrFutureInt() <= 31 { return JAVA_VERSION_9 + } else { + return JAVA_VERSION_11 } } diff --git a/java/sdk_library.go b/java/sdk_library.go index 7849f96f5..57ab2686f 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1392,10 +1392,6 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext Srcs []string Javacflags []string } - Openjdk11 struct { - Srcs []string - Javacflags []string - } Dist struct { Targets []string Dest *string @@ -1422,8 +1418,6 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext } props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags - props.Openjdk11.Srcs = module.properties.Openjdk11.Srcs - props.Openjdk11.Javacflags = module.properties.Openjdk11.Javacflags // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential // interop with older developer tools that don't support 1.9. props.Java_version = proptools.StringPtr("1.8") diff --git a/linkerconfig/proto/linker_config.proto b/linkerconfig/proto/linker_config.proto index fec66c85e..dccf311bb 100644 --- a/linkerconfig/proto/linker_config.proto +++ b/linkerconfig/proto/linker_config.proto @@ -34,4 +34,16 @@ message LinkerConfig { // Required libs from the module repeated string requireLibs = 4; + + message Contribution { + // Target namespace where this module contributes the search paths. + string namespace = 1; + // Search paths (inc. permitted paths) that this module contributes. + // Paths should be related to the current module and can use "${LIB}" variable which is + // expanded to "lib" or "lib64". + // e.g. ${LIB}/subdir + repeated string paths = 2; + } + // APEX can contribute search paths to specified namespaces. + repeated Contribution contributions = 5; } diff --git a/rust/Android.bp b/rust/Android.bp index 5e14da8ac..3fd68e556 100644 --- a/rust/Android.bp +++ b/rust/Android.bp @@ -14,6 +14,7 @@ bootstrap_go_package { "soong-snapshot", ], srcs: [ + "afdo.go", "androidmk.go", "benchmark.go", "binary.go", diff --git a/rust/afdo.go b/rust/afdo.go new file mode 100644 index 000000000..996fd7e0c --- /dev/null +++ b/rust/afdo.go @@ -0,0 +1,48 @@ +// Copyright 2022 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 rust + +import ( + "fmt" + + "android/soong/cc" +) + +const afdoFlagFormat = "-Zprofile-sample-use=%s" + +type afdo struct { + Properties cc.AfdoProperties +} + +func (afdo *afdo) props() []interface{} { + return []interface{}{&afdo.Properties} +} + +func (afdo *afdo) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags, PathDeps) { + if ctx.Host() { + return flags, deps + } + + if afdo != nil && afdo.Properties.Afdo { + if profileFile := afdo.Properties.GetAfdoProfileFile(ctx, ctx.ModuleName()); profileFile.Valid() { + profileUseFlag := fmt.Sprintf(afdoFlagFormat, profileFile) + flags.RustFlags = append(flags.RustFlags, profileUseFlag) + + profileFilePath := profileFile.Path() + deps.AfdoProfiles = append(deps.AfdoProfiles, profileFilePath) + } + } + return flags, deps +} diff --git a/rust/builder.go b/rust/builder.go index cfb9fe1e9..00035b9b7 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -245,6 +245,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl implicits = append(implicits, deps.StaticLibs...) implicits = append(implicits, deps.SharedLibDeps...) implicits = append(implicits, deps.srcProviderFiles...) + implicits = append(implicits, deps.AfdoProfiles...) implicits = append(implicits, deps.CrtBegin...) implicits = append(implicits, deps.CrtEnd...) diff --git a/rust/coverage.go b/rust/coverage.go index 8fdfa2342..050b811c7 100644 --- a/rust/coverage.go +++ b/rust/coverage.go @@ -57,18 +57,7 @@ func (cov *coverage) flags(ctx ModuleContext, flags Flags, deps PathDeps) (Flags flags.RustFlags = append(flags.RustFlags, "-Z instrument-coverage", "-g") flags.LinkFlags = append(flags.LinkFlags, - profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open", - // Upstream LLVM change 6d2d3bd0a6 made - // -z,start-stop-gc the default. It drops metadata - // sections like __llvm_prf_data unless they are marked - // SHF_GNU_RETAIN. https://reviews.llvm.org/D97448 - // marks generated sections, including __llvm_prf_data - // as SHF_GNU_RETAIN. However this change is not in - // the Rust toolchain. Since we link Rust libs with - // new lld, we should use nostart-stop-gc until the - // Rust toolchain updates past D97448. - "-Wl,-z,nostart-stop-gc", - ) + profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open") deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path()) } diff --git a/rust/rust.go b/rust/rust.go index 0a941bf2d..018d1dd27 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -148,6 +148,7 @@ type Module struct { makeLinkType string + afdo *afdo compiler compiler coverage *coverage clippy *clippy @@ -403,6 +404,7 @@ type PathDeps struct { SharedLibDeps android.Paths StaticLibs android.Paths ProcMacros RustLibraries + AfdoProfiles android.Paths // depFlags and depLinkFlags are rustc and linker (clang) flags. depFlags []string @@ -551,6 +553,7 @@ func DefaultsFactory(props ...interface{}) android.Module { module.AddProperties(props...) module.AddProperties( &BaseProperties{}, + &cc.AfdoProperties{}, &cc.VendorProperties{}, &BenchmarkProperties{}, &BindgenProperties{}, @@ -688,6 +691,9 @@ func (mod *Module) Init() android.Module { mod.AddProperties(&mod.Properties) mod.AddProperties(&mod.VendorProperties) + if mod.afdo != nil { + mod.AddProperties(mod.afdo.props()...) + } if mod.compiler != nil { mod.AddProperties(mod.compiler.compilerProps()...) } @@ -719,6 +725,7 @@ func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) } func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { module := newBaseModule(hod, multilib) + module.afdo = &afdo{} module.coverage = &coverage{} module.clippy = &clippy{} module.sanitize = &sanitize{} @@ -856,6 +863,9 @@ func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { } // Calculate rustc flags + if mod.afdo != nil { + flags, deps = mod.afdo.flags(ctx, flags, deps) + } if mod.compiler != nil { flags = mod.compiler.compilerFlags(ctx, flags) flags = mod.compiler.cfgFlags(ctx, flags) diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go index 28b6fb93a..7fe1d8538 100644 --- a/sh/sh_binary_test.go +++ b/sh/sh_binary_test.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "testing" "android/soong/android" @@ -215,3 +216,40 @@ func TestShTestHost_dataDeviceModules(t *testing.T) { actualData := entries.EntryMap["LOCAL_TEST_DATA"] android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", config, expectedData, actualData) } + +func TestShTestHost_dataDeviceModulesAutogenTradefedConfig(t *testing.T) { + ctx, config := testShBinary(t, ` + sh_test_host { + name: "foo", + src: "test.sh", + data_device_bins: ["bar"], + data_device_libs: ["libbar"], + } + + cc_binary { + name: "bar", + shared_libs: ["libbar"], + no_libcrt: true, + nocrt: true, + system_shared_libs: [], + stl: "none", + } + + cc_library { + name: "libbar", + no_libcrt: true, + nocrt: true, + system_shared_libs: [], + stl: "none", + } + `) + + buildOS := config.BuildOS.String() + fooModule := ctx.ModuleForTests("foo", buildOS+"_x86_64") + + expectedBinAutogenConfig := `<option name="push-file" key="bar" value="/data/local/tests/unrestricted/foo/bar" />` + autogen := fooModule.Rule("autogen") + if !strings.Contains(autogen.Args["extraConfigs"], expectedBinAutogenConfig) { + t.Errorf("foo extraConfings %v does not contain %q", autogen.Args["extraConfigs"], expectedBinAutogenConfig) + } +} diff --git a/tradefed/autogen.go b/tradefed/autogen.go index da5582973..c2429ab7a 100644 --- a/tradefed/autogen.go +++ b/tradefed/autogen.go @@ -188,20 +188,20 @@ func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp } func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string, - testSuites []string, autoGenConfig *bool, unitTest *bool) android.Path { + testSuites []string, config []Config, autoGenConfig *bool, unitTest *bool) android.Path { path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp) if autogenPath != nil { templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp) if templatePath.Valid() { - autogenTemplate(ctx, autogenPath, templatePath.String(), nil, "") + autogenTemplate(ctx, autogenPath, templatePath.String(), config, "") } else { if ctx.Device() { - autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", nil, "") + autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", config, "") } else { if Bool(unitTest) { - autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", nil, "") + autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", config, "") } else { - autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", nil, "") + autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", config, "") } } } diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 5961c4525..41de6bd7e 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -141,6 +141,8 @@ func runNinjaForBuild(ctx Context, config Config) { // RBE client "RBE_compare", + "RBE_num_local_reruns", + "RBE_num_remote_reruns", "RBE_exec_root", "RBE_exec_strategy", "RBE_invocation_id", |