Merge "Drop INTERNAL_PLATFORM_MISSING_USES_LIBRARIES."
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 0dd7dae..bd2d973 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -1470,6 +1470,13 @@
// python_test_host with test data
"sbom_writers_test",
+
+ // TODO(B/283193845): tradefed and its java_test_host dependents
+ "tradefed",
+ "permissive_mte_test",
+ "ICU4CTestRunner",
+
+ "HelloWorldHostTest", // TODO(b/280452825): Convert HelloWorldHostTest to b test
}
MixedBuildsDisabledList = []string{
diff --git a/bazel/bazel_proxy.go b/bazel/bazel_proxy.go
index 2940b99..229818d 100644
--- a/bazel/bazel_proxy.go
+++ b/bazel/bazel_proxy.go
@@ -26,10 +26,11 @@
"time"
)
-// Logs fatal events of ProxyServer.
+// Logs events of ProxyServer.
type ServerLogger interface {
Fatal(v ...interface{})
Fatalf(format string, v ...interface{})
+ Println(v ...interface{})
}
// CmdRequest is a request to the Bazel Proxy server.
@@ -71,9 +72,10 @@
// The ProxyServer will only live as long as soong_ui does; the
// underlying Bazel server will live past the duration of the build.
type ProxyServer struct {
- logger ServerLogger
- outDir string
- workspaceDir string
+ logger ServerLogger
+ outDir string
+ workspaceDir string
+ bazeliskVersion string
// The server goroutine will listen on this channel and stop handling requests
// once it is written to.
done chan struct{}
@@ -119,12 +121,17 @@
}
// NewProxyServer is a constructor for a ProxyServer.
-func NewProxyServer(logger ServerLogger, outDir string, workspaceDir string) *ProxyServer {
+func NewProxyServer(logger ServerLogger, outDir string, workspaceDir string, bazeliskVersion string) *ProxyServer {
+ if len(bazeliskVersion) > 0 {
+ logger.Println("** Using Bazelisk for this build, due to env var USE_BAZEL_VERSION=" + bazeliskVersion + " **")
+ }
+
return &ProxyServer{
- logger: logger,
- outDir: outDir,
- workspaceDir: workspaceDir,
- done: make(chan struct{}),
+ logger: logger,
+ outDir: outDir,
+ workspaceDir: workspaceDir,
+ done: make(chan struct{}),
+ bazeliskVersion: bazeliskVersion,
}
}
@@ -155,6 +162,9 @@
return fmt.Errorf("Error decoding request: %s", err)
}
+ if len(b.bazeliskVersion) > 0 {
+ req.Env = append(req.Env, "USE_BAZEL_VERSION="+b.bazeliskVersion)
+ }
stdout, stderr, cmdErr := ExecBazel("./build/bazel/bin/bazel", b.workspaceDir, req)
errorString := ""
if cmdErr != nil {
diff --git a/bp2build/java_test_host_conversion_test.go b/bp2build/java_test_host_conversion_test.go
new file mode 100644
index 0000000..f411ffb
--- /dev/null
+++ b/bp2build/java_test_host_conversion_test.go
@@ -0,0 +1,149 @@
+// Copyright 2023 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 bp2build
+
+import (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/java"
+)
+
+func runJavaTestHostTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ (&tc).ModuleTypeUnderTest = "java_test_host"
+ (&tc).ModuleTypeUnderTestFactory = java.TestHostFactory
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("java_library", java.LibraryFactory)
+ }, tc)
+}
+
+func TestJavaTestHostGeneral(t *testing.T) {
+ runJavaTestHostTestCase(t, Bp2buildTestCase{
+ Description: "java_test_host general",
+ Filesystem: map[string]string{},
+ Blueprint: `
+java_test_host {
+ name: "java_test_host-1",
+ srcs: ["a.java", "b.java"],
+ libs: ["lib_a"],
+ static_libs: ["static_libs_a"],
+ exclude_srcs: ["b.java"],
+ javacflags: ["-Xdoclint:all/protected"],
+ java_version: "8",
+}
+
+java_library {
+ name: "lib_a",
+ bazel_module: { bp2build_available: false },
+}
+
+java_library {
+ name: "static_libs_a",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_library", "java_test_host-1_lib", AttrNameToString{
+ "deps": `[
+ ":lib_a-neverlink",
+ ":static_libs_a",
+ ]`,
+ "java_version": `"8"`,
+ "javacopts": `["-Xdoclint:all/protected"]`,
+ "srcs": `["a.java"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{
+ "runtime_deps": `[":java_test_host-1_lib"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestJavaTestHostNoSrcs(t *testing.T) {
+ runJavaTestHostTestCase(t, Bp2buildTestCase{
+ Description: "java_test_host without srcs",
+ Filesystem: map[string]string{},
+ Blueprint: `
+java_test_host {
+ name: "java_test_host-1",
+ libs: ["lib_a"],
+ static_libs: ["static_libs_a"],
+}
+
+java_library {
+ name: "lib_a",
+ bazel_module: { bp2build_available: false },
+}
+
+java_library {
+ name: "static_libs_a",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{
+ "runtime_deps": `[
+ ":lib_a-neverlink",
+ ":static_libs_a",
+ ]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestJavaTestHostKotlinSrcs(t *testing.T) {
+ runJavaTestHostTestCase(t, Bp2buildTestCase{
+ Description: "java_test_host with .kt in srcs",
+ Filesystem: map[string]string{},
+ Blueprint: `
+java_test_host {
+ name: "java_test_host-1",
+ srcs: ["a.java", "b.kt"],
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{
+ "runtime_deps": `[":java_test_host-1_lib"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTarget("kt_jvm_library", "java_test_host-1_lib", AttrNameToString{
+ "srcs": `[
+ "a.java",
+ "b.kt",
+ ]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ },
+ })
+}
diff --git a/cc/lto.go b/cc/lto.go
index be8fc56..a8bed23 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -43,16 +43,13 @@
// referred to in blueprint files as "lto"
Lto struct {
Never *bool `android:"arch_variant"`
- Full *bool `android:"arch_variant"`
Thin *bool `android:"arch_variant"`
} `android:"arch_variant"`
// Dep properties indicate that this module needs to be built with LTO
// since it is an object dependency of an LTO module.
- FullEnabled bool `blueprint:"mutated"`
ThinEnabled bool `blueprint:"mutated"`
NoLtoEnabled bool `blueprint:"mutated"`
- FullDep bool `blueprint:"mutated"`
ThinDep bool `blueprint:"mutated"`
NoLtoDep bool `blueprint:"mutated"`
@@ -86,8 +83,6 @@
var ltoLdFlag string
if lto.ThinLTO() {
ltoCFlag = "-flto=thin -fsplit-lto-unit"
- } else if lto.FullLTO() {
- ltoCFlag = "-flto"
} else {
ltoCFlag = "-flto=thin -fsplit-lto-unit"
ltoLdFlag = "-Wl,--lto-O0"
@@ -126,13 +121,13 @@
}
func (lto *lto) LTO(ctx BaseModuleContext) bool {
- return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx)
+ return lto.ThinLTO() || lto.DefaultThinLTO(ctx)
}
func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool {
// LP32 has many subtle issues and less test coverage.
lib32 := ctx.Arch().ArchType.Multilib == "lib32"
- // CFI enables full LTO.
+ // CFI adds LTO flags by itself.
cfi := ctx.isCfi()
// Performance and binary size are less important for host binaries and tests.
host := ctx.Host()
@@ -143,10 +138,6 @@
return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !test && !vndk
}
-func (lto *lto) FullLTO() bool {
- return lto != nil && (proptools.Bool(lto.Properties.Lto.Full) || lto.Properties.FullEnabled)
-}
-
func (lto *lto) ThinLTO() bool {
return lto != nil && (proptools.Bool(lto.Properties.Lto.Thin) || lto.Properties.ThinEnabled)
}
@@ -164,12 +155,8 @@
globalThinLTO := GlobalThinLTO(mctx)
if m, ok := mctx.Module().(*Module); ok {
- full := m.lto.FullLTO()
thin := m.lto.ThinLTO()
never := m.lto.Never()
- if full && thin {
- mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive")
- }
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
tag := mctx.OtherModuleDependencyTag(dep)
@@ -187,9 +174,6 @@
}
if dep, ok := dep.(*Module); ok {
- if full && !dep.lto.FullLTO() {
- dep.lto.Properties.FullDep = true
- }
if !globalThinLTO && thin && !dep.lto.ThinLTO() {
dep.lto.Properties.ThinDep = true
}
@@ -212,9 +196,6 @@
// Create variations for LTO types required as static
// dependencies
variationNames := []string{""}
- if m.lto.Properties.FullDep && !m.lto.FullLTO() {
- variationNames = append(variationNames, "lto-full")
- }
if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() {
variationNames = append(variationNames, "lto-thin")
}
@@ -224,13 +205,10 @@
// Use correct dependencies if LTO property is explicitly set
// (mutually exclusive)
- if m.lto.FullLTO() {
- mctx.SetDependencyVariation("lto-full")
- }
if !globalThinLTO && m.lto.ThinLTO() {
mctx.SetDependencyVariation("lto-thin")
}
- // Never must be the last, it overrides Thin or Full.
+ // Never must be the last, it overrides Thin.
if globalThinLTO && m.lto.Never() {
mctx.SetDependencyVariation("lto-none")
}
@@ -247,9 +225,6 @@
}
// LTO properties for dependencies
- if name == "lto-full" {
- variation.lto.Properties.FullEnabled = true
- }
if name == "lto-thin" {
variation.lto.Properties.ThinEnabled = true
}
@@ -258,7 +233,6 @@
}
variation.Properties.PreventInstall = true
variation.Properties.HideFromMake = true
- variation.lto.Properties.FullDep = false
variation.lto.Properties.ThinDep = false
variation.lto.Properties.NoLtoDep = false
}
diff --git a/cc/test.go b/cc/test.go
index 27de06b..3f5f710 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -70,6 +70,10 @@
// Add MinApiLevelModuleController with ro.vndk.version property. If ro.vndk.version has an
// integer value and the value is less than the min_vndk_version, skip this module.
Min_vndk_version *int64
+
+ // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., GTest.
+ // The "key" is optional in each of these.
+ Test_runner_options []tradefed.Option
}
type TestBinaryProperties struct {
@@ -398,6 +402,7 @@
TestConfigTemplateProp: test.Properties.Test_config_template,
TestSuites: test.testDecorator.InstallerProperties.Test_suites,
Config: configs,
+ TestRunnerOptions: test.Properties.Test_options.Test_runner_options,
AutoGenConfig: test.Properties.Auto_gen_config,
TestInstallBase: testInstallBase,
DeviceTemplate: "${NativeTestConfigTemplate}",
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index e006c9d..d589925 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -552,6 +552,12 @@
}
writeMetrics(configuration, ctx.EventHandler, metricsDir)
}
+
+ // Register this environment variablesas being an implicit dependencies of
+ // soong_build. Changes to this environment variable will result in
+ // retriggering soong_build.
+ configuration.Getenv("USE_BAZEL_VERSION")
+
writeUsedEnvironmentFile(configuration)
// Touch the output file so that it's the newest file created by soong_build.
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index 875dbab..2954f8b 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -14,10 +14,6 @@
package genrule
-import (
- "android/soong/android"
-)
-
var (
DepfileAllowList = []string{
"depfile_allowed_for_test",
@@ -136,12 +132,3 @@
"external/perfetto",
}
)
-var DepfileAllowSet = map[string]bool{}
-var SandboxingDenyModuleSet = map[string]bool{}
-var SandboxingDenyPathSet = map[string]bool{}
-
-func init() {
- android.AddToStringSet(DepfileAllowSet, DepfileAllowList)
- android.AddToStringSet(SandboxingDenyModuleSet, append(DepfileAllowList, SandboxingDenyModuleList...))
- android.AddToStringSet(SandboxingDenyPathSet, SandboxingDenyPathList)
-}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index c830fcc..4992625 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -24,6 +24,7 @@
"path/filepath"
"strconv"
"strings"
+ "sync"
"android/soong/bazel/cquery"
@@ -60,6 +61,12 @@
PrepareForTestWithGenRuleBuildComponents,
)
+var DepfileAllowSet map[string]bool
+var SandboxingDenyModuleSet map[string]bool
+var SandboxingDenyPathSet map[string]bool
+var SandboxingDenyModuleSetLock sync.Mutex
+var DepfileAllowSetLock sync.Mutex
+
func RegisterGenruleBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("genrule_defaults", defaultsFactory)
@@ -595,6 +602,12 @@
// Allowlist genrule to use depfile until we have a solution to remove it.
// TODO(b/235582219): Remove allowlist for genrule
if Bool(g.properties.Depfile) {
+ if DepfileAllowSet == nil {
+ DepfileAllowSetLock.Lock()
+ defer DepfileAllowSetLock.Unlock()
+ DepfileAllowSet = map[string]bool{}
+ android.AddToStringSet(DepfileAllowSet, DepfileAllowList)
+ }
// TODO(b/283852474): Checking the GenruleSandboxing flag is temporary in
// order to pass the presubmit before internal master is updated.
if ctx.DeviceConfig().GenruleSandboxing() && !DepfileAllowSet[g.Name()] {
@@ -1024,8 +1037,19 @@
}
func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder {
- if !ctx.DeviceConfig().GenruleSandboxing() || SandboxingDenyPathSet[ctx.ModuleDir()] ||
- SandboxingDenyModuleSet[ctx.ModuleName()] {
+ if !ctx.DeviceConfig().GenruleSandboxing() {
+ return r.SandboxTools()
+ }
+ if SandboxingDenyModuleSet == nil {
+ SandboxingDenyModuleSetLock.Lock()
+ defer SandboxingDenyModuleSetLock.Unlock()
+ SandboxingDenyModuleSet = map[string]bool{}
+ SandboxingDenyPathSet = map[string]bool{}
+ android.AddToStringSet(SandboxingDenyModuleSet, append(DepfileAllowList, SandboxingDenyModuleList...))
+ android.AddToStringSet(SandboxingDenyPathSet, SandboxingDenyPathList)
+ }
+
+ if SandboxingDenyPathSet[ctx.ModuleDir()] || SandboxingDenyModuleSet[ctx.ModuleName()] {
return r.SandboxTools()
}
return r.SandboxInputs()
diff --git a/java/app.go b/java/app.go
index cdec1e1..58580d4 100755
--- a/java/app.go
+++ b/java/app.go
@@ -796,8 +796,9 @@
shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall
if shouldInstallAppPackage {
if a.privAppAllowlist.Valid() {
- installPath := android.PathForModuleInstall(ctx, "etc", "permissions")
- ctx.InstallFile(installPath, a.privAppAllowlist.Path().Base(), a.privAppAllowlist.Path())
+ allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions")
+ allowlistInstallFilename := a.installApkName + ".xml"
+ ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path())
}
var extraInstalledPaths android.Paths
diff --git a/java/app_test.go b/java/app_test.go
index 592859c..5aed178 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -3542,8 +3542,8 @@
}
// verify that permissions are copied to device
- app.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml")
- overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml")
+ app.Output("out/soong/target/product/test_device/system/etc/permissions/foo.xml")
+ overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/bar.xml")
}
func TestPrivappAllowlistAndroidMk(t *testing.T) {
@@ -3594,7 +3594,7 @@
t,
"androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml",
+ "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml",
)
overrideAndroidApp := overrideApp.Module().(*AndroidApp)
@@ -3621,6 +3621,6 @@
t,
"androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist",
overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0],
- "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml",
+ "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
)
}
diff --git a/java/base.go b/java/base.go
index 374138c..dd02ef8 100644
--- a/java/base.go
+++ b/java/base.go
@@ -2188,5 +2188,9 @@
if binary, ok := ctx.Module().(*Binary); ok {
javaBinaryHostBp2Build(ctx, binary)
}
+ case "java_test_host":
+ if testHost, ok := ctx.Module().(*TestHost); ok {
+ javaTestHostBp2Build(ctx, testHost)
+ }
}
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 116c833..35f6097 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -816,7 +816,7 @@
cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch])
}
- if global.EnableUffdGc {
+ if global.EnableUffdGc && image.target.Os == android.Android {
cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
}
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 8a521aa..151c94a 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -535,6 +535,14 @@
// b/223382732
FlagWithArg("--hide ", "ChangedDefault")
+ // Force metalava to ignore classes on the classpath when an API file contains missing classes.
+ // See b/285140653 for more information.
+ cmd.FlagWithArg("--api-class-resolution ", "api")
+
+ // Force metalava to sort overloaded methods by their order in the source code.
+ // See b/285312164 for more information.
+ cmd.FlagWithArg("--api-overloaded-method-order ", "source")
+
return cmd
}
diff --git a/java/java.go b/java/java.go
index aa9f936..4f7b401 100644
--- a/java/java.go
+++ b/java/java.go
@@ -936,6 +936,10 @@
// Extra <option> tags to add to the auto generated test xml file. The "key"
// is optional in each of these.
Tradefed_options []tradefed.Option
+
+ // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest.
+ // The "key" is optional in each of these.
+ Test_runner_options []tradefed.Option
}
type testProperties struct {
@@ -1218,6 +1222,7 @@
TestSuites: j.testProperties.Test_suites,
Config: configs,
OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options,
+ TestRunnerOptions: j.testProperties.Test_options.Test_runner_options,
AutoGenConfig: j.testProperties.Auto_gen_config,
UnitTest: j.testProperties.Test_options.Unit_test,
DeviceTemplate: "${JavaTestConfigTemplate}",
@@ -1416,6 +1421,8 @@
nil,
nil)
+ android.InitBazelModule(module)
+
InitJavaModuleMultiTargets(module, android.HostSupported)
return module
@@ -1728,6 +1735,14 @@
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
+ // Force metalava to ignore classes on the classpath when an API file contains missing classes.
+ // See b/285140653 for more information.
+ cmd.FlagWithArg("--api-class-resolution ", "api")
+
+ // Force metalava to sort overloaded methods by their order in the source code.
+ // See b/285312164 for more information.
+ cmd.FlagWithArg("--api-overloaded-method-order ", "source")
+
return cmd
}
@@ -3114,23 +3129,89 @@
return
}
- libName := m.Name() + "_lib"
+ libInfo := libraryCreationInfo{
+ deps: deps,
+ attrs: commonAttrs,
+ baseName: m.Name(),
+ hasKotlin: bp2BuildInfo.hasKotlin,
+ }
+ libName := createLibraryTarget(ctx, libInfo)
+ binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
+
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs)
+}
+
+type javaTestHostAttributes struct {
+ *javaCommonAttributes
+ Deps bazel.LabelListAttribute
+ Runtime_deps bazel.LabelListAttribute
+}
+
+// javaTestHostBp2Build is for java_test_host bp2build.
+func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) {
+ commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx)
+ depLabels := bp2BuildInfo.DepLabels
+
+ deps := depLabels.Deps
+ deps.Append(depLabels.StaticDeps)
+
+ var runtimeDeps bazel.LabelListAttribute
+ attrs := &javaTestHostAttributes{
+ Runtime_deps: runtimeDeps,
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_test",
+ Bzl_load_location: "//build/bazel/rules/java:test.bzl",
+ }
+
+ if commonAttrs.Srcs.IsEmpty() {
+ // if there are no sources, then the dependencies can only be used at runtime
+ attrs.Runtime_deps = deps
+ attrs.javaCommonAttributes = commonAttrs
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+ return
+ }
+
+ libInfo := libraryCreationInfo{
+ deps: deps,
+ attrs: commonAttrs,
+ baseName: m.Name(),
+ hasKotlin: bp2BuildInfo.hasKotlin,
+ }
+ libName := createLibraryTarget(ctx, libInfo)
+ attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
+
+ // Create the BazelTargetModule.
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
+}
+
+// libraryCreationInfo encapsulates the info needed to create java_library target from
+// java_binary_host or java_test_host.
+type libraryCreationInfo struct {
+ deps bazel.LabelListAttribute
+ attrs *javaCommonAttributes
+ baseName string
+ hasKotlin bool
+}
+
+// helper function that creates java_library target from java_binary_host or java_test_host,
+// and returns the library target name,
+func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string {
+ libName := libInfo.baseName + "_lib"
var libProps bazel.BazelTargetModuleProperties
- if bp2BuildInfo.hasKotlin {
+ if libInfo.hasKotlin {
libProps = ktJvmLibraryBazelTargetModuleProperties()
} else {
libProps = javaLibraryBazelTargetModuleProperties()
}
libAttrs := &javaLibraryAttributes{
- Deps: deps,
- javaCommonAttributes: commonAttrs,
+ Deps: libInfo.deps,
+ javaCommonAttributes: libInfo.attrs,
}
ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs)
- binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}})
-
- // Create the BazelTargetModule.
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs)
+ return libName
}
type bazelJavaImportAttributes struct {
diff --git a/java/java_test.go b/java/java_test.go
index ea89e6e..cd5c343 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -2298,3 +2298,27 @@
t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"])
}
}
+
+func TestTestRunnerOptions(t *testing.T) {
+ result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
+java_test_host {
+ name: "foo",
+ test_options: {
+ test_runner_options: [
+ {
+ name: "test-timeout",
+ value: "10m"
+ }
+ ]
+ }
+}
+`)
+
+ buildOS := result.Config.BuildOS.String()
+ args := result.ModuleForTests("foo", buildOS+"_common").
+ Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args
+ expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ")
+ if args["extraTestRunnerConfigs"] != expected {
+ t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"])
+ }
+}
diff --git a/rust/builder.go b/rust/builder.go
index 0aa2225..0dfaef4 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -261,7 +261,7 @@
// Disallow experimental features
modulePath := android.PathForModuleSrc(ctx).String()
if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) {
- rustcFlags = append(rustcFlags, "-Zallow-features=\"custom_inner_attributes,mixed_integer_ops\"")
+ rustcFlags = append(rustcFlags, "-Zallow-features=\"\"")
}
// Collect linker flags
diff --git a/rust/config/global.go b/rust/config/global.go
index 748bb3d..60acc6e 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -51,9 +51,6 @@
// Use v0 mangling to distinguish from C++ symbols
"-C symbol-mangling-version=v0",
"--color always",
- // TODO (b/267698452): Temporary workaround until the "no unstable
- // features" policy is enforced.
- "-A stable-features",
"-Zdylib-lto",
}
diff --git a/tests/genrule_sandbox_test.sh b/tests/genrule_sandbox_test.sh
new file mode 100755
index 0000000..21b476b
--- /dev/null
+++ b/tests/genrule_sandbox_test.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+# Copyright (C) 2023 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.
+
+set -e
+
+# Build the given genrule modules with GENRULE_SANDBOXING enabled and disabled,
+# then compare the output of the modules and report result.
+
+function die() { format=$1; shift; printf >&2 "$format\n" $@; exit 1; }
+
+function usage() {
+ die "usage: ${0##*/} <-t lunch_target> [module]..."
+}
+
+if [ ! -e "build/make/core/Makefile" ]; then
+ die "$0 must be run from the top of the Android source tree."
+fi
+
+declare TARGET=
+while getopts "t:" opt; do
+ case $opt in
+ t)
+ TARGET=$OPTARG ;;
+ *) usage ;;
+ esac
+done
+
+shift $((OPTIND-1))
+MODULES="$@"
+
+source build/envsetup.sh
+
+if [[ -n $TARGET ]]; then
+ lunch $TARGET
+fi
+
+if [[ -z ${OUT_DIR+x} ]]; then
+ OUT_DIR="out"
+fi
+
+OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)"
+PASS=true
+
+function cleanup {
+ if [ $PASS = true ]; then
+ rm -rf "${OUTPUT_DIR}"
+ fi
+}
+trap cleanup EXIT
+
+declare -A GEN_PATH_MAP
+
+function find_gen_paths() {
+ for module in $MODULES; do
+ module_path=$(pathmod "$module")
+ package_path=${module_path#$ANDROID_BUILD_TOP}
+ gen_path=$OUT_DIR/soong/.intermediates$package_path/$module
+ GEN_PATH_MAP[$module]=$gen_path
+ done
+}
+
+function store_outputs() {
+ local dir=$1; shift
+
+ for module in $MODULES; do
+ dest_dir=$dir/${module}
+ mkdir -p $dest_dir
+ gen_path=${GEN_PATH_MAP[$module]}
+ cp -r $gen_path $dest_dir
+ done
+}
+
+function cmp_outputs() {
+ local dir1=$1; shift
+ local dir2=$1; shift
+
+ for module in $MODULES; do
+ if ! diff -rq --exclude=genrule.sbox.textproto $dir1/$module $dir2/$module; then
+ PASS=false
+ echo "$module differ"
+ fi
+ done
+ if [ $PASS = true ]; then
+ echo "Test passed"
+ fi
+}
+
+if [ ! -f "$ANDROID_PRODUCT_OUT/module-info.json" ]; then
+ refreshmod
+fi
+
+find_gen_paths
+m --skip-soong-tests GENRULE_SANDBOXING=true "${MODULES[@]}"
+store_outputs "$OUTPUT_DIR/sandbox"
+m --skip-soong-tests GENRULE_SANDBOXING=false "${MODULES[@]}"
+store_outputs "$OUTPUT_DIR/non_sandbox"
+
+cmp_outputs "$OUTPUT_DIR/non_sandbox" "$OUTPUT_DIR/sandbox"
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index 49b09af..3c55c51 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -40,9 +40,9 @@
}
var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{
- Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g;s&{OUTPUT_FILENAME}&'${outputFileName}'&g;s&{TEST_INSTALL_BASE}&'${testInstallBase}'&g' $template > $out",
+ Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g;s&{EXTRA_TEST_RUNNER_CONFIGS}&'${extraTestRunnerConfigs}'&g;s&{OUTPUT_FILENAME}&'${outputFileName}'&g;s&{TEST_INSTALL_BASE}&'${testInstallBase}'&g' $template > $out",
CommandDeps: []string{"$template"},
-}, "name", "template", "extraConfigs", "outputFileName", "testInstallBase")
+}, "name", "template", "extraConfigs", "outputFileName", "testInstallBase", "extraTestRunnerConfigs")
func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string, autoGenConfig *bool, testConfigTemplateProp *string) (path android.Path, autogenPath android.WritablePath) {
p := getTestConfig(ctx, prop)
@@ -107,7 +107,7 @@
}
-func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) {
+func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, testRunnerConfigs []Option, outputFileName string, testInstallBase string) {
if template == "" {
ctx.ModuleErrorf("Empty template")
}
@@ -118,16 +118,27 @@
extraConfigs := strings.Join(configStrings, fmt.Sprintf("\\n%s", test_xml_indent))
extraConfigs = proptools.NinjaAndShellEscape(extraConfigs)
+ var testRunnerConfigStrings []string
+ for _, config := range testRunnerConfigs {
+ testRunnerConfigStrings = append(testRunnerConfigStrings, config.Config())
+ }
+ extraTestRunnerConfigs := strings.Join(testRunnerConfigStrings, fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent))
+ if len(extraTestRunnerConfigs) > 0 {
+ extraTestRunnerConfigs += fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent)
+ }
+ extraTestRunnerConfigs = proptools.NinjaAndShellEscape(extraTestRunnerConfigs)
+
ctx.Build(pctx, android.BuildParams{
Rule: autogenTestConfig,
Description: "test config",
Output: output,
Args: map[string]string{
- "name": name,
- "template": template,
- "extraConfigs": extraConfigs,
- "outputFileName": outputFileName,
- "testInstallBase": testInstallBase,
+ "name": name,
+ "template": template,
+ "extraConfigs": extraConfigs,
+ "outputFileName": outputFileName,
+ "testInstallBase": testInstallBase,
+ "extraTestRunnerConfigs": extraTestRunnerConfigs,
},
})
}
@@ -142,6 +153,7 @@
TestSuites []string
Config []Config
OptionsForAutogenerated []Option
+ TestRunnerOptions []Option
AutoGenConfig *bool
UnitTest *bool
TestInstallBase string
@@ -155,6 +167,7 @@
for _, c := range options.OptionsForAutogenerated {
configs = append(configs, c)
}
+ testRunnerConfigs := append([]Option{}, options.TestRunnerOptions...)
name := options.Name
if name == "" {
name = ctx.ModuleName()
@@ -163,15 +176,15 @@
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, options.TestConfigTemplateProp)
if templatePath.Valid() {
- autogenTemplate(ctx, name, autogenPath, templatePath.String(), configs, options.OutputFileName, options.TestInstallBase)
+ autogenTemplate(ctx, name, autogenPath, templatePath.String(), configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase)
} else {
if ctx.Device() {
- autogenTemplate(ctx, name, autogenPath, options.DeviceTemplate, configs, options.OutputFileName, options.TestInstallBase)
+ autogenTemplate(ctx, name, autogenPath, options.DeviceTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase)
} else {
if Bool(options.UnitTest) {
- autogenTemplate(ctx, name, autogenPath, options.HostUnitTestTemplate, configs, options.OutputFileName, options.TestInstallBase)
+ autogenTemplate(ctx, name, autogenPath, options.HostUnitTestTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase)
} else {
- autogenTemplate(ctx, name, autogenPath, options.HostTemplate, configs, options.OutputFileName, options.TestInstallBase)
+ autogenTemplate(ctx, name, autogenPath, options.HostTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase)
}
}
}
diff --git a/ui/build/config.go b/ui/build/config.go
index bfbf85d..711774a 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -231,8 +231,9 @@
func NewConfig(ctx Context, args ...string) Config {
ret := &configImpl{
- environ: OsEnvironment(),
- sandboxConfig: &SandboxConfig{},
+ environ: OsEnvironment(),
+ sandboxConfig: &SandboxConfig{},
+ ninjaWeightListSource: NINJA_LOG,
}
// Default matching ninja
@@ -1641,6 +1642,16 @@
return c.Environment().IsEnvTrue("USE_PERSISTENT_BAZEL")
}
+// GetBazeliskBazelVersion returns the Bazel version to use for this build,
+// or the empty string if the current canonical prod Bazel should be used.
+// This environment variable should only be set to debug the build system.
+// The Bazel version, if set, will be passed to Bazelisk, and Bazelisk will
+// handle downloading and invoking the correct Bazel binary.
+func (c *configImpl) GetBazeliskBazelVersion() string {
+ value, _ := c.Environment().Get("USE_BAZEL_VERSION")
+ return value
+}
+
func (c *configImpl) BazelModulesForceEnabledByFlag() string {
return c.bazelForceEnabledModules
}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 5d56531..61aaad8 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -35,48 +35,6 @@
ninjaWeightListFileName = ".ninja_weight_list"
)
-func useNinjaBuildLog(ctx Context, config Config, cmd *Cmd) {
- ninjaLogFile := filepath.Join(config.OutDir(), ninjaLogFileName)
- data, err := os.ReadFile(ninjaLogFile)
- var outputBuilder strings.Builder
- if err == nil {
- lines := strings.Split(strings.TrimSpace(string(data)), "\n")
- // ninja log: <start> <end> <restat> <name> <cmdhash>
- // ninja weight list: <name>,<end-start+1>
- for _, line := range lines {
- if strings.HasPrefix(line, "#") {
- continue
- }
- fields := strings.Split(line, "\t")
- path := fields[3]
- start, err := strconv.Atoi(fields[0])
- if err != nil {
- continue
- }
- end, err := strconv.Atoi(fields[1])
- if err != nil {
- continue
- }
- outputBuilder.WriteString(path)
- outputBuilder.WriteString(",")
- outputBuilder.WriteString(strconv.Itoa(end-start+1) + "\n")
- }
- } else {
- // If there is no ninja log file, just pass empty ninja weight list.
- // Because it is still efficient with critical path calculation logic even without weight.
- ctx.Verbosef("There is an error during reading ninja log, so ninja will use empty weight list: %s", err)
- }
-
- weightListFile := filepath.Join(config.OutDir(), ninjaWeightListFileName)
-
- err = os.WriteFile(weightListFile, []byte(outputBuilder.String()), 0644)
- if err == nil {
- cmd.Args = append(cmd.Args, "-o", "usesweightlist="+weightListFile)
- } else {
- ctx.Panicf("Could not write ninja weight list file %s", err)
- }
-}
-
// Constructs and runs the Ninja command line with a restricted set of
// environment variables. It's important to restrict the environment Ninja runs
// for hermeticity reasons, and to avoid spurious rebuilds.
@@ -131,7 +89,7 @@
switch config.NinjaWeightListSource() {
case NINJA_LOG:
- useNinjaBuildLog(ctx, config, cmd)
+ 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")
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 6de8d6f..986ec70 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -533,7 +533,7 @@
defer ctx.EndTrace()
if config.IsPersistentBazelEnabled() {
- bazelProxy := bazel.NewProxyServer(ctx.Logger, config.OutDir(), filepath.Join(config.SoongOutDir(), "workspace"))
+ bazelProxy := bazel.NewProxyServer(ctx.Logger, config.OutDir(), filepath.Join(config.SoongOutDir(), "workspace"), config.GetBazeliskBazelVersion())
bazelProxy.Start()
defer bazelProxy.Close()
}