Merge "Create soong_injection files in ReadWrite mode"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index e7bd920..fce8d7b 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -732,7 +732,6 @@
// aar support
"prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
- "prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
// ERROR: The dependencies for the following 1 jar(s) are not complete.
// 1.bazel-out/android_target-fastbuild/bin/prebuilts/tools/common/m2/_aar/robolectric-monitor-1.0.2-alpha1/classes_and_libs_merged.jar
"prebuilt_robolectric-monitor-1.0.2-alpha1",
@@ -1350,7 +1349,6 @@
"prebuilt_kotlin-stdlib-jdk8",
"prebuilt_kotlin-test",
// TODO(b/217750501) exclude_files property not supported
- "prebuilt_platform-robolectric-4.5.1-prebuilt",
"prebuilt_currysrc_org.eclipse",
}
diff --git a/android/config.go b/android/config.go
index 4a64b5b..9d9ab30 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1111,6 +1111,10 @@
return append([]string(nil), c.productVariables.NamespacesToExport...)
}
+func (c *config) IncludeTags() []string {
+ return c.productVariables.IncludeTags
+}
+
func (c *config) HostStaticBinaries() bool {
return Bool(c.productVariables.HostStaticBinaries)
}
diff --git a/android/register.go b/android/register.go
index 72f8af4..33e9ea3 100644
--- a/android/register.go
+++ b/android/register.go
@@ -161,6 +161,7 @@
func NewContext(config Config) *Context {
ctx := &Context{blueprint.NewContext(), config}
ctx.SetSrcDir(absSrcDir)
+ ctx.AddIncludeTags(config.IncludeTags()...)
return ctx
}
diff --git a/android/variable.go b/android/variable.go
index 28f22c9..9725895 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -452,6 +452,8 @@
GenerateAidlNdkPlatformBackend bool `json:",omitempty"`
IgnorePrefer32OnDevice bool `json:",omitempty"`
+
+ IncludeTags []string `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 883c3c8..876a052 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4130,6 +4130,41 @@
ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n")
}
+func TestOverrideApexManifestDefaultVersion(t *testing.T) {
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apex_name: "com.android.myapex",
+ native_shared_libs: ["mylib"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+ `, android.FixtureMergeEnv(map[string]string{
+ "OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION": "1234",
+ }))
+
+ module := ctx.ModuleForTests("myapex", "android_common_com.android.myapex_image")
+ apexManifestRule := module.Rule("apexManifestRule")
+ ensureContains(t, apexManifestRule.Args["default_version"], "1234")
+}
+
func TestCompileMultilibProp(t *testing.T) {
testCases := []struct {
compileMultiLibProp string
diff --git a/apex/builder.go b/apex/builder.go
index 9e368b6..4be34d2 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -236,6 +236,10 @@
}
manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json")
+ defaultVersion := android.DefaultUpdatableModuleVersion
+ if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" {
+ defaultVersion = override
+ }
ctx.Build(pctx, android.BuildParams{
Rule: apexManifestRule,
Input: src,
@@ -243,7 +247,7 @@
Args: map[string]string{
"provideNativeLibs": strings.Join(provideNativeLibs, " "),
"requireNativeLibs": strings.Join(requireNativeLibs, " "),
- "default_version": android.DefaultUpdatableModuleVersion,
+ "default_version": defaultVersion,
"opt": strings.Join(optCommands, " "),
},
})
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index 8aa2c3e..68dc383 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -789,3 +789,82 @@
},
})
}
+
+func TestCcBinaryWithIntegerOverflowProperty(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary with integer overflow property specified",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ sanitize: {
+ integer_overflow: true,
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `["ubsan_integer_overflow"]`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithMiscUndefinedProperty(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary with miscellaneous properties specified",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ]`,
+ }},
+ },
+ })
+}
+
+func TestCcBinaryWithUBSanPropertiesArchSpecific(t *testing.T) {
+ runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
+ description: "cc_binary has correct feature select when UBSan props are specified in arch specific blocks",
+ blueprint: `
+{rule_name} {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+ target: {
+ android: {
+ sanitize: {
+ misc_undefined: ["alignment"],
+ },
+ },
+ linux_glibc: {
+ sanitize: {
+ integer_overflow: true,
+ },
+ },
+ },
+}`,
+ targets: []testBazelTarget{
+ {"cc_binary", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ] + select({
+ "//build/bazel/platforms/os:android": ["ubsan_alignment"],
+ "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"],
+ "//conditions:default": [],
+ })`,
+ }},
+ },
+ })
+}
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index a1e83d8..5feb02e 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -3691,3 +3691,113 @@
},
)
}
+
+func TestCcLibraryWithIntegerOverflowProperty(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when integer_overflow property is provided",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ sanitize: {
+ integer_overflow: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `["ubsan_integer_overflow"]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["ubsan_integer_overflow"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryWithMiscUndefinedProperty(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct features when misc_undefined property is provided",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryWithUBSanPropertiesArchSpecific(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library has correct feature select when UBSan props are specified in arch specific blocks",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+ target: {
+ android: {
+ sanitize: {
+ misc_undefined: ["alignment"],
+ },
+ },
+ linux_glibc: {
+ sanitize: {
+ integer_overflow: true,
+ },
+ },
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ] + select({
+ "//build/bazel/platforms/os:android": ["ubsan_alignment"],
+ "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ }),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ] + select({
+ "//build/bazel/platforms/os:android": ["ubsan_alignment"],
+ "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 7e1d111..9b01b6f 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -886,3 +886,85 @@
},
})
}
+
+func TestCcLibrarySharedWithIntegerOverflowProperty(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when integer_overflow property is provided",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ sanitize: {
+ integer_overflow: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `["ubsan_integer_overflow"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithMiscUndefinedProperty(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct features when misc_undefined property is provided",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibrarySharedWithUBSanPropertiesArchSpecific(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared has correct feature select when UBSan props are specified in arch specific blocks",
+ Blueprint: `
+cc_library_shared {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+ target: {
+ android: {
+ sanitize: {
+ misc_undefined: ["alignment"],
+ },
+ },
+ linux_glibc: {
+ sanitize: {
+ integer_overflow: true,
+ },
+ },
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ] + select({
+ "//build/bazel/platforms/os:android": ["ubsan_alignment"],
+ "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index b47d1f1..cac7f9b 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1723,3 +1723,85 @@
},
})
}
+
+func TestCcLibraryStaticWithIntegerOverflowProperty(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when integer_overflow property is provided",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ sanitize: {
+ integer_overflow: true,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `["ubsan_integer_overflow"]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithMiscUndefinedProperty(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct features when misc_undefined property is provided",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ]`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticWithUBSanPropertiesArchSpecific(t *testing.T) {
+ runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_static has correct feature select when UBSan props are specified in arch specific blocks",
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ sanitize: {
+ misc_undefined: ["undefined", "nullability"],
+ },
+ target: {
+ android: {
+ sanitize: {
+ misc_undefined: ["alignment"],
+ },
+ },
+ linux_glibc: {
+ sanitize: {
+ integer_overflow: true,
+ },
+ },
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "features": `[
+ "ubsan_undefined",
+ "ubsan_nullability",
+ ] + select({
+ "//build/bazel/platforms/os:android": ["ubsan_alignment"],
+ "//build/bazel/platforms/os:linux": ["ubsan_integer_overflow"],
+ "//conditions:default": [],
+ })`,
+ "local_includes": `["."]`,
+ }),
+ },
+ })
+}
diff --git a/cc/afdo_test.go b/cc/afdo_test.go
index 5515464..fe3392a 100644
--- a/cc/afdo_test.go
+++ b/cc/afdo_test.go
@@ -15,28 +15,46 @@
package cc
import (
+ "strings"
"testing"
"android/soong/android"
+
"github.com/google/blueprint"
)
+type visitDirectDepsInterface interface {
+ VisitDirectDeps(blueprint.Module, func(dep blueprint.Module))
+}
+
+func hasDirectDep(ctx visitDirectDepsInterface, m android.Module, wantDep android.Module) bool {
+ var found bool
+ ctx.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+}
+
func TestAfdoDeps(t *testing.T) {
bp := `
- cc_library {
+ cc_library_shared {
name: "libTest",
- srcs: ["foo.c"],
+ srcs: ["test.c"],
static_libs: ["libFoo"],
afdo: true,
}
- cc_library {
+ cc_library_static {
name: "libFoo",
+ srcs: ["foo.c"],
static_libs: ["libBar"],
}
- cc_library {
+ cc_library_static {
name: "libBar",
+ srcs: ["bar.c"],
}
`
prepareForAfdoTest := android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libTest.afdo", "TEST")
@@ -46,25 +64,89 @@
prepareForAfdoTest,
).RunTestWithBp(t, bp)
- libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
- libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest").Module()
- libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest").Module()
+ libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+ libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_afdo-libTest")
+ libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_afdo-libTest")
- hasDep := func(m android.Module, wantDep android.Module) bool {
- var found bool
- result.VisitDirectDeps(m, func(dep blueprint.Module) {
- if dep == wantDep {
- found = true
- }
- })
- return found
- }
-
- if !hasDep(libTest, libFoo) {
+ if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
t.Errorf("libTest missing dependency on afdo variant of libFoo")
}
- if !hasDep(libFoo, libBar) {
+ if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
t.Errorf("libTest missing dependency on afdo variant of libBar")
}
+
+ cFlags := libTest.Rule("cc").Args["cFlags"]
+ if w := "-fprofile-sample-accurate"; !strings.Contains(cFlags, w) {
+ t.Errorf("Expected 'libTest' to enable afdo, but did not find %q in cflags %q", w, cFlags)
+ }
+
+ cFlags = libFoo.Rule("cc").Args["cFlags"]
+ if w := "-fprofile-sample-accurate"; !strings.Contains(cFlags, w) {
+ t.Errorf("Expected 'libFoo' to enable afdo, but did not find %q in cflags %q", w, cFlags)
+ }
+
+ cFlags = libBar.Rule("cc").Args["cFlags"]
+ if w := "-fprofile-sample-accurate"; !strings.Contains(cFlags, w) {
+ t.Errorf("Expected 'libBar' to enable afdo, but did not find %q in cflags %q", w, cFlags)
+ }
+}
+
+func TestAfdoEnabledOnStaticDepNoAfdo(t *testing.T) {
+ bp := `
+ cc_library_shared {
+ name: "libTest",
+ srcs: ["foo.c"],
+ static_libs: ["libFoo"],
+ }
+
+ cc_library_static {
+ name: "libFoo",
+ srcs: ["foo.c"],
+ static_libs: ["libBar"],
+ afdo: true, // TODO(b/256670524): remove support for enabling afdo from static only libraries, this can only propagate from shared libraries/binaries
+ }
+
+ cc_library_static {
+ name: "libBar",
+ }
+ `
+ prepareForAfdoTest := android.FixtureAddTextFile("toolchain/pgo-profiles/sampling/libFoo.afdo", "TEST")
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForAfdoTest,
+ ).RunTestWithBp(t, bp)
+
+ libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared").Module()
+ libFoo := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+ libBar := result.ModuleForTests("libBar", "android_arm64_armv8-a_static").Module()
+
+ if !hasDirectDep(result, libTest, libFoo.Module()) {
+ t.Errorf("libTest missing dependency on afdo variant of libFoo")
+ }
+
+ if !hasDirectDep(result, libFoo.Module(), libBar) {
+ t.Errorf("libFoo missing dependency on afdo variant of libBar")
+ }
+
+ fooVariants := result.ModuleVariantsForTests("foo")
+ for _, v := range fooVariants {
+ if strings.Contains(v, "afdo-") {
+ t.Errorf("Expected no afdo variant of 'foo', got %q", v)
+ }
+ }
+
+ cFlags := libFoo.Rule("cc").Args["cFlags"]
+ if w := "-fprofile-sample-accurate"; strings.Contains(cFlags, w) {
+ t.Errorf("Expected 'foo' to not enable afdo, but found %q in cflags %q", w, cFlags)
+ }
+
+ barVariants := result.ModuleVariantsForTests("bar")
+ for _, v := range barVariants {
+ if strings.Contains(v, "afdo-") {
+ t.Errorf("Expected no afdo variant of 'bar', got %q", v)
+ }
+ }
+
}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 6caa854..d41aa00 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -341,7 +341,7 @@
compilerAttributes
linkerAttributes
- // A combination of compilerAttributes.features and linkerAttributes.features
+ // A combination of compilerAttributes.features and linkerAttributes.features, as well as sanitizer features
features bazel.StringListAttribute
protoDependency *bazel.LabelAttribute
aidlDependency *bazel.LabelAttribute
@@ -781,7 +781,7 @@
(&linkerAttrs).wholeArchiveDeps.Add(bp2buildCcSysprop(ctx, module.Name(), module.Properties.Min_sdk_version, compilerAttrs.syspropSrcs))
}
- features := compilerAttrs.features.Clone().Append(linkerAttrs.features)
+ features := compilerAttrs.features.Clone().Append(linkerAttrs.features).Append(bp2buildSanitizerFeatures(ctx, module))
features.DeduplicateAxesFromBase()
return baseAttributes{
@@ -1364,3 +1364,20 @@
return attrs
}
+
+func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
+ sanitizerFeatures := bazel.StringListAttribute{}
+ bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+ var features []string
+ if sanitizerProps, ok := props.(*SanitizeProperties); ok {
+ if sanitizerProps.Sanitize.Integer_overflow != nil && *sanitizerProps.Sanitize.Integer_overflow {
+ features = append(features, "ubsan_integer_overflow")
+ }
+ for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined {
+ features = append(features, "ubsan_"+sanitizer)
+ }
+ sanitizerFeatures.SetSelectValue(axis, config, features)
+ }
+ })
+ return sanitizerFeatures
+}
diff --git a/cc/cc.go b/cc/cc.go
index 2ff5bba..e07edeb 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1859,7 +1859,11 @@
}
func (c *Module) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
- return c.bazelHandler != nil
+ // TODO(b/261058727): Remove this (enable mised builds for modules with UBSan)
+ ubsanEnabled := c.sanitize != nil &&
+ ((c.sanitize.Properties.Sanitize.Integer_overflow != nil && *c.sanitize.Properties.Sanitize.Integer_overflow) ||
+ c.sanitize.Properties.Sanitize.Misc_undefined != nil)
+ return c.bazelHandler != nil && !ubsanEnabled
}
func (c *Module) ProcessBazelQueryResponse(ctx android.ModuleContext) {
diff --git a/cc/library.go b/cc/library.go
index d1d1945..7059023 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -120,6 +120,9 @@
// Extra flags passed to header-abi-diff
Diff_flags []string
+
+ // Opt-in reference dump directories
+ Ref_dump_dirs []string
}
// Inject boringssl hash into the shared library. This is only intended for use by external/boringssl.
@@ -1911,6 +1914,16 @@
isLlndkOrNdk, allowExtensions, "current", errorMessage)
}
+func (library *libraryDecorator) optInAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+ baseName, nameExt string, isLlndkOrNdk bool, refDumpDir string) {
+
+ libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
+ errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName + " -ref-dump-dir $$ANDROID_BUILD_TOP/" + refDumpDir
+
+ library.sourceAbiDiff(ctx, referenceDump, baseName, nameExt,
+ isLlndkOrNdk, /* allowExtensions */ false, "current", errorMessage)
+}
+
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1955,6 +1968,19 @@
library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
fileName, isLlndk || isNdk, ctx.IsVndkExt())
}
+ // Check against the opt-in reference dumps.
+ for i, optInDumpDir := range library.Properties.Header_abi_checker.Ref_dump_dirs {
+ optInDumpDirPath := android.PathForModuleSrc(ctx, optInDumpDir)
+ // Ref_dump_dirs are not versioned.
+ // They do not contain subdir for binder bitness because 64-bit binder has been mandatory.
+ optInDumpFile := getRefAbiDumpFile(ctx, optInDumpDirPath.String(), fileName)
+ if !optInDumpFile.Valid() {
+ continue
+ }
+ library.optInAbiDiff(ctx, optInDumpFile.Path(),
+ fileName, "opt"+strconv.Itoa(i), isLlndk || isNdk,
+ optInDumpDirPath.String())
+ }
}
}
diff --git a/cc/lto_test.go b/cc/lto_test.go
index b52f2b6..afd2c77 100644
--- a/cc/lto_test.go
+++ b/cc/lto_test.go
@@ -24,29 +24,35 @@
func TestThinLtoDeps(t *testing.T) {
bp := `
- cc_library {
+ cc_library_shared {
name: "lto_enabled",
srcs: ["src.c"],
- static_libs: ["foo"],
+ static_libs: ["foo", "lib_never_lto"],
shared_libs: ["bar"],
lto: {
thin: true,
}
}
- cc_library {
+ cc_library_static {
name: "foo",
static_libs: ["baz"],
}
- cc_library {
+ cc_library_shared {
name: "bar",
static_libs: ["qux"],
}
- cc_library {
+ cc_library_static {
name: "baz",
}
- cc_library {
+ cc_library_static {
name: "qux",
}
+ cc_library_static {
+ name: "lib_never_lto",
+ lto: {
+ never: true,
+ },
+ }
`
result := android.GroupFixturePreparers(
@@ -54,8 +60,6 @@
).RunTestWithBp(t, bp)
libLto := result.ModuleForTests("lto_enabled", "android_arm64_armv8-a_shared").Module()
- libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module()
- libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module()
hasDep := func(m android.Module, wantDep android.Module) bool {
var found bool
@@ -67,12 +71,24 @@
return found
}
+ libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static_lto-thin").Module()
if !hasDep(libLto, libFoo) {
t.Errorf("'lto_enabled' missing dependency on thin lto variant of 'foo'")
}
+ libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin").Module()
if !hasDep(libFoo, libBaz) {
- t.Errorf("'lto_enabled' missing dependency on thin lto variant of transitive dep 'baz'")
+ t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
+ }
+
+ libNeverLto := result.ModuleForTests("lib_never_lto", "android_arm64_armv8-a_static_lto-thin").Module()
+ if !hasDep(libLto, libNeverLto) {
+ t.Errorf("'lto_enabled' missing dependency on NO-thin lto variant of 'lib_never_lto'")
+ }
+
+ libBar := result.ModuleForTests("bar", "android_arm64_armv8-a_shared").Module()
+ if !hasDep(libLto, libBar) {
+ t.Errorf("'lto_enabled' missing dependency on non-thin lto variant of 'bar'")
}
barVariants := result.ModuleVariantsForTests("bar")
@@ -88,3 +104,74 @@
}
}
}
+
+func TestThinLtoOnlyOnStaticDep(t *testing.T) {
+ bp := `
+ cc_library_shared {
+ name: "root",
+ srcs: ["src.c"],
+ static_libs: ["foo"],
+ }
+ cc_library_shared {
+ name: "root_no_lto",
+ srcs: ["src.c"],
+ static_libs: ["foo"],
+ lto: {
+ never: true,
+ }
+ }
+ cc_library_static {
+ name: "foo",
+ srcs: ["foo.c"],
+ static_libs: ["baz"],
+ lto: {
+ thin: true,
+ }
+ }
+ cc_library_static {
+ name: "baz",
+ srcs: ["baz.c"],
+ }
+`
+
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ ).RunTestWithBp(t, bp)
+
+ libRoot := result.ModuleForTests("root", "android_arm64_armv8-a_shared").Module()
+ libRootLtoNever := result.ModuleForTests("root_no_lto", "android_arm64_armv8-a_shared").Module()
+
+ hasDep := func(m android.Module, wantDep android.Module) bool {
+ var found bool
+ result.VisitDirectDeps(m, func(dep blueprint.Module) {
+ if dep == wantDep {
+ found = true
+ }
+ })
+ return found
+ }
+
+ libFoo := result.ModuleForTests("foo", "android_arm64_armv8-a_static")
+ if !hasDep(libRoot, libFoo.Module()) {
+ t.Errorf("'root' missing dependency on thin lto variant of 'foo'")
+ }
+
+ if !hasDep(libRootLtoNever, libFoo.Module()) {
+ t.Errorf("'root_no_lto' missing dependency on thin lto variant of 'foo'")
+ }
+
+ libFooCFlags := libFoo.Rule("cc").Args["cFlags"]
+ if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libFooCFlags, w) {
+ t.Errorf("'foo' expected to have flags %q, but got %q", w, libFooCFlags)
+ }
+
+ libBaz := result.ModuleForTests("baz", "android_arm64_armv8-a_static_lto-thin")
+ if !hasDep(libFoo.Module(), libBaz.Module()) {
+ t.Errorf("'foo' missing dependency on thin lto variant of transitive dep 'baz'")
+ }
+
+ libBazCFlags := libFoo.Rule("cc").Args["cFlags"]
+ if w := "-flto=thin -fsplit-lto-unit"; !strings.Contains(libBazCFlags, w) {
+ t.Errorf("'baz' expected to have flags %q, but got %q", w, libFooCFlags)
+ }
+}
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index b102d33..143602a 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -572,7 +572,7 @@
}
cc_binary {
- name: "bin_depends_ubsan",
+ name: "bin_depends_ubsan_static",
host_supported: true,
shared_libs: [
"libshared",
@@ -585,6 +585,14 @@
}
cc_binary {
+ name: "bin_depends_ubsan_shared",
+ host_supported: true,
+ shared_libs: [
+ "libsharedubsan",
+ ],
+ }
+
+ cc_binary {
name: "bin_no_ubsan",
host_supported: true,
shared_libs: [
@@ -607,6 +615,14 @@
host_supported: true,
}
+ cc_library_shared {
+ name: "libsharedubsan",
+ host_supported: true,
+ sanitize: {
+ undefined: true,
+ }
+ }
+
cc_library_static {
name: "libubsan",
host_supported: true,
@@ -632,22 +648,33 @@
check := func(t *testing.T, result *android.TestResult, variant string) {
staticVariant := variant + "_static"
+ sharedVariant := variant + "_shared"
minimalRuntime := result.ModuleForTests("libclang_rt.ubsan_minimal", staticVariant)
// The binaries, one with ubsan and one without
binWithUbsan := result.ModuleForTests("bin_with_ubsan", variant)
- binDependsUbsan := result.ModuleForTests("bin_depends_ubsan", variant)
+ binDependsUbsan := result.ModuleForTests("bin_depends_ubsan_static", variant)
+ libSharedUbsan := result.ModuleForTests("libsharedubsan", sharedVariant)
+ binDependsUbsanShared := result.ModuleForTests("bin_depends_ubsan_shared", variant)
binNoUbsan := result.ModuleForTests("bin_no_ubsan", variant)
android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_with_ubsan static libs",
strings.Split(binWithUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
- android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_depends_ubsan static libs",
+ android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in bin_depends_ubsan_static static libs",
strings.Split(binDependsUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
+ android.AssertStringListContains(t, "missing libclang_rt.ubsan_minimal in libsharedubsan static libs",
+ strings.Split(libSharedUbsan.Rule("ld").Args["libFlags"], " "),
+ minimalRuntime.OutputFiles(t, "")[0].String())
+
+ android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_depends_ubsan_shared static libs",
+ strings.Split(binDependsUbsanShared.Rule("ld").Args["libFlags"], " "),
+ minimalRuntime.OutputFiles(t, "")[0].String())
+
android.AssertStringListDoesNotContain(t, "unexpected libclang_rt.ubsan_minimal in bin_no_ubsan static libs",
strings.Split(binNoUbsan.Rule("ld").Args["libFlags"], " "),
minimalRuntime.OutputFiles(t, "")[0].String())
@@ -656,10 +683,18 @@
strings.Split(binWithUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
- android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan static libs",
+ android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_static static libs",
strings.Split(binDependsUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+ android.AssertStringListContains(t, "missing -Wl,--exclude-libs for minimal runtime in libsharedubsan static libs",
+ strings.Split(libSharedUbsan.Rule("ld").Args["ldFlags"], " "),
+ "-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+
+ android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_depends_ubsan_shared static libs",
+ strings.Split(binDependsUbsanShared.Rule("ld").Args["ldFlags"], " "),
+ "-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
+
android.AssertStringListDoesNotContain(t, "unexpected -Wl,--exclude-libs for minimal runtime in bin_no_ubsan static libs",
strings.Split(binNoUbsan.Rule("ld").Args["ldFlags"], " "),
"-Wl,--exclude-libs="+minimalRuntime.OutputFiles(t, "")[0].Base())
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 2ef7c12..bea8df0 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -114,6 +114,7 @@
ctx := android.NewContext(configuration)
ctx.SetNameInterface(newNameResolver(configuration))
ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies())
+ ctx.AddIncludeTags(configuration.IncludeTags()...)
return ctx
}
diff --git a/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index 1ee0edc..2ee420c 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -149,7 +149,7 @@
cmd.FlagWithArg("--prop ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, value)))
} else {
p := android.PathForModuleSrc(ctx, file)
- cmd.Input(p)
+ cmd.Implicit(p)
cmd.FlagWithArg("--prop_from_file ", proptools.ShellEscape(fmt.Sprintf("%s:%s", name, cmd.PathForInput(p))))
}
}
diff --git a/java/robolectric.go b/java/robolectric.go
index 1d56708..938abe1 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -296,6 +296,7 @@
entries.ExtraEntries = append(entries.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", "robolectric-tests")
})
entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 5fbbd0f..bfcf42d 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -29,10 +29,13 @@
# Test Setup
############
-OUTPUT_DIR="$(mktemp -d)"
+OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong"
BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel"
+export TARGET_PRODUCT="module_arm"
+[ "$#" -eq 1 ] && export TARGET_PRODUCT="$1"
+
function call_bazel() {
build/bazel/bin/bazel --output_base="$BAZEL_OUTPUT_DIR" $@
}
@@ -50,7 +53,7 @@
export UNBUNDLED_BUILD_SDKS_FROM_SOURCE=true # don't rely on prebuilts
export TARGET_BUILD_APPS="com.android.adbd com.android.tzdata build.bazel.examples.apex.minimal"
packages/modules/common/build/build_unbundled_mainline_module.sh \
- --product module_arm \
+ --product "$TARGET_PRODUCT" \
--dist_dir "$SOONG_OUTPUT_DIR"
######################
@@ -60,22 +63,15 @@
BAZEL_OUT="$(call_bazel info --config=bp2build output_path)"
-export TARGET_PRODUCT="module_arm"
call_bazel build --config=bp2build --config=ci --config=android \
//packages/modules/adb/apex:com.android.adbd \
//system/timezone/apex:com.android.tzdata \
//build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal.apex
# Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg.
-call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs
+call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs //system/apex/tools:deapexer
DEBUGFS_PATH="$BAZEL_OUT/linux_x86_64-fastbuild/bin/external/e2fsprogs/debugfs/debugfs"
-
-function run_deapexer() {
- call_bazel run --config=bp2build --config=linux_x86_64 //system/apex/tools:deapexer \
- -- \
- --debugfs_path="$DEBUGFS_PATH" \
- $@
-}
+DEAPEXER="$BAZEL_OUT/linux_x86_64-fastbuild/bin/system/apex/tools/deapexer --debugfs_path=$DEBUGFS_PATH"
#######
# Tests
@@ -92,8 +88,8 @@
local SOONG_LIST="$OUTPUT_DIR/soong.list"
local BAZEL_LIST="$OUTPUT_DIR/bazel.list"
- run_deapexer list "$SOONG_APEX" > "$SOONG_LIST"
- run_deapexer list "$BAZEL_APEX" > "$BAZEL_LIST"
+ $DEAPEXER list "$SOONG_APEX" > "$SOONG_LIST"
+ $DEAPEXER list "$BAZEL_APEX" > "$BAZEL_LIST"
if cmp -s "$SOONG_LIST" "$BAZEL_LIST"
then
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 1e07727..7a71b27 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -13,3 +13,4 @@
# The following tests build against the full source tree and don't rely on the
# mock client.
"$TOP/build/soong/tests/apex_comparison_tests.sh"
+"$TOP/build/soong/tests/apex_comparison_tests.sh" "module_arm64only"
diff --git a/ui/build/config.go b/ui/build/config.go
index 7651a0f..ef2e87e 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -111,6 +111,8 @@
metricsUploader string
bazelForceEnabledModules string
+
+ includeTags []string
}
const srcDirFileCheck = "build/soong/root.bp"
@@ -1079,6 +1081,14 @@
return c.parallel
}
+func (c *configImpl) GetIncludeTags() []string {
+ return c.includeTags
+}
+
+func (c *configImpl) SetIncludeTags(i []string) {
+ c.includeTags = i
+}
+
func (c *configImpl) HighmemParallel() int {
if i, ok := c.environ.GetInt("NINJA_HIGHMEM_NUM_JOBS"); ok {
return i
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index b3b3866..1e3e547 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -139,6 +139,7 @@
var BannerVars = []string{
"PLATFORM_VERSION_CODENAME",
"PLATFORM_VERSION",
+ "PRODUCT_INCLUDE_TAGS",
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_APPS",
@@ -289,4 +290,5 @@
config.SetBuildBrokenDupRules(makeVars["BUILD_BROKEN_DUP_RULES"] == "true")
config.SetBuildBrokenUsesNetwork(makeVars["BUILD_BROKEN_USES_NETWORK"] == "true")
config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"]))
+ config.SetIncludeTags(strings.Fields(makeVars["PRODUCT_INCLUDE_TAGS"]))
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index de3179a..b89ca20 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -403,6 +403,7 @@
}
blueprintCtx := blueprint.NewContext()
+ blueprintCtx.AddIncludeTags(config.GetIncludeTags()...)
blueprintCtx.SetIgnoreUnknownModuleTypes(true)
blueprintConfig := BlueprintConfig{
soongOutDir: config.SoongOutDir(),