Merge "Convert remaining rust tests to use test fixtures"
diff --git a/android/bazel.go b/android/bazel.go
index 5bb3879..51ff3cb 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -129,49 +129,61 @@
}
// Per-module denylist to always opt modules out.
- bp2buildModuleDoNotConvert = map[string]bool{
- "libBionicBenchmarksUtils": true,
- "libbionic_spawn_benchmark": true,
- "libc_jemalloc_wrapper": true,
- "libc_bootstrap": true,
- "libc_init_static": true,
- "libc_init_dynamic": true,
- "libc_tzcode": true,
- "libc_freebsd": true,
- "libc_freebsd_large_stack": true,
- "libc_netbsd": true,
- "libc_openbsd_ndk": true,
- "libc_openbsd_large_stack": true,
- "libc_openbsd": true,
- "libc_gdtoa": true,
- "libc_fortify": true,
- "libc_bionic": true,
- "libc_bionic_ndk": true,
- "libc_bionic_systrace": true,
- "libc_pthread": true,
- "libc_syscalls": true,
- "libc_aeabi": true,
- "libc_ndk": true,
- "libc_nopthread": true,
- "libc_common": true,
- "libc_static_dispatch": true,
- "libc_dynamic_dispatch": true,
- "libc_common_static": true,
- "libc_common_shared": true,
- "libc_unwind_static": true,
- "libc_nomalloc": true,
- "libasync_safe": true,
- "libc_malloc_debug_backtrace": true,
- "libsystemproperties": true,
- "libdl_static": true,
- "liblinker_main": true,
- "liblinker_malloc": true,
- "liblinker_debuggerd_stub": true,
- "libbionic_tests_headers_posix": true,
- "libc_dns": true,
+ bp2buildModuleDoNotConvertList = []string{
+ "libBionicBenchmarksUtils", // ruperts@, cc_library_static
+ "libbionic_spawn_benchmark", // ruperts@, cc_library_static, depends on //system/libbase
+ "libc_jemalloc_wrapper", // ruperts@, cc_library_static, depends on //external/jemalloc_new
+ "libc_bootstrap", // ruperts@, cc_library_static
+ "libc_init_static", // ruperts@, cc_library_static
+ "libc_init_dynamic", // ruperts@, cc_library_static
+ "libc_tzcode", // ruperts@, cc_library_static
+ "libc_freebsd", // ruperts@, cc_library_static
+ "libc_freebsd_large_stack", // ruperts@, cc_library_static
+ "libc_netbsd", // ruperts@, cc_library_static
+ "libc_openbsd_ndk", // ruperts@, cc_library_static
+ "libc_openbsd_large_stack", // ruperts@, cc_library_static
+ "libc_openbsd", // ruperts@, cc_library_static
+ "libc_gdtoa", // ruperts@, cc_library_static
+ "libc_fortify", // ruperts@, cc_library_static
+ "libc_bionic", // ruperts@, cc_library_static
+ "libc_bionic_ndk", // ruperts@, cc_library_static, depends on //bionic/libc/system_properties
+ "libc_bionic_systrace", // ruperts@, cc_library_static
+ "libc_pthread", // ruperts@, cc_library_static
+ "libc_syscalls", // ruperts@, cc_library_static
+ "libc_aeabi", // ruperts@, cc_library_static
+ "libc_ndk", // ruperts@, cc_library_static, depends on //bionic/libm:libm
+ "libc_nopthread", // ruperts@, cc_library_static, depends on //external/arm-optimized-routines
+ "libc_common", // ruperts@, cc_library_static, depends on //bionic/libc:libc_nopthread
+ "libc_static_dispatch", // ruperts@, cc_library_static
+ "libc_dynamic_dispatch", // ruperts@, cc_library_static
+ "libc_common_static", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libc_common_shared", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libc_unwind_static", // ruperts@, cc_library_static
+ "libc_nomalloc", // ruperts@, cc_library_static, depends on //bionic/libc:libc_common
+ "libasync_safe", // ruperts@, cc_library_static
+ "libc_malloc_debug_backtrace", // ruperts@, cc_library_static, depends on //system/libbase
+ "libsystemproperties", // ruperts@, cc_library_static, depends on //system/core/property_service/libpropertyinfoparser
+ "libdl_static", // ruperts@, cc_library_static
+ "liblinker_main", // ruperts@, cc_library_static, depends on //system/libbase
+ "liblinker_malloc", // ruperts@, cc_library_static, depends on //system/logging/liblog:liblog
+ "liblinker_debuggerd_stub", // ruperts@, cc_library_static, depends on //system/libbase
+ "libbionic_tests_headers_posix", // ruperts@, cc_library_static
+ "libc_dns", // ruperts@, cc_library_static
+ "generated_android_ids", // cparsons@, genrule
+ "note_memtag_heap_async", // cparsons@, cc_library_static
+ "note_memtag_heap_sync", // cparsons@, cc_library_static
}
+
+ // Used for quicker lookups
+ bp2buildModuleDoNotConvert = map[string]bool{}
)
+func init() {
+ for _, moduleName := range bp2buildModuleDoNotConvertList {
+ bp2buildModuleDoNotConvert[moduleName] = true
+ }
+}
+
// ConvertWithBp2build returns whether the given BazelModuleBase should be converted with bp2build.
func (b *BazelModuleBase) ConvertWithBp2build(ctx BazelConversionPathContext) bool {
if bp2buildModuleDoNotConvert[ctx.Module().Name()] {
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 0595d68..abc793f 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -27,6 +27,7 @@
"sync"
"android/soong/bazel/cquery"
+
"github.com/google/blueprint/bootstrap"
"android/soong/bazel"
@@ -37,7 +38,6 @@
const (
getAllFiles CqueryRequestType = iota
- getCcObjectFiles
getAllFilesAndCcObjectFiles
)
@@ -56,10 +56,6 @@
// Returns result files built by building the given bazel target label.
GetOutputFiles(label string, archType ArchType) ([]string, bool)
- // Returns object files produced by compiling the given cc-related target.
- // Retrieves these files from Bazel's CcInfo provider.
- GetCcObjectFiles(label string, archType ArchType) ([]string, bool)
-
// TODO(cparsons): Other cquery-related methods should be added here.
// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool)
@@ -116,11 +112,6 @@
return result, ok
}
-func (m MockBazelContext) GetCcObjectFiles(label string, archType ArchType) ([]string, bool) {
- result, ok := m.AllFiles[label]
- return result, ok
-}
-
func (m MockBazelContext) GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool) {
result, ok := m.AllFiles[label]
return result, result, ok
@@ -154,16 +145,6 @@
return ret, ok
}
-func (bazelCtx *bazelContext) GetCcObjectFiles(label string, archType ArchType) ([]string, bool) {
- rawString, ok := bazelCtx.cquery(label, cquery.GetCcObjectFiles, archType)
- var returnResult []string
- if ok {
- bazelOutput := strings.TrimSpace(rawString)
- returnResult = cquery.GetCcObjectFiles.ParseResult(bazelOutput).([]string)
- }
- return returnResult, ok
-}
-
func (bazelCtx *bazelContext) GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool) {
var outputFiles []string
var ccObjects []string
@@ -183,10 +164,6 @@
panic("unimplemented")
}
-func (n noopBazelContext) GetCcObjectFiles(label string, archType ArchType) ([]string, bool) {
- panic("unimplemented")
-}
-
func (n noopBazelContext) GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool) {
panic("unimplemented")
}
@@ -332,8 +309,13 @@
name = "sourceroot",
path = "%s",
)
+
+local_repository(
+ name = "rules_cc",
+ path = "%s/build/bazel/rules_cc",
+)
`
- return []byte(fmt.Sprintf(formatString, context.workspaceDir))
+ return []byte(fmt.Sprintf(formatString, context.workspaceDir, context.workspaceDir))
}
func (context *bazelContext) mainBzlFileContents() []byte {
@@ -344,73 +326,39 @@
# This file is generated by soong_build. Do not edit.
#####################################################
-def _x86_64_transition_impl(settings, attr):
+def _config_node_transition_impl(settings, attr):
return {
- "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:generic_x86_64",
+ "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:generic_%s" % attr.arch,
}
-def _x86_transition_impl(settings, attr):
- return {
- "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:generic_x86",
- }
-
-def _arm64_transition_impl(settings, attr):
- return {
- "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:generic_arm64",
- }
-
-def _arm_transition_impl(settings, attr):
- return {
- "//command_line_option:platforms": "@sourceroot//build/bazel/platforms:generic_arm",
- }
-
-x86_64_transition = transition(
- implementation = _x86_64_transition_impl,
+_config_node_transition = transition(
+ implementation = _config_node_transition_impl,
inputs = [],
outputs = [
"//command_line_option:platforms",
],
)
-x86_transition = transition(
- implementation = _x86_transition_impl,
- inputs = [],
- outputs = [
- "//command_line_option:platforms",
- ],
+def _passthrough_rule_impl(ctx):
+ return [DefaultInfo(files = depset(ctx.files.deps))]
+
+config_node = rule(
+ implementation = _passthrough_rule_impl,
+ attrs = {
+ "arch" : attr.string(mandatory = True),
+ "deps" : attr.label_list(cfg = _config_node_transition),
+ "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
+ },
)
-arm64_transition = transition(
- implementation = _arm64_transition_impl,
- inputs = [],
- outputs = [
- "//command_line_option:platforms",
- ],
-)
-
-arm_transition = transition(
- implementation = _arm_transition_impl,
- inputs = [],
- outputs = [
- "//command_line_option:platforms",
- ],
-)
-
-def _mixed_build_root_impl(ctx):
- all_files = ctx.files.deps_x86_64 + ctx.files.deps_x86 + ctx.files.deps_arm64 + ctx.files.deps_arm
- return [DefaultInfo(files = depset(all_files))]
# Rule representing the root of the build, to depend on all Bazel targets that
# are required for the build. Building this target will build the entire Bazel
# build tree.
mixed_build_root = rule(
- implementation = _mixed_build_root_impl,
+ implementation = _passthrough_rule_impl,
attrs = {
- "deps_x86_64" : attr.label_list(cfg = x86_64_transition),
- "deps_x86" : attr.label_list(cfg = x86_transition),
- "deps_arm64" : attr.label_list(cfg = arm64_transition),
- "deps_arm" : attr.label_list(cfg = arm_transition),
- "_allowlist_function_transition": attr.label(default = "@bazel_tools//tools/allowlists/function_transition_allowlist"),
+ "deps" : attr.label_list(),
},
)
@@ -446,44 +394,42 @@
// architecture mapping.
formatString := `
# This file is generated by soong_build. Do not edit.
-load(":main.bzl", "mixed_build_root", "phony_root")
+load(":main.bzl", "config_node", "mixed_build_root", "phony_root")
+
+%s
mixed_build_root(name = "buildroot",
- deps_x86_64 = [%s],
- deps_x86 = [%s],
- deps_arm64 = [%s],
- deps_arm = [%s],
+ deps = [%s],
)
phony_root(name = "phonyroot",
deps = [":buildroot"],
)
`
- var deps_x86_64 []string = nil
- var deps_x86 []string = nil
- var deps_arm64 []string = nil
- var deps_arm []string = nil
+ configNodeFormatString := `
+config_node(name = "%s",
+ arch = "%s",
+ deps = [%s],
+)
+`
+
+ configNodesSection := ""
+
+ labelsByArch := map[string][]string{}
for val, _ := range context.requests {
labelString := fmt.Sprintf("\"%s\"", canonicalizeLabel(val.label))
- switch getArchString(val) {
- case "x86_64":
- deps_x86_64 = append(deps_x86_64, labelString)
- case "x86":
- deps_x86 = append(deps_x86, labelString)
- case "arm64":
- deps_arm64 = append(deps_arm64, labelString)
- case "arm":
- deps_arm = append(deps_arm, labelString)
- default:
- panic(fmt.Sprintf("unhandled architecture %s for %v", getArchString(val), val))
- }
+ archString := getArchString(val)
+ labelsByArch[archString] = append(labelsByArch[archString], labelString)
}
- return []byte(fmt.Sprintf(formatString,
- strings.Join(deps_x86_64, ",\n "),
- strings.Join(deps_x86, ",\n "),
- strings.Join(deps_arm64, ",\n "),
- strings.Join(deps_arm, ",\n ")))
+ configNodeLabels := []string{}
+ for archString, labels := range labelsByArch {
+ configNodeLabels = append(configNodeLabels, fmt.Sprintf("\":%s\"", archString))
+ labelsString := strings.Join(labels, ",\n ")
+ configNodesSection += fmt.Sprintf(configNodeFormatString, archString, archString, labelsString)
+ }
+
+ return []byte(fmt.Sprintf(formatString, configNodesSection, strings.Join(configNodeLabels, ",\n ")))
}
func indent(original string) string {
diff --git a/android/fixture.go b/android/fixture.go
index 8d62958..5fc668a 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -26,16 +26,9 @@
// Fixture
// =======
// These determine the environment within which a test can be run. Fixtures are mutable and are
-// created by FixtureFactory instances and mutated by FixturePreparer instances. They are created by
-// first creating a base Fixture (which is essentially empty) and then applying FixturePreparer
-// instances to it to modify the environment.
-//
-// FixtureFactory (deprecated)
-// ===========================
-// These are responsible for creating fixtures. Factories are immutable and are intended to be
-// initialized once and reused to create multiple fixtures. Each factory has a list of fixture
-// preparers that prepare a fixture for running a test. Factories can also be used to create other
-// factories by extending them with additional fixture preparers.
+// created and mutated by FixturePreparer instances. They are created by first creating a base
+// Fixture (which is essentially empty) and then applying FixturePreparer instances to it to modify
+// the environment.
//
// FixturePreparer
// ===============
@@ -169,77 +162,6 @@
// PrepareForApex,
// )
//
-// // FixtureFactory instances have been deprecated, this remains for informational purposes to
-// // help explain some of the existing code but will be removed along with FixtureFactory.
-//
-// var javaFixtureFactory = android.NewFixtureFactory(
-// PrepareForIntegrationTestWithJava,
-// FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
-// ctx.RegisterModuleType("test_module", testModule)
-// }),
-// javaMockFS.AddToFixture(),
-// ...
-// }
-//
-// func TestJavaStuff(t *testing.T) {
-// result := javaFixtureFactory.RunTest(t,
-// android.FixtureWithRootAndroidBp(`java_library {....}`),
-// android.MockFS{...}.AddToFixture(),
-// )
-// ... test result ...
-// }
-//
-// package cc
-// var PrepareForTestWithCC = GroupFixturePreparers(
-// android.PrepareForArchMutator,
-// android.prepareForPrebuilts,
-// FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
-// ...
-// )
-//
-// package apex
-//
-// var PrepareForApex = GroupFixturePreparers(
-// ...
-// )
-//
-// Use modules and mutators from java, cc and apex. Any duplicate preparers (like
-// android.PrepareForArchMutator) will be automatically deduped.
-//
-// var apexFixtureFactory = android.NewFixtureFactory(
-// PrepareForJava,
-// PrepareForCC,
-// PrepareForApex,
-// )
-
-// Factory for Fixture objects.
-//
-// This is configured with a set of FixturePreparer objects that are used to
-// initialize each Fixture instance this creates.
-//
-// deprecated: Use FixturePreparer instead.
-type FixtureFactory interface {
- FixturePreparer
-}
-
-// Create a new FixtureFactory that will apply the supplied preparers.
-//
-// The buildDirSupplier is a pointer to the package level buildDir variable that is initialized by
-// the package level setUp method. It has to be a pointer to the variable as the variable will not
-// have been initialized at the time the factory is created. If it is nil then a test specific
-// temporary directory will be created instead.
-//
-// deprecated: The functionality provided by FixtureFactory will be merged into FixturePreparer
-func NewFixtureFactory(buildDirSupplier *string, preparers ...FixturePreparer) FixtureFactory {
- f := &fixtureFactory{
- buildDirSupplier: buildDirSupplier,
- compositeFixturePreparer: compositeFixturePreparer{
- preparers: dedupAndFlattenPreparers(nil, preparers),
- },
- }
- f.initBaseFixturePreparer(f)
- return f
-}
// A set of mock files to add to the mock file system.
type MockFS map[string][]byte
@@ -445,17 +367,8 @@
// Return the flattened and deduped list of simpleFixturePreparer pointers.
list() []*simpleFixturePreparer
- // Creates a copy of this instance and adds some additional preparers.
- //
- // Before the preparers are used they are combined with the preparers provided when the factory
- // was created, any groups of preparers are flattened, and the list is deduped so that each
- // preparer is only used once. See the file documentation in android/fixture.go for more details.
- //
- // deprecated: Use GroupFixturePreparers() instead.
- Extend(preparers ...FixturePreparer) FixturePreparer
-
// Create a Fixture.
- Fixture(t *testing.T, preparers ...FixturePreparer) Fixture
+ Fixture(t *testing.T) Fixture
// ExtendWithErrorHandler creates a new FixturePreparer that will use the supplied error handler
// to check the errors (may be 0) reported by the test.
@@ -466,12 +379,13 @@
// Run the test, checking any errors reported and returning a TestResult instance.
//
- // Shorthand for Fixture(t, preparers...).RunTest()
- RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult
+ // Shorthand for Fixture(t).RunTest()
+ RunTest(t *testing.T) *TestResult
// Run the test with the supplied Android.bp file.
//
- // Shorthand for RunTest(t, android.FixtureWithRootAndroidBp(bp))
+ // preparer.RunTestWithBp(t, bp) is shorthand for
+ // android.GroupFixturePreparers(preparer, android.FixtureWithRootAndroidBp(bp)).RunTest(t)
RunTestWithBp(t *testing.T, bp string) *TestResult
// RunTestWithConfig is a temporary method added to help ease the migration of existing tests to
@@ -705,13 +619,11 @@
NinjaDeps []string
}
-func createFixture(t *testing.T, buildDir string, base []*simpleFixturePreparer, extra []FixturePreparer) Fixture {
- all := dedupAndFlattenPreparers(base, extra)
-
+func createFixture(t *testing.T, buildDir string, preparers []*simpleFixturePreparer) Fixture {
config := TestConfig(buildDir, nil, "", nil)
ctx := NewTestContext(config)
fixture := &fixture{
- preparers: all,
+ preparers: preparers,
t: t,
config: config,
ctx: ctx,
@@ -720,7 +632,7 @@
errorHandler: FixtureExpectsNoErrors,
}
- for _, preparer := range all {
+ for _, preparer := range preparers {
preparer.function(fixture)
}
@@ -735,30 +647,25 @@
b.self = self
}
-func (b *baseFixturePreparer) Extend(preparers ...FixturePreparer) FixturePreparer {
- all := dedupAndFlattenPreparers(b.self.list(), preparers)
- return newFixturePreparer(all)
-}
-
-func (b *baseFixturePreparer) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture {
- return createFixture(t, t.TempDir(), b.self.list(), preparers)
+func (b *baseFixturePreparer) Fixture(t *testing.T) Fixture {
+ return createFixture(t, t.TempDir(), b.self.list())
}
func (b *baseFixturePreparer) ExtendWithErrorHandler(errorHandler FixtureErrorHandler) FixturePreparer {
- return b.self.Extend(newSimpleFixturePreparer(func(fixture *fixture) {
+ return GroupFixturePreparers(b.self, newSimpleFixturePreparer(func(fixture *fixture) {
fixture.errorHandler = errorHandler
}))
}
-func (b *baseFixturePreparer) RunTest(t *testing.T, preparers ...FixturePreparer) *TestResult {
+func (b *baseFixturePreparer) RunTest(t *testing.T) *TestResult {
t.Helper()
- fixture := b.self.Fixture(t, preparers...)
+ fixture := b.self.Fixture(t)
return fixture.RunTest()
}
func (b *baseFixturePreparer) RunTestWithBp(t *testing.T, bp string) *TestResult {
t.Helper()
- return b.RunTest(t, FixtureWithRootAndroidBp(bp))
+ return GroupFixturePreparers(b.self, FixtureWithRootAndroidBp(bp)).RunTest(t)
}
func (b *baseFixturePreparer) RunTestWithConfig(t *testing.T, config Config) *TestResult {
@@ -783,46 +690,6 @@
return fixture.RunTest()
}
-var _ FixtureFactory = (*fixtureFactory)(nil)
-
-type fixtureFactory struct {
- compositeFixturePreparer
-
- buildDirSupplier *string
-}
-
-// Override to preserve the buildDirSupplier.
-func (f *fixtureFactory) Extend(preparers ...FixturePreparer) FixturePreparer {
- // If there is no buildDirSupplier then just use the default implementation.
- if f.buildDirSupplier == nil {
- return f.baseFixturePreparer.Extend(preparers...)
- }
-
- all := dedupAndFlattenPreparers(f.preparers, preparers)
-
- // Create a new factory which uses the same buildDirSupplier as the previous one.
- extendedFactory := &fixtureFactory{
- buildDirSupplier: f.buildDirSupplier,
- compositeFixturePreparer: compositeFixturePreparer{
- preparers: all,
- },
- }
- extendedFactory.initBaseFixturePreparer(extendedFactory)
- return extendedFactory
-}
-
-func (f *fixtureFactory) Fixture(t *testing.T, preparers ...FixturePreparer) Fixture {
- // If there is no buildDirSupplier then just use the default implementation.
- if f.buildDirSupplier == nil {
- return f.baseFixturePreparer.Fixture(t, preparers...)
- }
-
- // Retrieve the buildDir from the supplier.
- buildDir := *f.buildDirSupplier
-
- return createFixture(t, buildDir, f.preparers, preparers)
-}
-
type fixture struct {
// The preparers used to create this fixture.
preparers []*simpleFixturePreparer
@@ -937,10 +804,10 @@
// that produced this result.
//
// e.g. assuming that this result was created by running:
-// factory.Extend(preparer1, preparer2).RunTest(t, preparer3, preparer4)
+// GroupFixturePreparers(preparer1, preparer2, preparer3).RunTest(t)
//
// Then this method will be equivalent to running:
-// GroupFixturePreparers(preparer1, preparer2, preparer3, preparer4)
+// GroupFixturePreparers(preparer1, preparer2, preparer3)
//
// This is intended for use by tests whose output is Android.bp files to verify that those files
// are valid, e.g. tests of the snapshots produced by the sdk module type.
diff --git a/android/fixture_test.go b/android/fixture_test.go
index 681a034..5b810e0 100644
--- a/android/fixture_test.go
+++ b/android/fixture_test.go
@@ -41,45 +41,42 @@
group := GroupFixturePreparers(preparer1, preparer2, preparer1, preparer1Then2)
- extension := group.Extend(preparer4, preparer2)
+ extension := GroupFixturePreparers(group, preparer4, preparer2)
- extension.Fixture(t, preparer1, preparer2, preparer2Then1, preparer3)
+ GroupFixturePreparers(extension, preparer1, preparer2, preparer2Then1, preparer3).Fixture(t)
AssertDeepEquals(t, "preparers called in wrong order",
[]string{"preparer1", "preparer2", "preparer4", "preparer3"}, list)
}
func TestFixtureValidateMockFS(t *testing.T) {
- buildDir := "<unused>"
- factory := NewFixtureFactory(&buildDir)
-
t.Run("absolute path", func(t *testing.T) {
AssertPanicMessageContains(t, "source path validation failed", "Path is outside directory: /abs/path/Android.bp", func() {
- factory.Fixture(t, FixtureAddFile("/abs/path/Android.bp", nil))
+ FixtureAddFile("/abs/path/Android.bp", nil).Fixture(t)
})
})
t.Run("not canonical", func(t *testing.T) {
AssertPanicMessageContains(t, "source path validation failed", `path "path/with/../in/it/Android.bp" is not a canonical path, use "path/in/it/Android.bp" instead`, func() {
- factory.Fixture(t, FixtureAddFile("path/with/../in/it/Android.bp", nil))
+ FixtureAddFile("path/with/../in/it/Android.bp", nil).Fixture(t)
})
})
t.Run("FixtureAddFile", func(t *testing.T) {
AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
- factory.Fixture(t, FixtureAddFile("out/Android.bp", nil))
+ FixtureAddFile("out/Android.bp", nil).Fixture(t)
})
})
t.Run("FixtureMergeMockFs", func(t *testing.T) {
AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
- factory.Fixture(t, FixtureMergeMockFs(MockFS{
+ FixtureMergeMockFs(MockFS{
"out/Android.bp": nil,
- }))
+ }).Fixture(t)
})
})
t.Run("FixtureModifyMockFS", func(t *testing.T) {
AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() {
- factory.Fixture(t, FixtureModifyMockFS(func(fs MockFS) {
+ FixtureModifyMockFS(func(fs MockFS) {
fs["out/Android.bp"] = nil
- }))
+ }).Fixture(t)
})
})
}
diff --git a/android/mutator.go b/android/mutator.go
index 9e99bee..e25e2e8 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -202,7 +202,7 @@
RegisterPrebuiltsPostDepsMutators,
RegisterVisibilityRuleEnforcer,
RegisterLicensesDependencyChecker,
- RegisterNeverallowMutator,
+ registerNeverallowMutator,
RegisterOverridePostDepsMutators,
}
@@ -539,7 +539,7 @@
Name: &name,
}
- b := t.CreateModule(factory, &nameProp, attrs).(BazelTargetModule)
+ b := t.createModuleWithoutInheritance(factory, &nameProp, attrs).(BazelTargetModule)
b.SetBazelTargetModuleProperties(bazelProps)
return b
}
@@ -608,6 +608,11 @@
return module
}
+func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module {
+ module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), props...).(Module)
+ return module
+}
+
func (b *bottomUpMutatorContext) MutatorName() string {
return b.bp.MutatorName()
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 7455e6a..a385bbc 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -42,7 +42,7 @@
// counts as a match
// - it has none of the "Without" properties matched (same rules as above)
-func RegisterNeverallowMutator(ctx RegisterMutatorsContext) {
+func registerNeverallowMutator(ctx RegisterMutatorsContext) {
ctx.BottomUp("neverallow", neverallowMutator).Parallel()
}
@@ -661,6 +661,22 @@
// Overrides the default neverallow rules for the supplied config.
//
// For testing only.
-func SetTestNeverallowRules(config Config, testRules []Rule) {
+func setTestNeverallowRules(config Config, testRules []Rule) {
config.Once(neverallowRulesKey, func() interface{} { return testRules })
}
+
+// Prepares for a test by setting neverallow rules and enabling the mutator.
+//
+// If the supplied rules are nil then the default rules are used.
+func PrepareForTestWithNeverallowRules(testRules []Rule) FixturePreparer {
+ return GroupFixturePreparers(
+ FixtureModifyConfig(func(config Config) {
+ if testRules != nil {
+ setTestNeverallowRules(config, testRules)
+ }
+ }),
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.PostDepsMutators(registerNeverallowMutator)
+ }),
+ )
+}
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index de0197a..268346a 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -292,7 +292,6 @@
ctx.RegisterModuleType("java_library_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("java_device_for_host", newMockJavaLibraryModule)
ctx.RegisterModuleType("makefile_goal", newMockMakefileGoalModule)
- ctx.PostDepsMutators(RegisterNeverallowMutator)
}),
)
@@ -301,12 +300,7 @@
t.Run(test.name, func(t *testing.T) {
GroupFixturePreparers(
prepareForNeverAllowTest,
- FixtureModifyConfig(func(config Config) {
- // If the test has its own rules then use them instead of the default ones.
- if test.rules != nil {
- SetTestNeverallowRules(config, test.rules)
- }
- }),
+ PrepareForTestWithNeverallowRules(test.rules),
test.fs.AddToFixture(),
).
ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern(test.expectedErrors)).
diff --git a/android/paths.go b/android/paths.go
index db9e06a..ba1ab11 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -286,9 +286,9 @@
return p.path
}
-// RelativeToPath returns an OptionalPath with the path that was embedded having been replaced by
-// the result of calling Path.RelativeToPath on it.
-func (p OptionalPath) RelativeToPath() OptionalPath {
+// RelativeToTop returns an OptionalPath with the path that was embedded having been replaced by the
+// result of calling Path.RelativeToTop on it.
+func (p OptionalPath) RelativeToTop() OptionalPath {
if !p.valid {
return p
}
diff --git a/android/register.go b/android/register.go
index 35469d4..4c8088d 100644
--- a/android/register.go
+++ b/android/register.go
@@ -192,6 +192,15 @@
t.register(ctx)
}
+ if ctx.config.BazelContext.BazelEnabled() {
+ // Hydrate the configuration of bp2build-enabled module types. This is
+ // required as a signal to identify which modules should be deferred to
+ // Bazel in mixed builds, if it is enabled.
+ for t, _ := range bp2buildMutators {
+ ctx.config.bp2buildModuleTypeConfig[t] = true
+ }
+ }
+
mutators := collateGloballyRegisteredMutators()
mutators.registerAll(ctx)
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 9c5ca41..d2a7d8d 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -645,7 +645,7 @@
rspFile := "out/soong/.intermediates/foo/rsp"
rspFile2 := "out/soong/.intermediates/foo/rsp2"
module := result.ModuleForTests("foo", "")
- check(t, module.Rule("rule").RelativeToTop(), module.Output(rspFile2).RelativeToTop(),
+ check(t, module.Rule("rule"), module.Output(rspFile2),
"cp bar "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
})
@@ -662,7 +662,7 @@
cmd := `rm -rf ` + outDir + `/gen && ` +
sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest
module := result.ModuleForTests("foo_sbox", "")
- check(t, module.Output("gen/foo_sbox").RelativeToTop(), module.Output(rspFile2).RelativeToTop(),
+ check(t, module.Output("gen/foo_sbox"), module.Output(rspFile2),
cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox})
})
t.Run("sbox_inputs", func(t *testing.T) {
@@ -679,7 +679,7 @@
sbox + ` --sandbox-path ` + sandboxPath + ` --manifest ` + manifest
module := result.ModuleForTests("foo_sbox_inputs", "")
- check(t, module.Output("gen/foo_sbox_inputs").RelativeToTop(), module.Output(rspFile2).RelativeToTop(),
+ check(t, module.Output("gen/foo_sbox_inputs"), module.Output(rspFile2),
cmd, outFile, depFile, rspFile, rspFile2, false, []string{manifest}, []string{sbox})
})
t.Run("singleton", func(t *testing.T) {
@@ -687,7 +687,7 @@
rspFile := filepath.Join("out/soong/singleton/rsp")
rspFile2 := filepath.Join("out/soong/singleton/rsp2")
singleton := result.SingletonForTests("rule_builder_test")
- check(t, singleton.Rule("rule").RelativeToTop(), singleton.Output(rspFile2).RelativeToTop(),
+ check(t, singleton.Rule("rule"), singleton.Output(rspFile2),
"cp bar "+outFile+" @"+rspFile+" @"+rspFile2,
outFile, outFile+".d", rspFile, rspFile2, true, nil, nil)
})
diff --git a/android/testing.go b/android/testing.go
index f4f5c98..ce27fca 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -551,6 +551,8 @@
// * CommandOrderOnly
//
// See PathRelativeToTop for more details.
+//
+// deprecated: this is no longer needed as TestingBuildParams are created in this form.
func (p TestingBuildParams) RelativeToTop() TestingBuildParams {
// If this is not a valid params then just return it back. That will make it easy to use with the
// Maybe...() methods.
diff --git a/android/variable.go b/android/variable.go
index 2ab51c7..dff48c2 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -448,6 +448,63 @@
}
}
+// ProductConfigContext requires the access to the Module to get product config properties.
+type ProductConfigContext interface {
+ Module() Module
+}
+
+// ProductConfigProperty contains the information for a single property (may be a struct) paired
+// with the appropriate ProductConfigVariable.
+type ProductConfigProperty struct {
+ ProductConfigVariable string
+ Property interface{}
+}
+
+// ProductConfigProperties is a map of property name to a slice of ProductConfigProperty such that
+// all it all product variable-specific versions of a property are easily accessed together
+type ProductConfigProperties map[string][]ProductConfigProperty
+
+// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
+// have been set for the module in the given context.
+func ProductVariableProperties(ctx ProductConfigContext) ProductConfigProperties {
+ module := ctx.Module()
+ moduleBase := module.base()
+
+ productConfigProperties := ProductConfigProperties{}
+
+ if moduleBase.variableProperties == nil {
+ return productConfigProperties
+ }
+
+ variableValues := reflect.ValueOf(moduleBase.variableProperties).Elem().FieldByName("Product_variables")
+ for i := 0; i < variableValues.NumField(); i++ {
+ variableValue := variableValues.Field(i)
+ // Check if any properties were set for the module
+ if variableValue.IsZero() {
+ continue
+ }
+ // e.g. Platform_sdk_version, Unbundled_build, Malloc_not_svelte, etc.
+ productVariableName := variableValues.Type().Field(i).Name
+ for j := 0; j < variableValue.NumField(); j++ {
+ property := variableValue.Field(j)
+ // If the property wasn't set, no need to pass it along
+ if property.IsZero() {
+ continue
+ }
+
+ // e.g. Asflags, Cflags, Enabled, etc.
+ propertyName := variableValue.Type().Field(j).Name
+ productConfigProperties[propertyName] = append(productConfigProperties[propertyName],
+ ProductConfigProperty{
+ ProductConfigVariable: productVariableName,
+ Property: property.Interface(),
+ })
+ }
+ }
+
+ return productConfigProperties
+}
+
func VariableMutator(mctx BottomUpMutatorContext) {
var module Module
var ok bool
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 11b23c6..0caad13 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -22,6 +22,7 @@
"reflect"
"regexp"
"sort"
+ "strconv"
"strings"
"testing"
@@ -49,18 +50,28 @@
func testApexError(t *testing.T, pattern, bp string, preparers ...android.FixturePreparer) {
t.Helper()
- apexFixtureFactory.Extend(preparers...).
+ android.GroupFixturePreparers(
+ prepareForApexTest,
+ android.GroupFixturePreparers(preparers...),
+ ).
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
RunTestWithBp(t, bp)
}
func testApex(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext {
t.Helper()
- factory := apexFixtureFactory.Extend(preparers...)
+
+ optionalBpPreparer := android.NullFixturePreparer
if bp != "" {
- factory = factory.Extend(android.FixtureWithRootAndroidBp(bp))
+ optionalBpPreparer = android.FixtureWithRootAndroidBp(bp)
}
- result := factory.RunTest(t)
+
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ android.GroupFixturePreparers(preparers...),
+ optionalBpPreparer,
+ ).RunTest(t)
+
return result.TestContext
}
@@ -114,8 +125,16 @@
},
)
-var apexFixtureFactory = android.NewFixtureFactory(
- nil,
+// Legacy preparer used for running tests within the apex package.
+//
+// This includes everything that was needed to run any test in the apex package prior to the
+// introduction of the test fixtures. Tests that are being converted to use fixtures directly
+// rather than through the testApex...() methods should avoid using this and instead use the
+// various preparers directly, using android.GroupFixturePreparers(...) to group them when
+// necessary.
+//
+// deprecated
+var prepareForApexTest = android.GroupFixturePreparers(
// General preparers in alphabetical order as test infrastructure will enforce correct
// registration order.
android.PrepareForTestWithAndroidBuildComponents,
@@ -485,7 +504,7 @@
}
`)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule").RelativeToTop()
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
// Make sure that Android.mk is created
ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
@@ -801,7 +820,7 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
// Ensure that mylib is linking with the latest version of stubs for mylib2
- ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_3/mylib2.so")
+ ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
@@ -1279,15 +1298,15 @@
name: "unspecified version links to the latest",
minSdkVersion: "",
apexVariant: "apex10000",
- shouldLink: "30",
- shouldNotLink: []string{"29"},
+ shouldLink: "current",
+ shouldNotLink: []string{"29", "30"},
},
{
name: "always use the latest",
minSdkVersion: "min_sdk_version: \"29\",",
apexVariant: "apex29",
- shouldLink: "30",
- shouldNotLink: []string{"29"},
+ shouldLink: "current",
+ shouldNotLink: []string{"29", "30"},
},
}
for _, tc := range testcases {
@@ -1354,7 +1373,11 @@
}
mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_"+tc.apexVariant).Rule("cc").Args["cFlags"]
- ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
+ ver := tc.shouldLink
+ if tc.shouldLink == "current" {
+ ver = strconv.Itoa(android.FutureApiLevelInt)
+ }
+ ensureContains(t, mylibCFlags, "__LIBBAR_API__="+ver)
})
}
}
@@ -1416,12 +1439,12 @@
// For dependency to libc
// Ensure that mylib is linking with the latest version of stubs
- ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_29/libc.so")
+ ensureContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared_current/libc.so")
// ... and not linking to the non-stub (impl) variant
ensureNotContains(t, mylibLdFlags, "libc/android_arm64_armv8-a_shared/libc.so")
// ... Cflags from stub is correctly exported to mylib
- ensureContains(t, mylibCFlags, "__LIBC_API__=29")
- ensureContains(t, mylibSharedCFlags, "__LIBC_API__=29")
+ ensureContains(t, mylibCFlags, "__LIBC_API__=10000")
+ ensureContains(t, mylibSharedCFlags, "__LIBC_API__=10000")
// For dependency to libm
// Ensure that mylib is linking with the non-stub (impl) variant
@@ -1527,12 +1550,14 @@
}
// platform liba is linked to non-stub version
expectLink("liba", "shared", "libz", "shared")
- // liba in myapex is linked to #30
- expectLink("liba", "shared_apex29", "libz", "shared_30")
+ // liba in myapex is linked to current
+ expectLink("liba", "shared_apex29", "libz", "shared_current")
+ expectNoLink("liba", "shared_apex29", "libz", "shared_30")
expectNoLink("liba", "shared_apex29", "libz", "shared_28")
expectNoLink("liba", "shared_apex29", "libz", "shared")
- // liba in otherapex is linked to #30
- expectLink("liba", "shared_apex30", "libz", "shared_30")
+ // liba in otherapex is linked to current
+ expectLink("liba", "shared_apex30", "libz", "shared_current")
+ expectNoLink("liba", "shared_apex30", "libz", "shared_30")
expectNoLink("liba", "shared_apex30", "libz", "shared_28")
expectNoLink("liba", "shared_apex30", "libz", "shared")
}
@@ -1583,7 +1608,8 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_apex10000", "libz", "shared_R")
+ expectLink("libx", "shared_apex10000", "libz", "shared_current")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_R")
expectNoLink("libx", "shared_apex10000", "libz", "shared_29")
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
@@ -1629,8 +1655,9 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_apex10000", "libz", "shared_2")
+ expectLink("libx", "shared_apex10000", "libz", "shared_current")
expectNoLink("libx", "shared_apex10000", "libz", "shared_1")
+ expectNoLink("libx", "shared_apex10000", "libz", "shared_2")
expectNoLink("libx", "shared_apex10000", "libz", "shared")
}
@@ -1677,7 +1704,8 @@
ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"]
ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libz", "shared", "libx", "shared_2")
+ expectLink("libz", "shared", "libx", "shared_current")
+ expectNoLink("libz", "shared", "libx", "shared_2")
expectNoLink("libz", "shared", "libz", "shared_1")
expectNoLink("libz", "shared", "libz", "shared")
}
@@ -1724,7 +1752,7 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_30")
+ expectLink("libx", "shared_hwasan_apex29", "libbar", "shared_current")
}
func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
@@ -2072,7 +2100,7 @@
private_key: "testkey.pem",
}
- // mylib in myapex will link to mylib2#30
+ // mylib in myapex will link to mylib2#current
// mylib in otherapex will link to mylib2(non-stub) in otherapex as well
cc_library {
name: "mylib",
@@ -2106,7 +2134,7 @@
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("mylib", "shared_apex29", "mylib2", "shared_30")
+ expectLink("mylib", "shared_apex29", "mylib2", "shared_current")
expectLink("mylib", "shared_apex30", "mylib2", "shared_apex30")
}
@@ -2174,10 +2202,10 @@
}
`, withSAsActiveCodeNames)
- // ensure libfoo is linked with "S" version of libbar stub
+ // ensure libfoo is linked with current version of libbar stub
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared_apex10000")
libFlags := libfoo.Rule("ld").Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_shared_T/libbar.so")
+ ensureContains(t, libFlags, "android_arm64_armv8-a_shared_current/libbar.so")
}
func TestFilesInSubDir(t *testing.T) {
@@ -2498,7 +2526,7 @@
vendorVariant := "android_vendor.VER_arm64_armv8-a"
- ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld").RelativeToTop()
+ ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld")
libs := names(ldRule.Args["libFlags"])
// VNDK libs(libvndk/libc++) as they are
ensureListContains(t, libs, "out/soong/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
@@ -4479,14 +4507,11 @@
if filepath.Base(output) == base {
foundLibfooJar = true
buildRule := s.Output(output)
- actual := android.NormalizePathForTesting(buildRule.Input)
- if actual != bootDexJarPath {
- t.Errorf("Incorrect boot dex jar path '%s', expected '%s'", actual, bootDexJarPath)
- }
+ android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String())
}
}
if !foundLibfooJar {
- t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs")
+ t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().BuildDir(), s.AllOutputs()))
}
}
@@ -4528,8 +4553,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4635,8 +4660,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4702,8 +4727,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -4771,8 +4796,8 @@
`
ctx := testDexpreoptWithApexes(t, bp, "", transform)
- checkBootDexJarPath(t, ctx, "libfoo", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
- checkBootDexJarPath(t, ctx, "libbar", ".intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
+ checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar")
+ checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar")
// Make sure that the dex file from the prebuilt_apex contributes to the hiddenapi index file.
checkHiddenAPIIndexInputs(t, ctx, `
@@ -5066,7 +5091,7 @@
}
// JNI libraries including transitive deps are
for _, jni := range []string{"libjni", "libfoo"} {
- jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToPath()
+ jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_sdk_shared_apex10000").Module().(*cc.Module).OutputFile().RelativeToTop()
// ... embedded inside APK (jnilibs.zip)
ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
// ... and not directly inside the APEX
@@ -5878,9 +5903,10 @@
}
func TestCompatConfig(t *testing.T) {
- result := apexFixtureFactory.
- Extend(java.PrepareForTestWithPlatformCompatConfig).
- RunTestWithBp(t, `
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ java.PrepareForTestWithPlatformCompatConfig,
+ ).RunTestWithBp(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -6423,68 +6449,46 @@
func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) *android.TestContext {
t.Helper()
- bp += cc.GatherRequiredDepsForTest(android.Android)
- bp += java.GatherRequiredDepsForTest()
-
- fs := map[string][]byte{
- "a.java": nil,
- "a.jar": nil,
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "AndroidManifest.xml": nil,
+ fs := android.MockFS{
+ "a.java": nil,
+ "a.jar": nil,
+ "apex_manifest.json": nil,
+ "AndroidManifest.xml": nil,
"system/sepolicy/apex/myapex-file_contexts": nil,
"system/sepolicy/apex/some-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/some-non-updatable-apex-file_contexts": nil,
"system/sepolicy/apex/com.android.art.debug-file_contexts": nil,
"framework/aidl/a.aidl": nil,
}
- cc.GatherRequiredFilesForTest(fs)
- for k, v := range filesForSdkLibrary {
- fs[k] = v
- }
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
-
- ctx := android.NewTestArchContext(config)
- ctx.RegisterModuleType("apex", BundleFactory)
- ctx.RegisterModuleType("apex_key", ApexKeyFactory)
- ctx.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
- ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- ctx.PreArchMutators(android.RegisterComponentsMutator)
- android.RegisterPrebuiltMutators(ctx)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterHiddenApiSingletonComponents(ctx)
- ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
- ctx.PreDepsMutators(RegisterPreDepsMutators)
- ctx.PostDepsMutators(RegisterPostDepsMutators)
-
- ctx.Register()
-
- pathCtx := android.PathContextForTesting(config)
- dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
- transformDexpreoptConfig(dexpreoptConfig)
- dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
-
- // Make sure that any changes to these dexpreopt properties are mirrored in the corresponding
- // product variables.
- config.TestProductVariables.BootJars = dexpreoptConfig.BootJars
- config.TestProductVariables.UpdatableBootJars = dexpreoptConfig.UpdatableBootJars
-
- _, errs := ctx.ParseBlueprintsFiles("Android.bp")
- android.FailIfErrored(t, errs)
-
- _, errs = ctx.PrepareBuildActions(config)
- if errmsg == "" {
- android.FailIfErrored(t, errs)
- } else if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, errmsg, errs)
- } else {
- t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errmsg != "" {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
}
- return ctx
+ result := android.GroupFixturePreparers(
+ cc.PrepareForTestWithCcDefaultModules,
+ java.PrepareForTestWithHiddenApiBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ PrepareForTestWithApexBuildComponents,
+ android.FixtureModifyConfig(func(config android.Config) {
+ pathCtx := android.PathContextForTesting(config)
+ dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
+ transformDexpreoptConfig(dexpreoptConfig)
+ dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
+
+ // Make sure that any changes to these dexpreopt properties are mirrored in the corresponding
+ // product variables.
+ config.TestProductVariables.BootJars = dexpreoptConfig.BootJars
+ config.TestProductVariables.UpdatableBootJars = dexpreoptConfig.UpdatableBootJars
+ }),
+ fs.AddToFixture(),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, bp)
+
+ return result.TestContext
}
func TestUpdatable_should_set_min_sdk_version(t *testing.T) {
@@ -6658,45 +6662,33 @@
public_key: "testkey.avbpubkey",
private_key: "testkey.pem",
}`
- fs := map[string][]byte{
+ fs := android.MockFS{
"lib1/src/A.java": nil,
"lib2/src/B.java": nil,
"system/sepolicy/apex/myapex-file_contexts": nil,
}
- config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
- android.SetTestNeverallowRules(config, rules)
- updatableBootJars := make([]string, 0, len(apexBootJars))
- for _, apexBootJar := range apexBootJars {
- updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ errorHandler := android.FixtureExpectsNoErrors
+ if errmsg != "" {
+ errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(errmsg)
}
- config.TestProductVariables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
- ctx := android.NewTestArchContext(config)
- ctx.RegisterModuleType("apex", BundleFactory)
- ctx.RegisterModuleType("apex_key", ApexKeyFactory)
- ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
- cc.RegisterRequiredBuildComponentsForTest(ctx)
- java.RegisterRequiredBuildComponentsForTest(ctx)
- ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
- ctx.PreDepsMutators(RegisterPreDepsMutators)
- ctx.PostDepsMutators(RegisterPostDepsMutators)
- ctx.PostDepsMutators(android.RegisterNeverallowMutator)
-
- ctx.Register()
-
- _, errs := ctx.ParseBlueprintsFiles("Android.bp")
- android.FailIfErrored(t, errs)
-
- _, errs = ctx.PrepareBuildActions(config)
- if errmsg == "" {
- android.FailIfErrored(t, errs)
- } else if len(errs) > 0 {
- android.FailIfNoMatchingErrors(t, errmsg, errs)
- return
- } else {
- t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
- }
+ android.GroupFixturePreparers(
+ android.PrepareForTestWithAndroidBuildComponents,
+ java.PrepareForTestWithJavaBuildComponents,
+ PrepareForTestWithApexBuildComponents,
+ android.PrepareForTestWithNeverallowRules(rules),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ updatableBootJars := make([]string, 0, len(apexBootJars))
+ for _, apexBootJar := range apexBootJars {
+ updatableBootJars = append(updatableBootJars, "myapex:"+apexBootJar)
+ }
+ variables.UpdatableBootJars = android.CreateTestConfiguredJarList(updatableBootJars)
+ }),
+ fs.AddToFixture(),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTestWithBp(t, bp)
}
func TestApexPermittedPackagesRules(t *testing.T) {
@@ -6849,7 +6841,7 @@
`)
ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
- ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").RelativeToTop().Args["libFlags"], " ")
+ ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ")
mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
}
@@ -6907,7 +6899,7 @@
`)
ensureLinkedLibIs := func(mod, variant, linkedLib, expectedVariant string) {
- ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").RelativeToTop().Args["libFlags"], " ")
+ ldFlags := strings.Split(ctx.ModuleForTests(mod, variant).Rule("ld").Args["libFlags"], " ")
mylibLdFlags := android.FilterListPred(ldFlags, func(s string) bool { return strings.HasPrefix(s, linkedLib) })
android.AssertArrayString(t, "unexpected "+linkedLib+" link library for "+mod, []string{linkedLib + expectedVariant}, mylibLdFlags)
}
@@ -7428,7 +7420,7 @@
t.Errorf("AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v", entry.mkEntries)
}
cflags := entry.mkEntries.EntryMap["LOCAL_EXPORT_CFLAGS"]
- expected := "-D__STUBLIB_API__=1"
+ expected := "-D__STUBLIB_API__=10000"
if !android.InList(expected, cflags) {
t.Errorf("LOCAL_EXPORT_CFLAGS expected to have %q, but got %q", expected, cflags)
}
diff --git a/bazel/properties.go b/bazel/properties.go
index 25e110a..1763f2d 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "regexp"
"sort"
)
@@ -31,6 +32,8 @@
const BazelTargetModuleNamePrefix = "__bp2build__"
+var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
+
// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
// string replacement.
type Label struct {
@@ -225,3 +228,23 @@
panic(fmt.Errorf("Unknown arch: %s", arch))
}
}
+
+// TryVariableSubstitution, replace string substitution formatting within each string in slice with
+// Starlark string.format compatible tag for productVariable.
+func TryVariableSubstitutions(slice []string, productVariable string) ([]string, bool) {
+ ret := make([]string, 0, len(slice))
+ changesMade := false
+ for _, s := range slice {
+ newS, changed := TryVariableSubstitution(s, productVariable)
+ ret = append(ret, newS)
+ changesMade = changesMade || changed
+ }
+ return ret, changesMade
+}
+
+// TryVariableSubstitution, replace string substitution formatting within s with Starlark
+// string.format compatible tag for productVariable.
+func TryVariableSubstitution(s string, productVariable string) (string, bool) {
+ sub := productVariableSubstitutionPattern.ReplaceAllString(s, "{"+productVariable+"}")
+ return sub, s != sub
+}
diff --git a/bloaty/Android.bp b/bloaty/Android.bp
index b1f1e39..96cc1a5 100644
--- a/bloaty/Android.bp
+++ b/bloaty/Android.bp
@@ -1,3 +1,7 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
bootstrap_go_package {
name: "soong-bloaty",
pkgPath: "android/soong/bloaty",
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index d48d975..e93b3dc 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -568,6 +568,13 @@
func escapeString(s string) string {
s = strings.ReplaceAll(s, "\\", "\\\\")
+
+ // b/184026959: Reverse the application of some common control sequences.
+ // These must be generated literally in the BUILD file.
+ s = strings.ReplaceAll(s, "\t", "\\t")
+ s = strings.ReplaceAll(s, "\n", "\\n")
+ s = strings.ReplaceAll(s, "\r", "\\r")
+
return strings.ReplaceAll(s, "\"", "\\\"")
}
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index ad88e97..49897b3 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -241,6 +241,22 @@
string_prop = "a",
)`,
},
+ {
+ bp: `custom {
+ name: "control_characters",
+ string_list_prop: ["\t", "\n"],
+ string_prop: "a\t\n\r",
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTarget: `custom(
+ name = "control_characters",
+ string_list_prop = [
+ "\t",
+ "\n",
+ ],
+ string_prop = "a\t\n\r",
+)`,
+ },
}
dir := "."
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index b007033..9461739 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -209,6 +209,34 @@
)`,
},
},
+ {
+ description: "cc_object with product variable",
+ moduleTypeUnderTest: "cc_object",
+ moduleTypeUnderTestFactory: cc.ObjectFactory,
+ moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
+ blueprint: `cc_object {
+ name: "foo",
+ include_build_directory: false,
+ product_variables: {
+ platform_sdk_version: {
+ asflags: ["-DPLATFORM_SDK_VERSION=%d"],
+ },
+ },
+
+ bazel_module: { bp2build_available: true },
+}
+`,
+ expectedBazelTargets: []string{`cc_object(
+ name = "foo",
+ asflags = [
+ "-DPLATFORM_SDK_VERSION={Platform_sdk_version}",
+ ],
+ copts = [
+ "-fno-addrsig",
+ ],
+)`,
+ },
+ },
}
dir := "."
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 205c71f..76e75da 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -16,7 +16,6 @@
import (
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"reflect"
@@ -27,33 +26,11 @@
"android/soong/android"
)
-var buildDir string
-
-func setUp() {
- var err error
- buildDir, err = ioutil.TempDir("", "soong_cc_test")
- if err != nil {
- panic(err)
- }
-}
-
-func tearDown() {
- os.RemoveAll(buildDir)
-}
-
func TestMain(m *testing.M) {
- run := func() int {
- setUp()
- defer tearDown()
-
- return m.Run()
- }
-
- os.Exit(run())
+ os.Exit(m.Run())
}
-var ccFixtureFactory = android.NewFixtureFactory(
- &buildDir,
+var prepareForCcTest = android.GroupFixturePreparers(
PrepareForTestWithCcIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
@@ -62,62 +39,62 @@
}),
)
-// testCcWithConfig runs tests using the ccFixtureFactory
+// testCcWithConfig runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
t.Helper()
- result := ccFixtureFactory.RunTestWithConfig(t, config)
+ result := prepareForCcTest.RunTestWithConfig(t, config)
return result.TestContext
}
-// testCc runs tests using the ccFixtureFactory
+// testCc runs tests using the prepareForCcTest
//
-// Do not add any new usages of this, instead use the ccFixtureFactory directly as it makes it much
+// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
// easier to customize the test behavior.
//
// If it is necessary to customize the behavior of an existing test that uses this then please first
-// convert the test to using ccFixtureFactory first and then in a following change add the
+// convert the test to using prepareForCcTest first and then in a following change add the
// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
// that it did not change the test behavior unexpectedly.
//
// deprecated
func testCc(t *testing.T, bp string) *android.TestContext {
t.Helper()
- result := ccFixtureFactory.RunTestWithBp(t, bp)
+ result := prepareForCcTest.RunTestWithBp(t, bp)
return result.TestContext
}
-// testCcNoVndk runs tests using the ccFixtureFactory
+// testCcNoVndk runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
t.Helper()
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
return testCcWithConfig(t, config)
}
-// testCcNoProductVndk runs tests using the ccFixtureFactory
+// testCcNoProductVndk runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
t.Helper()
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
return testCcWithConfig(t, config)
}
-// testCcErrorWithConfig runs tests using the ccFixtureFactory
+// testCcErrorWithConfig runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
@@ -125,33 +102,33 @@
func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
t.Helper()
- ccFixtureFactory.Extend().
+ prepareForCcTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
RunTestWithConfig(t, config)
}
-// testCcError runs tests using the ccFixtureFactory
+// testCcError runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcError(t *testing.T, pattern string, bp string) {
t.Helper()
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
testCcErrorWithConfig(t, pattern, config)
return
}
-// testCcErrorProductVndk runs tests using the ccFixtureFactory
+// testCcErrorProductVndk runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
//
// deprecated
func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
t.Helper()
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -189,7 +166,10 @@
},
}`
- result := ccFixtureFactory.Extend(PrepareForTestOnFuchsia).RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ PrepareForTestOnFuchsia,
+ ).RunTestWithBp(t, bp)
rt := false
fb := false
@@ -225,7 +205,10 @@
},
}`
- result := ccFixtureFactory.Extend(PrepareForTestOnFuchsia).RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ PrepareForTestOnFuchsia,
+ ).RunTestWithBp(t, bp)
ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
var objs []string
for _, o := range ld.Inputs {
@@ -470,7 +453,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -491,7 +474,7 @@
// Check VNDK snapshot output.
snapshotDir := "vndk-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
"arm64", "armv8-a"))
@@ -592,7 +575,7 @@
name: "llndk.libraries.txt",
insert_vndk_version: true,
}`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := testCcWithConfig(t, config)
@@ -642,7 +625,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
@@ -669,7 +652,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
@@ -720,7 +703,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
@@ -1345,7 +1328,7 @@
nocrt: true,
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -1790,7 +1773,7 @@
nocrt: true,
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -2117,7 +2100,7 @@
}
`
- ctx := ccFixtureFactory.RunTestWithBp(t, bp).TestContext
+ ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
@@ -2345,7 +2328,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
// native:vndk
@@ -2689,9 +2672,11 @@
expected := []string{
"android_vendor.VER_arm64_armv8-a_shared_1",
"android_vendor.VER_arm64_armv8-a_shared_2",
+ "android_vendor.VER_arm64_armv8-a_shared_current",
"android_vendor.VER_arm64_armv8-a_shared",
"android_vendor.VER_arm_armv7-a-neon_shared_1",
"android_vendor.VER_arm_armv7-a-neon_shared_2",
+ "android_vendor.VER_arm_armv7-a-neon_shared_current",
"android_vendor.VER_arm_armv7-a-neon_shared",
}
checkEquals(t, "variants for llndk stubs", expected, actual)
@@ -3137,7 +3122,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
@@ -3191,10 +3176,12 @@
"android_arm64_armv8-a_shared_1",
"android_arm64_armv8-a_shared_2",
"android_arm64_armv8-a_shared_3",
+ "android_arm64_armv8-a_shared_current",
"android_arm_armv7-a-neon_shared",
"android_arm_armv7-a-neon_shared_1",
"android_arm_armv7-a-neon_shared_2",
"android_arm_armv7-a-neon_shared_3",
+ "android_arm_armv7-a-neon_shared_current",
}
variantsMismatch := false
if len(variants) != len(expectedVariants) {
@@ -3453,7 +3440,8 @@
}
`
- result := ccFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
android.PrepareForTestWithVariables,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
@@ -3480,7 +3468,8 @@
}
`
- result := ccFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
android.PrepareForTestWithAllowMissingDependencies,
).RunTestWithBp(t, bp)
@@ -3532,7 +3521,7 @@
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
ctx := testCcWithConfig(t, config)
hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
@@ -3823,7 +3812,10 @@
func TestSanitizeMemtagHeap(t *testing.T) {
variant := "android_arm64_armv8-a"
- result := ccFixtureFactory.Extend(prepareForTestWithMemtagHeap).RunTest(t)
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
+ prepareForTestWithMemtagHeap,
+ ).RunTest(t)
ctx := result.TestContext
checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
@@ -3878,7 +3870,8 @@
func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
variant := "android_arm64_armv8-a"
- result := ccFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
prepareForTestWithMemtagHeap,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.SanitizeDevice = []string{"memtag_heap"}
@@ -3938,7 +3931,8 @@
func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
variant := "android_arm64_armv8-a"
- result := ccFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForCcTest,
prepareForTestWithMemtagHeap,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.SanitizeDevice = []string{"memtag_heap"}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
index fa0c6f2..45b343b 100644
--- a/cc/genrule_test.go
+++ b/cc/genrule_test.go
@@ -52,7 +52,7 @@
},
}
`
- config := android.TestArchConfig(buildDir, nil, bp, fs)
+ config := android.TestArchConfig(t.TempDir(), nil, bp, fs)
ctx := testGenruleContext(config)
diff --git a/cc/library.go b/cc/library.go
index 28e4f61..091acfe 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -65,7 +65,8 @@
// symbols that are exported for stubs variant of this library.
Symbol_file *string `android:"path"`
- // List versions to generate stubs libs for.
+ // List versions to generate stubs libs for. The version name "current" is always
+ // implicitly added.
Versions []string
}
@@ -171,6 +172,8 @@
// This variant is a stubs lib
BuildStubs bool `blueprint:"mutated"`
+ // This variant is the latest version
+ IsLatestVersion bool `blueprint:"mutated"`
// Version of the stubs lib
StubsVersion string `blueprint:"mutated"`
// List of all stubs versions associated with an implementation lib
@@ -504,12 +507,11 @@
return
}
isLibcxx := strings.HasPrefix(dir, "external/libcxx/include")
- j := 0
- for i, header := range glob {
+ for _, header := range glob {
if isLibcxx {
// Glob all files under this special directory, because of C++ headers with no
// extension.
- if !strings.HasSuffix(header, "/") {
+ if strings.HasSuffix(header, "/") {
continue
}
} else {
@@ -525,12 +527,8 @@
continue
}
}
- if i != j {
- glob[j] = glob[i]
- }
- j++
+ ret = append(ret, android.PathForSource(ctx, header))
}
- glob = glob[:j]
}
// Collect generated headers
@@ -780,7 +778,7 @@
type versionedInterface interface {
buildStubs() bool
- setBuildStubs()
+ setBuildStubs(isLatest bool)
hasStubsVariants() bool
setStubsVersion(string)
stubsVersion() string
@@ -1498,7 +1496,7 @@
if ctx.isVndk() && !ctx.IsVndkExt() {
return
}
- } else if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.directlyInAnyApex() {
+ } else if library.hasStubsVariants() && !ctx.Host() && ctx.directlyInAnyApex() {
// Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory.
// The original path becomes a symlink to the corresponding file in the
// runtime APEX.
@@ -1614,11 +1612,29 @@
}
func (library *libraryDecorator) hasStubsVariants() bool {
- return len(library.Properties.Stubs.Versions) > 0
+ // Just having stubs.symbol_file is enough to create a stub variant. In that case
+ // the stub for the future API level is created.
+ return library.Properties.Stubs.Symbol_file != nil ||
+ len(library.Properties.Stubs.Versions) > 0
}
func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
- return library.Properties.Stubs.Versions
+ if !library.hasStubsVariants() {
+ return nil
+ }
+
+ // Future API level is implicitly added if there isn't
+ vers := library.Properties.Stubs.Versions
+ if inList(android.FutureApiLevel.String(), vers) {
+ return vers
+ }
+ // In some cases, people use the raw value "10000" in the versions property.
+ // We shouldn't add the future API level in that case, otherwise there will
+ // be two identical versions.
+ if inList(strconv.Itoa(android.FutureApiLevel.FinalOrFutureInt()), vers) {
+ return vers
+ }
+ return append(vers, android.FutureApiLevel.String())
}
func (library *libraryDecorator) setStubsVersion(version string) {
@@ -1629,8 +1645,9 @@
return library.MutatedProperties.StubsVersion
}
-func (library *libraryDecorator) setBuildStubs() {
+func (library *libraryDecorator) setBuildStubs(isLatest bool) {
library.MutatedProperties.BuildStubs = true
+ library.MutatedProperties.IsLatestVersion = isLatest
}
func (library *libraryDecorator) setAllStubsVersions(versions []string) {
@@ -1642,8 +1659,7 @@
}
func (library *libraryDecorator) isLatestStubVersion() bool {
- versions := library.Properties.Stubs.Versions
- return versions[len(versions)-1] == library.stubsVersion()
+ return library.MutatedProperties.IsLatestVersion
}
func (library *libraryDecorator) availableFor(what string) bool {
@@ -1886,7 +1902,8 @@
c.stl = nil
c.Properties.PreventInstall = true
lib := moduleLibraryInterface(m)
- lib.setBuildStubs()
+ isLatest := i == (len(versions) - 1)
+ lib.setBuildStubs(isLatest)
if variants[i] != "" {
// A non-LLNDK stubs module is hidden from make and has a dependency from the
diff --git a/cc/library_test.go b/cc/library_test.go
index 49838b4..7975275 100644
--- a/cc/library_test.go
+++ b/cc/library_test.go
@@ -199,7 +199,7 @@
},
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
ctx := testCcWithConfig(t, config)
@@ -222,7 +222,7 @@
},
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.Platform_version_active_codenames = []string{"R"}
testCcErrorWithConfig(t, `"libfoo" .*: versions: not sorted`, config)
}
diff --git a/cc/linker.go b/cc/linker.go
index 6d0d416..21281d2 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -599,21 +599,20 @@
_ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh")
genSortedBssSymbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols",
blueprint.RuleParams{
- Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}",
- CommandDeps: []string{"$genSortedBssSymbolsPath", "${crossCompile}nm"},
+ Command: "CLANG_BIN=${clangBin} $genSortedBssSymbolsPath ${in} ${out}",
+ CommandDeps: []string{"$genSortedBssSymbolsPath", "${clangBin}/llvm-nm"},
},
- "crossCompile")
+ "clangBin")
)
func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string {
- crossCompile := gccCmd(flags.toolchain, "")
ctx.Build(pctx, android.BuildParams{
Rule: genSortedBssSymbols,
Description: "generate bss symbol order " + symbolOrderingFile.Base(),
Output: symbolOrderingFile,
Input: in,
Args: map[string]string{
- "crossCompile": crossCompile,
+ "clangBin": "${config.ClangBin}",
},
})
return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String()
diff --git a/cc/object.go b/cc/object.go
index abc3e83..ea8d7d3 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -53,8 +53,17 @@
}
func (handler *objectBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
- // TODO(b/181794963): restore mixed builds once cc_object incompatibility resolved
- return false
+ bazelCtx := ctx.Config().BazelContext
+ objPaths, ok := bazelCtx.GetOutputFiles(label, ctx.Arch().ArchType)
+ if ok {
+ if len(objPaths) != 1 {
+ ctx.ModuleErrorf("expected exactly one object file for '%s', but got %s", label, objPaths)
+ return false
+ }
+
+ handler.module.outputFile = android.OptionalPathForPath(android.PathForBazelOut(ctx, objPaths[0]))
+ }
+ return ok
}
type ObjectLinkerProperties struct {
@@ -106,6 +115,7 @@
Srcs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
+ Asflags []string
Local_include_dirs []string
}
@@ -149,6 +159,7 @@
var copts bazel.StringListAttribute
var srcs bazel.LabelListAttribute
var localIncludeDirs []string
+ var asFlags []string
for _, props := range m.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
copts.Value = baseCompilerProps.Cflags
@@ -174,6 +185,23 @@
}
}
+ productVariableProps := android.ProductVariableProperties(ctx)
+ if props, exists := productVariableProps["Asflags"]; exists {
+ // TODO(b/183595873): consider deduplicating handling of product variable properties
+ for _, prop := range props {
+ flags, ok := prop.Property.([]string)
+ if !ok {
+ ctx.ModuleErrorf("Could not convert product variable asflag property")
+ return
+ }
+ // TODO(b/183595873) handle other product variable usages -- as selects?
+ if newFlags, subbed := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable); subbed {
+ asFlags = append(asFlags, newFlags...)
+ }
+ }
+ }
+ // TODO(b/183595872) warn/error if we're not handling product variables
+
for arch, p := range m.GetArchProperties(&BaseCompilerProperties{}) {
if cProps, ok := p.(*BaseCompilerProperties); ok {
srcs.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcExcludes(ctx, cProps.Srcs, cProps.Exclude_srcs))
@@ -185,6 +213,7 @@
Srcs: srcs,
Deps: deps,
Copts: copts,
+ Asflags: asFlags,
Local_include_dirs: localIncludeDirs,
}
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index f72371a..fa6dd87 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -22,14 +22,17 @@
"github.com/google/blueprint"
)
-var prebuiltFixtureFactory = ccFixtureFactory.Extend(
+var prepareForPrebuiltTest = android.GroupFixturePreparers(
+ prepareForCcTest,
android.PrepareForTestWithAndroidMk,
)
func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext {
- result := prebuiltFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForPrebuiltTest,
fs.AddToFixture(),
- ).Extend(handlers...).RunTestWithBp(t, bp)
+ android.GroupFixturePreparers(handlers...),
+ ).RunTestWithBp(t, bp)
return result.TestContext
}
diff --git a/cc/proto_test.go b/cc/proto_test.go
index 3d636fb..b9c89c7 100644
--- a/cc/proto_test.go
+++ b/cc/proto_test.go
@@ -61,7 +61,7 @@
t.Errorf("expected %q in %q", w, cmd)
}
- foobarPath := foobar.Module().(android.HostToolProvider).HostToolPath().RelativeToPath().String()
+ foobarPath := foobar.Module().(android.HostToolProvider).HostToolPath().RelativeToTop().String()
if w := "--plugin=protoc-gen-foobar=" + foobarPath; !strings.Contains(cmd, w) {
t.Errorf("expected %q in %q", w, cmd)
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 0833277..8d13ceb 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -86,7 +86,7 @@
symbol_file: "",
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := testCcWithConfig(t, config)
@@ -94,7 +94,7 @@
// Check Vendor snapshot output.
snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
var jsonFiles []string
@@ -212,7 +212,7 @@
nocrt: true,
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
config.TestProductVariables.DirectedVendorSnapshot = true
@@ -224,7 +224,7 @@
// Check Vendor snapshot output.
snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
var includeJsonFiles []string
@@ -516,7 +516,7 @@
"vndk/libvndk.so": nil,
}
- config := TestConfig(buildDir, android.Android, nil, "", mockFS)
+ config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := CreateTestContext(config)
@@ -628,7 +628,7 @@
},
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := testCcWithConfig(t, config)
@@ -707,7 +707,7 @@
"device/vendor.cpp": nil,
}
- config := TestConfig(buildDir, android.Android, nil, "", mockFS)
+ config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := CreateTestContext(config)
@@ -730,7 +730,7 @@
// Verify the content of the vendor snapshot.
snapshotDir := "vendor-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
var includeJsonFiles []string
@@ -799,7 +799,7 @@
"device/vendor.cpp": nil,
}
- config := TestConfig(buildDir, android.Android, nil, "", mockFS)
+ config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := CreateTestContext(config)
@@ -873,7 +873,7 @@
recovery_available: true,
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := testCcWithConfig(t, config)
@@ -881,7 +881,7 @@
// Check Recovery snapshot output.
snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
var jsonFiles []string
@@ -991,7 +991,7 @@
"device/recovery.cpp": nil,
}
- config := TestConfig(buildDir, android.Android, nil, "", mockFS)
+ config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := CreateTestContext(config)
@@ -1014,7 +1014,7 @@
// Verify the content of the recovery snapshot.
snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
var includeJsonFiles []string
@@ -1091,7 +1091,7 @@
nocrt: true,
}
`
- config := TestConfig(buildDir, android.Android, nil, bp, nil)
+ config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
@@ -1104,7 +1104,7 @@
// Check recovery snapshot output.
snapshotDir := "recovery-snapshot"
- snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
+ snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
var includeJsonFiles []string
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index fcc80a9..7bd0868 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -387,6 +387,14 @@
}
defer in.Close()
+ // Remove the target before copying. In most cases the file won't exist, but if there are
+ // duplicate copy rules for a file and the source file was read-only the second copy could
+ // fail.
+ err = os.Remove(to)
+ if err != nil && !os.IsNotExist(err) {
+ return err
+ }
+
out, err := os.Create(to)
if err != nil {
return err
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index 20d9622..dbbc1d8 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -43,6 +43,10 @@
// Total size of the logical partition
Size *string
+ // List of partitions for default group. Default group has no size limit and automatically
+ // minimized when creating an image.
+ Default_group []partitionProperties
+
// List of groups. A group defines a fixed sized region. It can host one or more logical
// partitions and their total size is limited by the size of the group they are in.
Groups []groupProperties
@@ -52,7 +56,7 @@
}
type groupProperties struct {
- // Name of the partition group
+ // Name of the partition group. Can't be "default"; use default_group instead.
Name *string
// Size of the partition group
@@ -92,8 +96,9 @@
// Sparse the filesystem images and calculate their sizes
sparseImages := make(map[string]android.OutputPath)
sparseImageSizes := make(map[string]android.OutputPath)
- for _, group := range l.properties.Groups {
- for _, part := range group.Partitions {
+
+ sparsePartitions := func(partitions []partitionProperties) {
+ for _, part := range partitions {
sparseImg, sizeTxt := sparseFilesystem(ctx, part, builder)
pName := proptools.String(part.Name)
sparseImages[pName] = sparseImg
@@ -101,6 +106,12 @@
}
}
+ for _, group := range l.properties.Groups {
+ sparsePartitions(group.Partitions)
+ }
+
+ sparsePartitions(l.properties.Default_group)
+
cmd := builder.Command().BuiltTool("lpmake")
size := proptools.String(l.properties.Size)
@@ -123,10 +134,32 @@
groupNames := make(map[string]bool)
partitionNames := make(map[string]bool)
+ addPartitionsToGroup := func(partitions []partitionProperties, gName string) {
+ for _, part := range partitions {
+ pName := proptools.String(part.Name)
+ if pName == "" {
+ ctx.PropertyErrorf("groups.partitions.name", "must be set")
+ }
+ if _, ok := partitionNames[pName]; ok {
+ ctx.PropertyErrorf("groups.partitions.name", "already exists")
+ } else {
+ partitionNames[pName] = true
+ }
+ // Get size of the partition by reading the -size.txt file
+ pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
+ cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
+ cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
+ }
+ }
+
+ addPartitionsToGroup(l.properties.Default_group, "default")
+
for _, group := range l.properties.Groups {
gName := proptools.String(group.Name)
if gName == "" {
ctx.PropertyErrorf("groups.name", "must be set")
+ } else if gName == "default" {
+ ctx.PropertyErrorf("groups.name", `can't use "default" as a group name. Use default_group instead`)
}
if _, ok := groupNames[gName]; ok {
ctx.PropertyErrorf("group.name", "already exists")
@@ -142,21 +175,7 @@
}
cmd.FlagWithArg("--group=", gName+":"+gSize)
- for _, part := range group.Partitions {
- pName := proptools.String(part.Name)
- if pName == "" {
- ctx.PropertyErrorf("groups.partitions.name", "must be set")
- }
- if _, ok := partitionNames[pName]; ok {
- ctx.PropertyErrorf("groups.partitions.name", "already exists")
- } else {
- partitionNames[pName] = true
- }
- // Get size of the partition by reading the -size.txt file
- pSize := fmt.Sprintf("$(cat %s)", sparseImageSizes[pName])
- cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
- cmd.FlagWithInput("--image="+pName+"=", sparseImages[pName])
- }
+ addPartitionsToGroup(group.Partitions, gName)
}
l.output = android.PathForModuleOut(ctx, l.installFileName()).OutputPath
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 2ee456d..3f1e9f3 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -670,7 +670,8 @@
cmd: "cat $(in) > $(out)",
}
`
- result := prepareForGenRuleTest.Extend(
+ result := android.GroupFixturePreparers(
+ prepareForGenRuleTest,
android.FixtureModifyConfigAndContext(
func(config android.Config, ctx *android.TestContext) {
config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
diff --git a/java/Android.bp b/java/Android.bp
index b6c14ac..8334b85 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -50,6 +50,7 @@
"kotlin.go",
"lint.go",
"legacy_core_platform_api_usage.go",
+ "platform_bootclasspath.go",
"platform_compat_config.go",
"plugin.go",
"prebuilt_apis.go",
@@ -79,6 +80,7 @@
"java_test.go",
"jdeps_test.go",
"kotlin_test.go",
+ "platform_bootclasspath_test.go",
"platform_compat_config_test.go",
"plugin_test.go",
"rro_test.go",
diff --git a/java/app_test.go b/java/app_test.go
index 825ad20..a99ac62 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -652,7 +652,7 @@
} else {
aapt2link = m.Output("package-res.apk")
}
- aapt2link = aapt2link.RelativeToTop()
+ aapt2link = aapt2link
aapt2Flags := aapt2link.Args["flags"]
if test.assetFlag != "" {
android.AssertStringDoesContain(t, "asset flag", aapt2Flags, test.assetFlag)
@@ -1993,14 +1993,14 @@
`)
// Verify baz, which depends on the overridden module foo, has the correct classpath javac arg.
- javac := ctx.ModuleForTests("baz", "android_common").Rule("javac").RelativeToTop()
+ javac := ctx.ModuleForTests("baz", "android_common").Rule("javac")
fooTurbine := "out/soong/.intermediates/foo/android_common/turbine-combined/foo.jar"
if !strings.Contains(javac.Args["classpath"], fooTurbine) {
t.Errorf("baz classpath %v does not contain %q", javac.Args["classpath"], fooTurbine)
}
// Verify qux, which depends on the overriding module bar, has the correct classpath javac arg.
- javac = ctx.ModuleForTests("qux", "android_common").Rule("javac").RelativeToTop()
+ javac = ctx.ModuleForTests("qux", "android_common").Rule("javac")
barTurbine := "out/soong/.intermediates/foo/android_common_bar/turbine-combined/foo.jar"
if !strings.Contains(javac.Args["classpath"], barTurbine) {
t.Errorf("qux classpath %v does not contain %q", javac.Args["classpath"], barTurbine)
@@ -2077,7 +2077,7 @@
}
// Check if javac classpath has the correct jar file path. This checks instrumentation_for overrides.
- javac := variant.Rule("javac").RelativeToTop()
+ javac := variant.Rule("javac")
turbine := filepath.Join("out", "soong", ".intermediates", "foo", expected.targetVariant, "turbine-combined", "foo.jar")
if !strings.Contains(javac.Args["classpath"], turbine) {
t.Errorf("classpath %q does not contain %q", javac.Args["classpath"], turbine)
@@ -2151,7 +2151,7 @@
for _, test := range testCases {
variant := ctx.ModuleForTests(test.moduleName, test.variantName)
- params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml").RelativeToTop()
+ params := variant.MaybeOutput("test_config_fixer/AndroidTest.xml")
if len(test.expectedFlags) > 0 {
if params.Rule == nil {
@@ -2647,14 +2647,14 @@
t.Errorf("GENRULE_NOTICE is missing from notice files, %q", noticeInputs)
}
// aapt2 flags should include -A <NOTICE dir> so that its contents are put in the APK's /assets.
- res := foo.Output("package-res.apk").RelativeToTop()
+ res := foo.Output("package-res.apk")
aapt2Flags := res.Args["flags"]
e := "-A out/soong/.intermediates/foo/android_common/NOTICE"
android.AssertStringDoesContain(t, "expected.apkPath", aapt2Flags, e)
// bar has NOTICE files to process, but embed_notices is not set.
bar := result.ModuleForTests("bar", "android_common")
- res = bar.Output("package-res.apk").RelativeToTop()
+ res = bar.Output("package-res.apk")
aapt2Flags = res.Args["flags"]
e = "-A out/soong/.intermediates/bar/android_common/NOTICE"
android.AssertStringDoesNotContain(t, "bar shouldn't have the asset dir flag for NOTICE", aapt2Flags, e)
diff --git a/java/droiddoc.go b/java/droiddoc.go
index a8e2b0e..f7595b1 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -226,11 +226,8 @@
srcJars android.Paths
srcFiles android.Paths
sourcepaths android.Paths
- argFiles android.Paths
implicits android.Paths
- args []string
-
docZip android.WritablePath
stubsSrcJar android.WritablePath
}
@@ -480,15 +477,20 @@
j.sourcepaths = android.PathsForModuleSrc(ctx, []string{"."})
}
- j.argFiles = android.PathsForModuleSrc(ctx, j.properties.Arg_files)
+ return deps
+}
+
+func (j *Javadoc) expandArgs(ctx android.ModuleContext, cmd *android.RuleBuilderCommand) {
+ var argFiles android.Paths
argFilesMap := map[string]string{}
argFileLabels := []string{}
for _, label := range j.properties.Arg_files {
var paths = android.PathsForModuleSrc(ctx, []string{label})
if _, exists := argFilesMap[label]; !exists {
- argFilesMap[label] = strings.Join(paths.Strings(), " ")
+ argFilesMap[label] = strings.Join(cmd.PathsForInputs(paths), " ")
argFileLabels = append(argFileLabels, label)
+ argFiles = append(argFiles, paths...)
} else {
ctx.ModuleErrorf("multiple arg_files for %q, %q and %q",
label, argFilesMap[label], paths)
@@ -508,7 +510,7 @@
}
for _, flag := range flags {
- args, err := android.Expand(flag, func(name string) (string, error) {
+ expanded, err := android.Expand(flag, func(name string) (string, error) {
if strings.HasPrefix(name, "location ") {
label := strings.TrimSpace(strings.TrimPrefix(name, "location "))
if paths, ok := argFilesMap[label]; ok {
@@ -526,10 +528,10 @@
if err != nil {
ctx.PropertyErrorf(argsPropertyName, "%s", err.Error())
}
- j.args = append(j.args, args)
+ cmd.Flag(expanded)
}
- return deps
+ cmd.Implicits(argFiles)
}
func (j *Javadoc) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -563,6 +565,8 @@
Flag("-XDignore.symbol.file").
Flag("-Xdoclint:none")
+ j.expandArgs(ctx, cmd)
+
rule.Command().
BuiltTool("soong_zip").
Flag("-write_if_changed").
@@ -821,7 +825,7 @@
deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
}
- cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
+ d.expandArgs(ctx, cmd)
if d.properties.Compat_config != nil {
compatConfig := android.PathForModuleSrc(ctx, String(d.properties.Compat_config))
diff --git a/java/droiddoc_test.go b/java/droiddoc_test.go
index 2b324ae..8d1f591 100644
--- a/java/droiddoc_test.go
+++ b/java/droiddoc_test.go
@@ -80,7 +80,7 @@
barStubsOutput := barStubsOutputs[0]
barDoc := ctx.ModuleForTests("bar-doc", "android_common")
- javaDoc := barDoc.Rule("javadoc").RelativeToTop()
+ javaDoc := barDoc.Rule("javadoc")
if g, w := android.PathsRelativeToTop(javaDoc.Implicits), android.PathRelativeToTop(barStubsOutput); !inList(w, g) {
t.Errorf("implicits of bar-doc must contain %q, but was %q.", w, g)
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index e453e62..d7a0668 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -284,7 +284,7 @@
cmd.Flag("--include-annotations")
validatingNullability :=
- android.InList("--validate-nullability-from-merged-stubs", d.Javadoc.args) ||
+ strings.Contains(String(d.Javadoc.properties.Args), "--validate-nullability-from-merged-stubs") ||
String(d.properties.Validate_nullability_from_list) != ""
migratingNullability := String(d.properties.Previous_api) != ""
@@ -360,7 +360,16 @@
ctx.VisitDirectDepsWithTag(metalavaAPILevelsAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
for _, dep := range t.deps {
- if strings.HasSuffix(dep.String(), filename) {
+ if dep.Base() == filename {
+ cmd.Implicit(dep)
+ }
+ if filename != "android.jar" && dep.Base() == "android.jar" {
+ // Metalava implicitly searches these patterns:
+ // prebuilts/tools/common/api-versions/android-%/android.jar
+ // prebuilts/sdk/%/public/android.jar
+ // Add android.jar files from the api_levels_annotations_dirs directories to try
+ // to satisfy these patterns. If Metalava can't find a match for an API level
+ // between 1 and 28 in at least one pattern it will fail.
cmd.Implicit(dep)
}
}
@@ -473,7 +482,7 @@
rule := android.NewRuleBuilder(pctx, ctx)
- sandbox := proptools.Bool(d.Javadoc.properties.Sandbox)
+ sandbox := proptools.BoolDefault(d.Javadoc.properties.Sandbox, true)
if sandbox {
rule.Sbox(android.PathForModuleOut(ctx, "metalava"),
android.PathForModuleOut(ctx, "metalava.sbox.textproto")).
@@ -509,14 +518,8 @@
d.inclusionAnnotationsFlags(ctx, cmd)
d.apiLevelsAnnotationsFlags(ctx, cmd)
- if android.InList("--generate-documentation", d.Javadoc.args) {
- // Currently Metalava have the ability to invoke Javadoc in a separate process.
- // Pass "-nodocs" to suppress the Javadoc invocation when Metalava receives
- // "--generate-documentation" arg. This is not needed when Metalava removes this feature.
- d.Javadoc.args = append(d.Javadoc.args, "-nodocs")
- }
+ d.expandArgs(ctx, cmd)
- cmd.Flag(strings.Join(d.Javadoc.args, " ")).Implicits(d.Javadoc.argFiles)
for _, o := range d.Javadoc.properties.Out {
cmd.ImplicitOutput(android.PathForModuleGen(ctx, o))
}
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index c6db979..f8125fb 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -34,6 +34,7 @@
srcs: ["bar-doc/a.java"],
api_levels_annotations_dirs: ["droiddoc-templates-sdk"],
api_levels_annotations_enabled: true,
+ sandbox: false,
}
droidstubs {
@@ -43,6 +44,7 @@
api_levels_annotations_dirs: ["droiddoc-templates-sdk"],
api_levels_annotations_enabled: true,
api_levels_jar_filename: "android.other.jar",
+ sandbox: false,
}
`,
map[string][]byte{
@@ -81,10 +83,19 @@
func TestDroidstubsSandbox(t *testing.T) {
ctx, _ := testJavaWithFS(t, `
+ genrule {
+ name: "foo",
+ out: ["foo.txt"],
+ cmd: "touch $(out)",
+ }
+
droidstubs {
name: "bar-stubs",
srcs: ["bar-doc/a.java"],
sandbox: true,
+
+ args: "--reference $(location :foo)",
+ arg_files: [":foo"],
}
`,
map[string][]byte{
@@ -96,6 +107,11 @@
if g, w := metalava.Inputs.Strings(), []string{"bar-doc/a.java"}; !reflect.DeepEqual(w, g) {
t.Errorf("Expected inputs %q, got %q", w, g)
}
+
+ manifest := android.RuleBuilderSboxProtoForTests(t, m.Output("metalava.sbox.textproto"))
+ if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) {
+ t.Errorf("Expected command to contain %q, got %q", w, g)
+ }
}
func TestDroidstubsWithSystemModules(t *testing.T) {
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index d6c6a2d..5c449e5 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -39,7 +39,8 @@
prepareForJavaTest, PrepareForTestWithHiddenApiBuildComponents)
func TestHiddenAPISingleton(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -50,13 +51,14 @@
`)
hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi").RelativeToTop()
+ hiddenapiRule := hiddenAPI.Rule("hiddenapi")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPIIndexSingleton(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("bar"),
fixtureSetBootJarsProductVariable("platform:foo", "platform:bar"),
@@ -115,7 +117,8 @@
" replaced by the prebuilt module \"prebuilt_foo\" but unfortunately it does not provide a" +
" suitable boot dex jar"
- hiddenApiFixtureFactory.Extend(
+ android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)).
RunTestWithBp(t, `
@@ -134,7 +137,8 @@
}
func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_import {
@@ -145,13 +149,14 @@
`)
hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi").RelativeToTop()
+ hiddenapiRule := hiddenAPI.Rule("hiddenapi")
want := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, want)
}
func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -169,7 +174,7 @@
`)
hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi").RelativeToTop()
+ hiddenapiRule := hiddenAPI.Rule("hiddenapi")
fromSourceJarArg := "--boot-dex=out/soong/.intermediates/foo/android_common/aligned/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, fromSourceJarArg)
@@ -178,7 +183,8 @@
}
func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
).RunTestWithBp(t, `
java_library {
@@ -196,7 +202,7 @@
`)
hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi").RelativeToTop()
+ hiddenapiRule := hiddenAPI.Rule("hiddenapi")
prebuiltJarArg := "--boot-dex=out/soong/.intermediates/prebuilt_foo/android_common/dex/foo.jar"
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, prebuiltJarArg)
@@ -236,7 +242,8 @@
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
tc.preparer,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(tc.unbundledBuild)
@@ -244,7 +251,7 @@
).RunTest(t)
hiddenAPI := result.SingletonForTests("hiddenapi")
- hiddenapiRule := hiddenAPI.Rule("hiddenapi").RelativeToTop()
+ hiddenapiRule := hiddenAPI.Rule("hiddenapi")
wantPublicStubs := "--public-stub-classpath=" + generateSdkDexPath(tc.publicStub, tc.unbundledBuild)
android.AssertStringDoesContain(t, "hiddenapi command", hiddenapiRule.RuleParams.Command, wantPublicStubs)
@@ -286,7 +293,8 @@
// Where to find the prebuilt hiddenapi files:
prebuiltHiddenApiDir := "path/to/prebuilt/hiddenapi"
- result := hiddenApiFixtureFactory.Extend(
+ result := android.GroupFixturePreparers(
+ hiddenApiFixtureFactory,
fixtureSetBootJarsProductVariable("platform:foo"),
fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir),
).RunTestWithBp(t, `
@@ -307,7 +315,7 @@
cpRule := hiddenAPI.Rule("Cp")
actualCpInput := cpRule.BuildParams.Input
actualCpOutput := cpRule.BuildParams.Output
- encodeDexRule := foo.Rule("hiddenAPIEncodeDex").RelativeToTop()
+ encodeDexRule := foo.Rule("hiddenAPIEncodeDex")
actualFlagsCsv := encodeDexRule.BuildParams.Args["flagsCsv"]
android.AssertPathRelativeToTopEquals(t, "hiddenapi cp rule input", expectedCpInput, actualCpInput)
diff --git a/java/java.go b/java/java.go
index 9786947..70ad879 100644
--- a/java/java.go
+++ b/java/java.go
@@ -33,12 +33,12 @@
)
func init() {
- RegisterJavaBuildComponents(android.InitRegistrationContext)
+ registerJavaBuildComponents(android.InitRegistrationContext)
RegisterJavaSdkMemberTypes()
}
-func RegisterJavaBuildComponents(ctx android.RegistrationContext) {
+func registerJavaBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_defaults", DefaultsFactory)
ctx.RegisterModuleType("java_library", LibraryFactory)
diff --git a/java/java_test.go b/java/java_test.go
index 1d1a796..fdf7579 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -74,23 +74,6 @@
return result.TestContext, result.Config
}
-// testJavaErrorWithConfig is a legacy way of running tests of java modules that expect errors.
-//
-// See testJava for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testJavaErrorWithConfig(t *testing.T, pattern string, config android.Config) (*android.TestContext, android.Config) {
- t.Helper()
- // This must be done on the supplied config and not as part of the fixture because any changes to
- // the fixture's config will be ignored when RunTestWithConfig replaces it.
- pathCtx := android.PathContextForTesting(config)
- dexpreopt.SetTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
- result := prepareForJavaTest.
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
- RunTestWithConfig(t, config)
- return result.TestContext, result.Config
-}
-
// testJavaWithFS runs tests using the prepareForJavaTest
//
// See testJava for an explanation as to how to stop using this deprecated method.
@@ -250,7 +233,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac").RelativeToTop()
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
@@ -845,7 +828,12 @@
if expectedErrorPattern != "" {
errorHandler = android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorPattern)
}
- prepareForJavaTest.ExtendWithErrorHandler(errorHandler).RunTest(t, createPreparer(info))
+ android.GroupFixturePreparers(
+ prepareForJavaTest,
+ createPreparer(info),
+ ).
+ ExtendWithErrorHandler(errorHandler).
+ RunTest(t)
})
}
@@ -976,7 +964,7 @@
}
`)
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac").RelativeToTop()
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
@@ -1336,11 +1324,11 @@
}
`)
- fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine").RelativeToTop()
- barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine").RelativeToTop()
- barJavac := result.ModuleForTests("bar", "android_common").Rule("javac").RelativeToTop()
- barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine").RelativeToTop()
- bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac").RelativeToTop()
+ fooTurbine := result.ModuleForTests("foo", "android_common").Rule("turbine")
+ barTurbine := result.ModuleForTests("bar", "android_common").Rule("turbine")
+ barJavac := result.ModuleForTests("bar", "android_common").Rule("javac")
+ barTurbineCombined := result.ModuleForTests("bar", "android_common").Description("for turbine")
+ bazJavac := result.ModuleForTests("baz", "android_common").Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo inputs", []string{"a.java"}, fooTurbine.Inputs)
@@ -1363,7 +1351,7 @@
barHeaderJar := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
for i := 0; i < 3; i++ {
- barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i)).RelativeToTop()
+ barJavac := ctx.ModuleForTests("bar", "android_common").Description("javac" + strconv.Itoa(i))
if !strings.Contains(barJavac.Args["classpath"], barHeaderJar) {
t.Errorf("bar javac classpath %v does not contain %q", barJavac.Args["classpath"], barHeaderJar)
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
new file mode 100644
index 0000000..5507077
--- /dev/null
+++ b/java/platform_bootclasspath.go
@@ -0,0 +1,74 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package java
+
+import (
+ "android/soong/android"
+ "android/soong/dexpreopt"
+)
+
+func init() {
+ registerPlatformBootclasspathBuildComponents(android.InitRegistrationContext)
+}
+
+func registerPlatformBootclasspathBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("platform_bootclasspath", platformBootclasspathFactory)
+}
+
+type platformBootclasspathModule struct {
+ android.ModuleBase
+}
+
+func platformBootclasspathFactory() android.Module {
+ m := &platformBootclasspathModule{}
+ android.InitAndroidArchModule(m, android.DeviceSupported, android.MultilibCommon)
+ return m
+}
+
+func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if SkipDexpreoptBootJars(ctx) {
+ return
+ }
+
+ // Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
+ // path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
+ dexpreopt.RegisterToolDeps(ctx)
+}
+
+func (b *platformBootclasspathModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ // 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 := BootImageInfo{imageConfig: imageConfig}
+
+ // Make it available for other modules.
+ ctx.SetProvider(BootImageInfoProvider, info)
+}
+
+func (b *platformBootclasspathModule) getImageConfig(ctx android.EarlyModuleContext) *bootImageConfig {
+ return defaultBootImageConfig(ctx)
+}
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
new file mode 100644
index 0000000..1c81cfd
--- /dev/null
+++ b/java/platform_bootclasspath_test.go
@@ -0,0 +1,38 @@
+// 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.
+
+package java
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/dexpreopt"
+)
+
+// Contains some simple tests for platform_bootclasspath.
+
+var prepareForTestWithPlatformBootclasspath = android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ dexpreopt.PrepareForTestByEnablingDexpreopt,
+)
+
+func TestPlatformBootclasspath(t *testing.T) {
+ prepareForTestWithPlatformBootclasspath.
+ RunTestWithBp(t, `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `)
+}
diff --git a/java/rro_test.go b/java/rro_test.go
index 0a10d93..bad60bc 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -68,7 +68,7 @@
m := result.ModuleForTests("foo", "android_common")
// Check AAPT2 link flags.
- aapt2Flags := m.Output("package-res.apk").RelativeToTop().Args["flags"]
+ aapt2Flags := m.Output("package-res.apk").Args["flags"]
expectedFlags := []string{"--keep-raw-values", "--no-resource-deduping", "--no-resource-removal"}
absentFlags := android.RemoveListFromList(expectedFlags, strings.Split(aapt2Flags, " "))
if len(absentFlags) > 0 {
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 028c4fe..2b18465 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -313,10 +313,10 @@
checkClasspath := func(t *testing.T, result *android.TestResult, isJava8 bool) {
foo := result.ModuleForTests("foo", variant)
- javac := foo.Rule("javac").RelativeToTop()
+ javac := foo.Rule("javac")
var deps []string
- aidl := foo.MaybeRule("aidl").RelativeToTop()
+ aidl := foo.MaybeRule("aidl")
if aidl.Rule != nil {
deps = append(deps, android.PathRelativeToTop(aidl.Output))
}
@@ -376,7 +376,7 @@
checkClasspath(t, result, true /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant).Rule("aidl").RelativeToTop()
+ aidl := result.ModuleForTests("foo", variant).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -389,7 +389,7 @@
checkClasspath(t, result, false /* isJava8 */)
if testcase.host != android.Host {
- aidl := result.ModuleForTests("foo", variant).Rule("aidl").RelativeToTop()
+ aidl := result.ModuleForTests("foo", variant).Rule("aidl")
android.AssertStringDoesContain(t, "aidl command", aidl.RuleParams.Command, testcase.aidl+" -I.")
}
@@ -402,14 +402,16 @@
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 8 -target 8
t.Run("REL + Java language level 8", func(t *testing.T) {
- result := fixtureFactory.Extend(prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
+ result := android.GroupFixturePreparers(
+ fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bpJava8)
checkClasspath(t, result, true /* isJava8 */)
})
// Test again with PLATFORM_VERSION_CODENAME=REL, javac -source 9 -target 9
t.Run("REL + Java language level 9", func(t *testing.T) {
- result := fixtureFactory.Extend(prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ fixtureFactory, prepareWithPlatformVersionRel).RunTestWithBp(t, bp)
checkClasspath(t, result, false /* isJava8 */)
})
diff --git a/java/system_modules_test.go b/java/system_modules_test.go
index 120bbf7..7b5a386 100644
--- a/java/system_modules_test.go
+++ b/java/system_modules_test.go
@@ -50,7 +50,7 @@
`)
func TestJavaSystemModules(t *testing.T) {
- result := prepareForJavaTest.RunTest(t, addSourceSystemModules)
+ result := android.GroupFixturePreparers(prepareForJavaTest, addSourceSystemModules).RunTest(t)
// check the existence of the source module
sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
@@ -77,7 +77,7 @@
`)
func TestJavaSystemModulesImport(t *testing.T) {
- result := prepareForJavaTest.RunTest(t, addPrebuiltSystemModules)
+ result := android.GroupFixturePreparers(prepareForJavaTest, addPrebuiltSystemModules).RunTest(t)
// check the existence of the renamed prebuilt module
prebuiltSystemModules := result.ModuleForTests("system-modules", "android_common")
@@ -89,10 +89,11 @@
}
func TestJavaSystemModulesMixSourceAndPrebuilt(t *testing.T) {
- result := prepareForJavaTest.RunTest(t,
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
addSourceSystemModules,
addPrebuiltSystemModules,
- )
+ ).RunTest(t)
// check the existence of the source module
sourceSystemModules := result.ModuleForTests("system-modules", "android_common")
diff --git a/java/testing.go b/java/testing.go
index 221ceb1..80c107d 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -160,28 +160,6 @@
)
}
-func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) android.Config {
- bp += GatherRequiredDepsForTest()
-
- mockFS := android.MockFS{}
-
- cc.GatherRequiredFilesForTest(mockFS)
-
- for k, v := range fs {
- mockFS[k] = v
- }
-
- if env == nil {
- env = make(map[string]string)
- }
- if env["ANDROID_JAVA8_HOME"] == "" {
- env["ANDROID_JAVA8_HOME"] = "jdk8"
- }
- config := android.TestArchConfig(buildDir, env, bp, mockFS)
-
- return config
-}
-
func prebuiltApisFilesForLibs(apiLevels []string, sdkLibs []string) map[string][]byte {
fs := make(map[string][]byte)
for _, level := range apiLevels {
@@ -200,19 +178,6 @@
return fs
}
-// Register build components provided by this package that are needed by tests.
-//
-// In particular this must register all the components that are used in the `Android.bp` snippet
-// returned by GatherRequiredDepsForTest()
-//
-// deprecated: Use test fixtures instead, e.g. PrepareForTestWithJavaBuildComponents
-func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
- registerRequiredBuildComponentsForTest(ctx)
-
- // Make sure that any tool related module types needed by dexpreopt have been registered.
- dexpreopt.RegisterToolModulesForTest(ctx)
-}
-
// registerRequiredBuildComponentsForTest registers the build components used by
// PrepareForTestWithJavaDefaultModules.
//
@@ -228,7 +193,8 @@
RegisterDexpreoptBootJarsComponents(ctx)
RegisterDocsBuildComponents(ctx)
RegisterGenRuleBuildComponents(ctx)
- RegisterJavaBuildComponents(ctx)
+ registerJavaBuildComponents(ctx)
+ registerPlatformBootclasspathBuildComponents(ctx)
RegisterPrebuiltApisBuildComponents(ctx)
RegisterRuntimeResourceOverlayBuildComponents(ctx)
RegisterSdkLibraryBuildComponents(ctx)
@@ -236,23 +202,6 @@
RegisterSystemModulesBuildComponents(ctx)
}
-// Gather the module definitions needed by tests that depend upon code from this package.
-//
-// Returns an `Android.bp` snippet that defines the modules that are needed by this package.
-//
-// deprecated: Use test fixtures instead, e.g. PrepareForTestWithJavaDefaultModules
-func GatherRequiredDepsForTest() string {
- bp := gatherRequiredDepsForTest()
-
- // For class loader context and <uses-library> tests.
- bp += dexpreopt.CompatLibDefinitionsForTest()
-
- // Make sure that any tools needed for dexpreopting are defined.
- bp += dexpreopt.BpToolModulesForTest()
-
- return bp
-}
-
// gatherRequiredDepsForTest gathers the module definitions used by
// PrepareForTestWithJavaDefaultModules.
//
diff --git a/rust/project_json_test.go b/rust/project_json_test.go
index 7af4635..09d30db 100644
--- a/rust/project_json_test.go
+++ b/rust/project_json_test.go
@@ -28,9 +28,10 @@
// testProjectJson run the generation of rust-project.json. It returns the raw
// content of the generated file.
func testProjectJson(t *testing.T, bp string) []byte {
- result := prepareForRustTest.
- Extend(android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"})).
- RunTestWithBp(t, bp)
+ result := android.GroupFixturePreparers(
+ prepareForRustTest,
+ android.FixtureMergeEnv(map[string]string{"SOONG_GEN_RUST_PROJECT": "1"}),
+ ).RunTestWithBp(t, bp)
// The JSON file is generated via WriteFileToOutputDir. Therefore, it
// won't appear in the Output of the TestingSingleton. Manually verify
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
index 18174a4..30cb937 100755
--- a/scripts/build-mainline-modules.sh
+++ b/scripts/build-mainline-modules.sh
@@ -27,7 +27,6 @@
platform-mainline-test-exports
runtime-module-host-exports
runtime-module-sdk
- stats-log-api-gen-exports
statsd-module-sdk
statsd-module-sdk-for-art
tzdata-module-test-exports
diff --git a/scripts/gen_sorted_bss_symbols.sh b/scripts/gen_sorted_bss_symbols.sh
index 244ed0d..a9b61a1 100755
--- a/scripts/gen_sorted_bss_symbols.sh
+++ b/scripts/gen_sorted_bss_symbols.sh
@@ -18,11 +18,11 @@
# their sizes.
# Inputs:
# Environment:
-# CROSS_COMPILE: prefix added to nm tools
+# CLANG_BIN: path to the clang bin directory
# Arguments:
# $1: Input ELF file
# $2: Output symbol ordering file
set -o pipefail
-${CROSS_COMPILE}nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
+${CLANG_BIN}/llvm-nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
diff --git a/scripts/manifest_check.py b/scripts/manifest_check.py
index 907f239..8168fbf 100755
--- a/scripts/manifest_check.py
+++ b/scripts/manifest_check.py
@@ -74,7 +74,7 @@
return parser.parse_args()
-def enforce_uses_libraries(manifest, required, optional, relax, is_apk = False):
+def enforce_uses_libraries(manifest, required, optional, relax, is_apk, path):
"""Verify that the <uses-library> tags in the manifest match those provided
by the build system.
@@ -86,26 +86,36 @@
is_apk: if the manifest comes from an APK or an XML file
"""
if is_apk:
- manifest_required, manifest_optional = extract_uses_libs_apk(manifest)
+ manifest_required, manifest_optional, tags = extract_uses_libs_apk(manifest)
else:
- manifest_required, manifest_optional = extract_uses_libs_xml(manifest)
+ manifest_required, manifest_optional, tags = extract_uses_libs_xml(manifest)
- err = []
- if manifest_required != required:
- err.append('Expected required <uses-library> tags "%s", got "%s"' %
- (', '.join(required), ', '.join(manifest_required)))
+ if manifest_required == required and manifest_optional == optional:
+ return None
- if manifest_optional != optional:
- err.append('Expected optional <uses-library> tags "%s", got "%s"' %
- (', '.join(optional), ', '.join(manifest_optional)))
+ errmsg = ''.join([
+ 'mismatch in the <uses-library> tags between the build system and the '
+ 'manifest:\n',
+ '\t- required libraries in build system: [%s]\n' % ', '.join(required),
+ '\t vs. in the manifest: [%s]\n' % ', '.join(manifest_required),
+ '\t- optional libraries in build system: [%s]\n' % ', '.join(optional),
+ '\t vs. in the manifest: [%s]\n' % ', '.join(manifest_optional),
+ '\t- tags in the manifest (%s):\n' % path,
+ '\t\t%s\n' % '\t\t'.join(tags),
+ 'note: the following options are available:\n',
+ '\t- to temporarily disable the check on command line, rebuild with ',
+ 'RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" ',
+ 'and disable AOT-compilation in dexpreopt)\n',
+ '\t- to temporarily disable the check for the whole product, set ',
+ 'PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles\n',
+ '\t- to fix the check, make build system properties coherent with the '
+ 'manifest\n',
+ '\t- see build/make/Changes.md for details\n'])
- if err:
- errmsg = '\n'.join(err)
- if not relax:
- raise ManifestMismatchError(errmsg)
- return errmsg
+ if not relax:
+ raise ManifestMismatchError(errmsg)
- return None
+ return errmsg
def extract_uses_libs_apk(badging):
@@ -115,14 +125,19 @@
required = []
optional = []
+ lines = []
for match in re.finditer(pattern, badging):
+ lines.append(match.group(0))
libname = match.group(2)
if match.group(1) == None:
required.append(libname)
else:
optional.append(libname)
- return first_unique_elements(required), first_unique_elements(optional)
+ required = first_unique_elements(required)
+ optional = first_unique_elements(optional)
+ tags = first_unique_elements(lines)
+ return required, optional, tags
def extract_uses_libs_xml(xml):
@@ -143,7 +158,15 @@
required = [uses_library_name(x) for x in libs if uses_library_required(x)]
optional = [uses_library_name(x) for x in libs if not uses_library_required(x)]
- return first_unique_elements(required), first_unique_elements(optional)
+ # render <uses-library> tags as XML for a pretty error message
+ tags = []
+ for lib in libs:
+ tags.append(lib.toprettyxml())
+
+ required = first_unique_elements(required)
+ optional = first_unique_elements(optional)
+ tags = first_unique_elements(tags)
+ return required, optional, tags
def first_unique_elements(l):
@@ -278,7 +301,7 @@
# in the manifest. Raise an exception on mismatch, unless the script was
# passed a special parameter to suppress exceptions.
errmsg = enforce_uses_libraries(manifest, required, optional,
- args.enforce_uses_libraries_relax, is_apk)
+ args.enforce_uses_libraries_relax, is_apk, args.input)
# Create a status file that is empty on success, or contains an error
# message on failure. When exceptions are suppressed, dexpreopt command
diff --git a/scripts/manifest_check_test.py b/scripts/manifest_check_test.py
index 635ba9d..7159bdd 100755
--- a/scripts/manifest_check_test.py
+++ b/scripts/manifest_check_test.py
@@ -49,9 +49,9 @@
try:
relax = False
manifest_check.enforce_uses_libraries(doc, uses_libraries,
- optional_uses_libraries, relax, is_apk=False)
+ optional_uses_libraries, relax, False, 'path/to/X/AndroidManifest.xml')
manifest_check.enforce_uses_libraries(apk, uses_libraries,
- optional_uses_libraries, relax, is_apk=True)
+ optional_uses_libraries, relax, True, 'path/to/X/X.apk')
return True
except manifest_check.ManifestMismatchError:
return False
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index a886a18..b19fcc5 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -2407,6 +2407,7 @@
"1",
"2",
"3",
+ "current",
],
},
arch: {
@@ -2461,6 +2462,7 @@
"1",
"2",
"3",
+ "current",
],
},
target: {
@@ -2500,6 +2502,7 @@
"1",
"2",
"3",
+ "current",
],
},
target: {
diff --git a/sdk/testing.go b/sdk/testing.go
index 44970f7..9465e13 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -95,7 +95,10 @@
func testSdkWithFs(t *testing.T, bp string, fs android.MockFS) *android.TestResult {
t.Helper()
- return prepareForSdkTest.RunTest(t, fs.AddToFixture(), android.FixtureWithRootAndroidBp(bp))
+ return android.GroupFixturePreparers(
+ prepareForSdkTest,
+ fs.AddToFixture(),
+ ).RunTestWithBp(t, bp)
}
func testSdkError(t *testing.T, pattern, bp string) {