Merge "Add RBE metrics dump in Soong UI."
diff --git a/android/sdk.go b/android/sdk.go
index e823106..8115b69 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -266,6 +266,9 @@
SdkMemberType() SdkMemberType
}
+var _ SdkMemberTypeDependencyTag = (*sdkMemberDependencyTag)(nil)
+var _ ReplaceSourceWithPrebuilt = (*sdkMemberDependencyTag)(nil)
+
type sdkMemberDependencyTag struct {
blueprint.BaseDependencyTag
memberType SdkMemberType
@@ -275,6 +278,12 @@
return t.memberType
}
+// Prevent dependencies from the sdk/module_exports onto their members from being
+// replaced with a preferred prebuilt.
+func (t *sdkMemberDependencyTag) ReplaceSourceWithPrebuilt() bool {
+ return false
+}
+
func DependencyTagForSdkMemberType(memberType SdkMemberType) SdkMemberTypeDependencyTag {
return &sdkMemberDependencyTag{memberType: memberType}
}
diff --git a/apex/apex.go b/apex/apex.go
index d0c1a09..b29017d 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1750,9 +1750,15 @@
return false
}
+ dt := ctx.OtherModuleDependencyTag(child)
+
+ if _, ok := dt.(android.ExcludeFromApexContentsTag); ok {
+ return false
+ }
+
// Check for the direct dependencies that contribute to the payload
- if dt, ok := ctx.OtherModuleDependencyTag(child).(dependencyTag); ok {
- if dt.payload {
+ if adt, ok := dt.(dependencyTag); ok {
+ if adt.payload {
return do(ctx, parent, am, false /* externalDep */)
}
// As soon as the dependency graph crosses the APEX boundary, don't go further.
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c2cb200..f064338 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -5791,6 +5791,41 @@
}
}
+func TestNonPreferredPrebuiltDependency(t *testing.T) {
+ _, _ = testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ stubs: {
+ versions: ["10000"],
+ },
+ apex_available: ["myapex"],
+ }
+
+ cc_prebuilt_library_shared {
+ name: "mylib",
+ prefer: false,
+ srcs: ["prebuilt.so"],
+ stubs: {
+ versions: ["10000"],
+ },
+ apex_available: ["myapex"],
+ }
+ `)
+}
+
func TestMain(m *testing.M) {
run := func() int {
setUp()
diff --git a/docs/perf.md b/docs/perf.md
index 538adff..86a27b4 100644
--- a/docs/perf.md
+++ b/docs/perf.md
@@ -12,6 +12,41 @@

+### Critical path
+
+soong_ui logs the wall time of the longest dependency chain compared to the
+elapsed wall time in `$OUT_DIR/soong.log`. For example:
+```
+critical path took 3m10s
+elapsed time 5m16s
+perfect parallelism ratio 60%
+critical path:
+ 0:00 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/policy_2.conf
+ 0:04 build out/target/product/generic_arm64/obj/FAKE/sepolicy_neverallows_intermediates/sepolicy_neverallows
+ 0:13 build out/target/product/generic_arm64/obj/ETC/plat_sepolicy.cil_intermediates/plat_sepolicy.cil
+ 0:01 build out/target/product/generic_arm64/obj/ETC/plat_pub_versioned.cil_intermediates/plat_pub_versioned.cil
+ 0:02 build out/target/product/generic_arm64/obj/ETC/vendor_sepolicy.cil_intermediates/vendor_sepolicy.cil
+ 0:16 build out/target/product/generic_arm64/obj/ETC/sepolicy_intermediates/sepolicy
+ 0:00 build out/target/product/generic_arm64/obj/ETC/plat_seapp_contexts_intermediates/plat_seapp_contexts
+ 0:00 Install: out/target/product/generic_arm64/system/etc/selinux/plat_seapp_contexts
+ 0:02 build out/target/product/generic_arm64/obj/NOTICE.txt
+ 0:00 build out/target/product/generic_arm64/obj/NOTICE.xml.gz
+ 0:00 build out/target/product/generic_arm64/system/etc/NOTICE.xml.gz
+ 0:01 Installed file list: out/target/product/generic_arm64/installed-files.txt
+ 1:00 Target system fs image: out/target/product/generic_arm64/obj/PACKAGING/systemimage_intermediates/system.img
+ 0:01 Install system fs image: out/target/product/generic_arm64/system.img
+ 0:01 Target vbmeta image: out/target/product/generic_arm64/vbmeta.img
+ 1:26 Package target files: out/target/product/generic_arm64/obj/PACKAGING/target_files_intermediates/aosp_arm64-target_files-6663974.zip
+ 0:01 Package: out/target/product/generic_arm64/aosp_arm64-img-6663974.zip
+ 0:01 Dist: /buildbot/dist_dirs/aosp-master-linux-aosp_arm64-userdebug/6663974/aosp_arm64-img-6663974.zip
+```
+
+If the elapsed time is much longer than the critical path then additional
+parallelism on the build machine will improve total build times. If there are
+long individual times listed in the critical path then improving build times
+for those steps or adjusting dependencies so that those steps can run earlier
+in the build graph will improve total build times.
+
### Soong
Soong can be traced and profiled using the standard Go tools. It understands
diff --git a/java/java_test.go b/java/java_test.go
index 59a2ce7..fb00361 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -25,7 +25,6 @@
"strings"
"testing"
- "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -173,20 +172,6 @@
}
}
-func checkModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
- t.Helper()
- module := ctx.ModuleForTests(name, variant).Module()
- deps := []string{}
- ctx.VisitDirectDeps(module, func(m blueprint.Module) {
- deps = append(deps, m.Name())
- })
- sort.Strings(deps)
-
- if actual := deps; !reflect.DeepEqual(expected, actual) {
- t.Errorf("expected %#q, found %#q", expected, actual)
- }
-}
-
func TestJavaLinkType(t *testing.T) {
testJava(t, `
java_library {
@@ -647,7 +632,7 @@
}
}
- checkModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
`prebuilt_sdklib.stubs`,
`prebuilt_sdklib.stubs.source.test`,
`prebuilt_sdklib.stubs.system`,
@@ -675,7 +660,7 @@
}
`)
- checkModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
`dex2oatd`,
`prebuilt_sdklib`,
`sdklib.impl`,
@@ -684,7 +669,7 @@
`sdklib.xml`,
})
- checkModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
`prebuilt_sdklib.stubs`,
`sdklib.impl`,
// This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the
@@ -715,7 +700,7 @@
}
`)
- checkModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
`dex2oatd`,
`prebuilt_sdklib`,
`sdklib.impl`,
@@ -724,7 +709,7 @@
`sdklib.xml`,
})
- checkModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "prebuilt_sdklib", "android_common", []string{
`prebuilt_sdklib.stubs`,
`sdklib.impl`,
`sdklib.xml`,
@@ -1491,7 +1476,7 @@
}
`)
- checkModuleDependencies(t, ctx, "sdklib", "android_common", []string{
+ CheckModuleDependencies(t, ctx, "sdklib", "android_common", []string{
`dex2oatd`,
`sdklib.impl`,
`sdklib.stubs`,
diff --git a/java/testing.go b/java/testing.go
index f5688e6..94f054e 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -16,9 +16,13 @@
import (
"fmt"
+ "reflect"
+ "sort"
+ "testing"
"android/soong/android"
"android/soong/cc"
+ "github.com/google/blueprint"
)
func TestConfig(buildDir string, env map[string]string, bp string, fs map[string][]byte) android.Config {
@@ -216,3 +220,17 @@
return bp
}
+
+func CheckModuleDependencies(t *testing.T, ctx *android.TestContext, name, variant string, expected []string) {
+ t.Helper()
+ module := ctx.ModuleForTests(name, variant).Module()
+ deps := []string{}
+ ctx.VisitDirectDeps(module, func(m blueprint.Module) {
+ deps = append(deps, m.Name())
+ })
+ sort.Strings(deps)
+
+ if actual := deps; !reflect.DeepEqual(expected, actual) {
+ t.Errorf("expected %#q, found %#q", expected, actual)
+ }
+}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 123fe70..c59cd30 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -69,6 +69,28 @@
ensureListContains(t, inputs, arm64Output.String())
}
+func TestSdkCompileMultilibOverride(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["sdkmember"],
+ compile_multilib: "64",
+ }
+
+ cc_library_shared {
+ name: "sdkmember",
+ srcs: ["Test.cpp"],
+ stl: "none",
+ compile_multilib: "64",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAllCopyRules(`
+.intermediates/sdkmember/android_arm64_armv8-a_shared/sdkmember.so -> arm64/lib/sdkmember.so
+`))
+}
+
func TestBasicSdkWithCc(t *testing.T) {
result := testSdkWithCc(t, `
sdk {
@@ -79,6 +101,8 @@
cc_library_shared {
name: "sdkmember",
system_shared_libs: [],
+ stl: "none",
+ apex_available: ["mysdkapex"],
}
sdk_snapshot {
@@ -152,6 +176,13 @@
key: "myapex.key",
certificate: ":myapex.cert",
}
+
+ apex {
+ name: "mysdkapex",
+ native_shared_libs: ["sdkmember"],
+ key: "myapex.key",
+ certificate: ":myapex.cert",
+ }
`)
sdkMemberV1 := result.ModuleForTests("sdkmember_mysdk_1", "android_arm64_armv8-a_shared_myapex").Rule("toc").Output
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 7496b20..79da3f0 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -16,6 +16,8 @@
import (
"testing"
+
+ "android/soong/java"
)
func testSdkWithJava(t *testing.T, bp string) *testSdkResult {
@@ -26,6 +28,9 @@
"resource.test": nil,
"aidl/foo/bar/Test.aidl": nil,
+ // For java_import
+ "prebuilt.jar": nil,
+
// For java_sdk_library
"api/current.txt": nil,
"api/removed.txt": nil,
@@ -85,6 +90,52 @@
// Contains tests for SDK members provided by the java package.
+func TestSdkDependsOnSourceEvenWhenPrebuiltPreferred(t *testing.T) {
+ result := testSdkWithJava(t, `
+ sdk {
+ name: "mysdk",
+ java_header_libs: ["sdkmember"],
+ }
+
+ java_library {
+ name: "sdkmember",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ }
+
+ java_import {
+ name: "sdkmember",
+ prefer: true,
+ jars: ["prebuilt.jar"],
+ }
+ `)
+
+ // Make sure that the mysdk module depends on "sdkmember" and not "prebuilt_sdkmember".
+ java.CheckModuleDependencies(t, result.ctx, "mysdk", "android_common", []string{"sdkmember"})
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mysdk_sdkmember@current",
+ sdk_member_name: "sdkmember",
+ jars: ["java/sdkmember.jar"],
+}
+
+java_import {
+ name: "sdkmember",
+ prefer: false,
+ jars: ["java/sdkmember.jar"],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ java_header_libs: ["mysdk_sdkmember@current"],
+}
+`))
+}
+
func TestBasicSdkWithJavaLibrary(t *testing.T) {
result := testSdkWithJava(t, `
sdk {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index b9b8199..3e76008 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -218,7 +218,7 @@
Compile_multilib *string
}
p := &props{Compile_multilib: proptools.StringPtr("both")}
- ctx.AppendProperties(p)
+ ctx.PrependProperties(p)
})
return s
}
@@ -330,6 +330,11 @@
blueprint.BaseDependencyTag
}
+// Mark this tag so dependencies that use it are excluded from APEX contents.
+func (t dependencyTag) ExcludeFromApexContents() {}
+
+var _ android.ExcludeFromApexContentsTag = dependencyTag{}
+
// For dependencies from an in-development version of an SDK member to frozen versions of the same member
// e.g. libfoo -> libfoo.mysdk.11 and libfoo.mysdk.12
type sdkMemberVersionedDepTag struct {
diff --git a/sdk/testing.go b/sdk/testing.go
index 40abdcd..4d029e4 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -44,14 +44,15 @@
` + cc.GatherRequiredDepsForTest(android.Android, android.Windows)
mockFS := map[string][]byte{
- "build/make/target/product/security": nil,
- "apex_manifest.json": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/myapex2-file_contexts": nil,
- "myapex.avbpubkey": nil,
- "myapex.pem": nil,
- "myapex.x509.pem": nil,
- "myapex.pk8": nil,
+ "build/make/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/myapex2-file_contexts": nil,
+ "system/sepolicy/apex/mysdkapex-file_contexts": nil,
+ "myapex.avbpubkey": nil,
+ "myapex.pem": nil,
+ "myapex.x509.pem": nil,
+ "myapex.pk8": nil,
}
cc.GatherRequiredFilesForTest(mockFS)