Merge "Support LOCAL_ENFORCE_USES_LIBRARIES in androidmk"
diff --git a/android/config.go b/android/config.go
index 3db7980..79917ad 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1564,6 +1564,15 @@
return false
}
+// ApexOfJar returns the apex component of the first pair with the given jar name on the list, or
+// an empty string if not found.
+func (l *ConfiguredJarList) ApexOfJar(jar string) string {
+ if idx := IndexList(jar, l.jars); idx != -1 {
+ return l.Apex(IndexList(jar, l.jars))
+ }
+ return ""
+}
+
// IndexOfJar returns the first pair with the given jar name on the list, or -1
// if not found.
func (l *ConfiguredJarList) IndexOfJar(jar string) int {
diff --git a/android/sdk.go b/android/sdk.go
index 0adfd89..36c576d 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -284,11 +284,20 @@
// Add a property set with the specified name and return so that additional
// properties can be added.
AddPropertySet(name string) BpPropertySet
+
+ // Add comment for property (or property set).
+ AddCommentForProperty(name, text string)
}
// A .bp module definition.
type BpModule interface {
BpPropertySet
+
+ // ModuleType returns the module type of the module
+ ModuleType() string
+
+ // Name returns the name of the module or "" if no name has been specified.
+ Name() string
}
// An individual member of the SDK, includes all of the variants that the SDK
@@ -380,6 +389,10 @@
// The name of the member type property on an sdk module.
SdkPropertyName() string
+ // RequiresBpProperty returns true if this member type requires its property to be usable within
+ // an Android.bp file.
+ RequiresBpProperty() bool
+
// True if the member type supports the sdk/sdk_snapshot, false otherwise.
UsableWithSdkAndSdkSnapshot() bool
@@ -405,6 +418,10 @@
// the module is not allowed in whichever sdk property it was added.
IsInstance(module Module) bool
+ // UsesSourceModuleTypeInSnapshot returns true when the AddPrebuiltModule() method returns a
+ // source module type.
+ UsesSourceModuleTypeInSnapshot() bool
+
// Add a prebuilt module that the sdk will populate.
//
// The sdk module code generates the snapshot as follows:
@@ -448,15 +465,29 @@
// Base type for SdkMemberType implementations.
type SdkMemberTypeBase struct {
- PropertyName string
+ PropertyName string
+
+ // When set to true BpPropertyNotRequired indicates that the member type does not require the
+ // property to be specifiable in an Android.bp file.
+ BpPropertyNotRequired bool
+
SupportsSdk bool
HostOsDependent bool
+
+ // When set to true UseSourceModuleTypeInSnapshot indicates that the member type creates a source
+ // module type in its SdkMemberType.AddPrebuiltModule() method. That prevents the sdk snapshot
+ // code from automatically adding a prefer: true flag.
+ UseSourceModuleTypeInSnapshot bool
}
func (b *SdkMemberTypeBase) SdkPropertyName() string {
return b.PropertyName
}
+func (b *SdkMemberTypeBase) RequiresBpProperty() bool {
+ return !b.BpPropertyNotRequired
+}
+
func (b *SdkMemberTypeBase) UsableWithSdkAndSdkSnapshot() bool {
return b.SupportsSdk
}
@@ -465,6 +496,10 @@
return b.HostOsDependent
}
+func (b *SdkMemberTypeBase) UsesSourceModuleTypeInSnapshot() bool {
+ return b.UseSourceModuleTypeInSnapshot
+}
+
// Encapsulates the information about registered SdkMemberTypes.
type SdkMemberTypesRegistry struct {
// The list of types sorted by property name.
diff --git a/apex/apex.go b/apex/apex.go
index d26c06d..2c0df27 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2102,6 +2102,11 @@
}
}
+ // Add classpaths.proto config.
+ classpathProtoOutput := bootclasspathFragmentInfo.ClasspathFragmentProtoOutput
+ classpathProto := newApexFile(ctx, classpathProtoOutput, classpathProtoOutput.Base(), bootclasspathFragmentInfo.ClasspathFragmentProtoInstallDir.Rel(), etc, nil)
+ filesToAdd = append(filesToAdd, classpathProto)
+
return filesToAdd
}
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index e2b320c..7bb3ff6 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -279,6 +279,7 @@
).RunTest(t)
ensureExactContents(t, result.TestContext, "com.android.art", "android_common_com.android.art_image", []string{
+ "etc/classpaths/mybootclasspathfragment.pb",
"javalib/arm/boot.art",
"javalib/arm/boot.oat",
"javalib/arm/boot.vdex",
@@ -481,6 +482,7 @@
ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
// This does not include art, oat or vdex files as they are only included for the art boot
// image.
+ "etc/classpaths/mybootclasspathfragment.pb",
"javalib/bar.jar",
"javalib/foo.jar",
})
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index c543ef8..407073a 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -257,24 +257,74 @@
depsMutators: []android.RegisterMutatorFunc{cc.RegisterDepsBp2Build},
dir: "foo/bar",
filesystem: map[string]string{
- "foo/bar/a.cpp": "",
+ "foo/bar/both.cpp": "",
+ "foo/bar/sharedonly.cpp": "",
+ "foo/bar/staticonly.cpp": "",
"foo/bar/Android.bp": `
cc_library {
name: "a",
- shared: { whole_static_libs: ["b"] },
- static: { srcs: ["a.cpp"] },
+ srcs: ["both.cpp"],
+ cflags: ["bothflag"],
+ shared_libs: ["shared_dep_for_both"],
+ static_libs: ["static_dep_for_both"],
+ whole_static_libs: ["whole_static_lib_for_both"],
+ static: {
+ srcs: ["staticonly.cpp"],
+ cflags: ["staticflag"],
+ shared_libs: ["shared_dep_for_static"],
+ static_libs: ["static_dep_for_static"],
+ whole_static_libs: ["whole_static_lib_for_static"],
+ },
+ shared: {
+ srcs: ["sharedonly.cpp"],
+ cflags: ["sharedflag"],
+ shared_libs: ["shared_dep_for_shared"],
+ static_libs: ["static_dep_for_shared"],
+ whole_static_libs: ["whole_static_lib_for_shared"],
+ },
bazel_module: { bp2build_available: true },
}
-cc_library_static { name: "b" }
+cc_library_static { name: "static_dep_for_shared" }
+
+cc_library_static { name: "static_dep_for_static" }
+
+cc_library_static { name: "static_dep_for_both" }
+
+cc_library_static { name: "whole_static_lib_for_shared" }
+
+cc_library_static { name: "whole_static_lib_for_static" }
+
+cc_library_static { name: "whole_static_lib_for_both" }
+
+cc_library { name: "shared_dep_for_shared" }
+
+cc_library { name: "shared_dep_for_static" }
+
+cc_library { name: "shared_dep_for_both" }
`,
},
bp: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
name = "a",
- copts = ["-Ifoo/bar"],
- srcs = ["a.cpp"],
- static_deps_for_shared = [":b"],
+ copts = [
+ "bothflag",
+ "-Ifoo/bar",
+ ],
+ deps = [":static_dep_for_both"],
+ dynamic_deps = [":shared_dep_for_both"],
+ dynamic_deps_for_shared = [":shared_dep_for_shared"],
+ dynamic_deps_for_static = [":shared_dep_for_static"],
+ shared_copts = ["sharedflag"],
+ shared_srcs = ["sharedonly.cpp"],
+ srcs = ["both.cpp"],
+ static_copts = ["staticflag"],
+ static_deps_for_shared = [":static_dep_for_shared"],
+ static_deps_for_static = [":static_dep_for_static"],
+ static_srcs = ["staticonly.cpp"],
+ whole_archive_deps = [":whole_static_lib_for_both"],
+ whole_archive_deps_for_shared = [":whole_static_lib_for_shared"],
+ whole_archive_deps_for_static = [":whole_static_lib_for_static"],
)`},
},
{
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index bff9b07..d082db1 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -189,8 +189,6 @@
":header_lib_2",
":static_lib_1",
":static_lib_2",
- ":whole_static_lib_1",
- ":whole_static_lib_2",
],
includes = [
"export_include_dir_1",
@@ -201,6 +199,10 @@
"foo_static1.cc",
"foo_static2.cc",
],
+ whole_archive_deps = [
+ ":whole_static_lib_1",
+ ":whole_static_lib_2",
+ ],
)`, `cc_library_static(
name = "static_lib_1",
copts = ["-I."],
@@ -423,13 +425,14 @@
name = "foo_static",
copts = ["-I."],
deps = select({
- "//build/bazel/platforms/arch:arm64": [
- ":static_dep",
- ":static_dep2",
- ],
+ "//build/bazel/platforms/arch:arm64": [":static_dep"],
"//conditions:default": [],
}),
linkstatic = True,
+ whole_archive_deps = select({
+ "//build/bazel/platforms/arch:arm64": [":static_dep2"],
+ "//conditions:default": [],
+ }),
)`, `cc_library_static(
name = "static_dep",
copts = ["-I."],
@@ -458,13 +461,14 @@
name = "foo_static",
copts = ["-I."],
deps = select({
- "//build/bazel/platforms/os:android": [
- ":static_dep",
- ":static_dep2",
- ],
+ "//build/bazel/platforms/os:android": [":static_dep"],
"//conditions:default": [],
}),
linkstatic = True,
+ whole_archive_deps = select({
+ "//build/bazel/platforms/os:android": [":static_dep2"],
+ "//conditions:default": [],
+ }),
)`, `cc_library_static(
name = "static_dep",
copts = ["-I."],
@@ -497,10 +501,7 @@
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
copts = ["-I."],
- deps = [
- ":static_dep",
- ":static_dep2",
- ] + select({
+ deps = [":static_dep"] + select({
"//build/bazel/platforms/arch:arm64": [":static_dep4"],
"//conditions:default": [],
}) + select({
@@ -508,6 +509,7 @@
"//conditions:default": [],
}),
linkstatic = True,
+ whole_archive_deps = [":static_dep2"],
)`, `cc_library_static(
name = "static_dep",
copts = ["-I."],
@@ -732,8 +734,7 @@
cc_library_static { name: "static_dep" }
cc_library_static {
name: "foo_static",
- static_libs: ["static_dep"],
- whole_static_libs: ["static_dep"],
+ static_libs: ["static_dep", "static_dep"],
}`,
expectedBazelTargets: []string{`cc_library_static(
name = "foo_static",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 67f88e2..7d01986 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -85,7 +85,11 @@
}
type sharedAttributes struct {
- staticDeps bazel.LabelListAttribute
+ copts bazel.StringListAttribute
+ srcs bazel.LabelListAttribute
+ staticDeps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
}
// bp2buildParseSharedProps returns the attributes for the shared variant of a cc_library.
@@ -95,17 +99,35 @@
return sharedAttributes{}
}
- var staticDeps bazel.LabelListAttribute
+ copts := bazel.StringListAttribute{Value: lib.SharedProperties.Shared.Cflags}
- staticDeps.Value = android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Whole_static_libs)
+ srcs := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleSrc(ctx, lib.SharedProperties.Shared.Srcs)}
+
+ staticDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Static_libs)}
+
+ dynamicDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Shared_libs)}
+
+ wholeArchiveDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.SharedProperties.Shared.Whole_static_libs)}
return sharedAttributes{
- staticDeps: staticDeps,
+ copts: copts,
+ srcs: srcs,
+ staticDeps: staticDeps,
+ dynamicDeps: dynamicDeps,
+ wholeArchiveDeps: wholeArchiveDeps,
}
}
type staticAttributes struct {
- srcs bazel.LabelListAttribute
+ copts bazel.StringListAttribute
+ srcs bazel.LabelListAttribute
+ staticDeps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
}
// bp2buildParseStaticProps returns the attributes for the static variant of a cc_library.
@@ -115,11 +137,26 @@
return staticAttributes{}
}
- var srcs bazel.LabelListAttribute
- srcs.Value = android.BazelLabelForModuleSrc(ctx, lib.StaticProperties.Static.Srcs)
+ copts := bazel.StringListAttribute{Value: lib.StaticProperties.Static.Cflags}
+
+ srcs := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleSrc(ctx, lib.StaticProperties.Static.Srcs)}
+
+ staticDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Static_libs)}
+
+ dynamicDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Shared_libs)}
+
+ wholeArchiveDeps := bazel.LabelListAttribute{
+ Value: android.BazelLabelForModuleDeps(ctx, lib.StaticProperties.Static.Whole_static_libs)}
return staticAttributes{
- srcs: srcs,
+ copts: copts,
+ srcs: srcs,
+ staticDeps: staticDeps,
+ dynamicDeps: dynamicDeps,
+ wholeArchiveDeps: wholeArchiveDeps,
}
}
@@ -246,10 +283,11 @@
// Convenience struct to hold all attributes parsed from linker properties.
type linkerAttributes struct {
- deps bazel.LabelListAttribute
- dynamicDeps bazel.LabelListAttribute
- linkopts bazel.StringListAttribute
- versionScript bazel.LabelAttribute
+ deps bazel.LabelListAttribute
+ dynamicDeps bazel.LabelListAttribute
+ wholeArchiveDeps bazel.LabelListAttribute
+ linkopts bazel.StringListAttribute
+ versionScript bazel.LabelAttribute
}
// FIXME(b/187655838): Use the existing linkerFlags() function instead of duplicating logic here
@@ -266,6 +304,7 @@
func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkerAttributes {
var deps bazel.LabelListAttribute
var dynamicDeps bazel.LabelListAttribute
+ var wholeArchiveDeps bazel.LabelListAttribute
var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute
@@ -274,11 +313,11 @@
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
libs = append(libs, baseLinkerProps.Static_libs...)
- libs = append(libs, baseLinkerProps.Whole_static_libs...)
+ wholeArchiveLibs := baseLinkerProps.Whole_static_libs
libs = android.SortedUniqueStrings(libs)
deps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, libs))
-
linkopts.Value = getBp2BuildLinkerFlags(baseLinkerProps)
+ wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
if baseLinkerProps.Version_script != nil {
versionScript.Value = android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)
@@ -296,19 +335,19 @@
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
libs = append(libs, baseLinkerProps.Static_libs...)
- libs = append(libs, baseLinkerProps.Whole_static_libs...)
+ wholeArchiveLibs := baseLinkerProps.Whole_static_libs
libs = android.SortedUniqueStrings(libs)
deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs))
-
linkopts.SetValueForArch(arch.Name, getBp2BuildLinkerFlags(baseLinkerProps))
+ wholeArchiveDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
if baseLinkerProps.Version_script != nil {
versionScript.SetValueForArch(arch.Name,
android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
-
- sharedLibs := baseLinkerProps.Shared_libs
- dynamicDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}
+
+ sharedLibs := baseLinkerProps.Shared_libs
+ dynamicDeps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, sharedLibs))
}
}
@@ -317,8 +356,9 @@
libs := baseLinkerProps.Header_libs
libs = append(libs, baseLinkerProps.Export_header_lib_headers...)
libs = append(libs, baseLinkerProps.Static_libs...)
- libs = append(libs, baseLinkerProps.Whole_static_libs...)
+ wholeArchiveLibs := baseLinkerProps.Whole_static_libs
libs = android.SortedUniqueStrings(libs)
+ wholeArchiveDeps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, wholeArchiveLibs))
deps.SetValueForOS(os.Name, android.BazelLabelForModuleDeps(ctx, libs))
linkopts.SetValueForOS(os.Name, getBp2BuildLinkerFlags(baseLinkerProps))
@@ -329,10 +369,11 @@
}
return linkerAttributes{
- deps: deps,
- dynamicDeps: dynamicDeps,
- linkopts: linkopts,
- versionScript: versionScript,
+ deps: deps,
+ dynamicDeps: dynamicDeps,
+ wholeArchiveDeps: wholeArchiveDeps,
+ linkopts: linkopts,
+ versionScript: versionScript,
}
}
diff --git a/cc/library.go b/cc/library.go
index 7e960a7..c5ff9b1 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -220,16 +220,29 @@
// For bp2build conversion.
type bazelCcLibraryAttributes struct {
- Srcs bazel.LabelListAttribute
- Hdrs bazel.LabelListAttribute
- Copts bazel.StringListAttribute
- Linkopts bazel.StringListAttribute
- Deps bazel.LabelListAttribute
- Dynamic_deps bazel.LabelListAttribute
- User_link_flags bazel.StringListAttribute
- Includes bazel.StringListAttribute
- Static_deps_for_shared bazel.LabelListAttribute
- Version_script bazel.LabelAttribute
+ // Attributes pertaining to both static and shared variants.
+ Srcs bazel.LabelListAttribute
+ Hdrs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Dynamic_deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Includes bazel.StringListAttribute
+ Linkopts bazel.StringListAttribute
+ // Attributes pertaining to shared variant.
+ Shared_copts bazel.StringListAttribute
+ Shared_srcs bazel.LabelListAttribute
+ Static_deps_for_shared bazel.LabelListAttribute
+ Dynamic_deps_for_shared bazel.LabelListAttribute
+ Whole_archive_deps_for_shared bazel.LabelListAttribute
+ User_link_flags bazel.StringListAttribute
+ Version_script bazel.LabelAttribute
+ // Attributes pertaining to static variant.
+ Static_copts bazel.StringListAttribute
+ Static_srcs bazel.LabelListAttribute
+ Static_deps_for_static bazel.LabelListAttribute
+ Dynamic_deps_for_static bazel.LabelListAttribute
+ Whole_archive_deps_for_static bazel.LabelListAttribute
}
type bazelCcLibrary struct {
@@ -276,17 +289,26 @@
var srcs bazel.LabelListAttribute
srcs.Append(compilerAttrs.srcs)
- srcs.Append(staticAttrs.srcs)
attrs := &bazelCcLibraryAttributes{
- Srcs: srcs,
- Copts: compilerAttrs.copts,
- Linkopts: linkerAttrs.linkopts,
- Deps: linkerAttrs.deps,
- Dynamic_deps: linkerAttrs.dynamicDeps,
- Version_script: linkerAttrs.versionScript,
- Static_deps_for_shared: sharedAttrs.staticDeps,
- Includes: exportedIncludes,
+ Srcs: srcs,
+ Deps: linkerAttrs.deps,
+ Dynamic_deps: linkerAttrs.dynamicDeps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+ Copts: compilerAttrs.copts,
+ Includes: exportedIncludes,
+ Linkopts: linkerAttrs.linkopts,
+ Shared_copts: sharedAttrs.copts,
+ Shared_srcs: sharedAttrs.srcs,
+ Static_deps_for_shared: sharedAttrs.staticDeps,
+ Whole_archive_deps_for_shared: sharedAttrs.wholeArchiveDeps,
+ Dynamic_deps_for_shared: sharedAttrs.dynamicDeps,
+ Version_script: linkerAttrs.versionScript,
+ Static_copts: staticAttrs.copts,
+ Static_srcs: staticAttrs.srcs,
+ Static_deps_for_static: staticAttrs.staticDeps,
+ Whole_archive_deps_for_static: staticAttrs.wholeArchiveDeps,
+ Dynamic_deps_for_static: staticAttrs.dynamicDeps,
}
props := bazel.BazelTargetModuleProperties{
@@ -2194,13 +2216,14 @@
}
type bazelCcLibraryStaticAttributes struct {
- Copts bazel.StringListAttribute
- Srcs bazel.LabelListAttribute
- Deps bazel.LabelListAttribute
- Linkopts bazel.StringListAttribute
- Linkstatic bool
- Includes bazel.StringListAttribute
- Hdrs bazel.LabelListAttribute
+ Copts bazel.StringListAttribute
+ Srcs bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+ Whole_archive_deps bazel.LabelListAttribute
+ Linkopts bazel.StringListAttribute
+ Linkstatic bool
+ Includes bazel.StringListAttribute
+ Hdrs bazel.LabelListAttribute
}
type bazelCcLibraryStatic struct {
@@ -2221,9 +2244,11 @@
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module)
attrs := &bazelCcLibraryStaticAttributes{
- Copts: compilerAttrs.copts,
- Srcs: compilerAttrs.srcs,
- Deps: linkerAttrs.deps,
+ Copts: compilerAttrs.copts,
+ Srcs: compilerAttrs.srcs,
+ Deps: linkerAttrs.deps,
+ Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
+
Linkopts: linkerAttrs.linkopts,
Linkstatic: true,
Includes: exportedIncludes,
diff --git a/cc/linker.go b/cc/linker.go
index 73fc4f0..a9930ad 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -421,9 +421,13 @@
if !BoolDefault(linker.Properties.Pack_relocations, true) {
flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=none")
} else if ctx.Device() {
- // The SHT_RELR relocations is only supported by API level >= 28.
- // Do not turn this on if older version NDK is used.
- if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 28) {
+ // SHT_RELR relocations are only supported at API level >= 30.
+ // ANDROID_RELR relocations were supported at API level >= 28.
+ // Relocation packer was supported at API level >= 23.
+ // Do the best we can...
+ if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 30) {
+ flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,--pack-dyn-relocs=android+relr")
+ } else if CheckSdkVersionAtLeast(ctx, 28) {
flags.Global.LdFlags = append(flags.Global.LdFlags,
"-Wl,--pack-dyn-relocs=android+relr",
"-Wl,--use-android-relr-tags")
diff --git a/cmd/soong_build/writedocs.go b/cmd/soong_build/writedocs.go
index a69de6a..b7c260c 100644
--- a/cmd/soong_build/writedocs.go
+++ b/cmd/soong_build/writedocs.go
@@ -114,7 +114,10 @@
err = ioutil.WriteFile(filename, buf.Bytes(), 0666)
}
- // Now, produce per-package module lists with detailed information.
+ // Now, produce per-package module lists with detailed information, and a list
+ // of keywords.
+ keywordsTmpl := template.Must(template.New("file").Parse(keywordsTemplate))
+ keywordsBuf := &bytes.Buffer{}
for _, pkg := range packages {
// We need a module name getter/setter function because I couldn't
// find a way to keep it in a variable defined within the template.
@@ -141,7 +144,17 @@
if err != nil {
return err
}
+ err = keywordsTmpl.Execute(keywordsBuf, data)
+ if err != nil {
+ return err
+ }
}
+
+ // Write out list of keywords. This includes all module and property names, which is useful for
+ // building syntax highlighters.
+ keywordsFilename := filepath.Join(filepath.Dir(filename), "keywords.txt")
+ err = ioutil.WriteFile(keywordsFilename, keywordsBuf.Bytes(), 0666)
+
return err
}
@@ -413,4 +426,9 @@
</script>
{{end}}
`
+
+ keywordsTemplate = `
+{{range $moduleType := .Modules}}{{$moduleType.Name}}:{{range $property := $moduleType.Properties}}{{$property.Name}},{{end}}
+{{end}}
+`
)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index 6270b5b..bed629d 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -109,6 +109,8 @@
android.ModuleBase
android.ApexModuleBase
android.SdkBase
+ ClasspathFragmentBase
+
properties bootclasspathFragmentProperties
}
@@ -117,6 +119,7 @@
m.AddProperties(&m.properties)
android.InitApexModule(m)
android.InitSdkAwareModule(m)
+ initClasspathFragment(m, BOOTCLASSPATH)
android.InitAndroidArchModule(m, android.HostAndDeviceSupported, android.MultilibCommon)
android.AddLoadHook(m, func(ctx android.LoadHookContext) {
@@ -242,6 +245,22 @@
// BootclasspathFragmentApexContentInfo contains the bootclasspath_fragments contributions to the
// apex contents.
type BootclasspathFragmentApexContentInfo struct {
+ // ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
+ //
+ // The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
+ // for more details.
+ ClasspathFragmentProtoOutput android.OutputPath
+
+ // ClasspathFragmentProtoInstallDir contains information about on device location for the generated classpaths.proto file.
+ //
+ // The path encodes expected sub-location within partitions, i.e. etc/classpaths/<proto-file>,
+ // for ClasspathFragmentProtoOutput. To get sub-location, instead of the full output / make path
+ // use android.InstallPath#Rel().
+ //
+ // This is only relevant for APEX modules as they perform their own installation; while regular
+ // system files are installed via ClasspathFragmentBase#androidMkEntries().
+ ClasspathFragmentProtoInstallDir android.InstallPath
+
// The image config, internal to this module (and the dex_bootjars singleton).
//
// Will be nil if the BootclasspathFragmentApexContentInfo has not been provided for a specific module. That can occur
@@ -339,30 +358,47 @@
b.bootclasspathImageNameContentsConsistencyCheck(ctx)
}
+ // Generate classpaths.proto config
+ b.generateClasspathProtoBuildActions(ctx)
+
// Perform hidden API processing.
b.generateHiddenAPIBuildActions(ctx)
- // Nothing to do if skipping the dexpreopt of boot image jars.
- if SkipDexpreoptBootJars(ctx) {
- return
- }
-
- // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
- // GenerateSingletonBuildActions method as it cannot create it for itself.
- dexpreopt.GetGlobalSoongConfig(ctx)
-
- imageConfig := b.getImageConfig(ctx)
- if imageConfig == nil {
- return
- }
-
// Construct the boot image info from the config.
- info := BootclasspathFragmentApexContentInfo{imageConfig: imageConfig}
+ info := BootclasspathFragmentApexContentInfo{
+ ClasspathFragmentProtoInstallDir: b.classpathFragmentBase().installDirPath,
+ ClasspathFragmentProtoOutput: b.classpathFragmentBase().outputFilepath,
+ imageConfig: nil,
+ }
+
+ if !SkipDexpreoptBootJars(ctx) {
+ // Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
+ // GenerateSingletonBuildActions method as it cannot create it for itself.
+ dexpreopt.GetGlobalSoongConfig(ctx)
+ info.imageConfig = b.getImageConfig(ctx)
+ }
// Make it available for other modules.
ctx.SetProvider(BootclasspathFragmentApexContentInfoProvider, info)
}
+// generateClasspathProtoBuildActions generates all required build actions for classpath.proto config
+func (b *BootclasspathFragmentModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
+ var classpathJars []classpathJar
+ if "art" == proptools.String(b.properties.Image_name) {
+ // ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
+ classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
+ } else {
+ classpathJars = configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), b.classpathType)
+ }
+ b.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, classpathJars)
+}
+
+func (b *BootclasspathFragmentModule) ClasspathFragmentToConfiguredJarList(ctx android.ModuleContext) android.ConfiguredJarList {
+ // TODO(satayev): populate with actual content
+ return android.EmptyConfiguredJarList()
+}
+
func (b *BootclasspathFragmentModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
// Get a map of the image configs that are supported.
imageConfigs := genBootImageConfigs(ctx)
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index 2e05823..7422fa2 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -143,6 +143,8 @@
android.WriteFileRule(ctx, output, content.String())
}
+// Returns AndroidMkEntries objects to install generated classpath.proto.
+// Do not use this to install into APEXes as the injection of the generated files happen separately for APEXes.
func (c *ClasspathFragmentBase) androidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{{
Class: "ETC",
diff --git a/java/java.go b/java/java.go
index d74bf68..9a5fbfc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1222,6 +1222,13 @@
return LintDepSets{}
}
+func (j *Import) getStrictUpdatabilityLinting() bool {
+ return false
+}
+
+func (j *Import) setStrictUpdatabilityLinting(bool) {
+}
+
func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) {
ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...)
@@ -1545,6 +1552,13 @@
return true
}
+func (j *DexImport) getStrictUpdatabilityLinting() bool {
+ return false
+}
+
+func (j *DexImport) setStrictUpdatabilityLinting(bool) {
+}
+
func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if len(j.properties.Jars) != 1 {
ctx.PropertyErrorf("jars", "exactly one jar must be provided")
diff --git a/java/lint.go b/java/lint.go
index 5e39274..9f769df 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -103,6 +103,10 @@
type lintDepSetsIntf interface {
LintDepSets() LintDepSets
+
+ // Methods used to propagate strict_updatability_linting values.
+ getStrictUpdatabilityLinting() bool
+ setStrictUpdatabilityLinting(bool)
}
type LintDepSets struct {
@@ -153,6 +157,14 @@
return l.outputs.depSets
}
+func (l *linter) getStrictUpdatabilityLinting() bool {
+ return BoolDefault(l.properties.Lint.Strict_updatability_linting, false)
+}
+
+func (l *linter) setStrictUpdatabilityLinting(strictLinting bool) {
+ l.properties.Lint.Strict_updatability_linting = &strictLinting
+}
+
var _ lintDepSetsIntf = (*linter)(nil)
var _ lintOutputsIntf = (*linter)(nil)
@@ -260,7 +272,7 @@
cmd.FlagForEachArg("--error_check ", l.properties.Lint.Error_checks)
cmd.FlagForEachArg("--fatal_check ", l.properties.Lint.Fatal_checks)
- if BoolDefault(l.properties.Lint.Strict_updatability_linting, false) {
+ if l.getStrictUpdatabilityLinting() {
// Verify the module does not baseline issues that endanger safe updatability.
if baselinePath := l.getBaselineFilepath(ctx); baselinePath.Valid() {
cmd.FlagWithInput("--baseline ", baselinePath.Path())
@@ -586,6 +598,14 @@
func init() {
android.RegisterSingletonType("lint",
func() android.Singleton { return &lintSingleton{} })
+
+ registerLintBuildComponents(android.InitRegistrationContext)
+}
+
+func registerLintBuildComponents(ctx android.RegistrationContext) {
+ ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("enforce_strict_updatability_linting", enforceStrictUpdatabilityLintingMutator).Parallel()
+ })
}
func lintZip(ctx android.BuilderContext, paths android.Paths, outputPath android.WritablePath) {
@@ -604,3 +624,15 @@
rule.Build(outputPath.Base(), outputPath.Base())
}
+
+// Enforce the strict updatability linting to all applicable transitive dependencies.
+func enforceStrictUpdatabilityLintingMutator(ctx android.TopDownMutatorContext) {
+ m := ctx.Module()
+ if d, ok := m.(lintDepSetsIntf); ok && d.getStrictUpdatabilityLinting() {
+ ctx.VisitDirectDepsWithTag(staticLibTag, func(d android.Module) {
+ if a, ok := d.(lintDepSetsIntf); ok {
+ a.setStrictUpdatabilityLinting(true)
+ }
+ })
+ }
+}
diff --git a/java/lint_test.go b/java/lint_test.go
index a253df9..6d64de7 100644
--- a/java/lint_test.go
+++ b/java/lint_test.go
@@ -181,12 +181,22 @@
srcs: [
"a.java",
],
+ static_libs: ["bar"],
min_sdk_version: "29",
sdk_version: "current",
lint: {
strict_updatability_linting: true,
},
}
+
+ java_library {
+ name: "bar",
+ srcs: [
+ "a.java",
+ ],
+ min_sdk_version: "29",
+ sdk_version: "current",
+ }
`
fs := android.MockFS{
"lint-baseline.xml": nil,
@@ -201,4 +211,11 @@
"--baseline lint-baseline.xml --disallowed_issues NewApi") {
t.Error("did not restrict baselining NewApi")
}
+
+ bar := result.ModuleForTests("bar", "android_common")
+ sboxProto = android.RuleBuilderSboxProtoForTests(t, bar.Output("lint.sbox.textproto"))
+ if !strings.Contains(*sboxProto.Commands[0].Command,
+ "--baseline lint-baseline.xml --disallowed_issues NewApi") {
+ t.Error("did not restrict baselining NewApi")
+ }
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 1caffe4..c787e47 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -203,6 +203,7 @@
func (b *platformBootclasspathModule) generateClasspathProtoBuildActions(ctx android.ModuleContext) {
// ART and platform boot jars must have a corresponding entry in DEX2OATBOOTCLASSPATH
classpathJars := configuredJarListToClasspathJars(ctx, b.ClasspathFragmentToConfiguredJarList(ctx), BOOTCLASSPATH, DEX2OATBOOTCLASSPATH)
+
// TODO(satayev): remove updatable boot jars once each apex has its own fragment
global := dexpreopt.GetGlobalConfig(ctx)
classpathJars = append(classpathJars, configuredJarListToClasspathJars(ctx, global.UpdatableBootJars, BOOTCLASSPATH)...)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index aff4539..800e93b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2195,6 +2195,20 @@
}
}
+func (module *SdkLibraryImport) getStrictUpdatabilityLinting() bool {
+ if module.implLibraryModule == nil {
+ return false
+ } else {
+ return module.implLibraryModule.getStrictUpdatabilityLinting()
+ }
+}
+
+func (module *SdkLibraryImport) setStrictUpdatabilityLinting(strictLinting bool) {
+ if module.implLibraryModule != nil {
+ module.implLibraryModule.setStrictUpdatabilityLinting(strictLinting)
+ }
+}
+
// to satisfy apex.javaDependency interface
func (module *SdkLibraryImport) Stem() string {
return module.BaseModuleName()
diff --git a/java/testing.go b/java/testing.go
index 37e63f5..387d595 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -245,6 +245,7 @@
RegisterStubsBuildComponents(ctx)
RegisterSystemModulesBuildComponents(ctx)
registerSystemserverClasspathBuildComponents(ctx)
+ registerLintBuildComponents(ctx)
}
// gatherRequiredDepsForTest gathers the module definitions used by
diff --git a/scripts/Android.bp b/scripts/Android.bp
index b0a8669..1c02bd0 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -265,22 +265,3 @@
"linker_config_proto",
],
}
-
-python_binary_host {
- name: "conv_classpaths_proto",
- srcs: [
- "conv_classpaths_proto.py",
- ],
- version: {
- py2: {
- enabled: false,
- },
- py3: {
- enabled: true,
- embedded_launcher: true,
- },
- },
- libs: [
- "classpaths_proto_python",
- ],
-}
diff --git a/scripts/conv_classpaths_proto.py b/scripts/conv_classpaths_proto.py
deleted file mode 100644
index f49fbbb..0000000
--- a/scripts/conv_classpaths_proto.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import argparse
-
-import classpaths_pb2
-
-import google.protobuf.json_format as json_format
-import google.protobuf.text_format as text_format
-
-
-def encode(args):
- pb = classpaths_pb2.ExportedClasspathsJars()
- if args.format == 'json':
- json_format.Parse(args.input.read(), pb)
- else:
- text_format.Parse(args.input.read(), pb)
- args.output.write(pb.SerializeToString())
- args.input.close()
- args.output.close()
-
-
-def decode(args):
- pb = classpaths_pb2.ExportedClasspathsJars()
- pb.ParseFromString(args.input.read())
- if args.format == 'json':
- args.output.write(json_format.MessageToJson(pb))
- else:
- args.output.write(text_format.MessageToString(pb).encode('utf_8'))
- args.input.close()
- args.output.close()
-
-
-def main():
- parser = argparse.ArgumentParser('Convert classpaths.proto messages between binary and '
- 'human-readable formats.')
- parser.add_argument('-f', '--format', default='textproto',
- help='human-readable format, either json or text(proto), '
- 'defaults to textproto')
- parser.add_argument('-i', '--input',
- nargs='?', type=argparse.FileType('rb'), default=sys.stdin.buffer)
- parser.add_argument('-o', '--output',
- nargs='?', type=argparse.FileType('wb'),
- default=sys.stdout.buffer)
-
- subparsers = parser.add_subparsers()
-
- parser_encode = subparsers.add_parser('encode',
- help='convert classpaths protobuf message from '
- 'JSON to binary format',
- parents=[parser], add_help=False)
-
- parser_encode.set_defaults(func=encode)
-
- parser_decode = subparsers.add_parser('decode',
- help='print classpaths config in JSON format',
- parents=[parser], add_help=False)
- parser_decode.set_defaults(func=decode)
-
- args = parser.parse_args()
- args.func(args)
-
-
-if __name__ == '__main__':
- main()
diff --git a/sdk/bp.go b/sdk/bp.go
index 11ec8c6..e2dace8 100644
--- a/sdk/bp.go
+++ b/sdk/bp.go
@@ -25,6 +25,7 @@
type bpPropertySet struct {
properties map[string]interface{}
tags map[string]android.BpPropertyTag
+ comments map[string]string
order []string
}
@@ -133,10 +134,22 @@
return s.properties[name]
}
+func (s *bpPropertySet) getOptionalValue(name string) (interface{}, bool) {
+ value, ok := s.properties[name]
+ return value, ok
+}
+
func (s *bpPropertySet) getTag(name string) interface{} {
return s.tags[name]
}
+func (s *bpPropertySet) AddCommentForProperty(name, text string) {
+ if s.comments == nil {
+ s.comments = map[string]string{}
+ }
+ s.comments[name] = strings.TrimSpace(text)
+}
+
func (s *bpPropertySet) transformContents(transformer bpPropertyTransformer) {
var newOrder []string
for _, name := range s.order {
@@ -188,6 +201,12 @@
}
}
+func (s *bpPropertySet) removeProperty(name string) {
+ delete(s.properties, name)
+ delete(s.tags, name)
+ _, s.order = android.RemoveFromList(name, s.order)
+}
+
func (s *bpPropertySet) insertAfter(position string, name string, value interface{}) {
if s.properties[name] != nil {
panic("Property %q already exists in property set")
@@ -216,6 +235,19 @@
moduleType string
}
+func (m *bpModule) ModuleType() string {
+ return m.moduleType
+}
+
+func (m *bpModule) Name() string {
+ name, hasName := m.getOptionalValue("name")
+ if hasName {
+ return name.(string)
+ } else {
+ return ""
+ }
+}
+
var _ android.BpModule = (*bpModule)(nil)
type bpPropertyTransformer interface {
@@ -346,16 +378,26 @@
// is unique within this file.
func (f *bpFile) AddModule(module android.BpModule) {
m := module.(*bpModule)
- if name, ok := m.getValue("name").(string); ok {
- if f.modules[name] != nil {
- panic(fmt.Sprintf("Module %q already exists in bp file", name))
- }
-
- f.modules[name] = m
- f.order = append(f.order, m)
- } else {
- panic("Module does not have a name property, or it is not a string")
+ moduleType := module.ModuleType()
+ name := m.Name()
+ hasName := true
+ if name == "" {
+ // Use a prefixed module type as the name instead just in case this is something like a package
+ // of namespace module which does not require a name.
+ name = "#" + moduleType
+ hasName = false
}
+
+ if f.modules[name] != nil {
+ if hasName {
+ panic(fmt.Sprintf("Module %q already exists in bp file", name))
+ } else {
+ panic(fmt.Sprintf("Unnamed module type %q already exists in bp file", moduleType))
+ }
+ }
+
+ f.modules[name] = m
+ f.order = append(f.order, m)
}
func (f *bpFile) newModule(moduleType string) *bpModule {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 624c0fa..b1c8aeb 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -169,23 +169,27 @@
var fields []reflect.StructField
// Iterate over the member types creating StructField and sdkMemberListProperty objects.
- for f, memberType := range sdkMemberTypes {
+ nextFieldIndex := 0
+ for _, memberType := range sdkMemberTypes {
+
p := memberType.SdkPropertyName()
- // Create a dynamic exported field for the member type's property.
- fields = append(fields, reflect.StructField{
- Name: proptools.FieldNameForProperty(p),
- Type: reflect.TypeOf([]string{}),
- Tag: `android:"arch_variant"`,
- })
+ var getter func(properties interface{}) []string
+ var setter func(properties interface{}, list []string)
+ if memberType.RequiresBpProperty() {
+ // Create a dynamic exported field for the member type's property.
+ fields = append(fields, reflect.StructField{
+ Name: proptools.FieldNameForProperty(p),
+ Type: reflect.TypeOf([]string{}),
+ Tag: `android:"arch_variant"`,
+ })
- // Copy the field index for use in the getter func as using the loop variable directly will
- // cause all funcs to use the last value.
- fieldIndex := f
+ // Copy the field index for use in the getter func as using the loop variable directly will
+ // cause all funcs to use the last value.
+ fieldIndex := nextFieldIndex
+ nextFieldIndex += 1
- // Create an sdkMemberListProperty for the member type.
- memberListProperty := &sdkMemberListProperty{
- getter: func(properties interface{}) []string {
+ getter = func(properties interface{}) []string {
// The properties is expected to be of the following form (where
// <Module_types> is the name of an SdkMemberType.SdkPropertyName().
// properties *struct {<Module_types> []string, ....}
@@ -195,9 +199,9 @@
//
list := reflect.ValueOf(properties).Elem().Field(fieldIndex).Interface().([]string)
return list
- },
+ }
- setter: func(properties interface{}, list []string) {
+ setter = func(properties interface{}, list []string) {
// The properties is expected to be of the following form (where
// <Module_types> is the name of an SdkMemberType.SdkPropertyName().
// properties *struct {<Module_types> []string, ....}
@@ -206,8 +210,13 @@
// *properties.<Module_types> = list
//
reflect.ValueOf(properties).Elem().Field(fieldIndex).Set(reflect.ValueOf(list))
- },
+ }
+ }
+ // Create an sdkMemberListProperty for the member type.
+ memberListProperty := &sdkMemberListProperty{
+ getter: getter,
+ setter: setter,
memberType: memberType,
// Dependencies added directly from member properties are always exported.
@@ -402,6 +411,9 @@
// Add dependencies from enabled and non CommonOS variants to the sdk member variants.
if s.Enabled() && !s.IsCommonOSVariant() {
for _, memberListProperty := range s.memberListProperties() {
+ if memberListProperty.getter == nil {
+ continue
+ }
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
if len(names) > 0 {
tag := memberListProperty.dependencyTag
diff --git a/sdk/update.go b/sdk/update.go
index 853f6b0..a265676 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -266,8 +266,11 @@
}
s.builderForTests = builder
- // Create the prebuilt modules for each of the member modules.
+ // Group the variants for each member module together and then group the members of each member
+ // type together.
members := s.groupMemberVariantsByMemberThenType(ctx, memberVariantDeps)
+
+ // Create the prebuilt modules for each of the member modules.
for _, member := range members {
memberType := member.memberType
@@ -284,11 +287,6 @@
// to internal members with a unique module name and setting prefer: false.
unversionedTransformer := unversionedTransformation{
builder: builder,
- // Set the prefer based on the environment variable. This is a temporary work around to allow a
- // snapshot to be created that sets prefer: true.
- // TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
- // dynamically at build time not at snapshot generation time.
- prefer: ctx.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER"),
}
for _, unversioned := range builder.prebuiltOrder {
@@ -518,15 +516,19 @@
}
combined := sdkVariantToCombinedProperties[memberVariantDep.sdkVariant]
- memberTypeProperty := s.memberListProperty(memberVariantDep.memberType)
+ memberListProperty := s.memberListProperty(memberVariantDep.memberType)
memberName := ctx.OtherModuleName(memberVariantDep.variant)
+ if memberListProperty.getter == nil {
+ continue
+ }
+
// Append the member to the appropriate list, if it is not already present in the list.
- memberList := memberTypeProperty.getter(combined.dynamicProperties)
+ memberList := memberListProperty.getter(combined.dynamicProperties)
if !android.InList(memberName, memberList) {
memberList = append(memberList, memberName)
}
- memberTypeProperty.setter(combined.dynamicProperties, memberList)
+ memberListProperty.setter(combined.dynamicProperties, memberList)
}
return list
@@ -578,6 +580,9 @@
dynamicMemberTypeListProperties := combined.dynamicProperties
for _, memberListProperty := range s.memberListProperties() {
+ if memberListProperty.getter == nil {
+ continue
+ }
names := memberListProperty.getter(dynamicMemberTypeListProperties)
if len(names) > 0 {
propertySet.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names, false))
@@ -611,9 +616,11 @@
func (t unversionedToVersionedTransformation) transformModule(module *bpModule) *bpModule {
// Use a versioned name for the module but remember the original name for the
// snapshot.
- name := module.getValue("name").(string)
+ name := module.Name()
module.setProperty("name", t.builder.versionedSdkMemberName(name, true))
module.insertAfter("name", "sdk_member_name", name)
+ // Remove the prefer property if present as versioned modules never need marking with prefer.
+ module.removeProperty("prefer")
return module
}
@@ -629,20 +636,12 @@
type unversionedTransformation struct {
identityTransformation
builder *snapshotBuilder
- prefer bool
}
func (t unversionedTransformation) transformModule(module *bpModule) *bpModule {
// If the module is an internal member then use a unique name for it.
- name := module.getValue("name").(string)
+ name := module.Name()
module.setProperty("name", t.builder.unversionedSdkMemberName(name, true))
-
- // Set prefer. Setting this to false is not strictly required as that is the default but it does
- // provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to check
- // the behavior when a prebuilt is preferred. It also makes it explicit what the default behavior
- // is for the module.
- module.insertAfter("name", "prefer", t.prefer)
-
return module
}
@@ -693,12 +692,26 @@
func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
contents.Indent()
+ addComment := func(name string) {
+ if text, ok := set.comments[name]; ok {
+ for _, line := range strings.Split(text, "\n") {
+ contents.Printfln("// %s", line)
+ }
+ }
+ }
+
// Output the properties first, followed by the nested sets. This ensures a
// consistent output irrespective of whether property sets are created before
// or after the properties. This simplifies the creation of the module.
for _, name := range set.order {
value := set.getValue(name)
+ // Do not write property sets in the properties phase.
+ if _, ok := value.(*bpPropertySet); ok {
+ continue
+ }
+
+ addComment(name)
switch v := value.(type) {
case []string:
length := len(v)
@@ -719,9 +732,6 @@
case bool:
contents.Printfln("%s: %t,", name, v)
- case *bpPropertySet:
- // Do not write property sets in the properties phase.
-
default:
contents.Printfln("%s: %q,", name, value)
}
@@ -733,6 +743,7 @@
// Only write property sets in the sets phase.
switch v := value.(type) {
case *bpPropertySet:
+ addComment(name)
contents.Printfln("%s: {", name)
outputPropertySet(contents, v)
contents.Printfln("},")
@@ -751,7 +762,9 @@
func (s *sdk) GetUnversionedAndroidBpContentsForTests() string {
contents := &generatedContents{}
generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
- return !strings.Contains(module.properties["name"].(string), "@")
+ name := module.Name()
+ // Include modules that are either unversioned or have no name.
+ return !strings.Contains(name, "@")
})
return contents.content.String()
}
@@ -759,7 +772,9 @@
func (s *sdk) GetVersionedAndroidBpContentsForTests() string {
contents := &generatedContents{}
generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
- return strings.Contains(module.properties["name"].(string), "@")
+ name := module.Name()
+ // Include modules that are either versioned or have no name.
+ return name == "" || strings.Contains(name, "@")
})
return contents.content.String()
}
@@ -1381,6 +1396,21 @@
memberType := member.memberType
+ // Do not add the prefer property if the member snapshot module is a source module type.
+ if !memberType.UsesSourceModuleTypeInSnapshot() {
+ // Set the prefer based on the environment variable. This is a temporary work around to allow a
+ // snapshot to be created that sets prefer: true.
+ // TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
+ // dynamically at build time not at snapshot generation time.
+ prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
+
+ // Set prefer. Setting this to false is not strictly required as that is the default but it does
+ // provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
+ // check the behavior when a prebuilt is preferred. It also makes it explicit what the default
+ // behavior is for the module.
+ bpModule.insertAfter("name", "prefer", prefer)
+ }
+
// Group the variants by os type.
variantsByOsType := make(map[android.OsType][]android.Module)
variants := member.Variants()
diff --git a/third_party/zip/android_test.go b/third_party/zip/android_test.go
index 9932c1b..46588d4 100644
--- a/third_party/zip/android_test.go
+++ b/third_party/zip/android_test.go
@@ -140,3 +140,83 @@
t.Errorf("Expected UnompressedSize64 %d, got %d", w, g)
}
}
+
+// Test for b/187485108: zip64 output can't be read by p7zip 16.02.
+func TestZip64P7ZipRecords(t *testing.T) {
+ if testing.Short() {
+ t.Skip("slow test; skipping")
+ }
+
+ const size = uint32max + 1
+ zipBytes := &bytes.Buffer{}
+ zip := NewWriter(zipBytes)
+ f, err := zip.CreateHeaderAndroid(&FileHeader{
+ Name: "large",
+ Method: Store,
+ UncompressedSize64: size,
+ CompressedSize64: size,
+ })
+ if err != nil {
+ t.Fatalf("Create: %v", err)
+ }
+ _, err = f.Write(make([]byte, size))
+ if err != nil {
+ t.Fatalf("Write: %v", err)
+ }
+ err = zip.Close()
+ if err != nil {
+ t.Fatalf("Close: %v", err)
+ }
+
+ buf := zipBytes.Bytes()
+ p := findSignatureInBlock(buf)
+ if p < 0 {
+ t.Fatalf("Missing signature")
+ }
+
+ b := readBuf(buf[p+4:]) // skip signature
+ d := &directoryEnd{
+ diskNbr: uint32(b.uint16()),
+ dirDiskNbr: uint32(b.uint16()),
+ dirRecordsThisDisk: uint64(b.uint16()),
+ directoryRecords: uint64(b.uint16()),
+ directorySize: uint64(b.uint32()),
+ directoryOffset: uint64(b.uint32()),
+ commentLen: b.uint16(),
+ }
+
+ // p7zip 16.02 wants regular end record directoryRecords to be accurate.
+ if g, w := d.directoryRecords, uint64(1); g != w {
+ t.Errorf("wanted directoryRecords %d, got %d", w, g)
+ }
+
+ if g, w := d.directorySize, uint64(uint32max); g != w {
+ t.Errorf("wanted directorySize %d, got %d", w, g)
+ }
+
+ if g, w := d.directoryOffset, uint64(uint32max); g != w {
+ t.Errorf("wanted directoryOffset %d, got %d", w, g)
+ }
+
+ r := bytes.NewReader(buf)
+
+ p64, err := findDirectory64End(r, int64(p))
+ if err != nil {
+ t.Fatalf("findDirectory64End: %v", err)
+ }
+ if p < 0 {
+ t.Fatalf("findDirectory64End: not found")
+ }
+ err = readDirectory64End(r, p64, d)
+ if err != nil {
+ t.Fatalf("readDirectory64End: %v", err)
+ }
+
+ if g, w := d.directoryRecords, uint64(1); g != w {
+ t.Errorf("wanted directoryRecords %d, got %d", w, g)
+ }
+
+ if g, w := d.directoryOffset, uint64(uint32max); g <= w {
+ t.Errorf("wanted directoryOffset > %d, got %d", w, g)
+ }
+}
diff --git a/third_party/zip/writer.go b/third_party/zip/writer.go
index 8dd986e..f526838 100644
--- a/third_party/zip/writer.go
+++ b/third_party/zip/writer.go
@@ -155,7 +155,14 @@
// store max values in the regular end record to signal that
// that the zip64 values should be used instead
- records = uint16max
+ // BEGIN ANDROID CHANGE: only store uintmax for the number of entries in the regular
+ // end record if it doesn't fit. p7zip 16.02 rejects zip files where the number of
+ // entries in the regular end record is larger than the number of entries counted
+ // in the central directory.
+ if records > uint16max {
+ records = uint16max
+ }
+ // END ANDROID CHANGE
size = uint32max
offset = uint32max
}