Merge "Pass the `--cfg soong` flag when building rustdoc" into main
diff --git a/android/arch_list.go b/android/arch_list.go
index f4409a9..4233456 100644
--- a/android/arch_list.go
+++ b/android/arch_list.go
@@ -103,6 +103,7 @@
"kryo385",
"exynos-m1",
"exynos-m2",
+ "oryon",
},
X86: {},
X86_64: {},
diff --git a/android/license_metadata.go b/android/license_metadata.go
index 3fea029..8056189 100644
--- a/android/license_metadata.go
+++ b/android/license_metadata.go
@@ -45,8 +45,7 @@
}
var outputFiles Paths
- if outputFileProducer, ok := ctx.Module().(OutputFileProducer); ok {
- outputFiles, _ = outputFileProducer.OutputFiles("")
+ if outputFiles, err := outputFilesForModule(ctx, ctx.Module(), ""); err == nil {
outputFiles = PathsIfNonNil(outputFiles...)
}
diff --git a/android/module.go b/android/module.go
index 66f6e1b..4a6f5d1 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2491,6 +2491,8 @@
if outputFilesFromProvider != nil || err != OutputFilesProviderNotSet {
return outputFilesFromProvider, err
}
+ // TODO: add error when outputFilesFromProvider and err are both nil after
+ // OutputFileProducer and SourceFileProducer are deprecated.
if outputFileProducer, ok := module.(OutputFileProducer); ok {
paths, err := outputFileProducer.OutputFiles(tag)
if err != nil {
@@ -2505,7 +2507,7 @@
paths := sourceFileProducer.Srcs()
return paths, nil
} else {
- return nil, fmt.Errorf("module %q is not an OutputFileProducer or SourceFileProducer", pathContextName(ctx, module))
+ return nil, fmt.Errorf("module %q is not a SourceFileProducer or having valid output file for tag %q", pathContextName(ctx, module), tag)
}
}
diff --git a/apex/apex.go b/apex/apex.go
index a2c1f2c..ab50e85 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2095,20 +2095,10 @@
}
case testTag:
if ccTest, ok := child.(*cc.Module); ok {
- if ccTest.IsTestPerSrcAllTestsVariation() {
- // Multiple-output test module (where `test_per_src: true`).
- //
- // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
- // We do not add this variation to `filesInfo`, as it has no output;
- // however, we do add the other variations of this module as indirect
- // dependencies (see below).
- } else {
- // Single-output test module (where `test_per_src: false`).
- af := apexFileForExecutable(ctx, ccTest)
- af.class = nativeTest
- vctx.filesInfo = append(vctx.filesInfo, af)
- addAconfigFiles(vctx, ctx, child)
- }
+ af := apexFileForExecutable(ctx, ccTest)
+ af.class = nativeTest
+ vctx.filesInfo = append(vctx.filesInfo, af)
+ addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
} else {
ctx.PropertyErrorf("tests", "%q is not a cc module", depName)
@@ -2197,19 +2187,6 @@
addAconfigFiles(vctx, ctx, child)
return true // track transitive dependencies
}
- } else if cc.IsTestPerSrcDepTag(depTag) {
- if ch, ok := child.(*cc.Module); ok {
- af := apexFileForExecutable(ctx, ch)
- // Handle modules created as `test_per_src` variations of a single test module:
- // use the name of the generated test binary (`fileToCopy`) instead of the name
- // of the original test module (`depName`, shared by all `test_per_src`
- // variations of that module).
- af.androidMkModuleName = filepath.Base(af.builtFile.String())
- // these are not considered transitive dep
- af.transitiveDep = false
- vctx.filesInfo = append(vctx.filesInfo, af)
- return true // track transitive dependencies
- }
} else if cc.IsHeaderDepTag(depTag) {
// nothing
} else if java.IsJniDepTag(depTag) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index df9db74..15c713b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5728,7 +5728,6 @@
updatable: false,
tests: [
"mytest",
- "mytests",
],
}
@@ -5771,25 +5770,6 @@
"testdata/baz"
],
}
-
- cc_test {
- name: "mytests",
- gtest: false,
- srcs: [
- "mytest1.cpp",
- "mytest2.cpp",
- "mytest3.cpp",
- ],
- test_per_src: true,
- relative_install_path: "test",
- system_shared_libs: [],
- static_executable: true,
- stl: "none",
- data: [
- ":fg",
- ":fg2",
- ],
- }
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@@ -5803,11 +5783,6 @@
ensureContains(t, copyCmds, "image.apex/bin/test/baz")
ensureContains(t, copyCmds, "image.apex/bin/test/bar/baz")
- // Ensure that test deps built with `test_per_src` are copied into apex.
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest1")
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest2")
- ensureContains(t, copyCmds, "image.apex/bin/test/mytest3")
-
// Ensure the module is correctly translated.
bundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
data := android.AndroidMkDataForTest(t, ctx, bundle)
@@ -5817,9 +5792,6 @@
data.Custom(&builder, name, prefix, "", data)
androidMk := builder.String()
ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n")
- ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n")
ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 143e86f..4134653 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -351,9 +351,6 @@
ctx.subAndroidMk(entries, test.testDecorator)
entries.Class = "NATIVE_TESTS"
- if Bool(test.Properties.Test_per_src) {
- entries.SubName = "_" + String(test.binaryDecorator.Properties.Stem)
- }
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
if test.testConfig != nil {
entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String())
diff --git a/cc/cc.go b/cc/cc.go
index 24f6b83..134d89c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -51,7 +51,6 @@
ctx.BottomUp("sdk", sdkMutator).Parallel()
ctx.BottomUp("llndk", llndkMutator).Parallel()
ctx.BottomUp("link", LinkageMutator).Parallel()
- ctx.BottomUp("test_per_src", TestPerSrcMutator).Parallel()
ctx.BottomUp("version", versionMutator).Parallel()
ctx.BottomUp("begin", BeginMutator).Parallel()
})
@@ -799,7 +798,6 @@
dataLibDepTag = dependencyTag{name: "data lib"}
dataBinDepTag = dependencyTag{name: "data bin"}
runtimeDepTag = installDependencyTag{name: "runtime lib"}
- testPerSrcDepTag = dependencyTag{name: "test_per_src"}
stubImplDepTag = dependencyTag{name: "stub_impl"}
JniFuzzLibTag = dependencyTag{name: "jni_fuzz_lib_tag"}
FdoProfileTag = dependencyTag{name: "fdo_profile"}
@@ -826,11 +824,6 @@
return depTag == runtimeDepTag
}
-func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(dependencyTag)
- return ok && ccDepTag == testPerSrcDepTag
-}
-
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer, or "decorator",
@@ -1786,11 +1779,6 @@
return nil
}
-func (c *Module) IsTestPerSrcAllTestsVariation() bool {
- test, ok := c.linker.(testPerSrc)
- return ok && test.isAllTestsVariation()
-}
-
func (c *Module) DataPaths() []android.DataPath {
if p, ok := c.installer.(interface {
dataPaths() []android.DataPath
@@ -1943,16 +1931,6 @@
TopLevelTarget: c.testModule,
})
- // Handle the case of a test module split by `test_per_src` mutator.
- //
- // The `test_per_src` mutator adds an extra variation named "", depending on all the other
- // `test_per_src` variations of the test module. Set `outputFile` to an empty path for this
- // module and return early, as this module does not produce an output file per se.
- if c.IsTestPerSrcAllTestsVariation() {
- c.outputFile = android.OptionalPath{}
- return
- }
-
c.Properties.SubName = GetSubnameProperty(actx, c)
apexInfo, _ := android.ModuleProvider(actx, android.ApexInfoProvider)
if !apexInfo.IsForPlatform() {
@@ -3758,14 +3736,12 @@
}
// Overrides ApexModule.IsInstallabeToApex()
-// Only shared/runtime libraries and "test_per_src" tests are installable to APEX.
+// Only shared/runtime libraries .
func (c *Module) IsInstallableToApex() bool {
if lib := c.library; lib != nil {
// Stub libs and prebuilt libs in a versioned SDK are not
// installable to APEX even though they are shared libs.
return lib.shared() && !lib.buildStubs()
- } else if _, ok := c.linker.(testPerSrc); ok {
- return true
}
return false
}
diff --git a/cc/cc_test_only_property_test.go b/cc/cc_test_only_property_test.go
index c14f34e..972e86b 100644
--- a/cc/cc_test_only_property_test.go
+++ b/cc/cc_test_only_property_test.go
@@ -78,38 +78,6 @@
}
}
-func TestTestOnlyValueWithTestPerSrcProp(t *testing.T) {
- t.Parallel()
- ctx := android.GroupFixturePreparers(
- prepareForCcTest,
- ).RunTestWithBp(t, `
- // These should be test-only
- cc_test { name: "cc-test",
- gtest: false,
- test_per_src: true,
- srcs: ["foo_test.cpp"],
- test_options: { unit_test: false, },
- }
- `)
-
- // Ensure all variation of test-per-src tests are marked test-only.
- ctx.VisitAllModules(func(m blueprint.Module) {
- testOnly := false
- if provider, ok := android.OtherModuleProvider(ctx.TestContext.OtherModuleProviderAdaptor(), m, android.TestOnlyProviderKey); ok {
- if provider.TestOnly {
- testOnly = true
- }
- }
- if module, ok := m.(*Module); ok {
- if testModule, ok := module.installer.(*testBinary); ok {
- if !testOnly && *testModule.Properties.Test_per_src {
- t.Errorf("%v is not test-only but should be", m)
- }
- }
- }
- })
-}
-
func TestTestOnlyInTeamsProto(t *testing.T) {
t.Parallel()
ctx := android.GroupFixturePreparers(
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 632c76d..85c3edf 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -184,10 +184,6 @@
return ""
}
-func (txt *llndkLibrariesTxtModule) OutputFiles(tag string) (android.Paths, error) {
- return android.Paths{txt.outputFile}, nil
-}
-
func llndkMutator(mctx android.BottomUpMutatorContext) {
m, ok := mctx.Module().(*Module)
if !ok {
diff --git a/cc/sanitize.go b/cc/sanitize.go
index d72d7d3..d43a096 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1899,7 +1899,3 @@
func (txt *sanitizerLibrariesTxtModule) SubDir() string {
return ""
}
-
-func (txt *sanitizerLibrariesTxtModule) OutputFiles(tag string) (android.Paths, error) {
- return android.Paths{txt.outputFile}, nil
-}
diff --git a/cc/test.go b/cc/test.go
index a96af31..f5bb761 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -15,11 +15,9 @@
package cc
import (
+ "github.com/google/blueprint/proptools"
"path/filepath"
"strconv"
- "strings"
-
- "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/tradefed"
@@ -75,13 +73,9 @@
}
type TestBinaryProperties struct {
- // Create a separate binary for each source file. Useful when there is
- // global state that can not be torn down and reset between each test suite.
- Test_per_src *bool
-
// Disables the creation of a test-specific directory when used with
// relative_install_path. Useful if several tests need to be in the same
- // directory, but test_per_src doesn't work.
+ // directory.
No_named_install_directory *bool
// list of files or filegroup modules that provide data that should be installed alongside
@@ -174,86 +168,14 @@
return module.Init()
}
-type testPerSrc interface {
- testPerSrc() bool
- srcs() []string
- isAllTestsVariation() bool
- setSrc(string, string)
- unsetSrc()
-}
-
-func (test *testBinary) testPerSrc() bool {
- return Bool(test.Properties.Test_per_src)
-}
-
-func (test *testBinary) srcs() []string {
- return test.baseCompiler.Properties.Srcs
-}
-
func (test *testBinary) dataPaths() []android.DataPath {
return test.data
}
-func (test *testBinary) isAllTestsVariation() bool {
- stem := test.binaryDecorator.Properties.Stem
- return stem != nil && *stem == ""
-}
-
-func (test *testBinary) setSrc(name, src string) {
- test.baseCompiler.Properties.Srcs = []string{src}
- test.binaryDecorator.Properties.Stem = StringPtr(name)
-}
-
-func (test *testBinary) unsetSrc() {
- test.baseCompiler.Properties.Srcs = nil
- test.binaryDecorator.Properties.Stem = StringPtr("")
-}
-
func (test *testBinary) testBinary() bool {
return true
}
-var _ testPerSrc = (*testBinary)(nil)
-
-func TestPerSrcMutator(mctx android.BottomUpMutatorContext) {
- if m, ok := mctx.Module().(*Module); ok {
- if test, ok := m.linker.(testPerSrc); ok {
- numTests := len(test.srcs())
- if test.testPerSrc() && numTests > 0 {
- if duplicate, found := android.CheckDuplicate(test.srcs()); found {
- mctx.PropertyErrorf("srcs", "found a duplicate entry %q", duplicate)
- return
- }
- testNames := make([]string, numTests)
- for i, src := range test.srcs() {
- testNames[i] = strings.TrimSuffix(filepath.Base(src), filepath.Ext(src))
- }
- // In addition to creating one variation per test source file,
- // create an additional "all tests" variation named "", and have it
- // depends on all other test_per_src variations. This is useful to
- // create subsequent dependencies of a given module on all
- // test_per_src variations created above: by depending on
- // variation "", that module will transitively depend on all the
- // other test_per_src variations without the need to know their
- // name or even their number.
- testNames = append(testNames, "")
- tests := mctx.CreateLocalVariations(testNames...)
- allTests := tests[numTests]
- allTests.(*Module).linker.(testPerSrc).unsetSrc()
- // Prevent the "all tests" variation from being installable nor
- // exporting to Make, as it won't create any output file.
- allTests.(*Module).Properties.PreventInstall = true
- allTests.(*Module).Properties.HideFromMake = true
- for i, src := range test.srcs() {
- tests[i].(*Module).linker.(testPerSrc).setSrc(testNames[i], src)
- mctx.AddInterVariantDependency(testPerSrcDepTag, allTests, tests[i])
- }
- mctx.AliasVariation("")
- }
- }
- }
-}
-
type testDecorator struct {
LinkerProperties TestLinkerProperties
InstallerProperties TestInstallerProperties
@@ -382,10 +304,6 @@
}
moduleInfoJSON.TestConfig = append(moduleInfoJSON.TestConfig, test.extraTestConfigs.Strings()...)
- if Bool(test.Properties.Test_per_src) {
- moduleInfoJSON.SubName = "_" + String(test.binaryDecorator.Properties.Stem)
- }
-
moduleInfoJSON.DataDependencies = append(moduleInfoJSON.DataDependencies, test.Properties.Data_bins...)
if len(test.InstallerProperties.Test_suites) > 0 {
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 5a4818f..d04b2d1 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -50,6 +50,7 @@
ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory)
ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory)
ctx.RegisterModuleType("prebuilt_etc_cacerts", PrebuiltEtcCaCertsFactory)
+ ctx.RegisterModuleType("prebuilt_avb", PrebuiltAvbFactory)
ctx.RegisterModuleType("prebuilt_root", PrebuiltRootFactory)
ctx.RegisterModuleType("prebuilt_root_host", PrebuiltRootHostFactory)
ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
@@ -155,6 +156,9 @@
additionalDependencies *android.Paths
usedSrcsProperty bool
+ // installInRoot is used to return the value of the InstallInRoot() method. The default value is false.
+ // Currently, only prebuilt_avb can be set to true.
+ installInRoot bool
makeClass string
}
@@ -241,6 +245,10 @@
return proptools.Bool(p.properties.Debug_ramdisk_available) || p.ModuleBase.InstallInDebugRamdisk()
}
+func (p *PrebuiltEtc) InstallInRoot() bool {
+ return p.installInRoot
+}
+
func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool {
return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
}
@@ -494,12 +502,20 @@
func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) {
p.installDirBase = dirBase
+ p.installInRoot = false
p.AddProperties(&p.properties)
p.AddProperties(&p.subdirProperties)
}
func InitPrebuiltRootModule(p *PrebuiltEtc) {
p.installDirBase = "."
+ p.installInRoot = false
+ p.AddProperties(&p.properties)
+}
+
+func InitPrebuiltAvbModule(p *PrebuiltEtc) {
+ p.installDirBase = "avb"
+ p.installInRoot = true
p.AddProperties(&p.properties)
}
@@ -553,6 +569,20 @@
return module
}
+// Generally, a <partition> directory will contain a `system` subdirectory, but the <partition> of
+// `prebuilt_avb` will not have a `system` subdirectory.
+// Ultimately, prebuilt_avb will install the prebuilt artifact to the `avb` subdirectory under the
+// root directory of the partition: <partition_root>/avb.
+// prebuilt_avb does not allow adding any other subdirectories.
+func PrebuiltAvbFactory() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltAvbModule(module)
+ // This module is device-only
+ android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
+ android.InitDefaultableModule(module)
+ return module
+}
+
// prebuilt_root is for a prebuilt artifact that is installed in
// <partition>/ directory. Can't have any sub directories.
func PrebuiltRootFactory() android.Module {
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index c44574a..e739afe 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -244,6 +244,31 @@
`)
}
+func TestPrebuiltAvbInstallDirPath(t *testing.T) {
+ result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
+ prebuilt_avb {
+ name: "foo.conf",
+ src: "foo.conf",
+ filename: "foo.conf",
+ //recovery: true,
+ }
+ `)
+
+ p := result.Module("foo.conf", "android_arm64_armv8-a").(*PrebuiltEtc)
+ expected := "out/soong/target/product/test_device/root/avb"
+ android.AssertPathRelativeToTopEquals(t, "install dir", expected, p.installDirPath)
+}
+
+func TestPrebuiltAvdInstallDirPathValidate(t *testing.T) {
+ prepareForPrebuiltEtcTest.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern("filename cannot contain separator")).RunTestWithBp(t, `
+ prebuilt_avb {
+ name: "foo.conf",
+ src: "foo.conf",
+ filename: "foo/bar.conf",
+ }
+ `)
+}
+
func TestPrebuiltUserShareInstallDirPath(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_usr_share {
diff --git a/genrule/genrule.go b/genrule/genrule.go
index c0942d3..5b40768 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -754,6 +754,7 @@
func GenSrcsFactory() android.Module {
m := NewGenSrcs()
android.InitAndroidModule(m)
+ android.InitDefaultableModule(m)
return m
}
diff --git a/java/aar.go b/java/aar.go
index 3168d9b..2f49a95 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -798,18 +798,6 @@
aarFile android.WritablePath
}
-var _ android.OutputFileProducer = (*AndroidLibrary)(nil)
-
-// For OutputFileProducer interface
-func (a *AndroidLibrary) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case ".aar":
- return []android.Path{a.aarFile}, nil
- default:
- return a.Library.OutputFiles(tag)
- }
-}
-
var _ AndroidLibraryDependency = (*AndroidLibrary)(nil)
func (a *AndroidLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -911,6 +899,13 @@
android.SetProvider(ctx, FlagsPackagesProvider, FlagsPackages{
AconfigTextFiles: aconfigTextFilePaths,
})
+
+ a.setOutputFiles(ctx)
+}
+
+func (a *AndroidLibrary) setOutputFiles(ctx android.ModuleContext) {
+ ctx.SetOutputFiles([]android.Path{a.aarFile}, ".aar")
+ setOutputFiles(ctx, a.Library.Module)
}
func (a *AndroidLibrary) IDEInfo(dpInfo *android.IdeInfo) {
@@ -1021,20 +1016,6 @@
classLoaderContexts dexpreopt.ClassLoaderContextMap
}
-var _ android.OutputFileProducer = (*AARImport)(nil)
-
-// For OutputFileProducer interface
-func (a *AARImport) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case ".aar":
- return []android.Path{a.aarPath}, nil
- case "":
- return []android.Path{a.implementationAndResourcesJarFile}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-}
-
func (a *AARImport) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpecFrom(ctx, String(a.properties.Sdk_version))
}
@@ -1388,6 +1369,9 @@
android.SetProvider(ctx, JniPackageProvider, JniPackageInfo{
JniPackages: a.jniPackages,
})
+
+ ctx.SetOutputFiles([]android.Path{a.implementationAndResourcesJarFile}, "")
+ ctx.SetOutputFiles([]android.Path{a.aarPath}, ".aar")
}
func (a *AARImport) HeaderJars() android.Paths {
diff --git a/java/aar_test.go b/java/aar_test.go
index 18efd20..ebad310 100644
--- a/java/aar_test.go
+++ b/java/aar_test.go
@@ -159,21 +159,21 @@
bar := result.ModuleForTests("bar", "android_common")
baz := result.ModuleForTests("baz", "android_common")
- fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
- barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
- bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
+ fooOutputPaths := foo.OutputFiles(t, "")
+ barOutputPaths := bar.OutputFiles(t, "")
+ bazOutputPaths := baz.OutputFiles(t, "")
- android.AssertPathRelativeToTopEquals(t, "foo output path",
- "out/soong/.intermediates/foo/android_common/withres/foo.jar", fooOutputPath)
- android.AssertPathRelativeToTopEquals(t, "bar output path",
- "out/soong/.intermediates/bar/android_common/aar/bar.jar", barOutputPath)
- android.AssertPathRelativeToTopEquals(t, "baz output path",
- "out/soong/.intermediates/baz/android_common/withres/baz.jar", bazOutputPath)
+ android.AssertPathsRelativeToTopEquals(t, "foo output path",
+ []string{"out/soong/.intermediates/foo/android_common/withres/foo.jar"}, fooOutputPaths)
+ android.AssertPathsRelativeToTopEquals(t, "bar output path",
+ []string{"out/soong/.intermediates/bar/android_common/aar/bar.jar"}, barOutputPaths)
+ android.AssertPathsRelativeToTopEquals(t, "baz output path",
+ []string{"out/soong/.intermediates/baz/android_common/withres/baz.jar"}, bazOutputPaths)
android.AssertStringEquals(t, "foo relative output path",
- "foo.jar", fooOutputPath.Rel())
+ "foo.jar", fooOutputPaths[0].Rel())
android.AssertStringEquals(t, "bar relative output path",
- "bar.jar", barOutputPath.Rel())
+ "bar.jar", barOutputPaths[0].Rel())
android.AssertStringEquals(t, "baz relative output path",
- "baz.jar", bazOutputPath.Rel())
+ "baz.jar", bazOutputPaths[0].Rel())
}
diff --git a/java/app.go b/java/app.go
index e8c9bfe..fc2294c 100644
--- a/java/app.go
+++ b/java/app.go
@@ -1017,6 +1017,22 @@
isPrebuilt: false,
},
)
+
+ a.setOutputFiles(ctx)
+}
+
+func (a *AndroidApp) setOutputFiles(ctx android.ModuleContext) {
+ ctx.SetOutputFiles([]android.Path{a.proguardOptionsFile}, ".aapt.proguardOptionsFile")
+ if a.aaptSrcJar != nil {
+ ctx.SetOutputFiles([]android.Path{a.aaptSrcJar}, ".aapt.srcjar")
+ }
+ if a.rJar != nil {
+ ctx.SetOutputFiles([]android.Path{a.rJar}, ".aapt.jar")
+ }
+ ctx.SetOutputFiles([]android.Path{a.outputFile}, ".apk")
+ ctx.SetOutputFiles([]android.Path{a.exportPackage}, ".export-package.apk")
+ ctx.SetOutputFiles([]android.Path{a.aapt.manifestPath}, ".manifest.xml")
+ setOutputFiles(ctx, a.Library.Module)
}
type appDepsInterface interface {
@@ -1207,31 +1223,6 @@
return a.Library.DepIsInSameApex(ctx, dep)
}
-// For OutputFileProducer interface
-func (a *AndroidApp) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- // In some instances, it can be useful to reference the aapt-generated flags from another
- // target, e.g., system server implements services declared in the framework-res manifest.
- case ".aapt.proguardOptionsFile":
- return []android.Path{a.proguardOptionsFile}, nil
- case ".aapt.srcjar":
- if a.aaptSrcJar != nil {
- return []android.Path{a.aaptSrcJar}, nil
- }
- case ".aapt.jar":
- if a.rJar != nil {
- return []android.Path{a.rJar}, nil
- }
- case ".apk":
- return []android.Path{a.outputFile}, nil
- case ".export-package.apk":
- return []android.Path{a.exportPackage}, nil
- case ".manifest.xml":
- return []android.Path{a.aapt.manifestPath}, nil
- }
- return a.Library.OutputFiles(tag)
-}
-
func (a *AndroidApp) Privileged() bool {
return Bool(a.appProperties.Privileged)
}
diff --git a/java/app_import.go b/java/app_import.go
index dc8470d..fa87997 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -17,7 +17,6 @@
// This file contains the module implementations for android_app_import and android_test_import.
import (
- "fmt"
"reflect"
"strings"
@@ -422,6 +421,8 @@
},
)
+ ctx.SetOutputFiles([]android.Path{a.outputFile}, "")
+
// TODO: androidmk converter jni libs
}
@@ -461,15 +462,6 @@
return a.outputFile
}
-func (a *AndroidAppImport) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return []android.Path{a.outputFile}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-}
-
func (a *AndroidAppImport) JacocoReportClassesFile() android.Path {
return nil
}
diff --git a/java/app_test.go b/java/app_test.go
index 5770ab4..e878ccf 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -119,10 +119,7 @@
foo.Output(expectedOutput)
}
- outputFiles, err := foo.Module().(*AndroidApp).OutputFiles("")
- if err != nil {
- t.Fatal(err)
- }
+ outputFiles := foo.OutputFiles(t, "")
android.AssertPathsRelativeToTopEquals(t, `OutputFiles("")`, expectedOutputs, outputFiles)
}
diff --git a/java/base.go b/java/base.go
index ee8df3e..fc68d20 100644
--- a/java/base.go
+++ b/java/base.go
@@ -652,35 +652,21 @@
android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo)
}
-func (j *Module) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "":
- return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
- case android.DefaultDistTag:
- return android.Paths{j.outputFile}, nil
- case ".jar":
- return android.Paths{j.implementationAndResourcesJar}, nil
- case ".hjar":
- return android.Paths{j.headerJarFile}, nil
- case ".proguard_map":
- if j.dexer.proguardDictionary.Valid() {
- return android.Paths{j.dexer.proguardDictionary.Path()}, nil
- }
- return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
- case ".generated_srcjars":
- return j.properties.Generated_srcjars, nil
- case ".lint":
- if j.linter.outputs.xml != nil {
- return android.Paths{j.linter.outputs.xml}, nil
- }
- return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+// helper method for java modules to set OutputFilesProvider
+func setOutputFiles(ctx android.ModuleContext, m Module) {
+ ctx.SetOutputFiles(append(android.Paths{m.outputFile}, m.extraOutputFiles...), "")
+ ctx.SetOutputFiles(android.Paths{m.outputFile}, android.DefaultDistTag)
+ ctx.SetOutputFiles(android.Paths{m.implementationAndResourcesJar}, ".jar")
+ ctx.SetOutputFiles(android.Paths{m.headerJarFile}, ".hjar")
+ if m.dexer.proguardDictionary.Valid() {
+ ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map")
+ }
+ ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars")
+ if m.linter.outputs.xml != nil {
+ ctx.SetOutputFiles(android.Paths{m.linter.outputs.xml}, ".lint")
}
}
-var _ android.OutputFileProducer = (*Module)(nil)
-
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
initJavaModule(module, hod, false)
}
diff --git a/java/dex.go b/java/dex.go
index c75e774..7bb6925 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -91,6 +91,10 @@
// Exclude kotlinc generate files: *.kotlin_module, *.kotlin_builtins. Defaults to false.
Exclude_kotlinc_generated_files *bool
+
+ // Disable dex container (also known as "multi-dex").
+ // This may be necessary as a temporary workaround to mask toolchain bugs (see b/341652226).
+ No_dex_container *bool
}
type dexer struct {
diff --git a/java/droiddoc_test.go b/java/droiddoc_test.go
index 8d1f591..e584640 100644
--- a/java/droiddoc_test.go
+++ b/java/droiddoc_test.go
@@ -69,11 +69,7 @@
"bar-doc/a.java": nil,
"bar-doc/b.java": nil,
})
- barStubs := ctx.ModuleForTests("bar-stubs", "android_common")
- barStubsOutputs, err := barStubs.Module().(*Droidstubs).OutputFiles("")
- if err != nil {
- t.Errorf("Unexpected error %q retrieving \"bar-stubs\" output file", err)
- }
+ barStubsOutputs := ctx.ModuleForTests("bar-stubs", "android_common").OutputFiles(t, "")
if len(barStubsOutputs) != 1 {
t.Errorf("Expected one output from \"bar-stubs\" got %s", barStubsOutputs)
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 0157185..a8e0a22 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -283,66 +283,6 @@
return module
}
-func getStubsTypeAndTag(tag string) (StubsType, string, error) {
- if len(tag) == 0 {
- return Everything, "", nil
- }
- if tag[0] != '.' {
- return Unavailable, "", fmt.Errorf("tag must begin with \".\"")
- }
-
- stubsType := Everything
- // Check if the tag has a stubs type prefix (e.g. ".exportable")
- for st := Everything; st <= Exportable; st++ {
- if strings.HasPrefix(tag, "."+st.String()) {
- stubsType = st
- }
- }
-
- return stubsType, strings.TrimPrefix(tag, "."+stubsType.String()), nil
-}
-
-// Droidstubs' tag supports specifying with the stubs type.
-// While supporting the pre-existing tags, it also supports tags with
-// the stubs type prefix. Some examples are shown below:
-// {.annotations.zip} - pre-existing behavior. Returns the path to the
-// annotation zip.
-// {.exportable} - Returns the path to the exportable stubs src jar.
-// {.exportable.annotations.zip} - Returns the path to the exportable
-// annotations zip file.
-// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
-// xml file. For unsupported combinations, the default everything output file
-// is returned.
-func (d *Droidstubs) OutputFiles(tag string) (android.Paths, error) {
- stubsType, prefixRemovedTag, err := getStubsTypeAndTag(tag)
- if err != nil {
- return nil, err
- }
- switch prefixRemovedTag {
- case "":
- stubsSrcJar, err := d.StubsSrcJar(stubsType)
- return android.Paths{stubsSrcJar}, err
- case ".docs.zip":
- docZip, err := d.DocZip(stubsType)
- return android.Paths{docZip}, err
- case ".api.txt", android.DefaultDistTag:
- // This is the default dist path for dist properties that have no tag property.
- apiFilePath, err := d.ApiFilePath(stubsType)
- return android.Paths{apiFilePath}, err
- case ".removed-api.txt":
- removedApiFilePath, err := d.RemovedApiFilePath(stubsType)
- return android.Paths{removedApiFilePath}, err
- case ".annotations.zip":
- annotationsZip, err := d.AnnotationsZip(stubsType)
- return android.Paths{annotationsZip}, err
- case ".api_versions.xml":
- apiVersionsXmlFilePath, err := d.ApiVersionsXmlFilePath(stubsType)
- return android.Paths{apiVersionsXmlFilePath}, err
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-}
-
func (d *Droidstubs) AnnotationsZip(stubsType StubsType) (ret android.Path, err error) {
switch stubsType {
case Everything:
@@ -1363,6 +1303,46 @@
rule.Build("nullabilityWarningsCheck", "nullability warnings check")
}
+
+ d.setOutputFiles(ctx)
+}
+
+// This method sets the outputFiles property, which is used to set the
+// OutputFilesProvider later.
+// Droidstubs' tag supports specifying with the stubs type.
+// While supporting the pre-existing tags, it also supports tags with
+// the stubs type prefix. Some examples are shown below:
+// {.annotations.zip} - pre-existing behavior. Returns the path to the
+// annotation zip.
+// {.exportable} - Returns the path to the exportable stubs src jar.
+// {.exportable.annotations.zip} - Returns the path to the exportable
+// annotations zip file.
+// {.runtime.api_versions.xml} - Runtime stubs does not generate api versions
+// xml file. For unsupported combinations, the default everything output file
+// is returned.
+func (d *Droidstubs) setOutputFiles(ctx android.ModuleContext) {
+ tagToOutputFileFunc := map[string]func(StubsType) (android.Path, error){
+ "": d.StubsSrcJar,
+ ".docs.zip": d.DocZip,
+ ".api.txt": d.ApiFilePath,
+ android.DefaultDistTag: d.ApiFilePath,
+ ".removed-api.txt": d.RemovedApiFilePath,
+ ".annotations.zip": d.AnnotationsZip,
+ ".api_versions.xml": d.ApiVersionsXmlFilePath,
+ }
+ stubsTypeToPrefix := map[StubsType]string{
+ Everything: "",
+ Exportable: ".exportable",
+ }
+ for _, tag := range android.SortedKeys(tagToOutputFileFunc) {
+ for _, stubType := range android.SortedKeys(stubsTypeToPrefix) {
+ tagWithPrefix := stubsTypeToPrefix[stubType] + tag
+ outputFile, err := tagToOutputFileFunc[tag](stubType)
+ if err == nil {
+ ctx.SetOutputFiles(android.Paths{outputFile}, tagWithPrefix)
+ }
+ }
+ }
}
func (d *Droidstubs) createApiContribution(ctx android.DefaultableHookContext) {
diff --git a/java/java.go b/java/java.go
index a2fc5fb..5fdb4b8 100644
--- a/java/java.go
+++ b/java/java.go
@@ -977,6 +977,8 @@
TestOnly: Bool(j.sourceProperties.Test_only),
TopLevelTarget: j.sourceProperties.Top_level_test_target,
})
+
+ setOutputFiles(ctx, j.Module)
}
func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName string) {
@@ -1836,6 +1838,8 @@
// libraries. This is verified by TestBinary.
j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"),
ctx.ModuleName()+ext, j.wrapperFile)
+
+ setOutputFiles(ctx, j.Library.Module)
}
}
@@ -2752,6 +2756,9 @@
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
+
+ ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, "")
+ ctx.SetOutputFiles(android.Paths{j.combinedImplementationFile}, ".jar")
}
func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) {
@@ -2772,17 +2779,6 @@
ctx.InstallFile(installDir, jarName, outputFile)
}
-func (j *Import) OutputFiles(tag string) (android.Paths, error) {
- switch tag {
- case "", ".jar":
- return android.Paths{j.combinedImplementationFile}, nil
- default:
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
- }
-}
-
-var _ android.OutputFileProducer = (*Import)(nil)
-
func (j *Import) HeaderJars() android.Paths {
return android.PathsIfNonNil(j.combinedHeaderFile)
}
diff --git a/java/java_test.go b/java/java_test.go
index 2f27932..33079f3 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2993,23 +2993,23 @@
bar := result.ModuleForTests("bar", "android_common")
baz := result.ModuleForTests("baz", "android_common")
- fooOutputPath := android.OutputFileForModule(android.PathContext(nil), foo.Module(), "")
- barOutputPath := android.OutputFileForModule(android.PathContext(nil), bar.Module(), "")
- bazOutputPath := android.OutputFileForModule(android.PathContext(nil), baz.Module(), "")
+ fooOutputPaths := foo.OutputFiles(t, "")
+ barOutputPaths := bar.OutputFiles(t, "")
+ bazOutputPaths := baz.OutputFiles(t, "")
- android.AssertPathRelativeToTopEquals(t, "foo output path",
- "out/soong/.intermediates/foo/android_common/javac/foo.jar", fooOutputPath)
- android.AssertPathRelativeToTopEquals(t, "bar output path",
- "out/soong/.intermediates/bar/android_common/combined/bar.jar", barOutputPath)
- android.AssertPathRelativeToTopEquals(t, "baz output path",
- "out/soong/.intermediates/baz/android_common/combined/baz.jar", bazOutputPath)
+ android.AssertPathsRelativeToTopEquals(t, "foo output path",
+ []string{"out/soong/.intermediates/foo/android_common/javac/foo.jar"}, fooOutputPaths)
+ android.AssertPathsRelativeToTopEquals(t, "bar output path",
+ []string{"out/soong/.intermediates/bar/android_common/combined/bar.jar"}, barOutputPaths)
+ android.AssertPathsRelativeToTopEquals(t, "baz output path",
+ []string{"out/soong/.intermediates/baz/android_common/combined/baz.jar"}, bazOutputPaths)
android.AssertStringEquals(t, "foo relative output path",
- "foo.jar", fooOutputPath.Rel())
+ "foo.jar", fooOutputPaths[0].Rel())
android.AssertStringEquals(t, "bar relative output path",
- "bar.jar", barOutputPath.Rel())
+ "bar.jar", barOutputPaths[0].Rel())
android.AssertStringEquals(t, "baz relative output path",
- "baz.jar", bazOutputPath.Rel())
+ "baz.jar", bazOutputPaths[0].Rel())
}
func assertTestOnlyAndTopLevel(t *testing.T, ctx *android.TestResult, expectedTestOnly []string, expectedTopLevel []string) {
diff --git a/java/robolectric.go b/java/robolectric.go
index cb22fa0..4cad5b1 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -29,8 +29,12 @@
)
func init() {
- android.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
- android.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
+ RegisterRobolectricBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterRobolectricBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("android_robolectric_test", RobolectricTestFactory)
+ ctx.RegisterModuleType("android_robolectric_runtimes", robolectricRuntimesFactory)
}
var robolectricDefaultLibs = []string{
@@ -74,6 +78,8 @@
// Use strict mode to limit access of Robolectric API directly. See go/roboStrictMode
Strict_mode *bool
+
+ Jni_libs []string
}
type robolectricTest struct {
@@ -137,6 +143,10 @@
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(),
roboRuntimesTag, "robolectric-android-all-prebuilts")
+
+ for _, lib := range r.robolectricProperties.Jni_libs {
+ ctx.AddVariationDependencies(ctx.Config().BuildOSTarget.Variations(), jniLibTag, lib)
+ }
}
func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -270,6 +280,12 @@
installDeps = append(installDeps, installedData)
}
+ soInstallPath := installPath.Join(ctx, getLibPath(r.forceArchType))
+ for _, jniLib := range collectTransitiveJniDeps(ctx) {
+ installJni := ctx.InstallFile(soInstallPath, jniLib.path.Base(), jniLib.path)
+ installDeps = append(installDeps, installJni)
+ }
+
r.installFile = ctx.InstallFile(installPath, ctx.ModuleName()+".jar", r.combinedJar, installDeps...)
android.SetProvider(ctx, testing.TestModuleProviderKey, testing.TestModuleProviderData{})
}
diff --git a/java/robolectric_test.go b/java/robolectric_test.go
new file mode 100644
index 0000000..4775bac
--- /dev/null
+++ b/java/robolectric_test.go
@@ -0,0 +1,98 @@
+// Copyright 2024 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 (
+ "runtime"
+ "testing"
+
+ "android/soong/android"
+)
+
+var prepareRobolectricRuntime = android.GroupFixturePreparers(
+ android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
+ RegisterRobolectricBuildComponents(ctx)
+ }),
+ android.FixtureAddTextFile("robolectric/Android.bp", `
+ java_library {
+ name: "Robolectric_all-target_upstream",
+ srcs: ["Robo.java"]
+ }
+
+ java_library {
+ name: "mockito-robolectric-prebuilt",
+ srcs: ["Mockito.java"]
+ }
+
+ java_library {
+ name: "truth",
+ srcs: ["Truth.java"]
+ }
+
+ java_library {
+ name: "junitxml",
+ srcs: ["JUnitXml.java"]
+ }
+
+ java_library_host {
+ name: "robolectric-host-android_all",
+ srcs: ["Runtime.java"]
+ }
+
+ android_robolectric_runtimes {
+ name: "robolectric-android-all-prebuilts",
+ jars: ["android-all/Runtime.jar"],
+ lib: "robolectric-host-android_all",
+ }
+ `),
+)
+
+func TestRobolectricJniTest(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ t.Skip("requires linux")
+ }
+
+ ctx := android.GroupFixturePreparers(
+ PrepareForIntegrationTestWithJava,
+ prepareRobolectricRuntime,
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "inst-target",
+ srcs: ["App.java"],
+ platform_apis: true,
+ }
+
+ cc_library_shared {
+ name: "jni-lib1",
+ host_supported: true,
+ srcs: ["jni.cpp"],
+ }
+
+ android_robolectric_test {
+ name: "robo-test",
+ instrumentation_for: "inst-target",
+ srcs: ["FooTest.java"],
+ jni_libs: [
+ "jni-lib1"
+ ],
+ }
+ `)
+
+ CheckModuleHasDependency(t, ctx.TestContext, "robo-test", "android_common", "jni-lib1")
+
+ // Check that the .so files make it into the output.
+ module := ctx.ModuleForTests("robo-test", "android_common")
+ module.Output(installPathPrefix + "/robo-test/lib64/jni-lib1.so")
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e6cb6c4..1eb7ab8 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -538,9 +538,6 @@
// of the API.
Api_packages []string
- // list of package names that must be hidden from the API
- Hidden_api_packages []string
-
// the relative path to the directory containing the api specification files.
// Defaults to "api".
Api_dir *string
@@ -1086,57 +1083,26 @@
return regexp.MustCompile(fmt.Sprintf(`^\.(%s)\.(%s)$`, scopesRegexp, componentsRegexp))
}()
-// For OutputFileProducer interface
-//
-// .<scope>.<component name>, for all ComponentNames (for example: .public.removed-api.txt)
-func (c *commonToSdkLibraryAndImport) commonOutputFiles(tag string) (android.Paths, error) {
- if groups := tagSplitter.FindStringSubmatch(tag); groups != nil {
- scopeName := groups[1]
- component := groups[2]
-
- if scope, ok := scopeByName[scopeName]; ok {
- paths := c.findScopePaths(scope)
- if paths == nil {
- return nil, fmt.Errorf("%q does not provide api scope %s", c.module.RootLibraryName(), scopeName)
- }
-
- switch component {
- case stubsSourceComponentName:
- if paths.stubsSrcJar.Valid() {
- return android.Paths{paths.stubsSrcJar.Path()}, nil
- }
-
- case apiTxtComponentName:
- if paths.currentApiFilePath.Valid() {
- return android.Paths{paths.currentApiFilePath.Path()}, nil
- }
-
- case removedApiTxtComponentName:
- if paths.removedApiFilePath.Valid() {
- return android.Paths{paths.removedApiFilePath.Path()}, nil
- }
-
- case annotationsComponentName:
- if paths.annotationsZip.Valid() {
- return android.Paths{paths.annotationsZip.Path()}, nil
- }
- }
-
- return nil, fmt.Errorf("%s not available for api scope %s", component, scopeName)
- } else {
- return nil, fmt.Errorf("unknown scope %s in %s", scope, tag)
+func (module *commonToSdkLibraryAndImport) setOutputFiles(ctx android.ModuleContext) {
+ if module.doctagPaths != nil {
+ ctx.SetOutputFiles(module.doctagPaths, ".doctags")
+ }
+ for _, scopeName := range android.SortedKeys(scopeByName) {
+ paths := module.findScopePaths(scopeByName[scopeName])
+ if paths == nil {
+ continue
}
-
- } else {
- switch tag {
- case ".doctags":
- if c.doctagPaths != nil {
- return c.doctagPaths, nil
- } else {
- return nil, fmt.Errorf("no doctag_files specified on %s", c.module.RootLibraryName())
+ componentToOutput := map[string]android.OptionalPath{
+ stubsSourceComponentName: paths.stubsSrcJar,
+ apiTxtComponentName: paths.currentApiFilePath,
+ removedApiTxtComponentName: paths.removedApiFilePath,
+ annotationsComponentName: paths.annotationsZip,
+ }
+ for _, component := range android.SortedKeys(componentToOutput) {
+ if componentToOutput[component].Valid() {
+ ctx.SetOutputFiles(android.Paths{componentToOutput[component].Path()}, "."+scopeName+"."+component)
}
}
- return nil, nil
}
}
@@ -1579,20 +1545,6 @@
}
}
-func (module *SdkLibrary) OutputFiles(tag string) (android.Paths, error) {
- paths, err := module.commonOutputFiles(tag)
- if paths != nil || err != nil {
- return paths, err
- }
- if module.requiresRuntimeImplementationLibrary() {
- return module.implLibraryModule.OutputFiles(tag)
- }
- if tag == "" {
- return nil, nil
- }
- return nil, fmt.Errorf("unsupported module reference tag %q", tag)
-}
-
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if disableSourceApexVariant(ctx) {
// Prebuilts are active, do not create the installation rules for the source javalib.
@@ -1702,6 +1654,10 @@
}
}
android.SetProvider(ctx, android.AdditionalSdkInfoProvider, android.AdditionalSdkInfo{additionalSdkInfo})
+ module.setOutputFiles(ctx)
+ if module.requiresRuntimeImplementationLibrary() && module.implLibraryModule != nil {
+ setOutputFiles(ctx, module.implLibraryModule.Module)
+ }
}
func (module *SdkLibrary) BuiltInstalledForApex() []dexpreopterInstall {
@@ -2007,10 +1963,6 @@
if len(module.sdkLibraryProperties.Api_packages) != 0 {
droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
}
- if len(module.sdkLibraryProperties.Hidden_api_packages) != 0 {
- droidstubsArgs = append(droidstubsArgs,
- android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package "))
- }
droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
disabledWarnings := []string{"HiddenSuperclass"}
if proptools.BoolDefault(module.sdkLibraryProperties.Api_lint.Legacy_errors_allowed, true) {
@@ -2937,18 +2889,6 @@
var _ hiddenAPIModule = (*SdkLibraryImport)(nil)
-func (module *SdkLibraryImport) OutputFiles(tag string) (android.Paths, error) {
- paths, err := module.commonOutputFiles(tag)
- if paths != nil || err != nil {
- return paths, err
- }
- if module.implLibraryModule != nil {
- return module.implLibraryModule.OutputFiles(tag)
- } else {
- return nil, nil
- }
-}
-
func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
module.generateCommonBuildActions(ctx)
@@ -3031,6 +2971,11 @@
}
}
}
+
+ module.setOutputFiles(ctx)
+ if module.implLibraryModule != nil {
+ setOutputFiles(ctx, module.implLibraryModule.Module)
+ }
}
func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersion android.SdkSpec, headerJars bool) android.Paths {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 39f8c76..a8a1494 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -492,7 +492,7 @@
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": failed to get output file from module "foo" at tag ".public.annotations.zip": annotations.zip not available for api scope public`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".public.annotations.zip"`)).
RunTestWithBp(t, `
java_sdk_library {
name: "foo",
@@ -517,7 +517,7 @@
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
).
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`"foo" does not provide api scope system`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "bar" variant "android_common": unsupported module reference tag ".system.stubs.source"`)).
RunTestWithBp(t, `
java_sdk_library {
name: "foo",
@@ -606,7 +606,7 @@
t.Run("stubs.source", func(t *testing.T) {
prepareForJavaTest.
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`stubs.source not available for api scope public`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.stubs.source"`)).
RunTestWithBp(t, bp+`
java_library {
name: "bar",
@@ -621,7 +621,7 @@
t.Run("api.txt", func(t *testing.T) {
prepareForJavaTest.
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`api.txt not available for api scope public`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.api.txt"`)).
RunTestWithBp(t, bp+`
java_library {
name: "bar",
@@ -635,7 +635,7 @@
t.Run("removed-api.txt", func(t *testing.T) {
prepareForJavaTest.
- ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`removed-api.txt not available for api scope public`)).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`module "foo" is not a SourceFileProducer or having valid output file for tag ".public.removed-api.txt"`)).
RunTestWithBp(t, bp+`
java_library {
name: "bar",
diff --git a/rust/benchmark.go b/rust/benchmark.go
index c0f1e24..8c3e515 100644
--- a/rust/benchmark.go
+++ b/rust/benchmark.go
@@ -22,7 +22,7 @@
type BenchmarkProperties struct {
// Disables the creation of a test-specific directory when used with
// relative_install_path. Useful if several tests need to be in the same
- // directory, but test_per_src doesn't work.
+ // directory.
No_named_install_directory *bool
// the name of the test configuration (for example "AndroidBenchmark.xml") that should be
diff --git a/rust/rust.go b/rust/rust.go
index 6b7b2fb..3299861 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1107,7 +1107,6 @@
rlibDepTag = dependencyTag{name: "rlibTag", library: true}
dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true}
procMacroDepTag = dependencyTag{name: "procMacro", procMacro: true}
- testPerSrcDepTag = dependencyTag{name: "rust_unit_tests"}
sourceDepTag = dependencyTag{name: "source"}
dataLibDepTag = dependencyTag{name: "data lib"}
dataBinDepTag = dependencyTag{name: "data bin"}
diff --git a/rust/test.go b/rust/test.go
index 2583893..3087d8d 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -27,7 +27,7 @@
type TestProperties struct {
// Disables the creation of a test-specific directory when used with
// relative_install_path. Useful if several tests need to be in the same
- // directory, but test_per_src doesn't work.
+ // directory.
No_named_install_directory *bool
// the name of the test configuration (for example "AndroidTest.xml") that should be
diff --git a/ui/build/config.go b/ui/build/config.go
index 52c5e23..2470f84 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -121,6 +121,10 @@
// There's quite a bit of overlap with module-info.json and soong module graph. We
// could consider merging them.
moduleDebugFile string
+
+ // Whether to use n2 instead of ninja. This is controlled with the
+ // environment variable SOONG_USE_N2
+ useN2 bool
}
type NinjaWeightListSource uint
@@ -283,6 +287,10 @@
ret.moduleDebugFile, _ = filepath.Abs(shared.JoinPath(ret.SoongOutDir(), "soong-debug-info.json"))
}
+ if os.Getenv("SOONG_USE_N2") == "true" {
+ ret.useN2 = true
+ }
+
ret.environ.Unset(
// We're already using it
"USE_SOONG_UI",
@@ -339,6 +347,9 @@
// We read it here already, don't let others share in the fun
"GENERATE_SOONG_DEBUG",
+
+ // Use config.useN2 instead.
+ "SOONG_USE_N2",
)
if ret.UseGoma() || ret.ForceUseGoma() {
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index ae27330..1935e72 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -56,6 +56,17 @@
"-d", "stats",
"--frontend_file", fifo,
}
+ if config.useN2 {
+ executable = config.PrebuiltBuildTool("n2")
+ args = []string{
+ "-d", "trace",
+ // TODO: implement these features, or remove them.
+ //"-d", "keepdepfile",
+ //"-d", "keeprsp",
+ //"-d", "stats",
+ "--frontend-file", fifo,
+ }
+ }
args = append(args, config.NinjaArgs()...)
@@ -72,17 +83,21 @@
args = append(args, "-f", config.CombinedNinjaFile())
- args = append(args,
- "-o", "usesphonyoutputs=yes",
- "-w", "dupbuild=err",
- "-w", "missingdepfile=err")
+ if !config.useN2 {
+ args = append(args,
+ "-o", "usesphonyoutputs=yes",
+ "-w", "dupbuild=err",
+ "-w", "missingdepfile=err")
+ }
if !config.BuildBrokenMissingOutputs() {
// Missing outputs will be treated as errors.
// BUILD_BROKEN_MISSING_OUTPUTS can be used to bypass this check.
- args = append(args,
- "-w", "missingoutfile=err",
- )
+ if !config.useN2 {
+ args = append(args,
+ "-w", "missingoutfile=err",
+ )
+ }
}
cmd := Command(ctx, config, "ninja", executable, args...)
@@ -97,16 +112,22 @@
switch config.NinjaWeightListSource() {
case NINJA_LOG:
- cmd.Args = append(cmd.Args, "-o", "usesninjalogasweightlist=yes")
+ if !config.useN2 {
+ cmd.Args = append(cmd.Args, "-o", "usesninjalogasweightlist=yes")
+ }
case EVENLY_DISTRIBUTED:
// pass empty weight list means ninja considers every tasks's weight as 1(default value).
- cmd.Args = append(cmd.Args, "-o", "usesweightlist=/dev/null")
+ if !config.useN2 {
+ cmd.Args = append(cmd.Args, "-o", "usesweightlist=/dev/null")
+ }
case EXTERNAL_FILE:
fallthrough
case HINT_FROM_SOONG:
// The weight list is already copied/generated.
- ninjaWeightListPath := filepath.Join(config.OutDir(), ninjaWeightListFileName)
- cmd.Args = append(cmd.Args, "-o", "usesweightlist="+ninjaWeightListPath)
+ if !config.useN2 {
+ ninjaWeightListPath := filepath.Join(config.OutDir(), ninjaWeightListFileName)
+ cmd.Args = append(cmd.Args, "-o", "usesweightlist="+ninjaWeightListPath)
+ }
}
// Allow both NINJA_ARGS and NINJA_EXTRA_ARGS, since both have been
@@ -206,11 +227,16 @@
// We don't want this build broken flag to cause reanalysis, so allow it through to the
// actions.
"BUILD_BROKEN_INCORRECT_PARTITION_IMAGES",
+ "SOONG_USE_N2",
+ "RUST_BACKTRACE",
}, config.BuildBrokenNinjaUsesEnvVars()...)...)
}
cmd.Environment.Set("DIST_DIR", config.DistDir())
cmd.Environment.Set("SHELL", "/bin/bash")
+ if config.useN2 {
+ cmd.Environment.Set("RUST_BACKTRACE", "1")
+ }
// Print the environment variables that Ninja is operating in.
ctx.Verboseln("Ninja environment: ")
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 77fee0a..e18cc25 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -638,6 +638,22 @@
"--frontend_file", fifo,
"-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"),
}
+ if config.useN2 {
+ ninjaArgs = []string{
+ // TODO: implement these features, or remove them.
+ //"-d", "keepdepfile",
+ //"-d", "stats",
+ //"-o", "usesphonyoutputs=yes",
+ //"-o", "preremoveoutputs=yes",
+ //"-w", "dupbuild=err",
+ //"-w", "outputdir=err",
+ //"-w", "missingoutfile=err",
+ "-v",
+ "-j", strconv.Itoa(config.Parallel()),
+ "--frontend-file", fifo,
+ "-f", filepath.Join(config.SoongOutDir(), "bootstrap.ninja"),
+ }
+ }
if extra, ok := config.Environment().Get("SOONG_UI_NINJA_ARGS"); ok {
ctx.Printf(`CAUTION: arguments in $SOONG_UI_NINJA_ARGS=%q, e.g. "-n", can make soong_build FAIL or INCORRECT`, extra)
@@ -645,8 +661,13 @@
}
ninjaArgs = append(ninjaArgs, targets...)
+ ninjaCmd := config.PrebuiltBuildTool("ninja")
+ if config.useN2 {
+ ninjaCmd = config.PrebuiltBuildTool("n2")
+ }
+
cmd := Command(ctx, config, "soong bootstrap",
- config.PrebuiltBuildTool("ninja"), ninjaArgs...)
+ ninjaCmd, ninjaArgs...)
var ninjaEnv Environment