Merge "Remove special case code for obsolete files"
diff --git a/android/Android.bp b/android/Android.bp
index a32e8f2..f5e5606 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -78,9 +78,6 @@
"variable.go",
"visibility.go",
"writedocs.go",
-
- // Lock down environment access last
- "env.go",
],
testSrcs: [
"android_test.go",
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 31c31fb..2697007 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -67,7 +67,7 @@
// TODO(cparsons): Other cquery-related methods should be added here.
// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
- GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool)
+ GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error)
// ** End cquery methods
@@ -132,9 +132,9 @@
return result, ok
}
-func (m MockBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool) {
+func (m MockBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
result, ok := m.LabelToCcInfo[label]
- return result, ok
+ return result, ok, nil
}
func (m MockBazelContext) InvokeBazel() error {
@@ -163,21 +163,22 @@
return ret, ok
}
-func (bazelCtx *bazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool) {
+func (bazelCtx *bazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
result, ok := bazelCtx.cquery(label, cquery.GetCcInfo, archType)
if !ok {
- return cquery.CcInfo{}, ok
+ return cquery.CcInfo{}, ok, nil
}
bazelOutput := strings.TrimSpace(result)
- return cquery.GetCcInfo.ParseResult(bazelOutput), ok
+ ret, err := cquery.GetCcInfo.ParseResult(bazelOutput)
+ return ret, ok, err
}
func (n noopBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
panic("unimplemented")
}
-func (n noopBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool) {
+func (n noopBazelContext) GetCcInfo(label string, archType ArchType) (cquery.CcInfo, bool, error) {
panic("unimplemented")
}
diff --git a/android/config.go b/android/config.go
index 80651bb..c566e34 100644
--- a/android/config.go
+++ b/android/config.go
@@ -345,7 +345,7 @@
// multiple runs in the same program execution is carried over (such as Bazel
// context or environment deps).
func ConfigForAdditionalRun(c Config) (Config, error) {
- newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile)
+ newConfig, err := NewConfig(c.srcDir, c.buildDir, c.moduleListFile, c.env)
if err != nil {
return Config{}, err
}
@@ -356,12 +356,12 @@
// NewConfig creates a new Config object. The srcDir argument specifies the path
// to the root source directory. It also loads the config file, if found.
-func NewConfig(srcDir, buildDir string, moduleListFile string) (Config, error) {
+func NewConfig(srcDir, buildDir string, moduleListFile string, availableEnv map[string]string) (Config, error) {
// Make a config with default options.
config := &config{
ProductVariablesFileName: filepath.Join(buildDir, productVariablesFileName),
- env: originalEnv,
+ env: availableEnv,
srcDir: srcDir,
buildDir: buildDir,
diff --git a/android/env.go b/android/env.go
deleted file mode 100644
index 725a145..0000000
--- a/android/env.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 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 android
-
-import (
- "android/soong/shared"
-)
-
-// This file supports dependencies on environment variables. During build
-// manifest generation, any dependency on an environment variable is added to a
-// list. At the end of the build, a JSON file called soong.environment.used is
-// written containing the current value of all used environment variables. The
-// next time the top-level build script is run, soong_ui parses the compare the
-// contents of the used environment variables, then, if they changed, deletes
-// soong.environment.used to cause a rebuild.
-//
-// The dependency of build.ninja on soong.environment.used is declared in
-// build.ninja.d
-
-var originalEnv map[string]string
-
-func InitEnvironment(envFile string) {
- var err error
- originalEnv, err = shared.EnvFromFile(envFile)
- if err != nil {
- panic(err)
- }
-}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index ee4255e..f39c7e3 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4375,9 +4375,7 @@
// These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the
// propagation of paths to dex implementation jars from the former to the latter.
func TestPrebuiltExportDexImplementationJars(t *testing.T) {
- transform := func(config *dexpreopt.GlobalConfig) {
- // Empty transformation.
- }
+ transform := android.NullFixturePreparer
checkDexJarBuildPath := func(t *testing.T, ctx *android.TestContext, name string) {
// Make sure the import has been given the correct path to the dex jar.
@@ -4547,9 +4545,7 @@
}
func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) {
- transform := func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"myapex:libfoo", "myapex:libbar"})
- }
+ preparer := java.FixtureConfigureBootJars("myapex:libfoo", "myapex:libbar")
checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) {
t.Helper()
@@ -4605,7 +4601,7 @@
}
`
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer)
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")
@@ -4639,7 +4635,7 @@
}
`
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer)
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")
@@ -4698,7 +4694,7 @@
// prebuilt_apex module always depends on the prebuilt, and so it doesn't
// find the dex boot jar in it. We either need to disable the source libfoo
// or make the prebuilt libfoo preferred.
- testDexpreoptWithApexes(t, bp, "failed to find a dex jar path for module 'libfoo'", transform)
+ testDexpreoptWithApexes(t, bp, "failed to find a dex jar path for module 'libfoo'", preparer)
})
t.Run("prebuilt library preferred with source", func(t *testing.T) {
@@ -4746,7 +4742,7 @@
}
`
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer)
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")
@@ -4813,7 +4809,7 @@
}
`
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer)
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")
@@ -4830,7 +4826,7 @@
name: "myapex",
enabled: false,
key: "myapex.key",
- java_libs: ["libfoo"],
+ java_libs: ["libfoo", "libbar"],
}
apex_key {
@@ -4882,14 +4878,14 @@
}
`
- ctx := testDexpreoptWithApexes(t, bp, "", transform)
+ ctx := testDexpreoptWithApexes(t, bp, "", preparer)
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, `
-.intermediates/prebuilt_libbar/android_common_prebuilt_myapex/hiddenapi/index.csv
-.intermediates/prebuilt_libfoo/android_common_prebuilt_myapex/hiddenapi/index.csv
+.intermediates/prebuilt_libbar/android_common_myapex/hiddenapi/index.csv
+.intermediates/prebuilt_libfoo/android_common_myapex/hiddenapi/index.csv
`)
})
}
@@ -6440,7 +6436,7 @@
android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
}
-func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
+func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, preparer android.FixturePreparer) {
t.Helper()
bp := `
@@ -6528,10 +6524,10 @@
}
`
- testDexpreoptWithApexes(t, bp, errmsg, transformDexpreoptConfig)
+ testDexpreoptWithApexes(t, bp, errmsg, preparer)
}
-func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) *android.TestContext {
+func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.FixturePreparer) *android.TestContext {
t.Helper()
fs := android.MockFS{
@@ -6557,18 +6553,13 @@
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
- }),
+ preparer,
fs.AddToFixture(),
+ android.FixtureAddTextFile("frameworks/base/boot/Android.bp", `
+ platform_bootclasspath {
+ name: "platform-bootclasspath",
+ }
+ `),
).
ExtendWithErrorHandler(errorHandler).
RunTestWithBp(t, bp)
@@ -6608,92 +6599,95 @@
}
func TestNoUpdatableJarsInBootImage(t *testing.T) {
- var err string
- var transform func(*dexpreopt.GlobalConfig)
+ // Set the BootJars in dexpreopt.GlobalConfig and productVariables to the same value. This can
+ // result in an invalid configuration as it does not set the ArtApexJars and allows art apex
+ // modules to be included in the BootJars.
+ prepareSetBootJars := func(bootJars ...string) android.FixturePreparer {
+ return android.GroupFixturePreparers(
+ dexpreopt.FixtureSetBootJars(bootJars...),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
+ }),
+ )
+ }
+
+ // Set the ArtApexJars and BootJars in dexpreopt.GlobalConfig and productVariables all to the
+ // same value. This can result in an invalid configuration as it allows non art apex jars to be
+ // specified in the ArtApexJars configuration.
+ prepareSetArtJars := func(bootJars ...string) android.FixturePreparer {
+ return android.GroupFixturePreparers(
+ dexpreopt.FixtureSetArtBootJars(bootJars...),
+ dexpreopt.FixtureSetBootJars(bootJars...),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
+ }),
+ )
+ }
t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
- transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"com.android.art.debug:some-art-lib"})
- }
- testNoUpdatableJarsInBootImage(t, "", transform)
+ preparer := java.FixtureConfigureBootJars("com.android.art.debug:some-art-lib")
+ testNoUpdatableJarsInBootImage(t, "", preparer)
})
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
- err = `module "some-art-lib" from updatable apexes \["com.android.art.debug"\] is not allowed in the framework boot image`
- transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"com.android.art.debug:some-art-lib"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `module "some-art-lib" from updatable apexes \["com.android.art.debug"\] is not allowed in the framework boot image`
+ // Update the dexpreopt BootJars directly.
+ preparer := prepareSetBootJars("com.android.art.debug:some-art-lib")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the ART boot image`
- transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"some-updatable-apex:some-updatable-apex-lib"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the ART boot image`
+ // Update the dexpreopt ArtApexJars directly.
+ preparer := prepareSetArtJars("some-updatable-apex:some-updatable-apex-lib")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- err = `module "some-non-updatable-apex-lib" is not allowed in the ART boot image`
- transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `module "some-non-updatable-apex-lib" is not allowed in the ART boot image`
+ // Update the dexpreopt ArtApexJars directly.
+ preparer := prepareSetArtJars("some-non-updatable-apex:some-non-updatable-apex-lib")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
- err = `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image`
- transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"some-updatable-apex:some-updatable-apex-lib"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image`
+ preparer := java.FixtureConfigureBootJars("some-updatable-apex:some-updatable-apex-lib")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
- transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"some-non-updatable-apex:some-non-updatable-apex-lib"})
- }
- testNoUpdatableJarsInBootImage(t, "", transform)
+ preparer := java.FixtureConfigureBootJars("some-non-updatable-apex:some-non-updatable-apex-lib")
+ testNoUpdatableJarsInBootImage(t, "", preparer)
})
t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
- err = "failed to find a dex jar path for module 'nonexistent'"
- transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"platform:nonexistent"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `"platform-bootclasspath" depends on undefined module "nonexistent"`
+ preparer := java.FixtureConfigureBootJars("platform:nonexistent")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
- err = "failed to find a dex jar path for module 'nonexistent'"
- transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"platform:nonexistent"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `"platform-bootclasspath" depends on undefined module "nonexistent"`
+ preparer := java.FixtureConfigureBootJars("platform:nonexistent")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
- err = `module "some-platform-lib" is not allowed in the ART boot image`
- transform = func(config *dexpreopt.GlobalConfig) {
- config.ArtApexJars = android.CreateTestConfiguredJarList([]string{"platform:some-platform-lib"})
- }
- testNoUpdatableJarsInBootImage(t, err, transform)
+ err := `module "some-platform-lib" is not allowed in the ART boot image`
+ // Update the dexpreopt ArtApexJars directly.
+ preparer := prepareSetArtJars("platform:some-platform-lib")
+ testNoUpdatableJarsInBootImage(t, err, preparer)
})
t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
- transform = func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"platform:some-platform-lib"})
- }
- testNoUpdatableJarsInBootImage(t, "", transform)
+ preparer := java.FixtureConfigureBootJars("platform:some-platform-lib")
+ testNoUpdatableJarsInBootImage(t, "", preparer)
})
-
}
func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) {
- transform := func(config *dexpreopt.GlobalConfig) {
- config.BootJars = android.CreateTestConfiguredJarList([]string{"myapex:libfoo"})
- }
+ preparer := java.FixtureConfigureBootJars("myapex:libfoo")
t.Run("prebuilt no source", func(t *testing.T) {
testDexpreoptWithApexes(t, `
prebuilt_apex {
@@ -6713,7 +6707,7 @@
name: "libfoo",
jars: ["libfoo.jar"],
}
-`, "", transform)
+`, "", preparer)
})
t.Run("prebuilt no source", func(t *testing.T) {
@@ -6735,7 +6729,7 @@
name: "libfoo",
jars: ["libfoo.jar"],
}
-`, "", transform)
+`, "", preparer)
})
}
diff --git a/apex/boot_image_test.go b/apex/boot_image_test.go
index aa0d9c4..d447d70 100644
--- a/apex/boot_image_test.go
+++ b/apex/boot_image_test.go
@@ -19,7 +19,6 @@
"testing"
"android/soong/android"
- "android/soong/dexpreopt"
"android/soong/java"
)
@@ -42,8 +41,7 @@
result := android.GroupFixturePreparers(
prepareForTestWithBootImage,
// Configure some libraries in the art and framework boot images.
- dexpreopt.FixtureSetArtBootJars("com.android.art:baz", "com.android.art:quuz"),
- dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"),
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo", "platform:bar"),
prepareForTestWithArtApex,
java.PrepareForTestWithJavaSdkLibraryFiles,
@@ -169,7 +167,7 @@
prepareForTestWithArtApex,
// Configure some libraries in the art boot image.
- dexpreopt.FixtureSetArtBootJars("com.android.art:foo", "com.android.art:bar"),
+ java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
).RunTestWithBp(t, `
apex {
name: "com.android.art",
@@ -264,7 +262,7 @@
}),
// Configure some libraries in the art boot image.
- dexpreopt.FixtureSetArtBootJars("com.android.art:foo", "com.android.art:bar"),
+ java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
).RunTestWithBp(t, `
prebuilt_apex {
name: "com.android.art",
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index 2ea6401..74830d3 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -18,7 +18,6 @@
"testing"
"android/soong/android"
- "android/soong/dexpreopt"
"android/soong/java"
"github.com/google/blueprint"
)
@@ -37,9 +36,8 @@
prepareForTestWithArtApex,
prepareForTestWithMyapex,
// Configure some libraries in the art and framework boot images.
- dexpreopt.FixtureSetArtBootJars("com.android.art:baz", "com.android.art:quuz"),
- dexpreopt.FixtureSetBootJars("platform:foo"),
- dexpreopt.FixtureSetUpdatableBootJars("myapex:bar"),
+ java.FixtureConfigureBootJars("com.android.art:baz", "com.android.art:quuz", "platform:foo"),
+ java.FixtureConfigureUpdatableBootJars("myapex:bar"),
java.PrepareForTestWithJavaSdkLibraryFiles,
java.FixtureWithLastReleaseApis("foo"),
).RunTestWithBp(t, `
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 10a70a3..a9d24a7 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -172,7 +172,7 @@
// Create an ApexInfo for the prebuilt_apex.
apexInfo := android.ApexInfo{
- ApexVariationName: mctx.ModuleName(),
+ ApexVariationName: android.RemoveOptionalPrebuiltPrefix(mctx.ModuleName()),
InApexes: []string{mctx.ModuleName()},
ApexContents: []*android.ApexContents{apexContents},
ForPrebuiltApex: true,
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 7bd12a8..8049108 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -1,6 +1,7 @@
package cquery
import (
+ "fmt"
"strings"
)
@@ -39,7 +40,7 @@
// The given rawString must correspond to the string output which was created by evaluating the
// Starlark given in StarlarkFunctionBody.
func (g getOutputFilesRequestType) ParseResult(rawString string) []string {
- return strings.Split(rawString, ", ")
+ return splitOrEmpty(rawString, ", ")
}
type getCcInfoType struct{}
@@ -85,11 +86,14 @@
// ParseResult returns a value obtained by parsing the result of the request's Starlark function.
// The given rawString must correspond to the string output which was created by evaluating the
// Starlark given in StarlarkFunctionBody.
-func (g getCcInfoType) ParseResult(rawString string) CcInfo {
+func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
var outputFiles []string
var ccObjects []string
splitString := strings.Split(rawString, "|")
+ if expectedLen := 3; len(splitString) != expectedLen {
+ return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
+ }
outputFilesString := splitString[0]
ccStaticLibrariesString := splitString[1]
ccObjectsString := splitString[2]
@@ -100,7 +104,7 @@
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcStaticLibraryFiles: ccStaticLibraries,
- }
+ }, nil
}
// splitOrEmpty is a modification of strings.Split() that returns an empty list
diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go
new file mode 100644
index 0000000..56e03e2
--- /dev/null
+++ b/bazel/cquery/request_type_test.go
@@ -0,0 +1,89 @@
+package cquery
+
+import (
+ "fmt"
+ "reflect"
+ "testing"
+)
+
+func TestGetOutputFilesParseResults(t *testing.T) {
+ testCases := []struct {
+ description string
+ input string
+ expectedOutput []string
+ }{
+ {
+ description: "no result",
+ input: "",
+ expectedOutput: []string{},
+ },
+ {
+ description: "one result",
+ input: "test",
+ expectedOutput: []string{"test"},
+ },
+ {
+ description: "splits on comma with space",
+ input: "foo, bar",
+ expectedOutput: []string{"foo", "bar"},
+ },
+ }
+ for _, tc := range testCases {
+ actualOutput := GetOutputFiles.ParseResult(tc.input)
+ if !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
+ t.Errorf("%q: expected %#v != actual %#v", tc.description, tc.expectedOutput, actualOutput)
+ }
+ }
+}
+
+func TestGetCcInfoParseResults(t *testing.T) {
+ testCases := []struct {
+ description string
+ input string
+ expectedOutput CcInfo
+ expectedErrorMessage string
+ }{
+ {
+ description: "no result",
+ input: "||",
+ expectedOutput: CcInfo{
+ OutputFiles: []string{},
+ CcObjectFiles: []string{},
+ CcStaticLibraryFiles: []string{},
+ },
+ },
+ {
+ description: "only output",
+ input: "test||",
+ expectedOutput: CcInfo{
+ OutputFiles: []string{"test"},
+ CcObjectFiles: []string{},
+ CcStaticLibraryFiles: []string{},
+ },
+ },
+ {
+ description: "all items set",
+ input: "out1, out2|static_lib1, static_lib2|object1, object2",
+ expectedOutput: CcInfo{
+ OutputFiles: []string{"out1", "out2"},
+ CcObjectFiles: []string{"object1", "object2"},
+ CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
+ },
+ },
+ {
+ description: "too few result splits",
+ input: "|",
+ expectedOutput: CcInfo{},
+ expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 3, []string{"", ""}),
+ },
+ }
+ for _, tc := range testCases {
+ actualOutput, err := GetCcInfo.ParseResult(tc.input)
+ if (err == nil && tc.expectedErrorMessage != "") ||
+ (err != nil && err.Error() != tc.expectedErrorMessage) {
+ t.Errorf("%q: expected Error %s, got %s", tc.description, tc.expectedErrorMessage, err)
+ } else if err == nil && !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
+ t.Errorf("%q: expected %#v != actual %#v", tc.description, tc.expectedOutput, actualOutput)
+ }
+ }
+}
diff --git a/cc/library.go b/cc/library.go
index cb0aebf..53be3a5 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -483,12 +483,16 @@
func (handler *staticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
- outputPaths := ccInfo.OutputFiles
- objPaths := ccInfo.CcObjectFiles
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ if err != nil {
+ ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
+ return false
+ }
if !ok {
return ok
}
+ outputPaths := ccInfo.OutputFiles
+ objPaths := ccInfo.CcObjectFiles
if len(outputPaths) > 1 {
// TODO(cparsons): This is actually expected behavior for static libraries with no srcs.
// We should support this.
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 7857432..c19b1ff 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -329,11 +329,14 @@
func (h *prebuiltStaticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
bazelCtx := ctx.Config().BazelContext
- ccInfo, ok := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
- staticLibs := ccInfo.CcStaticLibraryFiles
+ ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+ if err != nil {
+ ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err)
+ }
if !ok {
return false
}
+ staticLibs := ccInfo.CcStaticLibraryFiles
if len(staticLibs) > 1 {
ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
return false
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index af05102..aa70768 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -559,10 +559,18 @@
return nil
}
+ // Flags specified directly to this module.
p.libraryDecorator.reexportDirs(android.PathsForModuleSrc(ctx, p.properties.Export_include_dirs)...)
p.libraryDecorator.reexportSystemDirs(android.PathsForModuleSrc(ctx, p.properties.Export_system_include_dirs)...)
p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
+ // Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
+ p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
+ p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
+ p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
+ p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
+ p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
+
in := android.PathForModuleSrc(ctx, *p.properties.Src)
p.unstrippedOutputFile = in
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 1c3f1b4..66396f7 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -424,6 +424,20 @@
srcs: ["client.cpp"],
}
+ cc_library_shared {
+ name: "libclient_cfi",
+ vendor: true,
+ nocrt: true,
+ no_libcrt: true,
+ stl: "none",
+ system_shared_libs: [],
+ static_libs: ["libvendor"],
+ sanitize: {
+ cfi: true,
+ },
+ srcs: ["client.cpp"],
+ }
+
cc_binary {
name: "bin_without_snapshot",
vendor: true,
@@ -492,13 +506,13 @@
arch: {
arm64: {
src: "libvndk.a",
- export_include_dirs: ["include/libvndk"],
},
arm: {
src: "libvndk.a",
- export_include_dirs: ["include/libvndk"],
},
},
+ shared_libs: ["libvndk"],
+ export_shared_lib_headers: ["libvndk"],
}
vendor_snapshot_shared {
@@ -584,10 +598,18 @@
vendor: true,
arch: {
arm64: {
+ cfi: {
+ src: "libvendor.cfi.a",
+ export_include_dirs: ["include/libvendor_cfi"],
+ },
src: "libvendor.a",
export_include_dirs: ["include/libvendor"],
},
arm: {
+ cfi: {
+ src: "libvendor.cfi.a",
+ export_include_dirs: ["include/libvendor_cfi"],
+ },
src: "libvendor.a",
export_include_dirs: ["include/libvendor"],
},
@@ -726,29 +748,31 @@
depsBp := GatherRequiredDepsForTest(android.Android)
mockFS := map[string][]byte{
- "deps/Android.bp": []byte(depsBp),
- "framework/Android.bp": []byte(frameworkBp),
- "framework/symbol.txt": nil,
- "vendor/Android.bp": []byte(vendorProprietaryBp),
- "vendor/bin": nil,
- "vendor/bin32": nil,
- "vendor/bin.cpp": nil,
- "vendor/client.cpp": nil,
- "vendor/include/libvndk/a.h": nil,
- "vendor/include/libvendor/b.h": nil,
- "vendor/libc++_static.a": nil,
- "vendor/libc++demangle.a": nil,
- "vendor/libgcc_striped.a": nil,
- "vendor/libvndk.a": nil,
- "vendor/libvendor.a": nil,
- "vendor/libvendor.so": nil,
- "vendor/lib32.a": nil,
- "vendor/lib32.so": nil,
- "vendor/lib64.a": nil,
- "vendor/lib64.so": nil,
- "vndk/Android.bp": []byte(vndkBp),
- "vndk/include/libvndk/a.h": nil,
- "vndk/libvndk.so": nil,
+ "deps/Android.bp": []byte(depsBp),
+ "framework/Android.bp": []byte(frameworkBp),
+ "framework/symbol.txt": nil,
+ "vendor/Android.bp": []byte(vendorProprietaryBp),
+ "vendor/bin": nil,
+ "vendor/bin32": nil,
+ "vendor/bin.cpp": nil,
+ "vendor/client.cpp": nil,
+ "vendor/include/libvndk/a.h": nil,
+ "vendor/include/libvendor/b.h": nil,
+ "vendor/include/libvendor_cfi/c.h": nil,
+ "vendor/libc++_static.a": nil,
+ "vendor/libc++demangle.a": nil,
+ "vendor/libgcc_striped.a": nil,
+ "vendor/libvndk.a": nil,
+ "vendor/libvendor.a": nil,
+ "vendor/libvendor.cfi.a": nil,
+ "vendor/libvendor.so": nil,
+ "vendor/lib32.a": nil,
+ "vendor/lib32.so": nil,
+ "vendor/lib64.a": nil,
+ "vendor/lib64.so": nil,
+ "vndk/Android.bp": []byte(vndkBp),
+ "vndk/include/libvndk/a.h": nil,
+ "vndk/libvndk.so": nil,
}
config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
@@ -766,6 +790,9 @@
staticVariant := "android_vendor.30_arm64_armv8-a_static"
binaryVariant := "android_vendor.30_arm64_armv8-a"
+ sharedCfiVariant := "android_vendor.30_arm64_armv8-a_shared_cfi"
+ staticCfiVariant := "android_vendor.30_arm64_armv8-a_static_cfi"
+
shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared"
binary32Variant := "android_vendor.30_arm_armv7-a-neon"
@@ -808,9 +835,22 @@
t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
}
- // bin_without_snapshot uses libvndk.vendor_static.30.arm64
+ // libclient_cfi uses libvendor.vendor_static.30.arm64's cfi variant
+ libclientCfiCcFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("cc").Args["cFlags"]
+ if !strings.Contains(libclientCfiCcFlags, "-Ivendor/include/libvendor_cfi") {
+ t.Errorf("flags for libclient_cfi must contain %#v, but was %#v.",
+ "-Ivendor/include/libvendor_cfi", libclientCfiCcFlags)
+ }
+
+ libclientCfiLdFlags := ctx.ModuleForTests("libclient_cfi", sharedCfiVariant).Rule("ld").Args["libFlags"]
+ libvendorCfiOutputPaths := getOutputPaths(ctx, staticCfiVariant, []string{"libvendor.vendor_static.30.arm64"})
+ if !strings.Contains(libclientCfiLdFlags, libvendorCfiOutputPaths[0].String()) {
+ t.Errorf("libflags for libclientCfi must contain %#v, but was %#v", libvendorCfiOutputPaths[0], libclientCfiLdFlags)
+ }
+
+ // bin_without_snapshot uses libvndk.vendor_static.30.arm64 (which reexports vndk's exported headers)
binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
- if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
+ if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivndk/include/libvndk") {
t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
"-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 431d621..a4554fc 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -75,8 +75,8 @@
return ctx
}
-func newConfig(srcDir, outDir string) android.Config {
- configuration, err := android.NewConfig(srcDir, outDir, bootstrap.CmdlineModuleListFile())
+func newConfig(srcDir, outDir string, availableEnv map[string]string) android.Config {
+ configuration, err := android.NewConfig(srcDir, outDir, bootstrap.CmdlineModuleListFile(), availableEnv)
if err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
@@ -188,12 +188,31 @@
shared.ReexecWithDelveMaybe(delveListen, delvePath)
android.InitSandbox(topDir)
- android.InitEnvironment(shared.JoinPath(topDir, outDir, "soong.environment.available"))
- usedVariablesFile := shared.JoinPath(outDir, "soong.environment.used")
+ // soong_ui dumps the available environment variables to
+ // soong.environment.available . Then soong_build itself is run with an empty
+ // environment so that the only way environment variables can be accessed is
+ // using Config, which tracks access to them.
+
+ // At the end of the build, a file called soong.environment.used is written
+ // containing the current value of all used environment variables. The next
+ // time soong_ui is run, it checks whether any environment variables that was
+ // used had changed and if so, it deletes soong.environment.used to cause a
+ // rebuild.
+ //
+ // The dependency of build.ninja on soong.environment.used is declared in
+ // build.ninja.d
+ availableEnvFile := shared.JoinPath(topDir, outDir, "soong.environment.available")
+ usedEnvFile := shared.JoinPath(topDir, outDir, "soong.environment.used")
+ availableEnv, err := shared.EnvFromFile(availableEnvFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "error reading available environment file %s: %s\n", availableEnvFile, err)
+ os.Exit(1)
+ }
+
// The top-level Blueprints file is passed as the first argument.
srcDir := filepath.Dir(flag.Arg(0))
- configuration := newConfig(srcDir, outDir)
+ configuration := newConfig(srcDir, outDir, availableEnv)
extraNinjaDeps := []string{
configuration.ProductVariablesFileName,
shared.JoinPath(outDir, "soong.environment.used"),
@@ -219,19 +238,19 @@
}
doChosenActivity(configuration, extraNinjaDeps)
- writeUsedVariablesFile(shared.JoinPath(topDir, usedVariablesFile), configuration)
+ writeUsedEnvironmentFile(usedEnvFile, configuration)
}
-func writeUsedVariablesFile(path string, configuration android.Config) {
+func writeUsedEnvironmentFile(path string, configuration android.Config) {
data, err := shared.EnvFileContents(configuration.EnvDeps())
if err != nil {
- fmt.Fprintf(os.Stderr, "error writing used variables file %s: %s\n", path, err)
+ fmt.Fprintf(os.Stderr, "error writing used environment file %s: %s\n", path, err)
os.Exit(1)
}
err = ioutil.WriteFile(path, data, 0666)
if err != nil {
- fmt.Fprintf(os.Stderr, "error writing used variables file %s: %s\n", path, err)
+ fmt.Fprintf(os.Stderr, "error writing used environment file %s: %s\n", path, err)
os.Exit(1)
}
diff --git a/java/hiddenapi_singleton_test.go b/java/hiddenapi_singleton_test.go
index 5c449e5..e5e1c25 100644
--- a/java/hiddenapi_singleton_test.go
+++ b/java/hiddenapi_singleton_test.go
@@ -23,12 +23,6 @@
"github.com/google/blueprint/proptools"
)
-func fixtureSetBootJarsProductVariable(bootJars ...string) android.FixturePreparer {
- return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
- })
-}
-
func fixtureSetPrebuiltHiddenApiDirProductVariable(prebuiltHiddenApiDir *string) android.FixturePreparer {
return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.PrebuiltHiddenApiDir = prebuiltHiddenApiDir
@@ -41,7 +35,7 @@
func TestHiddenAPISingleton(t *testing.T) {
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -61,7 +55,7 @@
hiddenApiFixtureFactory,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("bar"),
- fixtureSetBootJarsProductVariable("platform:foo", "platform:bar"),
+ FixtureConfigureBootJars("platform:foo", "platform:bar"),
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -119,7 +113,7 @@
android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(expectedErrorMessage)).
RunTestWithBp(t, `
java_library {
@@ -139,7 +133,7 @@
func TestHiddenAPISingletonWithPrebuilt(t *testing.T) {
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
).RunTestWithBp(t, `
java_import {
name: "foo",
@@ -157,7 +151,7 @@
func TestHiddenAPISingletonWithPrebuiltUseSource(t *testing.T) {
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -185,7 +179,7 @@
func TestHiddenAPISingletonWithPrebuiltOverrideSource(t *testing.T) {
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
).RunTestWithBp(t, `
java_library {
name: "foo",
@@ -295,7 +289,7 @@
result := android.GroupFixturePreparers(
hiddenApiFixtureFactory,
- fixtureSetBootJarsProductVariable("platform:foo"),
+ FixtureConfigureBootJars("platform:foo"),
fixtureSetPrebuiltHiddenApiDirProductVariable(&prebuiltHiddenApiDir),
).RunTestWithBp(t, `
java_import {
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index d98ce67..d700980 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -208,7 +208,30 @@
// error, unless missing dependencies are allowed. The simplest way to handle that is to add a
// dependency that will not be satisfied and the default behavior will handle it.
if !addedDep {
- ctx.AddFarVariationDependencies(variations, tag, name)
+ // Add dependency on the unprefixed (i.e. source or renamed prebuilt) module which we know does
+ // not exist. The resulting error message will contain useful information about the available
+ // variants.
+ reportMissingVariationDependency(ctx, variations, name)
+
+ // Add dependency on the missing prefixed prebuilt variant too if a module with that name exists
+ // so that information about its available variants will be reported too.
+ if ctx.OtherModuleExists(prebuiltName) {
+ reportMissingVariationDependency(ctx, variations, prebuiltName)
+ }
+ }
+}
+
+// reportMissingVariationDependency intentionally adds a dependency on a missing variation in order
+// to generate an appropriate error message with information about the available variations.
+func reportMissingVariationDependency(ctx android.BottomUpMutatorContext, variations []blueprint.Variation, name string) {
+ modules := ctx.AddFarVariationDependencies(variations, nil, name)
+ if len(modules) != 1 {
+ panic(fmt.Errorf("Internal Error: expected one module, found %d", len(modules)))
+ return
+ }
+ if modules[0] != nil {
+ panic(fmt.Errorf("Internal Error: expected module to be missing but was found: %q", modules[0]))
+ return
}
}
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index a0d0501..c740911 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -31,7 +31,7 @@
func TestPlatformBootclasspath(t *testing.T) {
preparer := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
- dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"),
+ FixtureConfigureBootJars("platform:foo", "platform:bar"),
android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
name: "platform-bootclasspath",
@@ -135,7 +135,7 @@
func TestPlatformBootclasspath_Dist(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForTestWithPlatformBootclasspath,
- dexpreopt.FixtureSetBootJars("platform:foo", "platform:bar"),
+ FixtureConfigureBootJars("platform:foo", "platform:bar"),
android.PrepareForTestWithAndroidMk,
android.FixtureWithRootAndroidBp(`
platform_bootclasspath {
diff --git a/java/testing.go b/java/testing.go
index 6ebc747..aee0710 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -178,6 +178,43 @@
return fs
}
+// FixtureConfigureBootJars configures the boot jars in both the dexpreopt.GlobalConfig and
+// Config.productVariables structs. As a side effect that enables dexpreopt.
+func FixtureConfigureBootJars(bootJars ...string) android.FixturePreparer {
+ artBootJars := []string{}
+ for _, j := range bootJars {
+ artApex := false
+ for _, artApexName := range artApexNames {
+ if strings.HasPrefix(j, artApexName+":") {
+ artApex = true
+ break
+ }
+ }
+ if artApex {
+ artBootJars = append(artBootJars, j)
+ }
+ }
+ return android.GroupFixturePreparers(
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.BootJars = android.CreateTestConfiguredJarList(bootJars)
+ }),
+ dexpreopt.FixtureSetBootJars(bootJars...),
+ dexpreopt.FixtureSetArtBootJars(artBootJars...),
+ )
+}
+
+// FixtureConfigureUpdatableBootJars configures the updatable boot jars in both the
+// dexpreopt.GlobalConfig and Config.productVariables structs. As a side effect that enables
+// dexpreopt.
+func FixtureConfigureUpdatableBootJars(bootJars ...string) android.FixturePreparer {
+ return android.GroupFixturePreparers(
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.UpdatableBootJars = android.CreateTestConfiguredJarList(bootJars)
+ }),
+ dexpreopt.FixtureSetUpdatableBootJars(bootJars...),
+ )
+}
+
// registerRequiredBuildComponentsForTest registers the build components used by
// PrepareForTestWithJavaDefaultModules.
//
diff --git a/rust/Android.bp b/rust/Android.bp
index a29c474..a6c4e07 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -14,6 +14,7 @@
],
srcs: [
"androidmk.go",
+ "benchmark.go",
"binary.go",
"bindgen.go",
"builder.go",
@@ -35,6 +36,7 @@
"testing.go",
],
testSrcs: [
+ "benchmark_test.go",
"binary_test.go",
"bindgen_test.go",
"builder_test.go",
diff --git a/rust/androidmk.go b/rust/androidmk.go
index dea32a3..940710e 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -107,6 +107,20 @@
cc.AndroidMkWriteTestData(test.data, ret)
}
+func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
+ benchmark.binaryDecorator.AndroidMk(ctx, ret)
+ ret.Class = "NATIVE_TESTS"
+ ret.ExtraEntries = append(ret.ExtraEntries,
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.AddCompatibilityTestSuites(benchmark.Properties.Test_suites...)
+ if benchmark.testConfig != nil {
+ entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String())
+ }
+ entries.SetBool("LOCAL_NATIVE_BENCHMARK", true)
+ entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(benchmark.Properties.Auto_gen_config, true))
+ })
+}
+
func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
ctx.SubAndroidMk(ret, library.baseCompiler)
diff --git a/rust/benchmark.go b/rust/benchmark.go
new file mode 100644
index 0000000..b89f5cd
--- /dev/null
+++ b/rust/benchmark.go
@@ -0,0 +1,129 @@
+// Copyright 2020 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 rust
+
+import (
+ "android/soong/android"
+ "android/soong/tradefed"
+)
+
+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.
+ No_named_install_directory *bool
+
+ // the name of the test configuration (for example "AndroidBenchmark.xml") that should be
+ // installed with the module.
+ Test_config *string `android:"path,arch_variant"`
+
+ // the name of the test configuration template (for example "AndroidBenchmarkTemplate.xml") that
+ // should be installed with the module.
+ Test_config_template *string `android:"path,arch_variant"`
+
+ // list of compatibility suites (for example "cts", "vts") that the module should be
+ // installed into.
+ Test_suites []string `android:"arch_variant"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
+}
+
+type benchmarkDecorator struct {
+ *binaryDecorator
+ Properties BenchmarkProperties
+ testConfig android.Path
+}
+
+func NewRustBenchmark(hod android.HostOrDeviceSupported) (*Module, *benchmarkDecorator) {
+ // Build both 32 and 64 targets for device benchmarks.
+ // Cannot build both for host benchmarks yet if the benchmark depends on
+ // something like proc-macro2 that cannot be built for both.
+ multilib := android.MultilibBoth
+ if hod != android.DeviceSupported && hod != android.HostAndDeviceSupported {
+ multilib = android.MultilibFirst
+ }
+ module := newModule(hod, multilib)
+
+ benchmark := &benchmarkDecorator{
+ binaryDecorator: &binaryDecorator{
+ baseCompiler: NewBaseCompiler("nativebench", "nativebench64", InstallInData),
+ },
+ }
+
+ module.compiler = benchmark
+ module.AddProperties(&benchmark.Properties)
+ return module, benchmark
+}
+
+func init() {
+ android.RegisterModuleType("rust_benchmark", RustBenchmarkFactory)
+ android.RegisterModuleType("rust_benchmark_host", RustBenchmarkHostFactory)
+}
+
+func RustBenchmarkFactory() android.Module {
+ module, _ := NewRustBenchmark(android.HostAndDeviceSupported)
+ return module.Init()
+}
+
+func RustBenchmarkHostFactory() android.Module {
+ module, _ := NewRustBenchmark(android.HostSupported)
+ return module.Init()
+}
+
+func (benchmark *benchmarkDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep {
+ return rlibAutoDep
+}
+
+func (benchmark *benchmarkDecorator) stdLinkage(ctx *depsContext) RustLinkage {
+ return RlibLinkage
+}
+
+func (benchmark *benchmarkDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
+ flags = benchmark.binaryDecorator.compilerFlags(ctx, flags)
+ return flags
+}
+
+func (benchmark *benchmarkDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
+ deps = benchmark.binaryDecorator.compilerDeps(ctx, deps)
+
+ deps.Rustlibs = append(deps.Rustlibs, "libcriterion")
+
+ return deps
+}
+
+func (benchmark *benchmarkDecorator) compilerProps() []interface{} {
+ return append(benchmark.binaryDecorator.compilerProps(), &benchmark.Properties)
+}
+
+func (benchmark *benchmarkDecorator) install(ctx ModuleContext) {
+ benchmark.testConfig = tradefed.AutoGenRustBenchmarkConfig(ctx,
+ benchmark.Properties.Test_config,
+ benchmark.Properties.Test_config_template,
+ benchmark.Properties.Test_suites,
+ nil,
+ benchmark.Properties.Auto_gen_config)
+
+ // default relative install path is module name
+ if !Bool(benchmark.Properties.No_named_install_directory) {
+ benchmark.baseCompiler.relative = ctx.ModuleName()
+ } else if String(benchmark.baseCompiler.Properties.Relative_install_path) == "" {
+ ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
+ }
+
+ benchmark.binaryDecorator.install(ctx)
+}
diff --git a/rust/benchmark_test.go b/rust/benchmark_test.go
new file mode 100644
index 0000000..734dda7
--- /dev/null
+++ b/rust/benchmark_test.go
@@ -0,0 +1,54 @@
+// Copyright 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 rust
+
+import (
+ "strings"
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestRustBenchmark(t *testing.T) {
+ ctx := testRust(t, `
+ rust_benchmark_host {
+ name: "my_bench",
+ srcs: ["foo.rs"],
+ }`)
+
+ testingModule := ctx.ModuleForTests("my_bench", "linux_glibc_x86_64")
+ expectedOut := "my_bench/linux_glibc_x86_64/my_bench"
+ outPath := testingModule.Output("my_bench").Output.String()
+ if !strings.Contains(outPath, expectedOut) {
+ t.Errorf("wrong output path: %v; expected: %v", outPath, expectedOut)
+ }
+}
+
+func TestRustBenchmarkLinkage(t *testing.T) {
+ ctx := testRust(t, `
+ rust_benchmark {
+ name: "my_bench",
+ srcs: ["foo.rs"],
+ }`)
+
+ testingModule := ctx.ModuleForTests("my_bench", "android_arm64_armv8-a").Module().(*Module)
+
+ if !android.InList("libcriterion.rlib-std", testingModule.Properties.AndroidMkRlibs) {
+ t.Errorf("rlib-std variant for libcriterion not detected as a rustlib-defined rlib dependency for device rust_benchmark module")
+ }
+ if !android.InList("libstd", testingModule.Properties.AndroidMkRlibs) {
+ t.Errorf("Device rust_benchmark module 'my_bench' does not link libstd as an rlib")
+ }
+}
diff --git a/rust/rust.go b/rust/rust.go
index 34e197a..ca85d74 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -434,6 +434,7 @@
module.AddProperties(
&BaseProperties{},
&cc.VendorProperties{},
+ &BenchmarkProperties{},
&BindgenProperties{},
&BaseCompilerProperties{},
&BinaryCompilerProperties{},
diff --git a/rust/testing.go b/rust/testing.go
index 75adcfc..1e01cc0 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -192,11 +192,19 @@
srcs:["foo.rs"],
host_supported: true,
}
+ rust_library {
+ name: "libcriterion",
+ crate_name: "criterion",
+ srcs:["foo.rs"],
+ host_supported: true,
+ }
`
return bp
}
func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("rust_benchmark", RustBenchmarkFactory)
+ ctx.RegisterModuleType("rust_benchmark_host", RustBenchmarkHostFactory)
ctx.RegisterModuleType("rust_binary", RustBinaryFactory)
ctx.RegisterModuleType("rust_binary_host", RustBinaryHostFactory)
ctx.RegisterModuleType("rust_bindgen", RustBindgenFactory)
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 27d71e8..3d96c84 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -245,6 +245,25 @@
return path
}
+func AutoGenRustBenchmarkConfig(ctx android.ModuleContext, testConfigProp *string,
+ testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+ if autogenPath != nil {
+ templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+ if templatePath.Valid() {
+ autogenTemplate(ctx, autogenPath, templatePath.String(), config, "")
+ } else {
+ if ctx.Device() {
+ autogenTemplate(ctx, autogenPath, "${RustDeviceBenchmarkConfigTemplate}", config, "")
+ } else {
+ autogenTemplate(ctx, autogenPath, "${RustHostBenchmarkConfigTemplate}", config, "")
+ }
+ }
+ return autogenPath
+ }
+ return path
+}
+
func AutoGenRobolectricTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
testSuites []string, autoGenConfig *bool) android.Path {
path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
diff --git a/tradefed/config.go b/tradefed/config.go
index f3566a8..999424c 100644
--- a/tradefed/config.go
+++ b/tradefed/config.go
@@ -34,6 +34,8 @@
pctx.SourcePathVariable("PythonBinaryHostTestConfigTemplate", "build/make/core/python_binary_host_test_config_template.xml")
pctx.SourcePathVariable("RustDeviceTestConfigTemplate", "build/make/core/rust_device_test_config_template.xml")
pctx.SourcePathVariable("RustHostTestConfigTemplate", "build/make/core/rust_host_test_config_template.xml")
+ pctx.SourcePathVariable("RustDeviceBenchmarkConfigTemplate", "build/make/core/rust_device_benchmark_config_template.xml")
+ pctx.SourcePathVariable("RustHostBenchmarkConfigTemplate", "build/make/core/rust_host_benchmark_config_template.xml")
pctx.SourcePathVariable("RobolectricTestConfigTemplate", "build/make/core/robolectric_test_config_template.xml")
pctx.SourcePathVariable("ShellTestConfigTemplate", "build/make/core/shell_test_config_template.xml")
diff --git a/tradefed/makevars.go b/tradefed/makevars.go
index f9682e4..9b5a20f 100644
--- a/tradefed/makevars.go
+++ b/tradefed/makevars.go
@@ -33,6 +33,8 @@
ctx.Strict("PYTHON_BINARY_HOST_TEST_CONFIG_TEMPLATE", "${PythonBinaryHostTestConfigTemplate}")
ctx.Strict("RUST_DEVICE_TEST_CONFIG_TEMPLATE", "${RustDeviceTestConfigTemplate}")
ctx.Strict("RUST_HOST_TEST_CONFIG_TEMPLATE", "${RustHostTestConfigTemplate}")
+ ctx.Strict("RUST_DEVICE_BENCHMARK_CONFIG_TEMPLATE", "${RustDeviceBenchmarkConfigTemplate}")
+ ctx.Strict("RUST_HOST_BENCHMARK_CONFIG_TEMPLATE", "${RustHostBenchmarkConfigTemplate}")
ctx.Strict("SHELL_TEST_CONFIG_TEMPLATE", "${ShellTestConfigTemplate}")
ctx.Strict("EMPTY_TEST_CONFIG", "${EmptyTestConfig}")