Merge "Rename collectTransitiveHeaderJars and friends to mention R8" into main
diff --git a/android/module.go b/android/module.go
index 297a1dc..712569e 100644
--- a/android/module.go
+++ b/android/module.go
@@ -492,6 +492,10 @@
// vintf_fragment Modules required from this module.
Vintf_fragment_modules proptools.Configurable[[]string] `android:"path"`
+
+ // List of module names that are prevented from being installed when this module gets
+ // installed.
+ Overrides []string
}
type distProperties struct {
diff --git a/android/module_context.go b/android/module_context.go
index 6c52a7e..3889e40 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -561,6 +561,7 @@
func (m *moduleContext) packageFile(fullInstallPath InstallPath, srcPath Path, executable bool) PackagingSpec {
licenseFiles := m.Module().EffectiveLicenseFiles()
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
spec := PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: srcPath,
@@ -571,6 +572,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
}
m.packagingSpecs = append(m.packagingSpecs, spec)
return spec
@@ -689,6 +692,7 @@
m.installFiles = append(m.installFiles, fullInstallPath)
}
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -698,6 +702,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
@@ -733,6 +739,7 @@
m.installFiles = append(m.installFiles, fullInstallPath)
}
+ overrides := CopyOf(m.Module().base().commonProperties.Overrides)
m.packagingSpecs = append(m.packagingSpecs, PackagingSpec{
relPathInPackage: Rel(m, fullInstallPath.PartitionDir(), fullInstallPath.String()),
srcPath: nil,
@@ -742,6 +749,8 @@
skipInstall: m.skipInstall(),
aconfigPaths: m.getAconfigPaths(),
archType: m.target.Arch.ArchType,
+ overrides: &overrides,
+ owner: m.ModuleName(),
})
return fullInstallPath
diff --git a/android/neverallow.go b/android/neverallow.go
index a68f5ea..233ca61 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -182,6 +182,7 @@
"packages/modules/SdkExtensions/derive_sdk",
// These are for apps and shouldn't be used by non-SDK variant modules.
"prebuilts/ndk",
+ "frameworks/native/libs/binder/ndk",
"tools/test/graphicsbenchmark/apps/sample_app",
"tools/test/graphicsbenchmark/functional_tests/java",
"vendor/xts/gts-tests/hostsidetests/gamedevicecert/apps/javatests",
diff --git a/android/packaging.go b/android/packaging.go
index 42009d5..61dfa7e 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -56,6 +56,12 @@
// ArchType of the module which produced this packaging spec
archType ArchType
+
+ // List of module names that this packaging spec overrides
+ overrides *[]string
+
+ // Name of the module where this packaging spec is output of
+ owner string
}
func (p *PackagingSpec) Equals(other *PackagingSpec) bool {
@@ -325,7 +331,10 @@
}
func (p *PackagingBase) GatherPackagingSpecsWithFilter(ctx ModuleContext, filter func(PackagingSpec) bool) map[string]PackagingSpec {
- m := make(map[string]PackagingSpec)
+ // all packaging specs gathered from the dep.
+ var all []PackagingSpec
+ // list of module names overridden
+ var overridden []string
var arches []ArchType
for _, target := range getSupportedTargets(ctx) {
@@ -357,17 +366,33 @@
continue
}
}
- dstPath := ps.relPathInPackage
- if existingPs, ok := m[dstPath]; ok {
- if !existingPs.Equals(&ps) {
- ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
- }
- continue
+ all = append(all, ps)
+ if ps.overrides != nil {
+ overridden = append(overridden, *ps.overrides...)
}
-
- m[dstPath] = ps
}
})
+
+ // all minus packaging specs that are overridden
+ var filtered []PackagingSpec
+ for _, ps := range all {
+ if ps.owner != "" && InList(ps.owner, overridden) {
+ continue
+ }
+ filtered = append(filtered, ps)
+ }
+
+ m := make(map[string]PackagingSpec)
+ for _, ps := range filtered {
+ dstPath := ps.relPathInPackage
+ if existingPs, ok := m[dstPath]; ok {
+ if !existingPs.Equals(&ps) {
+ ctx.ModuleErrorf("packaging conflict at %v:\n%v\n%v", dstPath, existingPs, ps)
+ }
+ continue
+ }
+ m[dstPath] = ps
+ }
return m
}
diff --git a/android/packaging_test.go b/android/packaging_test.go
index 19b46fe..0f7bb39 100644
--- a/android/packaging_test.go
+++ b/android/packaging_test.go
@@ -28,6 +28,7 @@
props struct {
Deps []string
Skip_install *bool
+ Overrides []string
}
}
@@ -650,3 +651,64 @@
runPackagingTest(t, config, bp, tc.expected)
}
}
+
+func TestOverrides(t *testing.T) {
+ bpTemplate := `
+ component {
+ name: "foo",
+ deps: ["bar"],
+ }
+
+ component {
+ name: "bar",
+ }
+
+ component {
+ name: "bar_override",
+ overrides: ["bar"],
+ }
+
+ component {
+ name: "baz",
+ deps: ["bar_override"],
+ }
+
+ package_module {
+ name: "package",
+ deps: %DEPS%,
+ }
+ `
+ testcases := []struct {
+ deps []string
+ expected []string
+ }{
+ {
+ deps: []string{"foo"},
+ expected: []string{"lib64/foo", "lib64/bar"},
+ },
+ {
+ deps: []string{"foo", "bar_override"},
+ expected: []string{"lib64/foo", "lib64/bar_override"},
+ },
+ {
+ deps: []string{"foo", "bar", "bar_override"},
+ expected: []string{"lib64/foo", "lib64/bar_override"},
+ },
+ {
+ deps: []string{"bar", "bar_override"},
+ expected: []string{"lib64/bar_override"},
+ },
+ {
+ deps: []string{"foo", "baz"},
+ expected: []string{"lib64/foo", "lib64/baz", "lib64/bar_override"},
+ },
+ }
+ for _, tc := range testcases {
+ config := testConfig{
+ multiTarget: true,
+ depsCollectFirstTargetOnly: false,
+ }
+ bp := strings.Replace(bpTemplate, "%DEPS%", `["`+strings.Join(tc.deps, `", "`)+`"]`, -1)
+ runPackagingTest(t, config, bp, tc.expected)
+ }
+}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 95e2b92..18bbcab 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -463,6 +463,8 @@
r.build(name, desc, true)
}
+var sandboxEnvOnceKey = NewOnceKey("sandbox_environment_variables")
+
func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) {
name = ninjaNameEscape(name)
@@ -580,16 +582,44 @@
})
}
- // Set OUT_DIR to the relative path of the sandboxed out directory.
- // Otherwise, OUT_DIR will be inherited from the rest of the build,
- // which will allow scripts to escape the sandbox if OUT_DIR is an
- // absolute path.
- command.Env = append(command.Env, &sbox_proto.EnvironmentVariable{
- Name: proto.String("OUT_DIR"),
- State: &sbox_proto.EnvironmentVariable_Value{
- Value: sboxOutSubDir,
- },
- })
+ // Only allow the build to access certain environment variables
+ command.DontInheritEnv = proto.Bool(true)
+ command.Env = r.ctx.Config().Once(sandboxEnvOnceKey, func() interface{} {
+ // The list of allowed variables was found by running builds of all
+ // genrules and seeing what failed
+ var result []*sbox_proto.EnvironmentVariable
+ inheritedVars := []string{
+ "PATH",
+ "JAVA_HOME",
+ "TMPDIR",
+ // Allow RBE variables because the art tests invoke RBE manually
+ "RBE_log_dir",
+ "RBE_platform",
+ "RBE_server_address",
+ // TODO: RBE_exec_root is set to the absolute path to the root of the source
+ // tree, which we don't want sandboxed actions to find. Remap it to ".".
+ "RBE_exec_root",
+ }
+ for _, v := range inheritedVars {
+ result = append(result, &sbox_proto.EnvironmentVariable{
+ Name: proto.String(v),
+ State: &sbox_proto.EnvironmentVariable_Inherit{
+ Inherit: true,
+ },
+ })
+ }
+ // Set OUT_DIR to the relative path of the sandboxed out directory.
+ // Otherwise, OUT_DIR will be inherited from the rest of the build,
+ // which will allow scripts to escape the sandbox if OUT_DIR is an
+ // absolute path.
+ result = append(result, &sbox_proto.EnvironmentVariable{
+ Name: proto.String("OUT_DIR"),
+ State: &sbox_proto.EnvironmentVariable_Value{
+ Value: sboxOutSubDir,
+ },
+ })
+ return result
+ }).([]*sbox_proto.EnvironmentVariable)
command.Chdir = proto.Bool(true)
}
diff --git a/android/selects_test.go b/android/selects_test.go
index fc020a4..90d7091 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -1009,6 +1009,28 @@
},
expectedError: `variable already set in inherited scope, previous assignment:`,
},
+ {
+ name: "Basic string list postprocessor",
+ bp: `
+my_defaults {
+ name: "defaults_a",
+ my_string_list: ["a", "b", "c"],
+ string_list_postprocessor_add_to_elements: "1",
+}
+my_defaults {
+ name: "defaults_b",
+ my_string_list: ["d", "e", "f"],
+ string_list_postprocessor_add_to_elements: "2",
+}
+my_module_type {
+ name: "foo",
+ defaults: ["defaults_a", "defaults_b"],
+}
+`,
+ provider: selectsTestProvider{
+ my_string_list: &[]string{"d2", "e2", "f2", "a1", "b1", "c1"},
+ },
+ },
}
for _, tc := range testCases {
@@ -1161,9 +1183,15 @@
return m
}
+type selectsMockDefaultsProperties struct {
+ String_list_postprocessor_add_to_elements string
+}
+
type selectsMockModuleDefaults struct {
ModuleBase
DefaultsModuleBase
+ myProperties selectsMockModuleProperties
+ defaultsProperties selectsMockDefaultsProperties
}
func (d *selectsMockModuleDefaults) GenerateAndroidBuildActions(ctx ModuleContext) {
@@ -1173,10 +1201,22 @@
module := &selectsMockModuleDefaults{}
module.AddProperties(
- &selectsMockModuleProperties{},
+ &module.myProperties,
+ &module.defaultsProperties,
)
InitDefaultsModule(module)
+ AddLoadHook(module, func(lhc LoadHookContext) {
+ if module.defaultsProperties.String_list_postprocessor_add_to_elements != "" {
+ module.myProperties.My_string_list.AddPostProcessor(func(x []string) []string {
+ for i := range x {
+ x[i] = x[i] + module.defaultsProperties.String_list_postprocessor_add_to_elements
+ }
+ return x
+ })
+ }
+ })
+
return module
}
diff --git a/androidmk/parser/ast.go b/androidmk/parser/ast.go
index d5d1354..c3d198f 100644
--- a/androidmk/parser/ast.go
+++ b/androidmk/parser/ast.go
@@ -84,6 +84,7 @@
Prerequisites *MakeString
RecipePos Pos
Recipe string
+ RecipeEndPos Pos
}
func (x *Rule) Dump() string {
@@ -95,7 +96,7 @@
}
func (x *Rule) Pos() Pos { return x.Target.Pos() }
-func (x *Rule) End() Pos { return Pos(int(x.RecipePos) + len(x.Recipe)) }
+func (x *Rule) End() Pos { return x.RecipeEndPos }
type Variable struct {
Name *MakeString
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index 8a20bb0..f2477db 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -448,6 +448,7 @@
Prerequisites: prerequisites,
Recipe: recipe,
RecipePos: recipePos,
+ RecipeEndPos: p.pos(),
})
}
}
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
index fb03c23..e238f8b 100644
--- a/androidmk/parser/parser_test.go
+++ b/androidmk/parser/parser_test.go
@@ -124,3 +124,25 @@
})
}
}
+
+func TestRuleEnd(t *testing.T) {
+ name := "ruleEndTest"
+ in := `all:
+ifeq (A, A)
+ echo foo
+ echo foo
+ echo foo
+ echo foo
+endif
+ echo bar
+`
+ p := NewParser(name, bytes.NewBufferString(in))
+ got, errs := p.Parse()
+ if len(errs) != 0 {
+ t.Fatalf("Unexpected errors while parsing: %v", errs)
+ }
+
+ if got[0].End() < got[len(got) -1].Pos() {
+ t.Errorf("Rule's end (%d) is smaller than directive that inside of rule's start (%v)\n", got[0].End(), got[len(got) -1].Pos())
+ }
+}
diff --git a/apex/apex.go b/apex/apex.go
index 373c562..6421c8e 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1942,8 +1942,6 @@
// visitor skips these from this list of module names
unwantedTransitiveDeps []string
-
- aconfigFiles []android.Path
}
func (vctx *visitorContext) normalizeFileInfo(mctx android.ModuleContext) {
@@ -2010,7 +2008,6 @@
fi := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
- addAconfigFiles(vctx, ctx, child)
// Collect the list of stub-providing libs except:
// - VNDK libs are only for vendors
// - bootstrap bionic libs are treated as provided by system
@@ -2022,7 +2019,6 @@
fi := apexFileForRustLibrary(ctx, ch)
fi.isJniLib = isJniLib
vctx.filesInfo = append(vctx.filesInfo, fi)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
@@ -2031,11 +2027,9 @@
switch ch := child.(type) {
case *cc.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch))
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *rust.Module:
vctx.filesInfo = append(vctx.filesInfo, apexFileForRustExecutable(ctx, ch))
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("binaries",
@@ -2075,7 +2069,6 @@
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
@@ -2084,14 +2077,11 @@
switch ap := child.(type) {
case *java.AndroidApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
case *java.AndroidAppImport:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
case *java.AndroidTestHelperApp:
vctx.filesInfo = append(vctx.filesInfo, apexFilesForAndroidApp(ctx, ap)...)
- addAconfigFiles(vctx, ctx, child)
case *java.AndroidAppSet:
appDir := "app"
if ap.Privileged() {
@@ -2105,7 +2095,6 @@
af := newApexFile(ctx, ap.OutputFile(), ap.BaseModuleName(), appDirName, appSet, ap)
af.certificate = java.PresignedCertificate
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
default:
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
@@ -2137,7 +2126,6 @@
for _, etcFile := range filesToCopy {
vctx.filesInfo = append(vctx.filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, etcFile))
}
- addAconfigFiles(vctx, ctx, child)
} else {
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
}
@@ -2152,7 +2140,6 @@
af := apexFileForExecutable(ctx, ccTest)
af.class = nativeTest
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else {
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
@@ -2232,7 +2219,6 @@
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else if rm, ok := child.(*rust.Module); ok {
if !android.IsDepInSameApex(ctx, am, am) {
@@ -2242,7 +2228,6 @@
af := apexFileForRustLibrary(ctx, rm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if cc.IsHeaderDepTag(depTag) {
@@ -2265,7 +2250,6 @@
af := apexFileForRustLibrary(ctx, rustm)
af.transitiveDep = true
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
} else if rust.IsRlibDepTag(depTag) {
@@ -2284,7 +2268,6 @@
return false
}
vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("bootclasspath_fragments",
@@ -2299,7 +2282,6 @@
if profileAf := apexFileForJavaModuleProfile(ctx, child.(javaModule)); profileAf != nil {
vctx.filesInfo = append(vctx.filesInfo, *profileAf)
}
- addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
default:
ctx.PropertyErrorf("systemserverclasspath_fragments",
@@ -2317,19 +2299,6 @@
return false
}
-func addAconfigFiles(vctx *visitorContext, ctx android.ModuleContext, module blueprint.Module) {
- if dep, ok := android.OtherModuleProvider(ctx, module, android.AconfigPropagatingProviderKey); ok {
- if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
- vctx.aconfigFiles = append(vctx.aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
- }
- }
-
- validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
- if validationFlag == "error" || validationFlag == "warning" {
- android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), module, validationFlag == "error")
- }
-}
-
func (a *apexBundle) shouldCheckDuplicate(ctx android.ModuleContext) bool {
// TODO(b/263308293) remove this
if a.properties.IsCoverageVariant {
@@ -2411,13 +2380,16 @@
// 3) some fields in apexBundle struct are configured
a.installDir = android.PathForModuleInstall(ctx, "apex")
a.filesInfo = vctx.filesInfo
- a.aconfigFiles = android.FirstUniquePaths(vctx.aconfigFiles)
a.setPayloadFsType(ctx)
a.setSystemLibLink(ctx)
a.compatSymlinks = makeCompatSymlinks(a.BaseModuleName(), ctx)
////////////////////////////////////////////////////////////////////////////////////////////
+ // 3.a) some artifacts are generated from the collected files
+ a.filesInfo = append(a.filesInfo, a.buildAconfigFiles(ctx)...)
+
+ ////////////////////////////////////////////////////////////////////////////////////////////
// 4) generate the build rules to create the APEX. This is done in builder.go.
a.buildManifest(ctx, vctx.provideNativeLibs, vctx.requireNativeLibs)
a.buildApex(ctx)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 8305333..685cb37 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -267,6 +267,7 @@
}
func ensureMatches(t *testing.T, result string, expectedRex string) {
+ t.Helper()
ok, err := regexp.MatchString(expectedRex, result)
if err != nil {
t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
@@ -277,6 +278,14 @@
}
}
+func ensureListContainsMatch(t *testing.T, result []string, expectedRex string) {
+ t.Helper()
+ p := regexp.MustCompile(expectedRex)
+ if android.IndexListPred(func(s string) bool { return p.MatchString(s) }, result) == -1 {
+ t.Errorf("%q is not found in %v", expectedRex, result)
+ }
+}
+
func ensureListContains(t *testing.T, result []string, expected string) {
t.Helper()
if !android.InList(expected, result) {
@@ -10791,14 +10800,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 8 {
- t.Fatalf("Expected 5 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 12 {
+ t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[4], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[5], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[6], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[7], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -10926,14 +10935,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 12 {
- t.Fatalf("Expected 12 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 16 {
+ t.Fatalf("Expected 16 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[8], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[9], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[10], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[11], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
@@ -11094,14 +11103,14 @@
mod := ctx.ModuleForTests("myapex", "android_common_myapex")
s := mod.Rule("apexRule").Args["copy_commands"]
copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
- if len(copyCmds) != 32 {
- t.Fatalf("Expected 28 commands, got %d in:\n%s", len(copyCmds), s)
+ if len(copyCmds) != 36 {
+ t.Fatalf("Expected 36 commands, got %d in:\n%s", len(copyCmds), s)
}
- ensureMatches(t, copyCmds[28], "^cp -f .*/aconfig_flags.pb .*/image.apex/etc$")
- ensureMatches(t, copyCmds[29], "^cp -f .*/package.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[30], "^cp -f .*/flag.map .*/image.apex/etc$")
- ensureMatches(t, copyCmds[31], "^cp -f .*/flag.val .*/image.apex/etc$")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/aconfig_flags.pb .*/image.apex/etc/aconfig_flags.pb")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/package.map .*/image.apex/etc/package.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.map .*/image.apex/etc/flag.map")
+ ensureListContainsMatch(t, copyCmds, "^cp -f .*/flag.val .*/image.apex/etc/flag.val")
inputs := []string{
"my_aconfig_declarations_foo/intermediate.pb",
diff --git a/apex/builder.go b/apex/builder.go
index 0d08483..437189f 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -83,6 +83,7 @@
pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
pctx.HostBinToolVariable("apex_elf_checker", "apex_elf_checker")
pctx.HostBinToolVariable("aconfig", "aconfig")
+ pctx.HostBinToolVariable("host_apex_verifier", "host_apex_verifier")
}
type createStorageStruct struct {
@@ -249,6 +250,13 @@
Description: "run apex_linkerconfig_validation",
}, "image_dir")
+ apexHostVerifierRule = pctx.StaticRule("apexHostVerifierRule", blueprint.RuleParams{
+ Command: `${host_apex_verifier} --deapexer=${deapexer} --debugfs=${debugfs_static} ` +
+ `--fsckerofs=${fsck_erofs} --apex=${in} && touch ${out}`,
+ CommandDeps: []string{"${host_apex_verifier}", "${deapexer}", "${debugfs_static}", "${fsck_erofs}"},
+ Description: "run host_apex_verifier",
+ })
+
assembleVintfRule = pctx.StaticRule("assembleVintfRule", blueprint.RuleParams{
Command: `rm -f $out && VINTF_IGNORE_TARGET_FCM_VERSION=true ${assemble_vintf} -i $in -o $out`,
CommandDeps: []string{"${assemble_vintf}"},
@@ -262,6 +270,58 @@
}, "tool_path", "unwanted")
)
+func (a *apexBundle) buildAconfigFiles(ctx android.ModuleContext) []apexFile {
+ var aconfigFiles android.Paths
+ for _, file := range a.filesInfo {
+ if file.module == nil {
+ continue
+ }
+ if dep, ok := android.OtherModuleProvider(ctx, file.module, android.AconfigPropagatingProviderKey); ok {
+ if len(dep.AconfigFiles) > 0 && dep.AconfigFiles[ctx.ModuleName()] != nil {
+ aconfigFiles = append(aconfigFiles, dep.AconfigFiles[ctx.ModuleName()]...)
+ }
+ }
+
+ validationFlag := ctx.DeviceConfig().AconfigContainerValidation()
+ if validationFlag == "error" || validationFlag == "warning" {
+ android.VerifyAconfigBuildMode(ctx, ctx.ModuleName(), file.module, validationFlag == "error")
+ }
+ }
+ aconfigFiles = android.FirstUniquePaths(aconfigFiles)
+
+ var files []apexFile
+ if len(aconfigFiles) > 0 {
+ apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.AllDeclarationsRule,
+ Inputs: aconfigFiles,
+ Output: apexAconfigFile,
+ Description: "combine_aconfig_declarations",
+ Args: map[string]string{
+ "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "),
+ },
+ })
+ files = append(files, newApexFile(ctx, apexAconfigFile, "aconfig_flags", "etc", etc, nil))
+
+ for _, info := range createStorageInfo {
+ outputFile := android.PathForModuleOut(ctx, info.Output_file)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: aconfig.CreateStorageRule,
+ Inputs: aconfigFiles,
+ Output: outputFile,
+ Description: info.Desc,
+ Args: map[string]string{
+ "container": ctx.ModuleName(),
+ "file_type": info.File_type,
+ "cache_files": android.JoinPathsWithPrefix(aconfigFiles, "--cache "),
+ },
+ })
+ files = append(files, newApexFile(ctx, outputFile, info.File_type, "etc", etc, nil))
+ }
+ }
+ return files
+}
+
// buildManifest creates buile rules to modify the input apex_manifest.json to add information
// gathered by the build system such as provided/required native libraries. Two output files having
// different formats are generated. a.manifestJsonOut is JSON format for Q devices, and
@@ -644,48 +704,10 @@
outHostBinDir := ctx.Config().HostToolPath(ctx, "").String()
prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
- defaultReadOnlyFiles := []string{"apex_manifest.json", "apex_manifest.pb"}
- aconfigDest := imageDir.Join(ctx, "etc").String()
- if len(a.aconfigFiles) > 0 {
- apexAconfigFile := android.PathForModuleOut(ctx, "aconfig_flags.pb")
- ctx.Build(pctx, android.BuildParams{
- Rule: aconfig.AllDeclarationsRule,
- Inputs: a.aconfigFiles,
- Output: apexAconfigFile,
- Description: "combine_aconfig_declarations",
- Args: map[string]string{
- "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
- },
- })
-
- copyCommands = append(copyCommands, "cp -f "+apexAconfigFile.String()+" "+aconfigDest)
- implicitInputs = append(implicitInputs, apexAconfigFile)
- defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+apexAconfigFile.Base())
-
- for _, info := range createStorageInfo {
- outputFile := android.PathForModuleOut(ctx, info.Output_file)
- ctx.Build(pctx, android.BuildParams{
- Rule: aconfig.CreateStorageRule,
- Inputs: a.aconfigFiles,
- Output: outputFile,
- Description: info.Desc,
- Args: map[string]string{
- "container": ctx.ModuleName(),
- "file_type": info.File_type,
- "cache_files": android.JoinPathsWithPrefix(a.aconfigFiles, "--cache "),
- },
- })
-
- copyCommands = append(copyCommands, "cp -f "+outputFile.String()+" "+aconfigDest)
- implicitInputs = append(implicitInputs, outputFile)
- defaultReadOnlyFiles = append(defaultReadOnlyFiles, "etc/"+outputFile.Base())
- }
- }
-
////////////////////////////////////////////////////////////////////////////////////
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
// in this APEX. The file will be used by apexer in later steps.
- cannedFsConfig := a.buildCannedFsConfig(ctx, defaultReadOnlyFiles)
+ cannedFsConfig := a.buildCannedFsConfig(ctx)
implicitInputs = append(implicitInputs, cannedFsConfig)
////////////////////////////////////////////////////////////////////////////////////
@@ -952,6 +974,9 @@
validations = append(validations,
runApexElfCheckerUnwanted(ctx, unsignedOutputFile.OutputPath, a.properties.Unwanted_transitive_deps))
}
+ if !a.testApex && android.InList(a.payloadFsType, []fsType{ext4, erofs}) {
+ validations = append(validations, runApexHostVerifier(ctx, unsignedOutputFile.OutputPath))
+ }
ctx.Build(pctx, android.BuildParams{
Rule: rule,
Description: "signapk",
@@ -1139,8 +1164,8 @@
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
}
-func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext, defaultReadOnlyFiles []string) android.OutputPath {
- var readOnlyPaths = defaultReadOnlyFiles
+func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
+ var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
var appSetDirs []string
appSetFiles := make(map[string]android.Path)
@@ -1246,3 +1271,13 @@
})
return timestamp
}
+
+func runApexHostVerifier(ctx android.ModuleContext, apexFile android.OutputPath) android.Path {
+ timestamp := android.PathForModuleOut(ctx, "host_apex_verifier.timestamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apexHostVerifierRule,
+ Input: apexFile,
+ Output: timestamp,
+ })
+ return timestamp
+}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 5250b86..47b6114 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -103,8 +103,17 @@
// https://github.com/android-ndk/ndk/issues/265.
Unversioned_until *string
- // Headers presented by this library to the Public API Surface
+ // DO NOT USE THIS
+ // NDK libraries should not export their headers. Headers belonging to NDK
+ // libraries should be added to the NDK with an ndk_headers module.
Export_header_libs []string
+
+ // Do not add other export_* properties without consulting with danalbert@.
+ // Consumers of ndk_library modules should emulate the typical NDK build
+ // behavior as closely as possible (that is, all NDK APIs are exposed to
+ // builds via --sysroot). Export behaviors used in Soong will not be present
+ // for app developers as they don't use Soong, and reliance on these export
+ // behaviors can mask issues with the NDK sysroot.
}
type stubDecorator struct {
@@ -484,8 +493,7 @@
// Add a dependency on the header modules of this ndk_library
func (linker *stubDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
return Deps{
- ReexportHeaderLibHeaders: linker.properties.Export_header_libs,
- HeaderLibs: linker.properties.Export_header_libs,
+ HeaderLibs: linker.properties.Export_header_libs,
}
}
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 6459ea1..f3931a4 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -275,7 +275,10 @@
if !state.Inherit {
return nil, fmt.Errorf("Can't have inherit set to false")
}
- env = append(env, *envVar.Name+"="+os.Getenv(*envVar.Name))
+ val, ok := os.LookupEnv(*envVar.Name)
+ if ok {
+ env = append(env, *envVar.Name+"="+val)
+ }
default:
return nil, fmt.Errorf("Unhandled state type")
}
diff --git a/java/app.go b/java/app.go
index 56eb917..d5c220d 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1473,7 +1473,23 @@
return testConfig
}
+func (a *AndroidTestHelperApp) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
+ // Instrument the android_test_helper target to log potential API calls at the run time.
+ // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
+ ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
+ a.setApiMapper(true)
+ }
+ a.AndroidApp.DepsMutator(ctx)
+}
+
func (a *AndroidTest) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if len(a.ApexProperties.Apex_available) == 0 && ctx.Config().IsEnvTrue("EMMA_API_MAPPER") {
+ // Instrument the android_test_helper target to log potential API calls at the run time.
+ // Contact android-xts-infra team before using the environment var EMMA_API_MAPPER.
+ ctx.AddVariationDependencies(nil, staticLibTag, "apimapper-helper-device-lib")
+ a.setApiMapper(true)
+ }
a.AndroidApp.DepsMutator(ctx)
}
diff --git a/java/base.go b/java/base.go
index 652cc00..b049b41 100644
--- a/java/base.go
+++ b/java/base.go
@@ -233,6 +233,10 @@
// Contributing api surface of the stub module. Is not visible to bp modules, and should
// only be set for stub submodules generated by the java_sdk_library
Stub_contributing_api *string `blueprint:"mutated"`
+
+ // If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject
+ // bytecode to log API calls.
+ ApiMapper bool `blueprint:"mutated"`
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -739,6 +743,10 @@
ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir())
}
+func (j *Module) shouldApiMapper() bool {
+ return j.properties.ApiMapper
+}
+
func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool {
return j.properties.Supports_static_instrumentation &&
j.shouldInstrument(ctx) &&
@@ -767,6 +775,10 @@
j.properties.Instrument = value
}
+func (j *Module) setApiMapper(value bool) {
+ j.properties.ApiMapper = value
+}
+
func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version))
}
@@ -1600,6 +1612,18 @@
outputFile = ravenizerOutput
}
+ if j.shouldApiMapper() {
+ inputFile := outputFile
+ apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apimapper,
+ Description: "apimapper",
+ Input: inputFile,
+ Output: apiMapperFile,
+ })
+ outputFile = apiMapperFile
+ }
+
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
// Time stamp file created by the package check rule.
diff --git a/java/builder.go b/java/builder.go
index 49207e5..81b0feb 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -265,6 +265,13 @@
},
)
+ apimapper = pctx.AndroidStaticRule("apimapper",
+ blueprint.RuleParams{
+ Command: "${apimapper} --in-jar $in --out-jar $out",
+ CommandDeps: []string{"${apimapper}"},
+ },
+ )
+
zipalign = pctx.AndroidStaticRule("zipalign",
blueprint.RuleParams{
Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
@@ -315,6 +322,7 @@
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("ravenizer", "ravenizer")
+ pctx.HostBinToolVariable("apimapper", "apimapper")
pctx.HostBinToolVariable("keep-flagged-apis", "keep-flagged-apis")
}