Merge "Add jni support to java_fuzz_host"
diff --git a/Android.bp b/Android.bp
index 42a8e5c..63de015 100644
--- a/Android.bp
+++ b/Android.bp
@@ -119,3 +119,14 @@
dexpreopt_systemserver_check {
name: "dexpreopt_systemserver_check",
}
+
+// buildinfo.prop contains common properties for system/build.prop, like ro.build.version.*
+buildinfo_prop {
+ name: "buildinfo.prop",
+
+ // not installable because this will be included to system/build.prop
+ installable: false,
+
+ // Currently, only microdroid can refer to buildinfo.prop
+ visibility: ["//packages/modules/Virtualization/microdroid"],
+}
diff --git a/OWNERS b/OWNERS
index 0cfb241..0662016 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,12 +2,13 @@
# approving build related projects.
# AMER
-ahumesky@google.com
+agespino@google.com
alexmarquez@google.com
asmundak@google.com
ccross@android.com
colefaust@google.com
cparsons@google.com
+dacek@google.com
delmerico@google.com
dwillemsen@google.com
eakammer@google.com
@@ -17,13 +18,12 @@
spandandas@google.com
tradical@google.com
usta@google.com
+vinhdaitran@google.com
weiwli@google.com
yudiliu@google.com
-yuntaoxu@google.com
# APAC
jingwen@google.com
-ruperts@google.com
# EMEA
hansson@google.com
diff --git a/android/Android.bp b/android/Android.bp
index 87b021f..d583703 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -36,6 +36,7 @@
"bazel.go",
"bazel_handler.go",
"bazel_paths.go",
+ "buildinfo_prop.go",
"config.go",
"config_bp2build.go",
"csuite_config.go",
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 72961e6..26cfd57 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -313,6 +313,7 @@
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
"libc_musl_sysroot_bionic_arch_headers", // depends on soong_zip
+ "libc_musl_sysroot_zlib_headers", // depends on soong_zip and zip2zip
"libc_musl_sysroot_bionic_headers", // 218405924, depends on soong_zip and generates duplicate srcs
"libc_musl_sysroot_libc++_headers", "libc_musl_sysroot_libc++abi_headers", // depends on soong_zip, zip2zip
"robolectric-sqlite4java-native", // depends on soong_zip, a go binary
@@ -367,6 +368,10 @@
"timezone-host", // depends on unconverted modules: art.module.api.annotations
"truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
"truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
+
+ // b/215723302; awaiting tz{data,_version} to then rename targets conflicting with srcs
+ "tzdata",
+ "tz_version",
}
Bp2buildCcLibraryStaticOnlyList = []string{}
diff --git a/android/androidmk.go b/android/androidmk.go
index e9c63fb..5c715b4 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -578,7 +578,7 @@
}
}
- if !base.InRamdisk() && !base.InVendorRamdisk() {
+ if !base.InVendorRamdisk() {
a.AddPaths("LOCAL_FULL_INIT_RC", base.initRcPaths)
}
if len(base.vintfFragmentsPaths) > 0 {
diff --git a/android/arch.go b/android/arch.go
index 6b81022..f732a7d 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1199,14 +1199,6 @@
if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
mergePropertyStruct(ctx, genProps, bionicProperties)
}
-
- // Special case: to ease the transition from glibc to musl, apply linux_glibc
- // properties (which has historically mean host linux) to musl variants.
- field = "Linux_glibc"
- prefix = "target.linux_glibc"
- if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok {
- mergePropertyStruct(ctx, genProps, bionicProperties)
- }
}
// Handle target OS properties in the form:
@@ -1426,14 +1418,6 @@
if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
result = append(result, osArchProperties)
}
-
- // Special case: to ease the transition from glibc to musl, apply linux_glibc
- // properties (which has historically mean host linux) to musl variants.
- field = "Linux_glibc_" + archType.Name
- userFriendlyField = "target.linux_glibc_" + archType.Name
- if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok {
- result = append(result, osArchProperties)
- }
}
}
diff --git a/android/arch_test.go b/android/arch_test.go
index 68dc7f5..dd0b115 100644
--- a/android/arch_test.go
+++ b/android/arch_test.go
@@ -606,12 +606,12 @@
{
module: "foo",
variant: "linux_musl_x86_64",
- property: []string{"root", "host", "linux", "host_linux", "musl", "linux_glibc", "linux_musl", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_musl_x86_64", "linux_glibc_x86_64"},
+ property: []string{"root", "host", "linux", "host_linux", "musl", "linux_musl", "not_windows", "x86_64", "lib64", "linux_x86_64", "linux_musl_x86_64"},
},
{
module: "foo",
variant: "linux_musl_x86",
- property: []string{"root", "host", "linux", "host_linux", "musl", "linux_glibc", "linux_musl", "not_windows", "x86", "lib32", "linux_x86", "linux_musl_x86", "linux_glibc_x86"},
+ property: []string{"root", "host", "linux", "host_linux", "musl", "linux_musl", "not_windows", "x86", "lib32", "linux_x86", "linux_musl_x86"},
},
},
},
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index d851a98..6b2be69 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -853,7 +853,8 @@
// build statement have later timestamps than the outputs.
rule.Restat()
- rule.Build(fmt.Sprintf("bazel %d", index), buildStatement.Mnemonic)
+ desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths)
+ rule.Build(fmt.Sprintf("bazel %d", index), desc)
}
}
diff --git a/android/buildinfo_prop.go b/android/buildinfo_prop.go
new file mode 100644
index 0000000..6339a71
--- /dev/null
+++ b/android/buildinfo_prop.go
@@ -0,0 +1,182 @@
+// 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 android
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+)
+
+func init() {
+ ctx := InitRegistrationContext
+ ctx.RegisterSingletonModuleType("buildinfo_prop", buildinfoPropFactory)
+}
+
+type buildinfoPropProperties struct {
+ // Whether this module is directly installable to one of the partitions. Default: true.
+ Installable *bool
+}
+
+type buildinfoPropModule struct {
+ SingletonModuleBase
+
+ properties buildinfoPropProperties
+
+ outputFilePath OutputPath
+ installPath InstallPath
+}
+
+var _ OutputFileProducer = (*buildinfoPropModule)(nil)
+
+func (p *buildinfoPropModule) installable() bool {
+ return proptools.BoolDefault(p.properties.Installable, true)
+}
+
+// OutputFileProducer
+func (p *buildinfoPropModule) OutputFiles(tag string) (Paths, error) {
+ if tag != "" {
+ return nil, fmt.Errorf("unsupported tag %q", tag)
+ }
+ return Paths{p.outputFilePath}, nil
+}
+
+func (p *buildinfoPropModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ p.outputFilePath = PathForModuleOut(ctx, p.Name()).OutputPath
+ if !ctx.Config().KatiEnabled() {
+ WriteFileRule(ctx, p.outputFilePath, "# no buildinfo.prop if kati is disabled")
+ return
+ }
+
+ rule := NewRuleBuilder(pctx, ctx)
+ cmd := rule.Command().Text("(")
+
+ writeString := func(str string) {
+ cmd.Text(`echo "` + str + `" && `)
+ }
+
+ writeString("# begin build properties")
+ writeString("# autogenerated by build/soong/android/buildinfo_prop.go")
+
+ writeProp := func(key, value string) {
+ if strings.Contains(key, "=") {
+ panic(fmt.Errorf("wrong property key %q: key must not contain '='", key))
+ }
+ writeString(key + "=" + value)
+ }
+
+ config := ctx.Config()
+
+ writeProp("ro.build.version.sdk", config.PlatformSdkVersion().String())
+ writeProp("ro.build.version.preview_sdk", config.PlatformPreviewSdkVersion())
+ writeProp("ro.build.version.codename", config.PlatformSdkCodename())
+ writeProp("ro.build.version.all_codenames", strings.Join(config.PlatformVersionActiveCodenames(), ","))
+ writeProp("ro.build.version.release", config.PlatformVersionLastStable())
+ writeProp("ro.build.version.release_or_codename", config.PlatformVersionName())
+ writeProp("ro.build.version.security_patch", config.PlatformSecurityPatch())
+ writeProp("ro.build.version.base_os", config.PlatformBaseOS())
+ writeProp("ro.build.version.min_supported_target_sdk", config.PlatformMinSupportedTargetSdkVersion())
+
+ if config.Eng() {
+ writeProp("ro.build.type", "eng")
+ } else if config.Debuggable() {
+ writeProp("ro.build.type", "userdebug")
+ } else {
+ writeProp("ro.build.type", "user")
+ }
+
+ // Currently, only a few properties are implemented to unblock microdroid use case.
+ // TODO(b/189164487): support below properties as well and replace build/make/tools/buildinfo.sh
+ /*
+ if $BOARD_USE_VBMETA_DIGTEST_IN_FINGERPRINT {
+ writeProp("ro.build.legacy.id", config.BuildID())
+ } else {
+ writeProp("ro.build.id", config.BuildId())
+ }
+ writeProp("ro.build.display.id", $BUILD_DISPLAY_ID)
+ writeProp("ro.build.version.incremental", $BUILD_NUMBER)
+ writeProp("ro.build.version.preview_sdk_fingerprint", $PLATFORM_PREVIEW_SDK_FINGERPRINT)
+ writeProp("ro.build.version.known_codenames", $PLATFORM_VERSION_KNOWN_CODENAMES)
+ writeProp("ro.build.version.release_or_preview_display", $PLATFORM_DISPLAY_VERSION)
+ writeProp("ro.build.date", `$DATE`)
+ writeProp("ro.build.date.utc", `$DATE +%s`)
+ writeProp("ro.build.user", $BUILD_USERNAME)
+ writeProp("ro.build.host", $BUILD_HOSTNAME)
+ writeProp("ro.build.tags", $BUILD_VERSION_TAGS)
+ writeProp("ro.build.flavor", $TARGET_BUILD_FLAVOR)
+ // These values are deprecated, use "ro.product.cpu.abilist"
+ // instead (see below).
+ writeString("# ro.product.cpu.abi and ro.product.cpu.abi2 are obsolete,")
+ writeString("# use ro.product.cpu.abilist instead.")
+ writeProp("ro.product.cpu.abi", $TARGET_CPU_ABI)
+ if [ -n "$TARGET_CPU_ABI2" ] {
+ writeProp("ro.product.cpu.abi2", $TARGET_CPU_ABI2)
+ }
+
+ if [ -n "$PRODUCT_DEFAULT_LOCALE" ] {
+ writeProp("ro.product.locale", $PRODUCT_DEFAULT_LOCALE)
+ }
+ writeProp("ro.wifi.channels", $PRODUCT_DEFAULT_WIFI_CHANNELS)
+ writeString("# ro.build.product is obsolete; use ro.product.device")
+ writeProp("ro.build.product", $TARGET_DEVICE)
+
+ writeString("# Do not try to parse description or thumbprint")
+ writeProp("ro.build.description", $PRIVATE_BUILD_DESC)
+ if [ -n "$BUILD_THUMBPRINT" ] {
+ writeProp("ro.build.thumbprint", $BUILD_THUMBPRINT)
+ }
+ */
+
+ writeString("# end build properties")
+
+ cmd.Text("true) > ").Output(p.outputFilePath)
+ rule.Build("build.prop", "generating build.prop")
+
+ if !p.installable() {
+ p.SkipInstall()
+ }
+
+ p.installPath = PathForModuleInstall(ctx)
+ ctx.InstallFile(p.installPath, p.Name(), p.outputFilePath)
+}
+
+func (f *buildinfoPropModule) GenerateSingletonBuildActions(ctx SingletonContext) {
+ // does nothing; buildinfo_prop is a singeton because two buildinfo modules don't make sense.
+}
+
+func (p *buildinfoPropModule) AndroidMkEntries() []AndroidMkEntries {
+ return []AndroidMkEntries{AndroidMkEntries{
+ Class: "ETC",
+ OutputFile: OptionalPathForPath(p.outputFilePath),
+ ExtraEntries: []AndroidMkExtraEntriesFunc{
+ func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_PATH", p.installPath.String())
+ entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
+ entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
+ },
+ },
+ }}
+}
+
+// buildinfo_prop module generates a build.prop file, which contains a set of common
+// system/build.prop properties, such as ro.build.version.*. Not all properties are implemented;
+// currently this module is only for microdroid.
+func buildinfoPropFactory() SingletonModule {
+ module := &buildinfoPropModule{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ return module
+}
diff --git a/android/config.go b/android/config.go
index cb2fc61..250c312 100644
--- a/android/config.go
+++ b/android/config.go
@@ -777,8 +777,12 @@
return String(c.productVariables.Platform_base_os)
}
+func (c *config) PlatformVersionLastStable() string {
+ return String(c.productVariables.Platform_version_last_stable)
+}
+
func (c *config) MinSupportedSdkVersion() ApiLevel {
- return uncheckedFinalApiLevel(16)
+ return uncheckedFinalApiLevel(19)
}
func (c *config) FinalApiLevels() []ApiLevel {
diff --git a/android/hooks.go b/android/hooks.go
index 5e3a4a7..2ad3b5f 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -89,8 +89,17 @@
l.appendPrependHelper(props, proptools.PrependMatchingProperties)
}
-func (l *loadHookContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
- inherited := []interface{}{&l.Module().base().commonProperties}
+func (l *loadHookContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
+ return l.bp.CreateModule(factory, name, props...)
+}
+
+type createModuleContext interface {
+ Module() Module
+ createModule(blueprint.ModuleFactory, string, ...interface{}) blueprint.Module
+}
+
+func createModule(ctx createModuleContext, factory ModuleFactory, ext string, props ...interface{}) Module {
+ inherited := []interface{}{&ctx.Module().base().commonProperties}
var typeName string
if typeNameLookup, ok := ModuleTypeByFactory()[reflect.ValueOf(factory)]; ok {
@@ -101,12 +110,12 @@
filePath, _ := factoryFunc.FileLine(factoryPtr)
typeName = fmt.Sprintf("%s_%s", path.Base(filePath), factoryFunc.Name())
}
- typeName = typeName + "_loadHookModule"
+ typeName = typeName + "_" + ext
- module := l.bp.CreateModule(ModuleFactoryAdaptor(factory), typeName, append(inherited, props...)...).(Module)
+ module := ctx.createModule(ModuleFactoryAdaptor(factory), typeName, append(inherited, props...)...).(Module)
- if l.Module().base().variableProperties != nil && module.base().variableProperties != nil {
- src := l.Module().base().variableProperties
+ if ctx.Module().base().variableProperties != nil && module.base().variableProperties != nil {
+ src := ctx.Module().base().variableProperties
dst := []interface{}{
module.base().variableProperties,
// Put an empty copy of the src properties into dst so that properties in src that are not in dst
@@ -122,6 +131,10 @@
return module
}
+func (l *loadHookContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
+ return createModule(l, factory, "_loadHookModule", props...)
+}
+
func (l *loadHookContext) registerScopedModuleType(name string, factory blueprint.ModuleFactory) {
l.bp.RegisterScopedModuleType(name, factory)
}
diff --git a/android/licenses.go b/android/licenses.go
index e60c7a2..bd14b26 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -335,4 +335,6 @@
ctx.Strict("TEXTNOTICE", ctx.Config().HostToolPath(ctx, "textnotice").String())
ctx.Strict("COMPLIANCENOTICE_BOM", ctx.Config().HostToolPath(ctx, "compliancenotice_bom").String())
ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String())
+ ctx.Strict("COMPLIANCE_LISTSHARE", ctx.Config().HostToolPath(ctx, "compliance_listshare").String())
+ ctx.Strict("COMPLIANCE_CHECKSHARE", ctx.Config().HostToolPath(ctx, "compliance_checkshare").String())
}
diff --git a/android/module.go b/android/module.go
index 66a5f60..ab68e24 100644
--- a/android/module.go
+++ b/android/module.go
@@ -3734,6 +3734,8 @@
Installed_paths []string `json:"installed,omitempty"`
SrcJars []string `json:"srcjars,omitempty"`
Paths []string `json:"path,omitempty"`
+ Static_libs []string `json:"static_libs,omitempty"`
+ Libs []string `json:"libs,omitempty"`
}
func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error {
diff --git a/android/mutator.go b/android/mutator.go
index 739e4ee..02a6143 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,12 +15,9 @@
package android
import (
- "reflect"
-
"android/soong/bazel"
"github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
)
// Phases:
@@ -553,29 +550,16 @@
t.Module().base().commonProperties.DebugName = name
}
+func (t *topDownMutatorContext) createModule(factory blueprint.ModuleFactory, name string, props ...interface{}) blueprint.Module {
+ return t.bp.CreateModule(factory, name, props...)
+}
+
func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...interface{}) Module {
- inherited := []interface{}{&t.Module().base().commonProperties}
- module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), append(inherited, props...)...).(Module)
-
- if t.Module().base().variableProperties != nil && module.base().variableProperties != nil {
- src := t.Module().base().variableProperties
- dst := []interface{}{
- module.base().variableProperties,
- // Put an empty copy of the src properties into dst so that properties in src that are not in dst
- // don't cause a "failed to find property to extend" error.
- proptools.CloneEmptyProperties(reflect.ValueOf(src)).Interface(),
- }
- err := proptools.AppendMatchingProperties(dst, src, nil)
- if err != nil {
- panic(err)
- }
- }
-
- return module
+ return createModule(t, factory, "_topDownMutatorModule", props...)
}
func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module {
- module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), props...).(Module)
+ module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), "", props...).(Module)
return module
}
diff --git a/android/variable.go b/android/variable.go
index 077b810..373891a 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -199,6 +199,7 @@
Platform_preview_sdk_version *string `json:",omitempty"`
Platform_min_supported_target_sdk_version *string `json:",omitempty"`
Platform_base_os *string `json:",omitempty"`
+ Platform_version_last_stable *string `json:",omitempty"`
DeviceName *string `json:",omitempty"`
DeviceProduct *string `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index a7b0a4f..76af1b8 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1656,13 +1656,20 @@
var _ androidApp = (*java.AndroidApp)(nil)
var _ androidApp = (*java.AndroidAppImport)(nil)
+const APEX_VERSION_PLACEHOLDER = "__APEX_VERSION_PLACEHOLDER__"
+
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp androidApp) apexFile {
appDir := "app"
if aapp.Privileged() {
appDir = "priv-app"
}
- dirInApex := filepath.Join(appDir, aapp.InstallApkName())
+
+ // TODO(b/224589412, b/226559955): Ensure that the subdirname is suffixed
+ // so that PackageManager correctly invalidates the existing installed apk
+ // in favour of the new APK-in-APEX. See bugs for more information.
+ dirInApex := filepath.Join(appDir, aapp.InstallApkName()+"@"+APEX_VERSION_PLACEHOLDER)
fileToCopy := aapp.OutputFile()
+
af := newApexFile(ctx, fileToCopy, aapp.BaseModuleName(), dirInApex, app, aapp)
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
af.lintDepSets = aapp.LintDepSets()
@@ -1895,8 +1902,12 @@
if ap.Privileged() {
appDir = "priv-app"
}
- af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(),
- filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
+ // TODO(b/224589412, b/226559955): Ensure that the dirname is
+ // suffixed so that PackageManager correctly invalidates the
+ // existing installed apk in favour of the new APK-in-APEX.
+ // See bugs for more information.
+ appDirName := filepath.Join(appDir, ap.BaseModuleName()+"@"+APEX_VERSION_PLACEHOLDER)
+ af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
af.certificate = java.PresignedCertificate
filesInfo = append(filesInfo, af)
} else {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 77cbb58..4a52115 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -682,7 +682,7 @@
"etc/myetc",
"javalib/myjar.jar",
"lib64/mylib.so",
- "app/AppFoo/AppFoo.apk",
+ "app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk",
"overlay/blue/rro.apk",
"etc/bpf/bpf.o",
"etc/bpf/bpf2.o",
@@ -5682,8 +5682,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
+ ensureContains(t, copyCmds, "image.apex/app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk")
+ ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv@__APEX_VERSION_PLACEHOLDER__/AppFooPriv.apk")
appZipRule := ctx.ModuleForTests("AppFoo", "android_common_apex10000").Description("zip jni libs")
// JNI libraries are uncompressed
@@ -5745,8 +5745,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk")
+ ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt@__APEX_VERSION_PLACEHOLDER__/AppFooPrebuilt.apk")
+ ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt@__APEX_VERSION_PLACEHOLDER__/AwesomePrebuiltAppFooPriv.apk")
}
func TestApexWithAppImportsPrefer(t *testing.T) {
@@ -5787,7 +5787,7 @@
}))
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
- "app/AppFoo/AppFooPrebuilt.apk",
+ "app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFooPrebuilt.apk",
})
}
@@ -5820,7 +5820,7 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk")
+ ensureContains(t, copyCmds, "image.apex/app/TesterHelpAppFoo@__APEX_VERSION_PLACEHOLDER__/TesterHelpAppFoo.apk")
}
func TestApexPropertiesShouldBeDefaultable(t *testing.T) {
@@ -6263,8 +6263,8 @@
apexRule := module.Rule("apexRule")
copyCmds := apexRule.Args["copy_commands"]
- ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
- ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk")
+ ensureNotContains(t, copyCmds, "image.apex/app/app@__APEX_VERSION_PLACEHOLDER__/app.apk")
+ ensureContains(t, copyCmds, "image.apex/app/override_app@__APEX_VERSION_PLACEHOLDER__/override_app.apk")
ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o")
ensureContains(t, copyCmds, "image.apex/etc/bpf/override_bpf.o")
@@ -7168,7 +7168,7 @@
content := bundleConfigRule.Args["content"]
ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
- ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
+ ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo@__APEX_VERSION_PLACEHOLDER__/AppFoo.apk"}]}`)
}
func TestAppSetBundle(t *testing.T) {
@@ -7199,9 +7199,9 @@
if len(copyCmds) != 3 {
t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
- ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
- ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
+ ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__$")
+ ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__$")
+ ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet@__APEX_VERSION_PLACEHOLDER__ .*/AppSet.zip$")
}
func TestAppSetBundlePrebuilt(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 293f388..d4765d0 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -107,14 +107,16 @@
`--canned_fs_config ${canned_fs_config} ` +
`--include_build_info ` +
`--payload_type image ` +
- `--key ${key} ${opt_flags} ${image_dir} ${out} `,
+ `--key ${key} ` +
+ `--apex_version_placeholder ${apex_version_placeholder} ` +
+ `${opt_flags} ${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}",
"${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}", "${make_erofs}",
"${soong_zip}", "${zipalign}", "${aapt2}", "prebuilts/sdk/current/public/android.jar"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
Description: "APEX ${image_dir} => ${out}",
- }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type")
+ }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type", "apex_version_placeholder")
zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{
Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
@@ -122,12 +124,13 @@
`APEXER_TOOL_PATH=${tool_path} ` +
`${apexer} --force --manifest ${manifest} ` +
`--payload_type zip ` +
+ `--apex_version_placeholder ${apex_version_placeholder} ` +
`${image_dir} ${out} `,
CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"},
Rspfile: "${out}.copy_commands",
RspfileContent: "${copy_commands}",
Description: "ZipAPEX ${image_dir} => ${out}",
- }, "tool_path", "image_dir", "copy_commands", "manifest")
+ }, "tool_path", "image_dir", "copy_commands", "manifest", "apex_version_placeholder")
apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
blueprint.RuleParams{
@@ -388,7 +391,7 @@
imageDir := android.PathForModuleOut(ctx, "image"+suffix)
- installSymbolFiles := !ctx.Config().KatiEnabled() || a.ExportedToMake()
+ installSymbolFiles := (!ctx.Config().KatiEnabled() || a.ExportedToMake()) && a.installable()
// b/140136207. When there are overriding APEXes for a VNDK APEX, the symbols file for the overridden
// APEX and the overriding APEX will have the same installation paths at /apex/com.android.vndk.v<ver>
@@ -658,14 +661,15 @@
Output: unsignedOutputFile,
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
- "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": imageDir.String(),
- "copy_commands": strings.Join(copyCommands, " && "),
- "manifest": a.manifestPbOut.String(),
- "file_contexts": fileContexts.String(),
- "canned_fs_config": cannedFsConfig.String(),
- "key": a.privateKeyFile.String(),
- "opt_flags": strings.Join(optFlags, " "),
+ "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
+ "image_dir": imageDir.String(),
+ "copy_commands": strings.Join(copyCommands, " && "),
+ "manifest": a.manifestPbOut.String(),
+ "file_contexts": fileContexts.String(),
+ "canned_fs_config": cannedFsConfig.String(),
+ "key": a.privateKeyFile.String(),
+ "opt_flags": strings.Join(optFlags, " "),
+ "apex_version_placeholder": APEX_VERSION_PLACEHOLDER,
},
})
@@ -757,10 +761,11 @@
Output: unsignedOutputFile,
Description: "apex (" + apexType.name() + ")",
Args: map[string]string{
- "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
- "image_dir": imageDir.String(),
- "copy_commands": strings.Join(copyCommands, " && "),
- "manifest": a.manifestPbOut.String(),
+ "tool_path": outHostBinDir + ":" + prebuiltSdkToolsBinDir,
+ "image_dir": imageDir.String(),
+ "copy_commands": strings.Join(copyCommands, " && "),
+ "manifest": a.manifestPbOut.String(),
+ "apex_version_placeholder": APEX_VERSION_PLACEHOLDER,
},
})
}
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 8f78968..e0ce194 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -45,7 +45,9 @@
"cc_library_shared_conversion_test.go",
"cc_library_static_conversion_test.go",
"cc_object_conversion_test.go",
+ "cc_prebuilt_library_conversion_test.go",
"cc_prebuilt_library_shared_test.go",
+ "cc_prebuilt_library_static_test.go",
"conversion_test.go",
"filegroup_conversion_test.go",
"genrule_conversion_test.go",
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index 17337f0..037564b 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -130,6 +130,7 @@
},
sdk_version: "current",
min_sdk_version: "29",
+ use_version_lib: true,
}
`,
targets: []testBazelTarget{
@@ -153,8 +154,9 @@
"keep_symbols_list": ["symbol"],
"none": True,
}`,
- "sdk_version": `"current"`,
- "min_sdk_version": `"29"`,
+ "sdk_version": `"current"`,
+ "min_sdk_version": `"29"`,
+ "use_version_lib": `True`,
},
},
},
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 5767861..2775a10 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -117,6 +117,7 @@
include_build_directory: false,
sdk_version: "current",
min_sdk_version: "29",
+ use_version_lib: true,
}
`,
expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
@@ -142,8 +143,9 @@
"//build/bazel/platforms/os:linux_bionic": ["bionic.cpp"],
"//conditions:default": [],
})`,
- "sdk_version": `"current"`,
- "min_sdk_version": `"29"`,
+ "sdk_version": `"current"`,
+ "min_sdk_version": `"29"`,
+ "use_version_lib": `True`,
}),
})
}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 22c9dfe..7c2c100 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -176,8 +176,8 @@
":whole_static_lib_1",
":whole_static_lib_2",
]`,
- "sdk_version": `"current"`,
- "min_sdk_version": `"29"`,
+ "sdk_version": `"current"`,
+ "min_sdk_version": `"29"`,
}),
},
})
@@ -496,3 +496,27 @@
},
)
}
+
+func TestCcLibrarySharedSystemSharedLibsSharedEmpty(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ description: "cc_library_shared system_shared_libs empty shared default",
+ moduleTypeUnderTest: "cc_library_shared",
+ moduleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ blueprint: soongCcLibrarySharedPreamble + `
+cc_defaults {
+ name: "empty_defaults",
+ shared: {
+ system_shared_libs: [],
+ },
+ include_build_directory: false,
+}
+cc_library_shared {
+ name: "empty",
+ defaults: ["empty_defaults"],
+}
+`,
+ expectedBazelTargets: []string{makeBazelTarget("cc_library_shared", "empty", attrNameToString{
+ "system_dynamic_deps": "[]",
+ })},
+ })
+}
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
new file mode 100644
index 0000000..3cf8969
--- /dev/null
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -0,0 +1,250 @@
+// 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 bp2build
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/cc"
+)
+
+func TestPrebuiltLibraryStaticAndSharedSimple(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library static and shared simple",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ srcs: ["libf.so"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+ "static_library": `"libf.so"`,
+ }),
+ makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+ "shared_library": `"libf.so"`,
+ }),
+ },
+ })
+}
+
+func TestPrebuiltLibraryWithArchVariance(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library with arch variance",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ arch: {
+ arm64: { srcs: ["libf.so"], },
+ arm: { srcs: ["libg.so"], },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+ "static_library": `select({
+ "//build/bazel/platforms/arch:arm": "libg.so",
+ "//build/bazel/platforms/arch:arm64": "libf.so",
+ "//conditions:default": None,
+ })`,
+ }),
+ makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+ "shared_library": `select({
+ "//build/bazel/platforms/arch:arm": "libg.so",
+ "//build/bazel/platforms/arch:arm64": "libf.so",
+ "//conditions:default": None,
+ })`,
+ }),
+ },
+ })
+}
+
+func TestPrebuiltLibraryAdditionalAttrs(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library additional attributes",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "testdir/1/": "",
+ "testdir/2/": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ srcs: ["libf.so"],
+ export_include_dirs: ["testdir/1/"],
+ export_system_include_dirs: ["testdir/2/"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+ "static_library": `"libf.so"`,
+ "export_includes": `["testdir/1/"]`,
+ "export_system_includes": `["testdir/2/"]`,
+ }),
+ // TODO(b/229374533): When fixed, update this test
+ makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+ "shared_library": `"libf.so"`,
+ }),
+ },
+ })
+}
+
+func TestPrebuiltLibrarySharedStanzaFails(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library with shared stanza fails because multiple sources",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ srcs: ["libf.so"],
+ shared: {
+ srcs: ["libg.so"],
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedErr: fmt.Errorf("Expected at most one source file"),
+ })
+}
+
+func TestPrebuiltLibraryStaticStanzaFails(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library with static stanza fails because multiple sources",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ srcs: ["libf.so"],
+ static: {
+ srcs: ["libg.so"],
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedErr: fmt.Errorf("Expected at most one source file"),
+ })
+}
+
+func TestPrebuiltLibrarySharedAndStaticStanzas(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library with both shared and static stanzas",
+ moduleTypeUnderTest: "cc_prebuilt_library",
+ moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library {
+ name: "libtest",
+ static: {
+ srcs: ["libf.so"],
+ },
+ shared: {
+ srcs: ["libg.so"],
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+ "static_library": `"libf.so"`,
+ }),
+ makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+ "shared_library": `"libg.so"`,
+ }),
+ },
+ })
+}
+
+// TODO(b/228623543): When this bug is fixed, enable this test
+//func TestPrebuiltLibraryOnlyShared(t *testing.T) {
+// runBp2BuildTestCaseSimple(t,
+// bp2buildTestCase{
+// description: "prebuilt library shared only",
+// moduleTypeUnderTest: "cc_prebuilt_library",
+// moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+// filesystem: map[string]string{
+// "libf.so": "",
+// },
+// blueprint: `
+//cc_prebuilt_library {
+// name: "libtest",
+// srcs: ["libf.so"],
+// static: {
+// enabled: false,
+// },
+// bazel_module: { bp2build_available: true },
+//}`,
+// expectedBazelTargets: []string{
+// makeBazelTarget("prebuilt_library_shared", "libtest", attrNameToString{
+// "shared_library": `"libf.so"`,
+// }),
+// },
+// })
+//}
+
+// TODO(b/228623543): When this bug is fixed, enable this test
+//func TestPrebuiltLibraryOnlyStatic(t *testing.T) {
+// runBp2BuildTestCaseSimple(t,
+// bp2buildTestCase{
+// description: "prebuilt library static only",
+// moduleTypeUnderTest: "cc_prebuilt_library",
+// moduleTypeUnderTestFactory: cc.PrebuiltLibraryFactory,
+// filesystem: map[string]string{
+// "libf.so": "",
+// },
+// blueprint: `
+//cc_prebuilt_library {
+// name: "libtest",
+// srcs: ["libf.so"],
+// shared: {
+// enabled: false,
+// },
+// bazel_module: { bp2build_available: true },
+//}`,
+// expectedBazelTargets: []string{
+// makeBazelTarget("prebuilt_library_static", "libtest_bp2build_cc_library_static", attrNameToString{
+// "static_library": `"libf.so"`,
+// }),
+// },
+// })
+//}
diff --git a/bp2build/cc_prebuilt_library_shared_test.go b/bp2build/cc_prebuilt_library_shared_test.go
index ef2fddc..57905e5 100644
--- a/bp2build/cc_prebuilt_library_shared_test.go
+++ b/bp2build/cc_prebuilt_library_shared_test.go
@@ -1,6 +1,7 @@
package bp2build
import (
+ "fmt"
"testing"
"android/soong/cc"
@@ -59,3 +60,26 @@
},
})
}
+
+func TestSharedPrebuiltLibrarySharedStanzaFails(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library shared with shared stanza fails because multiple sources",
+ moduleTypeUnderTest: "cc_prebuilt_library_shared",
+ moduleTypeUnderTestFactory: cc.PrebuiltSharedLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_shared {
+ name: "libtest",
+ srcs: ["libf.so"],
+ shared: {
+ srcs: ["libg.so"],
+ },
+ bazel_module: { bp2build_available: true},
+}`,
+ expectedErr: fmt.Errorf("Expected at most one source file"),
+ })
+}
diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go
new file mode 100644
index 0000000..3feb1f1
--- /dev/null
+++ b/bp2build/cc_prebuilt_library_static_test.go
@@ -0,0 +1,98 @@
+// 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 bp2build
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/cc"
+)
+
+func TestStaticPrebuiltLibrary(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library static simple",
+ moduleTypeUnderTest: "cc_prebuilt_library_static",
+ moduleTypeUnderTestFactory: cc.PrebuiltStaticLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_static {
+ name: "libtest",
+ srcs: ["libf.so"],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest", attrNameToString{
+ "static_library": `"libf.so"`,
+ }),
+ },
+ })
+}
+
+func TestStaticPrebuiltLibraryWithArchVariance(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library static with arch variance",
+ moduleTypeUnderTest: "cc_prebuilt_library_static",
+ moduleTypeUnderTestFactory: cc.PrebuiltStaticLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_static {
+ name: "libtest",
+ arch: {
+ arm64: { srcs: ["libf.so"], },
+ arm: { srcs: ["libg.so"], },
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_library_static", "libtest", attrNameToString{
+ "static_library": `select({
+ "//build/bazel/platforms/arch:arm": "libg.so",
+ "//build/bazel/platforms/arch:arm64": "libf.so",
+ "//conditions:default": None,
+ })`,
+ }),
+ },
+ })
+}
+
+func TestStaticPrebuiltLibraryStaticStanzaFails(t *testing.T) {
+ runBp2BuildTestCaseSimple(t,
+ bp2buildTestCase{
+ description: "prebuilt library with static stanza fails because multiple sources",
+ moduleTypeUnderTest: "cc_prebuilt_library_static",
+ moduleTypeUnderTestFactory: cc.PrebuiltStaticLibraryFactory,
+ filesystem: map[string]string{
+ "libf.so": "",
+ "libg.so": "",
+ },
+ blueprint: `
+cc_prebuilt_library_static {
+ name: "libtest",
+ srcs: ["libf.so"],
+ static: {
+ srcs: ["libg.so"],
+ },
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedErr: fmt.Errorf("Expected at most one source file"),
+ })
+}
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index 3a5d5bb..2e4b221 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -45,11 +45,11 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("prebuilt_etc", "apex_tz_version", attrNameToString{
+ makeBazelTarget("prebuilt_file", "apex_tz_version", attrNameToString{
"filename": `"tz_version"`,
"installable": `False`,
"src": `"version/tz_version"`,
- "sub_dir": `"tz"`,
+ "dir": `"etc/tz"`,
})}})
}
@@ -75,7 +75,7 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("prebuilt_etc", "apex_tz_version", attrNameToString{
+ makeBazelTarget("prebuilt_file", "apex_tz_version", attrNameToString{
"filename": `"tz_version"`,
"installable": `False`,
"src": `select({
@@ -83,7 +83,7 @@
"//build/bazel/platforms/arch:arm64": "arm64",
"//conditions:default": "version/tz_version",
})`,
- "sub_dir": `"tz"`,
+ "dir": `"etc/tz"`,
})}})
}
@@ -114,7 +114,7 @@
}
`,
expectedBazelTargets: []string{
- makeBazelTarget("prebuilt_etc", "apex_tz_version", attrNameToString{
+ makeBazelTarget("prebuilt_file", "apex_tz_version", attrNameToString{
"filename": `"tz_version"`,
"installable": `False`,
"src": `select({
@@ -125,6 +125,59 @@
"//build/bazel/platforms/os_arch:linux_bionic_arm64": "darwin_or_arm64",
"//conditions:default": "version/tz_version",
})`,
- "sub_dir": `"tz"`,
+ "dir": `"etc/tz"`,
+ })}})
+}
+
+func runPrebuiltUsrShareTestCase(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ (&tc).moduleTypeUnderTest = "prebuilt_usr_share"
+ (&tc).moduleTypeUnderTestFactory = etc.PrebuiltUserShareFactory
+ runBp2BuildTestCase(t, registerPrebuiltEtcModuleTypes, tc)
+}
+
+func registerPrebuiltUsrShareModuleTypes(ctx android.RegistrationContext) {
+}
+
+func TestPrebuiltUsrShareSimple(t *testing.T) {
+ runPrebuiltUsrShareTestCase(t, bp2buildTestCase{
+ description: "prebuilt_usr_share - simple example",
+ filesystem: map[string]string{},
+ blueprint: `
+prebuilt_usr_share {
+ name: "apex_tz_version",
+ src: "version/tz_version",
+ filename: "tz_version",
+ sub_dir: "tz",
+ installable: false,
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_file", "apex_tz_version", attrNameToString{
+ "filename": `"tz_version"`,
+ "installable": `False`,
+ "src": `"version/tz_version"`,
+ "dir": `"usr/share/tz"`,
+ })}})
+}
+
+func TestPrebuiltEtcNoSubdir(t *testing.T) {
+ runPrebuiltEtcTestCase(t, bp2buildTestCase{
+ description: "prebuilt_etc - no subdir",
+ filesystem: map[string]string{},
+ blueprint: `
+prebuilt_etc {
+ name: "apex_tz_version",
+ src: "version/tz_version",
+ filename: "tz_version",
+ installable: false,
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_file", "apex_tz_version", attrNameToString{
+ "filename": `"tz_version"`,
+ "installable": `False`,
+ "src": `"version/tz_version"`,
+ "dir": `"etc"`,
})}})
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 156e082..029ba49 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -84,8 +84,9 @@
expectedBazelTargets []string
filesystem map[string]string
dir string
- expectedErr error
- unconvertedDepsMode unconvertedDepsMode
+ // An error with a string contained within the string of the expected error
+ expectedErr error
+ unconvertedDepsMode unconvertedDepsMode
}
func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
diff --git a/build_test.bash b/build_test.bash
index 1dc6660..8b91e2c 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -25,7 +25,8 @@
# Products that are broken or otherwise don't work with multiproduct_kati
SKIPPED_PRODUCTS=(
- # Both of these products are for soong-only builds, and will fail the kati stage.
+ # These products are for soong-only builds, and will fail the kati stage.
+ linux_bionic
mainline_sdk
ndk
)
diff --git a/cc/Android.bp b/cc/Android.bp
index 9103a48..b105e7c 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -100,6 +100,7 @@
"proto_test.go",
"sanitize_test.go",
"test_data_test.go",
+ "tidy_test.go",
"vendor_public_library_test.go",
"vendor_snapshot_test.go",
],
diff --git a/cc/OWNERS b/cc/OWNERS
index a438b15..ffbf14a 100644
--- a/cc/OWNERS
+++ b/cc/OWNERS
@@ -1,4 +1,4 @@
per-file ndk_*.go = danalbert@google.com
-per-file tidy.go = srhines@google.com, chh@google.com
+per-file tidy*.go = srhines@google.com, chh@google.com
per-file afdo.go,afdo_test.go,lto.go,pgo.go = srhines@google.com, pirama@google.com, yikong@google.com
per-file coverage.go = pirama@google.com, srhines@google.com, allenhair@google.com
diff --git a/cc/binary.go b/cc/binary.go
index 89e7262..c5017c1 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -615,6 +615,7 @@
Linkopts: baseAttrs.linkopts,
Link_crt: baseAttrs.linkCrt,
Use_libcrt: baseAttrs.useLibcrt,
+ Use_version_lib: baseAttrs.useVersionLib,
Rtti: baseAttrs.rtti,
Stl: baseAttrs.stl,
Cpp_std: baseAttrs.cppStd,
@@ -665,8 +666,9 @@
Linkopts bazel.StringListAttribute
Additional_linker_inputs bazel.LabelListAttribute
- Link_crt bazel.BoolAttribute
- Use_libcrt bazel.BoolAttribute
+ Link_crt bazel.BoolAttribute
+ Use_libcrt bazel.BoolAttribute
+ Use_version_lib bazel.BoolAttribute
Rtti bazel.BoolAttribute
Stl *string
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 811e228..cc378b3 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -141,6 +141,7 @@
}
}
+// Parses properties common to static and shared libraries. Also used for prebuilt libraries.
func bp2buildParseStaticOrSharedProps(ctx android.BazelConversionPathContext, module *Module, lib *libraryDecorator, isStatic bool) staticOrSharedAttributes {
attrs := staticOrSharedAttributes{}
@@ -198,30 +199,72 @@
// Convenience struct to hold all attributes parsed from prebuilt properties.
type prebuiltAttributes struct {
- Src bazel.LabelAttribute
+ Src bazel.LabelAttribute
+ Enabled bazel.BoolAttribute
}
// NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
-func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) prebuiltAttributes {
+ manySourceFileError := func(axis bazel.ConfigurationAxis, config string) {
+ ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most one source file for %s %s\n", axis, config)
+ }
var srcLabelAttribute bazel.LabelAttribute
- for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltLinkerProperties{}) {
- for config, props := range configToProps {
- if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
- if len(prebuiltLinkerProperties.Srcs) > 1 {
- ctx.ModuleErrorf("Bp2BuildParsePrebuiltLibraryProps: Expected at most once source file for %s %s\n", axis, config)
- continue
- } else if len(prebuiltLinkerProperties.Srcs) == 0 {
- continue
- }
- src := android.BazelLabelForModuleSrcSingle(ctx, prebuiltLinkerProperties.Srcs[0])
- srcLabelAttribute.SetSelectValue(axis, config, src)
- }
+ parseSrcs := func(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, srcs []string) {
+ if len(srcs) > 1 {
+ manySourceFileError(axis, config)
+ return
+ } else if len(srcs) == 0 {
+ return
}
+ if srcLabelAttribute.SelectValue(axis, config) != nil {
+ manySourceFileError(axis, config)
+ return
+ }
+
+ src := android.BazelLabelForModuleSrcSingle(ctx, srcs[0])
+ srcLabelAttribute.SetSelectValue(axis, config, src)
+ }
+
+ bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ if prebuiltLinkerProperties, ok := props.(*prebuiltLinkerProperties); ok {
+ parseSrcs(ctx, axis, config, prebuiltLinkerProperties.Srcs)
+ }
+ })
+
+ var enabledLabelAttribute bazel.BoolAttribute
+ parseAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
+ if props.Enabled != nil {
+ enabledLabelAttribute.SetSelectValue(axis, config, props.Enabled)
+ }
+ parseSrcs(ctx, axis, config, props.Srcs)
+ }
+
+ if isStatic {
+ bp2BuildPropParseHelper(ctx, module, &StaticProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ if staticProperties, ok := props.(*StaticProperties); ok {
+ parseAttrs(axis, config, staticProperties.Static)
+ }
+ })
+ } else {
+ bp2BuildPropParseHelper(ctx, module, &SharedProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ if sharedProperties, ok := props.(*SharedProperties); ok {
+ parseAttrs(axis, config, sharedProperties.Shared)
+ }
+ })
}
return prebuiltAttributes{
- Src: srcLabelAttribute,
+ Src: srcLabelAttribute,
+ Enabled: enabledLabelAttribute,
+ }
+}
+
+func bp2BuildPropParseHelper(ctx android.ArchVariantContext, module *Module, propsType interface{}, parseFunc func(axis bazel.ConfigurationAxis, config string, props interface{})) {
+ for axis, configToProps := range module.GetArchVariantProperties(ctx, propsType) {
+ for config, props := range configToProps {
+ parseFunc(axis, config, props)
+ }
}
}
@@ -542,8 +585,8 @@
}
func bp2BuildParseSdkAttributes(module *Module) sdkAttributes {
- return sdkAttributes {
- Sdk_version: module.Properties.Sdk_version,
+ return sdkAttributes{
+ Sdk_version: module.Properties.Sdk_version,
Min_sdk_version: module.Properties.Min_sdk_version,
}
}
diff --git a/cc/cc.go b/cc/cc.go
index 154c353..c2d0f6e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3557,13 +3557,14 @@
case fullLibrary:
if !prebuilt {
libraryBp2Build(ctx, c)
+ } else {
+ prebuiltLibraryBp2Build(ctx, c)
}
case headerLibrary:
libraryHeadersBp2Build(ctx, c)
case staticLibrary:
-
if prebuilt {
- prebuiltLibraryStaticBp2Build(ctx, c)
+ prebuiltLibraryStaticBp2Build(ctx, c, false)
} else {
sharedOrStaticLibraryBp2Build(ctx, c, true)
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 9c71683..3caf327 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -286,8 +286,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r450784b"
- ClangDefaultShortVersion = "14.0.4"
+ ClangDefaultVersion = "clang-r450784d"
+ ClangDefaultShortVersion = "14.0.6"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/library.go b/cc/library.go
index 035a90e..0abcb6f 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -352,6 +352,7 @@
Stl: compilerAttrs.stl,
Cpp_std: compilerAttrs.cppStd,
C_std: compilerAttrs.cStd,
+ Use_version_lib: linkerAttrs.useVersionLib,
Features: linkerAttrs.features,
}
@@ -374,6 +375,7 @@
Stl: compilerAttrs.stl,
Cpp_std: compilerAttrs.cppStd,
C_std: compilerAttrs.cStd,
+ Use_version_lib: linkerAttrs.useVersionLib,
Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
diff --git a/cc/ndk_abi.go b/cc/ndk_abi.go
index 927fa2e..3456c32 100644
--- a/cc/ndk_abi.go
+++ b/cc/ndk_abi.go
@@ -46,7 +46,7 @@
if m, ok := module.(*Module); ok {
if installer, ok := m.installer.(*stubDecorator); ok {
- if canDumpAbi() {
+ if canDumpAbi(ctx.Config()) {
depPaths = append(depPaths, installer.abiDumpPath)
}
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index fc682ff..5ef41ea 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -53,9 +53,9 @@
abitidy = pctx.AndroidStaticRule("abitidy",
blueprint.RuleParams{
- Command: "$abitidy --all -i $in -o $out",
+ Command: "$abitidy --all $flags -i $in -o $out",
CommandDeps: []string{"$abitidy"},
- })
+ }, "flags")
abidiff = pctx.AndroidStaticRule("abidiff",
blueprint.RuleParams{
@@ -104,6 +104,12 @@
// used. This is only needed to work around platform bugs like
// https://github.com/android-ndk/ndk/issues/265.
Unversioned_until *string
+
+ // If true, does not emit errors when APIs lacking type information are
+ // found. This is false by default and should not be enabled outside bionic,
+ // where it is enabled pending a fix for http://b/190554910 (no debug info
+ // for asm implemented symbols).
+ Allow_untyped_symbols *bool
}
type stubDecorator struct {
@@ -315,8 +321,18 @@
}
// Feature flag.
-func canDumpAbi() bool {
- return runtime.GOOS != "darwin"
+func canDumpAbi(config android.Config) bool {
+ if runtime.GOOS == "darwin" {
+ return false
+ }
+ // abidw doesn't currently handle top-byte-ignore correctly. Disable ABI
+ // dumping for those configs while we wait for a fix. We'll still have ABI
+ // checking coverage from non-hwasan builds.
+ // http://b/190554910
+ if android.InList("hwaddress", config.SanitizeDevice()) {
+ return false
+ }
+ return true
}
// Feature flag to disable diffing against prebuilts.
@@ -339,14 +355,22 @@
"symbolList": symbolList.String(),
},
})
+
this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
this.apiLevel.String(), ctx.Arch().ArchType.String(),
this.libraryName(ctx), "abi.xml")
+ untypedFlag := "--abort-on-untyped-symbols"
+ if proptools.BoolDefault(this.properties.Allow_untyped_symbols, false) {
+ untypedFlag = ""
+ }
ctx.Build(pctx, android.BuildParams{
Rule: abitidy,
Description: fmt.Sprintf("abitidy %s", implementationLibrary),
Input: abiRawPath,
Output: this.abiDumpPath,
+ Args: map[string]string{
+ "flags": untypedFlag,
+ },
})
}
@@ -444,7 +468,7 @@
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile, c.apiLevel, "")
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
c.versionScriptPath = nativeAbiResult.versionScript
- if canDumpAbi() {
+ if canDumpAbi(ctx.Config()) {
c.dumpAbi(ctx, nativeAbiResult.symbolList)
if canDiffAbi() {
c.diffAbi(ctx)
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 5980319..f54c6f8 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -253,6 +253,7 @@
func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) {
module, library := NewLibrary(hod)
module.compiler = nil
+ module.bazelable = true
prebuilt := &prebuiltLibraryLinker{
libraryDecorator: library,
@@ -338,8 +339,21 @@
Export_system_includes bazel.StringListAttribute
}
-func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Module) {
- prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module)
+// TODO(b/228623543): The below is not entirely true until the bug is fixed. For now, both targets are always generated
+// Implements bp2build for cc_prebuilt_library modules. This will generate:
+// * Only a prebuilt_library_static if the shared.enabled property is set to false across all variants.
+// * Only a prebuilt_library_shared if the static.enabled property is set to false across all variants
+// * Both a prebuilt_library_static and prebuilt_library_shared if the aforementioned properties are not false across
+// all variants
+//
+// In all cases, prebuilt_library_static target names will be appended with "_bp2build_cc_library_static".
+func prebuiltLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+ prebuiltLibraryStaticBp2Build(ctx, module, true)
+ prebuiltLibrarySharedBp2Build(ctx, module)
+}
+
+func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Module, fullBuild bool) {
+ prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, true)
exportedIncludes := Bp2BuildParseExportedIncludesForPrebuiltLibrary(ctx, module)
attrs := &bazelPrebuiltLibraryStaticAttributes{
@@ -354,7 +368,10 @@
}
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
+ if fullBuild {
+ name += "_bp2build_cc_library_static"
+ }
+ ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name}, attrs, prebuiltAttrs.Enabled)
}
type bazelPrebuiltLibrarySharedAttributes struct {
@@ -362,7 +379,7 @@
}
func prebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext, module *Module) {
- prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module)
+ prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, false)
attrs := &bazelPrebuiltLibrarySharedAttributes{
Shared_library: prebuiltAttrs.Src,
@@ -374,7 +391,7 @@
}
name := android.RemoveOptionalPrebuiltPrefix(module.Name())
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
+ ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name}, attrs, prebuiltAttrs.Enabled)
}
type prebuiltObjectProperties struct {
@@ -510,7 +527,16 @@
func (p *prebuiltObjectLinker) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
if len(p.properties.Srcs) > 0 {
- return p.Prebuilt.SingleSourcePath(ctx)
+ // Copy objects to a name matching the final installed name
+ in := p.Prebuilt.SingleSourcePath(ctx)
+ outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".o")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpExecutable,
+ Description: "prebuilt",
+ Output: outputFile,
+ Input: in,
+ })
+ return outputFile
}
return nil
}
diff --git a/cc/tidy.go b/cc/tidy.go
index 750e9de..03e967d 100644
--- a/cc/tidy.go
+++ b/cc/tidy.go
@@ -76,9 +76,10 @@
// the global WITH_TIDY or module 'tidy' property is true.
flags.Tidy = true
- // If explicitly enabled, by global default or local tidy property,
+ // If explicitly enabled, by global WITH_TIDY or local tidy:true property,
// set flags.NeedTidyFiles to make this module depend on .tidy files.
- if ctx.Config().ClangTidy() || Bool(tidy.Properties.Tidy) {
+ // Note that locally set tidy:true is ignored if ALLOW_LOCAL_TIDY_TRUE is not set to true.
+ if ctx.Config().IsEnvTrue("WITH_TIDY") || (ctx.Config().IsEnvTrue("ALLOW_LOCAL_TIDY_TRUE") && Bool(tidy.Properties.Tidy)) {
flags.NeedTidyFiles = true
}
diff --git a/cc/tidy_test.go b/cc/tidy_test.go
new file mode 100644
index 0000000..339b302
--- /dev/null
+++ b/cc/tidy_test.go
@@ -0,0 +1,98 @@
+// 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 (
+ "fmt"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestWithTidy(t *testing.T) {
+ // When WITH_TIDY=1 or (ALLOW_LOCAL_TIDY_TRUE=1 and local tidy:true)
+ // a C++ library should depend on .tidy files.
+ testCases := []struct {
+ withTidy, allowLocalTidyTrue string // "_" means undefined
+ needTidyFile []bool // for {libfoo_0, libfoo_1} and {libbar_0, libbar_1}
+ }{
+ {"_", "_", []bool{false, false, false}},
+ {"_", "0", []bool{false, false, false}},
+ {"_", "1", []bool{false, true, false}},
+ {"_", "true", []bool{false, true, false}},
+ {"0", "_", []bool{false, false, false}},
+ {"0", "1", []bool{false, true, false}},
+ {"1", "_", []bool{true, true, false}},
+ {"1", "false", []bool{true, true, false}},
+ {"1", "1", []bool{true, true, false}},
+ {"true", "_", []bool{true, true, false}},
+ }
+ bp := `
+ cc_library_shared {
+ name: "libfoo_0", // depends on .tidy if WITH_TIDY=1
+ srcs: ["foo.c"],
+ }
+ cc_library_shared { // depends on .tidy if WITH_TIDY=1 or ALLOW_LOCAL_TIDY_TRUE=1
+ name: "libfoo_1",
+ srcs: ["foo.c"],
+ tidy: true,
+ }
+ cc_library_shared { // no .tidy
+ name: "libfoo_2",
+ srcs: ["foo.c"],
+ tidy: false,
+ }
+ cc_library_static {
+ name: "libbar_0", // depends on .tidy if WITH_TIDY=1
+ srcs: ["bar.c"],
+ }
+ cc_library_static { // depends on .tidy if WITH_TIDY=1 or ALLOW_LOCAL_TIDY_TRUE=1
+ name: "libbar_1",
+ srcs: ["bar.c"],
+ tidy: true,
+ }
+ cc_library_static { // no .tidy
+ name: "libbar_2",
+ srcs: ["bar.c"],
+ tidy: false,
+ }`
+ for index, test := range testCases {
+ testName := fmt.Sprintf("case%d,%v,%v", index, test.withTidy, test.allowLocalTidyTrue)
+ t.Run(testName, func(t *testing.T) {
+ testEnv := map[string]string{}
+ if test.withTidy != "_" {
+ testEnv["WITH_TIDY"] = test.withTidy
+ }
+ if test.allowLocalTidyTrue != "_" {
+ testEnv["ALLOW_LOCAL_TIDY_TRUE"] = test.allowLocalTidyTrue
+ }
+ ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
+ for n := 0; n < 3; n++ {
+ checkLibraryRule := func(foo, variant, ruleName string) {
+ libName := fmt.Sprintf("lib%s_%d", foo, n)
+ tidyFile := "out/soong/.intermediates/" + libName + "/" + variant + "/obj/" + foo + ".tidy"
+ depFiles := ctx.ModuleForTests(libName, variant).Rule(ruleName).Validations.Strings()
+ if test.needTidyFile[n] {
+ android.AssertStringListContains(t, libName+" needs .tidy file", depFiles, tidyFile)
+ } else {
+ android.AssertStringListDoesNotContain(t, libName+" does not need .tidy file", depFiles, tidyFile)
+ }
+ }
+ checkLibraryRule("foo", "android_arm64_armv8-a_shared", "ld")
+ checkLibraryRule("bar", "android_arm64_armv8-a_static", "ar")
+ }
+ })
+ }
+}
diff --git a/cmd/go2bp/go2bp.go b/cmd/go2bp/go2bp.go
index 07cb5df..fb5a746 100644
--- a/cmd/go2bp/go2bp.go
+++ b/cmd/go2bp/go2bp.go
@@ -335,12 +335,15 @@
}
cmd := exec.Command("go", "list", "-json", "./...")
- output, err := cmd.Output()
- if err != nil {
- fmt.Fprintf(os.Stderr, "Failed to dump the go packages: %v\n", err)
+ var stdoutb, stderrb bytes.Buffer
+ cmd.Stdout = &stdoutb
+ cmd.Stderr = &stderrb
+ if err := cmd.Run(); err != nil {
+ fmt.Fprintf(os.Stderr, "Running %q to dump the Go packages failed: %v, stderr:\n%s\n",
+ cmd.String(), err, stderrb.Bytes())
os.Exit(1)
}
- decoder := json.NewDecoder(bytes.NewReader(output))
+ decoder := json.NewDecoder(bytes.NewReader(stdoutb.Bytes()))
pkgs := []*GoPackage{}
pkgMap := map[string]*GoPackage{}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index a142833..719771f 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -474,6 +474,7 @@
// This module is device-only
android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
android.InitDefaultableModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -668,25 +669,17 @@
// For Bazel / bp2build
-type bazelPrebuiltEtcAttributes struct {
+type bazelPrebuiltFileAttributes struct {
Src bazel.LabelAttribute
Filename string
- Sub_dir string
+ Dir string
Installable bazel.BoolAttribute
}
// ConvertWithBp2build performs bp2build conversion of PrebuiltEtc
-func (p *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- // All prebuilt_* modules are PrebuiltEtc, but at this time, we only convert prebuilt_etc modules.
- if p.installDirBase != "etc" {
- return
- }
-
- prebuiltEtcBp2BuildInternal(ctx, p)
-}
-
-func prebuiltEtcBp2BuildInternal(ctx android.TopDownMutatorContext, module *PrebuiltEtc) {
- var srcLabelAttribute bazel.LabelAttribute
+// All prebuilt_* modules are PrebuiltEtc, which we treat uniformily as *PrebuiltFile*
+func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+ var src bazel.LabelAttribute
for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) {
for config, p := range configToProps {
props, ok := p.(*prebuiltEtcProperties)
@@ -695,7 +688,7 @@
}
if props.Src != nil {
label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
- srcLabelAttribute.SetSelectValue(axis, config, label)
+ src.SetSelectValue(axis, config, label)
}
}
}
@@ -705,26 +698,30 @@
filename = *module.properties.Filename
}
- var subDir string
- if module.subdirProperties.Sub_dir != nil {
- subDir = *module.subdirProperties.Sub_dir
+ var dir = module.installDirBase
+ // prebuilt_file supports only `etc` or `usr/share`
+ if !(dir == "etc" || dir == "usr/share") {
+ return
+ }
+ if subDir := module.subdirProperties.Sub_dir; subDir != nil {
+ dir = dir + "/" + *subDir
}
- var installableBoolAttribute bazel.BoolAttribute
- if module.properties.Installable != nil {
- installableBoolAttribute.Value = module.properties.Installable
+ var installable bazel.BoolAttribute
+ if install := module.properties.Installable; install != nil {
+ installable.Value = install
}
- attrs := &bazelPrebuiltEtcAttributes{
- Src: srcLabelAttribute,
+ attrs := &bazelPrebuiltFileAttributes{
+ Src: src,
Filename: filename,
- Sub_dir: subDir,
- Installable: installableBoolAttribute,
+ Dir: dir,
+ Installable: installable,
}
props := bazel.BazelTargetModuleProperties{
- Rule_class: "prebuilt_etc",
- Bzl_load_location: "//build/bazel/rules:prebuilt_etc.bzl",
+ Rule_class: "prebuilt_file",
+ Bzl_load_location: "//build/bazel/rules:prebuilt_file.bzl",
}
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, attrs)
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 33beb37..352b451 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -228,6 +228,15 @@
return output
}
+// Calculates avb_salt from some input for deterministic output.
+func (b *bootimg) salt() string {
+ var input []string
+ input = append(input, b.properties.Cmdline...)
+ input = append(input, proptools.StringDefault(b.properties.Partition_name, b.Name()))
+ input = append(input, proptools.String(b.properties.Header_version))
+ return sha1sum(input)
+}
+
func (b *bootimg) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
var sb strings.Builder
var deps android.Paths
@@ -248,6 +257,7 @@
addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index
partitionName := proptools.StringDefault(b.properties.Partition_name, b.Name())
addStr("partition_name", partitionName)
+ addStr("avb_salt", b.salt())
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
android.WriteFileRule(ctx, propFile, sb.String())
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index ccf9e9d..6e1e78a 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -15,7 +15,9 @@
package filesystem
import (
+ "crypto/sha256"
"fmt"
+ "io"
"path/filepath"
"strings"
@@ -88,6 +90,13 @@
// Symbolic links to be created under root with "ln -sf <target> <name>".
Symlinks []symlinkDefinition
+
+ // Seconds since unix epoch to override timestamps of file entries
+ Fake_timestamp *string
+
+ // When set, passed to mkuserimg_mke2fs --mke2fs_uuid & --mke2fs_hash_seed.
+ // Otherwise, they'll be set as random which might cause indeterministic build output.
+ Uuid *string
}
// android_filesystem packages a set of modules and their transitive dependencies into a filesystem
@@ -276,6 +285,11 @@
return fcBin.OutputPath
}
+// Calculates avb_salt from entry list (sorted) for deterministic output.
+func (f *filesystem) salt() string {
+ return sha1sum(f.entries)
+}
+
func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android.OutputPath, toolDeps android.Paths) {
type prop struct {
name string
@@ -321,12 +335,19 @@
addStr("avb_add_hashtree_footer_args", "--do_not_generate_fec")
partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name())
addStr("partition_name", partitionName)
+ addStr("avb_salt", f.salt())
}
if proptools.String(f.properties.File_contexts) != "" {
addPath("selinux_fc", f.buildFileContexts(ctx))
}
-
+ if timestamp := proptools.String(f.properties.Fake_timestamp); timestamp != "" {
+ addStr("timestamp", timestamp)
+ }
+ if uuid := proptools.String(f.properties.Uuid); uuid != "" {
+ addStr("uuid", uuid)
+ addStr("hash_seed", uuid)
+ }
propFile = android.PathForModuleOut(ctx, "prop").OutputPath
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().Text("rm").Flag("-rf").Output(propFile)
@@ -451,3 +472,11 @@
}
return specs
}
+
+func sha1sum(values []string) string {
+ h := sha256.New()
+ for _, value := range values {
+ io.WriteString(h, value)
+ }
+ return fmt.Sprintf("%x", h.Sum(nil))
+}
diff --git a/java/aar.go b/java/aar.go
index 8e10253..00ff7e7 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -598,16 +598,26 @@
// AAR (android library) prebuilts
//
+// Properties for android_library_import
type AARImportProperties struct {
+ // ARR (android library prebuilt) filepath. Exactly one ARR is required.
Aars []string `android:"path"`
-
- Sdk_version *string
+ // If not blank, set to the version of the sdk to compile against.
+ // Defaults to private.
+ // Values are of one of the following forms:
+ // 1) numerical API level, "current", "none", or "core_platform"
+ // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
+ // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
+ // If the SDK kind is empty, it will be set to public
+ Sdk_version *string
+ // If not blank, set the minimum version of the sdk that the compiled artifacts will run against.
+ // Defaults to sdk_version if not set. See sdk_version for possible values.
Min_sdk_version *string
-
+ // List of java static libraries that the included ARR (android library prebuilts) has dependencies to.
Static_libs []string
- Libs []string
-
- // if set to true, run Jetifier against .aar file. Defaults to false.
+ // List of java libraries that the included ARR (android library prebuilts) has dependencies to.
+ Libs []string
+ // If set to true, run Jetifier against .aar file. Defaults to false.
Jetifier *bool
}
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 7772b70..3fa3520 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -82,8 +82,8 @@
if minSdkVersion.FinalOrFutureInt() >= 23 {
args = append(args, fmt.Sprintf("--extract-native-libs=%v", !params.UseEmbeddedNativeLibs))
} else if params.UseEmbeddedNativeLibs {
- ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%d doesn't support it",
- minSdkVersion)
+ ctx.ModuleErrorf("module attempted to store uncompressed native libraries, but minSdkVersion=%s doesn't support it",
+ minSdkVersion.String())
}
}
diff --git a/java/base.go b/java/base.go
index 5802099..245ffbb 100644
--- a/java/base.go
+++ b/java/base.go
@@ -185,12 +185,12 @@
// constructing a new module.
type DeviceProperties struct {
// If not blank, set to the version of the sdk to compile against.
- // Defaults to compiling against the current platform.
+ // Defaults to private.
// Values are of one of the following forms:
- // 1) numerical API level or "current"
- // 2) An SDK kind with an API level: "<sdk kind>_<API level>". See
- // build/soong/android/sdk_version.go for the complete and up to date list of
- // SDK kinds. If the SDK kind value is empty, it will be set to public.
+ // 1) numerical API level, "current", "none", or "core_platform"
+ // 2) An SDK kind with an API level: "<sdk kind>_<API level>"
+ // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds.
+ // If the SDK kind is empty, it will be set to public.
Sdk_version *string
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
@@ -207,7 +207,7 @@
// Whether to compile against the platform APIs instead of an SDK.
// If true, then sdk_version must be empty. The value of this field
- // is ignored when module's type isn't android_app.
+ // is ignored when module's type isn't android_app, android_test, or android_test_helper_app.
Platform_apis *bool
Aidl struct {
@@ -442,9 +442,6 @@
// manifest file to use instead of properties.Manifest
overrideManifest android.OptionalPath
- // map of SDK version to class loader context
- classLoaderContexts dexpreopt.ClassLoaderContextMap
-
// list of plugins that this java module is exporting
exportedPluginJars android.Paths
@@ -1481,11 +1478,11 @@
}
if ctx.Device() {
- lintSDKVersionString := func(sdkSpec android.SdkSpec) string {
+ lintSDKVersion := func(sdkSpec android.SdkSpec) android.ApiLevel {
if v := sdkSpec.ApiLevel; !v.IsPreview() {
- return v.String()
+ return v
} else {
- return ctx.Config().DefaultAppTargetSdk(ctx).String()
+ return ctx.Config().DefaultAppTargetSdk(ctx)
}
}
@@ -1494,9 +1491,9 @@
j.linter.srcJars = srcJars
j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...)
j.linter.classes = j.implementationJarFile
- j.linter.minSdkVersion = lintSDKVersionString(j.MinSdkVersion(ctx))
- j.linter.targetSdkVersion = lintSDKVersionString(j.TargetSdkVersion(ctx))
- j.linter.compileSdkVersion = lintSDKVersionString(j.SdkVersion(ctx))
+ j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx))
+ j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx))
+ j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx))
j.linter.compileSdkKind = j.SdkVersion(ctx).Kind
j.linter.javaLanguageLevel = flags.javaVersion.String()
j.linter.kotlinLanguageLevel = "1.3"
@@ -1694,6 +1691,8 @@
dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String())
}
dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...)
+ dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...)
+ dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...)
}
func (j *Module) CompilerDeps() []string {
diff --git a/java/config/config.go b/java/config/config.go
index 95b841f..46c91a2 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -81,7 +81,17 @@
exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "4096M")
exportedVars.ExportStringStaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
- exportedVars.ExportStringListStaticVariable("DexFlags", []string{
+ // D8 invocations are shorter lived, so we restrict their JIT tiering relative to R8.
+ // Note that the `-JXX` prefix syntax is specific to the R8/D8 invocation wrappers.
+ exportedVars.ExportStringListStaticVariable("D8Flags", []string{
+ `-JXX:OnError="cat hs_err_pid%p.log"`,
+ "-JXX:CICompilerCount=6",
+ "-JXX:+UseDynamicNumberOfGCThreads",
+ "-JXX:+TieredCompilation",
+ "-JXX:TieredStopAtLevel=1",
+ })
+
+ exportedVars.ExportStringListStaticVariable("R8Flags", []string{
`-JXX:OnError="cat hs_err_pid%p.log"`,
"-JXX:CICompilerCount=6",
"-JXX:+UseDynamicNumberOfGCThreads",
diff --git a/java/config/makevars.go b/java/config/makevars.go
index df447a1..bc6848f 100644
--- a/java/config/makevars.go
+++ b/java/config/makevars.go
@@ -78,7 +78,8 @@
ctx.Strict("CLASS2NONSDKLIST", "${Class2NonSdkList}")
ctx.Strict("HIDDENAPI", "${HiddenAPI}")
- ctx.Strict("DEX_FLAGS", "${DexFlags}")
+ ctx.Strict("D8_FLAGS", "${D8Flags}")
+ ctx.Strict("R8_FLAGS", "${R8Flags}")
ctx.Strict("AIDL", "${AidlCmd}")
ctx.Strict("AAPT2", "${Aapt2Cmd}")
diff --git a/java/dex.go b/java/dex.go
index 84665e7..13d6e4a 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -95,7 +95,7 @@
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`mkdir -p $$(dirname $tmpJar) && ` +
`${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
- `$d8Template${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $tmpJar && ` +
+ `$d8Template${config.D8Cmd} ${config.D8Flags} --output $outDir $d8Flags $tmpJar && ` +
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
@@ -128,7 +128,7 @@
`mkdir -p $$(dirname ${outUsage}) && ` +
`mkdir -p $$(dirname $tmpJar) && ` +
`${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
- `$r8Template${config.R8Cmd} ${config.DexFlags} -injars $tmpJar --output $outDir ` +
+ `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $tmpJar --output $outDir ` +
`--no-data-resources ` +
`-printmapping ${outDict} ` +
`-printusage ${outUsage} ` +
diff --git a/java/jdeps.go b/java/jdeps.go
index eff9a31..3734335 100644
--- a/java/jdeps.go
+++ b/java/jdeps.go
@@ -71,6 +71,8 @@
dpInfo.Jars = android.FirstUniqueStrings(dpInfo.Jars)
dpInfo.SrcJars = android.FirstUniqueStrings(dpInfo.SrcJars)
dpInfo.Paths = android.FirstUniqueStrings(dpInfo.Paths)
+ dpInfo.Static_libs = android.FirstUniqueStrings(dpInfo.Static_libs)
+ dpInfo.Libs = android.FirstUniqueStrings(dpInfo.Libs)
moduleInfos[name] = dpInfo
mkProvider, ok := module.(android.AndroidMkDataProvider)
diff --git a/java/lint.go b/java/lint.go
index e97c9c2..426a2af 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -75,9 +75,9 @@
extraLintCheckJars android.Paths
test bool
library bool
- minSdkVersion string
- targetSdkVersion string
- compileSdkVersion string
+ minSdkVersion android.ApiLevel
+ targetSdkVersion android.ApiLevel
+ compileSdkVersion android.ApiLevel
compileSdkKind android.SdkKind
javaLanguageLevel string
kotlinLanguageLevel string
@@ -300,7 +300,7 @@
Text(`echo "<manifest xmlns:android='http://schemas.android.com/apk/res/android'" &&`).
Text(`echo " android:versionCode='1' android:versionName='1' >" &&`).
Textf(`echo " <uses-sdk android:minSdkVersion='%s' android:targetSdkVersion='%s'/>" &&`,
- l.minSdkVersion, l.targetSdkVersion).
+ l.minSdkVersion.String(), l.targetSdkVersion.String()).
Text(`echo "</manifest>"`).
Text(") >").Output(manifestPath)
@@ -325,7 +325,7 @@
return
}
- if l.minSdkVersion != l.compileSdkVersion {
+ if l.minSdkVersion.CompareTo(l.compileSdkVersion) == -1 {
l.extraMainlineLintErrors = append(l.extraMainlineLintErrors, updatabilityChecks...)
_, filtered := android.FilterList(l.properties.Lint.Warning_checks, updatabilityChecks)
if len(filtered) != 0 {
@@ -427,7 +427,7 @@
FlagWithOutput("--html ", html).
FlagWithOutput("--text ", text).
FlagWithOutput("--xml ", xml).
- FlagWithArg("--compile-sdk-version ", l.compileSdkVersion).
+ FlagWithArg("--compile-sdk-version ", l.compileSdkVersion.String()).
FlagWithArg("--java-language-level ", l.javaLanguageLevel).
FlagWithArg("--kotlin-language-level ", l.kotlinLanguageLevel).
FlagWithArg("--url ", fmt.Sprintf(".=.,%s=out", android.PathForOutput(ctx).String())).
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 4bc0c5f..1eee354 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -28,6 +28,11 @@
--disable_check SuspiciousImport
--disable_check UnusedResources
--disable_check ViewConstructor
+# Disable NewApi checks for the platform since platform is the one that implements
+# the API. This prevents noisy lint warnings like b/228956345#1
+# NewApi checks will continue to be enforced for apex deps since
+# lint.strict_updatability_linting will be true for those Soong modules
+--disable_check NewApi
# Downgrade existing errors to warnings
--warning_check AppCompatResource # 55 occurences in 10 modules
@@ -66,7 +71,6 @@
--warning_check MissingTvBanner # 3 occurences in 3 modules
--warning_check NamespaceTypo # 3 occurences in 3 modules
--warning_check NetworkSecurityConfig # 46 occurences in 12 modules
---warning_check NewApi # 1996 occurences in 122 modules
--warning_check NotSibling # 15 occurences in 10 modules
--warning_check ObjectAnimatorBinding # 14 occurences in 5 modules
--warning_check OnClick # 49 occurences in 21 modules
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 8f4fea4..d4da4f5 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -531,7 +531,7 @@
func (ctx *parseContext) handleAssignment(a *mkparser.Assignment) []starlarkNode {
// Handle only simple variables
- if !a.Name.Const() {
+ if !a.Name.Const() || a.Target != nil {
return []starlarkNode{ctx.newBadNode(a, "Only simple variables are handled")}
}
name := a.Name.Strings[0]
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index de75129..6887ca4 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -1242,13 +1242,15 @@
desc: "Ignore make rules",
mkname: "product.mk",
in: `
+foo: PRIVATE_VARIABLE = some_tool $< $@
foo: foo.c
gcc -o $@ $*`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
- rblf.mk2rbc_error("product.mk:2", "unsupported line rule: foo: foo.c\n#gcc -o $@ $*")
+ rblf.mk2rbc_error("product.mk:2", "Only simple variables are handled")
+ rblf.mk2rbc_error("product.mk:3", "unsupported line rule: foo: foo.c\n#gcc -o $@ $*")
`,
},
{
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index ae96e1f..e49f3d4 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -60,29 +60,32 @@
}
type provenanceInfoSingleton struct {
+ mergedMetaDataFile android.OutputPath
}
-func (b *provenanceInfoSingleton) GenerateBuildActions(context android.SingletonContext) {
+func (p *provenanceInfoSingleton) GenerateBuildActions(context android.SingletonContext) {
allMetaDataFiles := make([]android.Path, 0)
context.VisitAllModulesIf(moduleFilter, func(module android.Module) {
if p, ok := module.(ProvenanceMetadata); ok {
allMetaDataFiles = append(allMetaDataFiles, p.ProvenanceMetaDataFile())
}
})
- mergedMetaDataFile := android.PathForOutput(context, "provenance_metadata.textproto")
+ p.mergedMetaDataFile = android.PathForOutput(context, "provenance_metadata.textproto")
context.Build(pctx, android.BuildParams{
Rule: mergeProvenanceMetaData,
Description: "merge provenance metadata",
Inputs: allMetaDataFiles,
- Output: mergedMetaDataFile,
+ Output: p.mergedMetaDataFile,
})
context.Build(pctx, android.BuildParams{
Rule: blueprint.Phony,
Description: "phony rule of merge provenance metadata",
- Inputs: []android.Path{mergedMetaDataFile},
+ Inputs: []android.Path{p.mergedMetaDataFile},
Output: android.PathForPhony(context, "provenance_metadata"),
})
+
+ context.Phony("droidcore", android.PathForPhony(context, "provenance_metadata"))
}
func moduleFilter(module android.Module) bool {
@@ -110,3 +113,9 @@
return artifactMetaDataFile
}
+
+func (p *provenanceInfoSingleton) MakeVars(ctx android.MakeVarsContext) {
+ ctx.DistForGoal("droidcore", p.mergedMetaDataFile)
+}
+
+var _ android.SingletonMakeVarsProvider = (*provenanceInfoSingleton)(nil)
diff --git a/rust/config/global.go b/rust/config/global.go
index 2d5fa99..6bfa9cf 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.59.0"
+ RustDefaultVersion = "1.60.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/library_test.go b/rust/library_test.go
index d78dcdd..4633cc7 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -200,23 +200,34 @@
func TestAutoDeps(t *testing.T) {
ctx := testRust(t, `
- rust_library_host {
- name: "libbar",
- srcs: ["bar.rs"],
- crate_name: "bar",
- }
+ rust_library_host {
+ name: "libbar",
+ srcs: ["bar.rs"],
+ crate_name: "bar",
+ }
+ rust_library_host_rlib {
+ name: "librlib_only",
+ srcs: ["bar.rs"],
+ crate_name: "rlib_only",
+ }
rust_library_host {
name: "libfoo",
srcs: ["foo.rs"],
crate_name: "foo",
- rustlibs: ["libbar"],
+ rustlibs: [
+ "libbar",
+ "librlib_only",
+ ],
}
- rust_ffi_host {
- name: "libfoo.ffi",
- srcs: ["foo.rs"],
- crate_name: "foo",
- rustlibs: ["libbar"],
- }`)
+ rust_ffi_host {
+ name: "libfoo.ffi",
+ srcs: ["foo.rs"],
+ crate_name: "foo",
+ rustlibs: [
+ "libbar",
+ "librlib_only",
+ ],
+ }`)
libfooRlib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_rlib_rlib-std")
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib")
@@ -239,7 +250,9 @@
if android.InList("libbar.dylib-std", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
t.Errorf("libbar present as rlib dependency in dynamic lib")
}
-
+ if !android.InList("librlib_only.dylib-std", dyn.Module().(*Module).Properties.AndroidMkRlibs) {
+ t.Errorf("librlib_only should be selected by rustlibs as an rlib.")
+ }
}
}
diff --git a/rust/rust.go b/rust/rust.go
index 2a7bdcf..c4fd148 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1368,13 +1368,12 @@
}
// rlibs
+ rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
for _, lib := range deps.Rlibs {
depTag := rlibDepTag
lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
- {Mutator: "rust_libraries", Variation: rlibVariation},
- }...), depTag, lib)
+ actx.AddVariationDependencies(rlibDepVariations, depTag, lib)
}
// dylibs
@@ -1386,21 +1385,25 @@
// rustlibs
if deps.Rustlibs != nil && !mod.compiler.Disabled() {
autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
- if autoDep.depTag == rlibDepTag {
- for _, lib := range deps.Rustlibs {
- depTag := autoDep.depTag
- lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
- actx.AddVariationDependencies(append(rlibDepVariations, []blueprint.Variation{
- {Mutator: "rust_libraries", Variation: autoDep.variation},
- }...), depTag, lib)
+ for _, lib := range deps.Rustlibs {
+ if autoDep.depTag == rlibDepTag {
+ // Handle the rlib deptag case
+ addRlibDependency(actx, lib, mod, snapshotInfo, rlibDepVariations)
+ } else {
+ // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
+ // Check for the existence of the dylib deptag variant. Select it if available,
+ // otherwise select the rlib variant.
+ autoDepVariations := append(commonDepVariations,
+ blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
+ if actx.OtherModuleDependencyVariantExists(autoDepVariations, lib) {
+ actx.AddVariationDependencies(autoDepVariations, autoDep.depTag, lib)
+ } else {
+ // If there's no dylib dependency available, try to add the rlib dependency instead.
+ addRlibDependency(actx, lib, mod, snapshotInfo, rlibDepVariations)
+ }
}
- } else {
- actx.AddVariationDependencies(
- append(commonDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation}),
- autoDep.depTag, deps.Rustlibs...)
}
}
-
// stdlibs
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
@@ -1476,6 +1479,12 @@
actx.AddFarVariationDependencies(ctx.Config().BuildOSTarget.Variations(), procMacroDepTag, deps.ProcMacros...)
}
+// addRlibDependency will add an rlib dependency, rewriting to the snapshot library if available.
+func addRlibDependency(actx android.BottomUpMutatorContext, lib string, mod *Module, snapshotInfo *cc.SnapshotInfo, variations []blueprint.Variation) {
+ lib = cc.RewriteSnapshotLib(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Rlibs)
+ actx.AddVariationDependencies(variations, rlibDepTag, lib)
+}
+
func BeginMutator(ctx android.BottomUpMutatorContext) {
if mod, ok := ctx.Module().(*Module); ok && mod.Enabled() {
mod.beginMutator(ctx)
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 4c847a1..4773579 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -188,3 +188,8 @@
"get_clang_version.py",
],
}
+
+sh_binary_host {
+ name: "list_image",
+ src: "list_image.sh",
+}
diff --git a/scripts/list_image.sh b/scripts/list_image.sh
new file mode 100755
index 0000000..0542fa6
--- /dev/null
+++ b/scripts/list_image.sh
@@ -0,0 +1,51 @@
+#! /bin/bash
+
+# Recursively list Android image directory.
+set -eu
+set -o pipefail
+
+function die() { format=$1; shift; printf "$format\n" "$@"; exit 1; }
+
+# Figure out the filer utility.
+declare filer=
+[[ -z "${ANDROID_HOST_OUT:-}" ]] || filer=${ANDROID_HOST_OUT}/bin/debugfs_static
+if [[ "${1:-}" =~ --debugfs_path=(.*) ]]; then
+ filer=${BASH_REMATCH[1]}
+ shift
+fi
+if [[ -z "${filer:-}" ]]; then
+ maybefiler="$(dirname $0)/debugfs_static"
+ [[ ! -x "$maybefiler" ]] || filer="$maybefiler"
+fi
+
+(( $# >0 )) || die "%s [--debugfs_path=<path>] IMAGE" "$0"
+
+[[ -n "${filer:-}" ]] || die "cannot locate 'debugfs' executable: \
+--debugfs_path= is missing, ANDROID_HOST_OUT is not set, \
+and 'debugfs_static' is not colocated with this script"
+declare -r image="$1"
+
+function dolevel() {
+ printf "%s/\n" "$1"
+ # Each line of the file output consists of 6 fields separated with '/'.
+ # The second one contains the file's attributes, and the fifth its name.
+ $filer -R "ls -l -p $1" "$image" 2>/dev/null |\
+ sed -nr 's|^/.*/(.*)/.*/.*/(.+)/.*/$|\2 \1|p' | LANG=C sort | \
+ while read name attr; do
+ [[ "$name" != '.' && "$name" != '..' ]] || continue
+ path="$1/$name"
+ # If the second char of the attributes is '4', it is a directory.
+ if [[ $attr =~ ^.4 ]]; then
+ dolevel "$path"
+ else
+ printf "%s\n" "$path"
+ fi
+ done
+}
+
+# The filer always prints its version on stderr, so we are going
+# to redirect it to the bit bucket. On the other hand, the filer's
+# return code on error is still 0. Let's run it once to without
+# redirecting stderr to see that there is at least one entry.
+$filer -R "ls -l -p" "$image" | grep -q -m1 -P '^/.*/.*/.*/.*/.+/.*/$'
+dolevel .
diff --git a/scripts/test_config_fixer.py b/scripts/test_config_fixer.py
index c150e8c..3dbc22e 100644
--- a/scripts/test_config_fixer.py
+++ b/scripts/test_config_fixer.py
@@ -28,6 +28,8 @@
from manifest import parse_test_config
from manifest import write_xml
+KNOWN_PREPARERS = ['com.android.tradefed.targetprep.TestAppInstallSetup',
+ 'com.android.tradefed.targetprep.suite.SuiteApkInstaller']
def parse_args():
"""Parse commandline arguments."""
@@ -64,7 +66,7 @@
tests = get_children_with_tag(test_config, 'target_preparer')
for test in tests:
- if test.getAttribute('class') == "com.android.tradefed.targetprep.TestAppInstallSetup":
+ if test.getAttribute('class') in KNOWN_PREPARERS:
options = get_children_with_tag(test, 'option')
for option in options:
if option.getAttribute('name') == "test-file-name":
diff --git a/scripts/test_config_fixer_test.py b/scripts/test_config_fixer_test.py
index d00a593..39ce5b3 100644
--- a/scripts/test_config_fixer_test.py
+++ b/scripts/test_config_fixer_test.py
@@ -70,7 +70,7 @@
class OverwriteTestFileNameTest(unittest.TestCase):
""" Unit tests for overwrite_test_file_name function """
- test_config = (
+ test_config_test_app_install_setup = (
'<?xml version="1.0" encoding="utf-8"?>\n'
'<configuration description="Runs some tests.">\n'
' <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">\n'
@@ -82,15 +82,38 @@
' </test>\n'
'</configuration>\n')
- def test_all(self):
- doc = minidom.parseString(self.test_config % ("foo.apk"))
+ test_config_suite_apk_installer = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<configuration description="Runs some tests.">\n'
+ ' <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">\n'
+ ' <option name="test-file-name" value="%s"/>\n'
+ ' </target_preparer>\n'
+ ' <test class="com.android.tradefed.testtype.AndroidJUnitTest">\n'
+ ' <option name="package" value="com.android.foo"/>\n'
+ ' <option name="runtime-hint" value="20s"/>\n'
+ ' </test>\n'
+ '</configuration>\n')
+
+ def test_testappinstallsetup(self):
+ doc = minidom.parseString(self.test_config_test_app_install_setup % ("foo.apk"))
test_config_fixer.overwrite_test_file_name(doc, "bar.apk")
output = io.StringIO()
test_config_fixer.write_xml(output, doc)
# Only the matching package name in a test node should be updated.
- expected = self.test_config % ("bar.apk")
+ expected = self.test_config_test_app_install_setup % ("bar.apk")
+ self.assertEqual(expected, output.getvalue())
+
+ def test_suiteapkinstaller(self):
+ doc = minidom.parseString(self.test_config_suite_apk_installer % ("foo.apk"))
+
+ test_config_fixer.overwrite_test_file_name(doc, "bar.apk")
+ output = io.StringIO()
+ test_config_fixer.write_xml(output, doc)
+
+ # Only the matching package name in a test node should be updated.
+ expected = self.test_config_suite_apk_installer % ("bar.apk")
self.assertEqual(expected, output.getvalue())
diff --git a/ui/build/build.go b/ui/build/build.go
index d261f89..aadf4af 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -18,6 +18,7 @@
"io/ioutil"
"os"
"path/filepath"
+ "sync"
"text/template"
"android/soong/ui/metrics"
@@ -205,6 +206,8 @@
return
}
+ defer waitForDist(ctx)
+
// checkProblematicFiles aborts the build if Android.mk or CleanSpec.mk are found at the root of the tree.
checkProblematicFiles(ctx)
@@ -329,8 +332,18 @@
}
}
+var distWaitGroup sync.WaitGroup
+
+// waitForDist waits for all backgrounded distGzipFile and distFile writes to finish
+func waitForDist(ctx Context) {
+ ctx.BeginTrace("soong_ui", "dist")
+ defer ctx.EndTrace()
+
+ distWaitGroup.Wait()
+}
+
// distGzipFile writes a compressed copy of src to the distDir if dist is enabled. Failures
-// are printed but non-fatal.
+// are printed but non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
func distGzipFile(ctx Context, config Config, src string, subDirs ...string) {
if !config.Dist() {
return
@@ -343,13 +356,17 @@
ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
}
- if err := gzipFileToDir(src, destDir); err != nil {
- ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
- }
+ distWaitGroup.Add(1)
+ go func() {
+ defer distWaitGroup.Done()
+ if err := gzipFileToDir(src, destDir); err != nil {
+ ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
+ }
+ }()
}
// distFile writes a copy of src to the distDir if dist is enabled. Failures are printed but
-// non-fatal.
+// non-fatal. Uses the distWaitGroup func for backgrounding (optimization).
func distFile(ctx Context, config Config, src string, subDirs ...string) {
if !config.Dist() {
return
@@ -362,7 +379,11 @@
ctx.Printf("failed to mkdir %s: %s", destDir, err.Error())
}
- if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
- ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
- }
+ distWaitGroup.Add(1)
+ go func() {
+ defer distWaitGroup.Done()
+ if _, err := copyFile(src, filepath.Join(destDir, filepath.Base(src))); err != nil {
+ ctx.Printf("failed to dist %s: %s", filepath.Base(src), err.Error())
+ }
+ }()
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 11311f9..285f156 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -205,6 +205,9 @@
"CCACHE_SLOPPINESS",
"CCACHE_BASEDIR",
"CCACHE_CPP2",
+
+ // LLVM compiler wrapper options
+ "TOOLCHAIN_RUSAGE_OUTPUT",
}
allVars := append(append([]string{
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 41de6bd..dab1a9b 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -169,6 +169,9 @@
"CCACHE_BASEDIR",
"CCACHE_CPP2",
"CCACHE_DIR",
+
+ // LLVM compiler wrapper options
+ "TOOLCHAIN_RUSAGE_OUTPUT",
}, config.BuildBrokenNinjaUsesEnvVars()...)...)
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index c7f22f9..8992b4f 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -15,7 +15,9 @@
package build
import (
+ "errors"
"fmt"
+ "io/fs"
"io/ioutil"
"os"
"path/filepath"
@@ -491,10 +493,14 @@
ninja("bootstrap", "bootstrap.ninja", targets...)
- var soongBuildMetrics *soong_metrics_proto.SoongBuildMetrics
if shouldCollectBuildSoongMetrics(config) {
soongBuildMetrics := loadSoongBuildMetrics(ctx, config)
- logSoongBuildMetrics(ctx, soongBuildMetrics)
+ if soongBuildMetrics != nil {
+ logSoongBuildMetrics(ctx, soongBuildMetrics)
+ if ctx.Metrics != nil {
+ ctx.Metrics.SetSoongBuildMetrics(soongBuildMetrics)
+ }
+ }
}
distGzipFile(ctx, config, config.SoongNinjaFile(), "soong")
@@ -504,9 +510,6 @@
distGzipFile(ctx, config, config.SoongMakeVarsMk(), "soong")
}
- if shouldCollectBuildSoongMetrics(config) && ctx.Metrics != nil {
- ctx.Metrics.SetSoongBuildMetrics(soongBuildMetrics)
- }
if config.JsonModuleGraph() {
distGzipFile(ctx, config, config.ModuleGraphFile(), "soong")
}
@@ -538,8 +541,12 @@
func loadSoongBuildMetrics(ctx Context, config Config) *soong_metrics_proto.SoongBuildMetrics {
soongBuildMetricsFile := filepath.Join(config.LogsDir(), "soong_build_metrics.pb")
- buf, err := ioutil.ReadFile(soongBuildMetricsFile)
- if err != nil {
+ buf, err := os.ReadFile(soongBuildMetricsFile)
+ if errors.Is(err, fs.ErrNotExist) {
+ // Soong may not have run during this invocation
+ ctx.Verbosef("Failed to read metrics file, %s: %s", soongBuildMetricsFile, err)
+ return nil
+ } else if err != nil {
ctx.Fatalf("Failed to load %s: %s", soongBuildMetricsFile, err)
}
soongBuildMetrics := &soong_metrics_proto.SoongBuildMetrics{}