diff options
| -rw-r--r-- | android/config.go | 24 | ||||
| -rw-r--r-- | android/module.go | 11 | ||||
| -rw-r--r-- | android/paths.go | 8 | ||||
| -rw-r--r-- | apex/androidmk.go | 2 | ||||
| -rw-r--r-- | apex/apex.go | 46 | ||||
| -rw-r--r-- | apex/apex_test.go | 289 | ||||
| -rw-r--r-- | cc/cc.go | 3 | ||||
| -rw-r--r-- | cc/vndk.go | 8 | ||||
| -rw-r--r-- | dexpreopt/dexpreopt.go | 12 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 16 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 10 | ||||
| -rw-r--r-- | java/java.go | 17 | ||||
| -rw-r--r-- | java/prebuilt_apis.go | 35 | ||||
| -rw-r--r-- | java/sdk.go | 26 | ||||
| -rw-r--r-- | java/sdk_test.go | 67 | ||||
| -rw-r--r-- | java/testing.go | 78 | ||||
| -rw-r--r-- | sdk/update.go | 33 | ||||
| -rw-r--r-- | ui/build/ninja.go | 1 | ||||
| -rw-r--r-- | ui/build/soong.go | 1 | ||||
| -rw-r--r-- | ui/status/ninja.go | 2 | ||||
| -rw-r--r-- | ui/status/ninja_frontend/frontend.pb.go | 167 | ||||
| -rw-r--r-- | ui/status/ninja_frontend/frontend.proto | 7 |
22 files changed, 583 insertions, 280 deletions
diff --git a/android/config.go b/android/config.go index ee31c1003..59118ce86 100644 --- a/android/config.go +++ b/android/config.go @@ -897,27 +897,31 @@ func (c *config) ModulesLoadedByPrivilegedModules() []string { } // Expected format for apexJarValue = <apex name>:<jar name> -func SplitApexJarPair(apexJarValue string) (string, string) { - var apexJarPair []string = strings.SplitN(apexJarValue, ":", 2) - if apexJarPair == nil || len(apexJarPair) != 2 { - panic(fmt.Errorf("malformed apexJarValue: %q, expected format: <apex>:<jar>", - apexJarValue)) +func SplitApexJarPair(ctx PathContext, str string) (string, string) { + pair := strings.SplitN(str, ":", 2) + if len(pair) == 2 { + return pair[0], pair[1] + } else { + reportPathErrorf(ctx, "malformed (apex, jar) pair: '%s', expected format: <apex>:<jar>", str) + return "error-apex", "error-jar" } - return apexJarPair[0], apexJarPair[1] } -func GetJarsFromApexJarPairs(apexJarPairs []string) []string { +func GetJarsFromApexJarPairs(ctx PathContext, apexJarPairs []string) []string { modules := make([]string, len(apexJarPairs)) for i, p := range apexJarPairs { - _, jar := SplitApexJarPair(p) + _, jar := SplitApexJarPair(ctx, p) modules[i] = jar } return modules } func (c *config) BootJars() []string { - return append(GetJarsFromApexJarPairs(c.productVariables.BootJars), - GetJarsFromApexJarPairs(c.productVariables.UpdatableBootJars)...) + ctx := NullPathContext{Config{ + config: c, + }} + return append(GetJarsFromApexJarPairs(ctx, c.productVariables.BootJars), + GetJarsFromApexJarPairs(ctx, c.productVariables.UpdatableBootJars)...) } func (c *config) DexpreoptGlobalConfig(ctx PathContext) ([]byte, error) { diff --git a/android/module.go b/android/module.go index 7e64f0adf..45477ea80 100644 --- a/android/module.go +++ b/android/module.go @@ -104,6 +104,8 @@ type EarlyModuleContext interface { type BaseModuleContext interface { EarlyModuleContext + blueprintBaseModuleContext() blueprint.BaseModuleContext + OtherModuleName(m blueprint.Module) string OtherModuleDir(m blueprint.Module) string OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) @@ -1439,6 +1441,10 @@ func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.Depen return b.bp.GetDirectDepWithTag(name, tag) } +func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext { + return b.bp +} + type moduleContext struct { bp blueprint.ModuleContext baseModuleContext @@ -2361,3 +2367,8 @@ type IdeInfo struct { Installed_paths []string `json:"installed,omitempty"` SrcJars []string `json:"srcjars,omitempty"` } + +func CheckBlueprintSyntax(ctx BaseModuleContext, filename string, contents string) []error { + bpctx := ctx.blueprintBaseModuleContext() + return blueprint.CheckBlueprintSyntax(bpctx.ModuleFactories(), filename, contents) +} diff --git a/android/paths.go b/android/paths.go index 8bb9a96dd..fcea65c55 100644 --- a/android/paths.go +++ b/android/paths.go @@ -43,6 +43,14 @@ type PathGlobContext interface { var _ PathContext = SingletonContext(nil) var _ PathContext = ModuleContext(nil) +// "Null" path context is a minimal path context for a given config. +type NullPathContext struct { + config Config +} + +func (NullPathContext) AddNinjaFileDeps(...string) {} +func (ctx NullPathContext) Config() Config { return ctx.config } + type ModuleInstallPathContext interface { BaseModuleContext diff --git a/apex/androidmk.go b/apex/androidmk.go index 09d360709..6b168fee4 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -121,7 +121,7 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, apexName, mo fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " ")) } if len(fi.dataPaths) > 0 { - fmt.Println(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(fi.dataPaths), " ")) + fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(fi.dataPaths), " ")) } if fi.module != nil && len(fi.module.NoticeFiles()) > 0 { diff --git a/apex/apex.go b/apex/apex.go index 4b59c6d93..9659c3fcd 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1848,6 +1848,51 @@ func (a *apexBundle) checkUpdatable(ctx android.ModuleContext) { } } +// Ensures that a lib providing stub isn't statically linked +func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext) { + // Practically, we only care about regular APEXes on the device. + if ctx.Host() || a.testApex || a.vndkApex { + return + } + + a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { + if ccm, ok := to.(*cc.Module); ok { + apexName := ctx.ModuleName() + fromName := ctx.OtherModuleName(from) + toName := ctx.OtherModuleName(to) + + // If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither + // do any of its dependencies. + if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) { + // As soon as the dependency graph crosses the APEX boundary, don't go further. + return false + } + + // TODO(jiyong) remove this check when R is published to AOSP. Currently, libstatssocket + // is capable of providing a stub variant, but is being statically linked from the bluetooth + // APEX. + if toName == "libstatssocket" { + return false + } + + // The dynamic linker and crash_dump tool in the runtime APEX is the only exception to this rule. + // It can't make the static dependencies dynamic because it can't + // do the dynamic linking for itself. + if apexName == "com.android.runtime" && (fromName == "linker" || fromName == "crash_dump") { + return false + } + + isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName) + if isStubLibraryFromOtherApex && !externalDep { + ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+ + "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false)) + } + + } + return true + }) +} + func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild() switch a.properties.ApexType { @@ -1885,6 +1930,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.checkApexAvailability(ctx) a.checkUpdatable(ctx) + a.checkStaticLinkingToStubLibraries(ctx) handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case) diff --git a/apex/apex_test.go b/apex/apex_test.go index 5461debf4..3c25b523c 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4508,10 +4508,78 @@ func TestAppBundle(t *testing.T) { ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`) } -func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) { +func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) { t.Helper() - bp = bp + ` + bp := ` + java_library { + name: "some-updatable-apex-lib", + srcs: ["a.java"], + sdk_version: "current", + apex_available: [ + "some-updatable-apex", + ], + } + + java_library { + name: "some-non-updatable-apex-lib", + srcs: ["a.java"], + apex_available: [ + "some-non-updatable-apex", + ], + } + + java_library { + name: "some-platform-lib", + srcs: ["a.java"], + sdk_version: "current", + installable: true, + } + + java_library { + name: "some-art-lib", + srcs: ["a.java"], + sdk_version: "current", + apex_available: [ + "com.android.art.something", + ], + hostdex: true, + } + + apex { + name: "some-updatable-apex", + key: "some-updatable-apex.key", + java_libs: ["some-updatable-apex-lib"], + updatable: true, + min_sdk_version: "current", + } + + apex { + name: "some-non-updatable-apex", + key: "some-non-updatable-apex.key", + java_libs: ["some-non-updatable-apex-lib"], + } + + apex_key { + name: "some-updatable-apex.key", + } + + apex_key { + name: "some-non-updatable-apex.key", + } + + apex { + name: "com.android.art.something", + key: "com.android.art.something.key", + java_libs: ["some-art-lib"], + updatable: true, + min_sdk_version: "current", + } + + apex_key { + name: "com.android.art.something.key", + } + filegroup { name: "some-updatable-apex-file_contexts", srcs: [ @@ -4598,145 +4666,86 @@ func TestUpdatable_should_set_min_sdk_version(t *testing.T) { } func TestNoUpdatableJarsInBootImage(t *testing.T) { - bp := ` - java_library { - name: "some-updatable-apex-lib", - srcs: ["a.java"], - sdk_version: "current", - apex_available: [ - "some-updatable-apex", - ], - } - java_library { - name: "some-non-updatable-apex-lib", - srcs: ["a.java"], - apex_available: [ - "some-non-updatable-apex", - ], - } + var error string + var transform func(*dexpreopt.GlobalConfig) - java_library { - name: "some-platform-lib", - srcs: ["a.java"], - sdk_version: "current", - installable: true, + t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) { + transform = func(config *dexpreopt.GlobalConfig) { + config.ArtApexJars = []string{"com.android.art.something:some-art-lib"} } + testNoUpdatableJarsInBootImage(t, "", transform) + }) - java_library { - name: "some-art-lib", - srcs: ["a.java"], - sdk_version: "current", - apex_available: [ - "com.android.art.something", - ], - hostdex: true, + t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) { + error = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image" + transform = func(config *dexpreopt.GlobalConfig) { + config.BootJars = []string{"com.android.art.something:some-art-lib"} } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - apex { - name: "some-updatable-apex", - key: "some-updatable-apex.key", - java_libs: ["some-updatable-apex-lib"], - updatable: true, - min_sdk_version: "current", + t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) { + error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image" + transform = func(config *dexpreopt.GlobalConfig) { + config.ArtApexJars = []string{"some-updatable-apex:some-updatable-apex-lib"} } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - apex { - name: "some-non-updatable-apex", - key: "some-non-updatable-apex.key", - java_libs: ["some-non-updatable-apex-lib"], + t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) { + error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image" + transform = func(config *dexpreopt.GlobalConfig) { + config.ArtApexJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"} } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - apex_key { - name: "some-updatable-apex.key", + t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) { + error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image" + transform = func(config *dexpreopt.GlobalConfig) { + config.BootJars = []string{"some-updatable-apex:some-updatable-apex-lib"} } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - apex_key { - name: "some-non-updatable-apex.key", + 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 = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"} } + testNoUpdatableJarsInBootImage(t, "", transform) + }) - apex { - name: "com.android.art.something", - key: "com.android.art.something.key", - java_libs: ["some-art-lib"], - updatable: true, - min_sdk_version: "current", + t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) { + error = "failed to find a dex jar path for module 'nonexistent'" + transform = func(config *dexpreopt.GlobalConfig) { + config.ArtApexJars = []string{"platform:nonexistent"} } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - apex_key { - name: "com.android.art.something.key", + t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) { + error = "failed to find a dex jar path for module 'nonexistent'" + transform = func(config *dexpreopt.GlobalConfig) { + config.BootJars = []string{"platform:nonexistent"} } - ` - - var error string - var transform func(*dexpreopt.GlobalConfig) - - // updatable jar from ART apex in the ART boot image => ok - transform = func(config *dexpreopt.GlobalConfig) { - config.ArtApexJars = []string{"com.android.art.something:some-art-lib"} - } - testNoUpdatableJarsInBootImage(t, "", bp, transform) - - // updatable jar from ART apex in the framework boot image => error - error = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image" - transform = func(config *dexpreopt.GlobalConfig) { - config.BootJars = []string{"com.android.art.something:some-art-lib"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) - - // updatable jar from some other apex in the ART boot image => error - error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image" - transform = func(config *dexpreopt.GlobalConfig) { - config.ArtApexJars = []string{"some-updatable-apex:some-updatable-apex-lib"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) - - // non-updatable jar from some other apex in the ART boot image => error - error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image" - transform = func(config *dexpreopt.GlobalConfig) { - config.ArtApexJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) - - // updatable jar from some other apex in the framework boot image => error - error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image" - transform = func(config *dexpreopt.GlobalConfig) { - config.BootJars = []string{"some-updatable-apex:some-updatable-apex-lib"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) - - // non-updatable jar from some other apex in the framework boot image => ok - transform = func(config *dexpreopt.GlobalConfig) { - config.BootJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"} - } - testNoUpdatableJarsInBootImage(t, "", bp, transform) - - // nonexistent jar in the ART boot image => error - error = "failed to find a dex jar path for module 'nonexistent'" - transform = func(config *dexpreopt.GlobalConfig) { - config.ArtApexJars = []string{"platform:nonexistent"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) - - // nonexistent jar in the framework boot image => error - error = "failed to find a dex jar path for module 'nonexistent'" - transform = func(config *dexpreopt.GlobalConfig) { - config.BootJars = []string{"platform:nonexistent"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) + testNoUpdatableJarsInBootImage(t, error, transform) + }) - // platform jar in the ART boot image => error - error = "module 'some-platform-lib' is not allowed in the ART boot image" - transform = func(config *dexpreopt.GlobalConfig) { - config.ArtApexJars = []string{"platform:some-platform-lib"} - } - testNoUpdatableJarsInBootImage(t, error, bp, transform) + t.Run("platform jar in the ART boot image => error", func(t *testing.T) { + error = "module 'some-platform-lib' is not allowed in the ART boot image" + transform = func(config *dexpreopt.GlobalConfig) { + config.ArtApexJars = []string{"platform:some-platform-lib"} + } + testNoUpdatableJarsInBootImage(t, error, transform) + }) - // platform jar in the framework boot image => ok - transform = func(config *dexpreopt.GlobalConfig) { - config.BootJars = []string{"platform:some-platform-lib"} - } - testNoUpdatableJarsInBootImage(t, "", bp, transform) + t.Run("platform jar in the framework boot image => ok", func(t *testing.T) { + transform = func(config *dexpreopt.GlobalConfig) { + config.BootJars = []string{"platform:some-platform-lib"} + } + testNoUpdatableJarsInBootImage(t, "", transform) + }) } func TestTestFor(t *testing.T) { @@ -4833,6 +4842,42 @@ func TestApexSet(t *testing.T) { } } +func TestNoStaticLinkingToStubsLib(t *testing.T) { + testApexError(t, `.*required by "mylib" is a native library providing stub.*`, ` + 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"], + static_libs: ["otherlib"], + system_shared_libs: [], + stl: "none", + apex_available: [ "myapex" ], + } + + cc_library { + name: "otherlib", + srcs: ["mylib.cpp"], + system_shared_libs: [], + stl: "none", + stubs: { + versions: ["1", "2", "3"], + }, + apex_available: [ "myapex" ], + } + `) +} + func TestMain(m *testing.M) { run := func() int { setUp() @@ -2881,6 +2881,9 @@ func (c *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Modu return false } } + } else if ctx.OtherModuleDependencyTag(dep) == llndkImplDep { + // We don't track beyond LLNDK + return false } return true } diff --git a/cc/vndk.go b/cc/vndk.go index dbe1f3b5b..e5e453305 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -309,7 +309,13 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { panic(err) } - if m.HasStubsVariants() { + if m.HasStubsVariants() && name != "libz" { + // b/155456180 libz is the ONLY exception here. We don't want to make + // libz an LLNDK library because we in general can't guarantee that + // libz will behave consistently especially about the compression. + // i.e. the compressed output might be different across releases. + // As the library is an external one, it's risky to keep the compatibility + // promise if it becomes an LLNDK. mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK") } diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index f1dde9c22..fc0356301 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -82,7 +82,7 @@ func GenerateDexpreoptRule(ctx android.PathContext, globalSoong *GlobalSoongConf if !dexpreoptDisabled(ctx, global, module) { // Don't preopt individual boot jars, they will be preopted together. - if !contains(android.GetJarsFromApexJarPairs(global.BootJars), module.Name) { + if !contains(android.GetJarsFromApexJarPairs(ctx, global.BootJars), module.Name) { appImage := (generateProfile || module.ForceCreateAppImage || global.DefaultAppImages) && !module.NoCreateAppImage @@ -104,7 +104,7 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo // Don't preopt system server jars that are updatable. for _, p := range global.UpdatableSystemServerJars { - if _, jar := android.SplitApexJarPair(p); jar == module.Name { + if _, jar := android.SplitApexJarPair(ctx, p); jar == module.Name { return true } } @@ -113,7 +113,7 @@ func dexpreoptDisabled(ctx android.PathContext, global *GlobalConfig, module *Mo // Also preopt system server jars since selinux prevents system server from loading anything from // /data. If we don't do this they will need to be extracted which is not favorable for RAM usage // or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options. - if global.OnlyPreoptBootImageAndSystemServer && !contains(android.GetJarsFromApexJarPairs(global.BootJars), module.Name) && + if global.OnlyPreoptBootImageAndSystemServer && !contains(android.GetJarsFromApexJarPairs(ctx, global.BootJars), module.Name) && !contains(global.SystemServerJars, module.Name) && !module.PreoptExtractedApk { return true } @@ -561,8 +561,8 @@ func makefileMatch(pattern, s string) bool { } // Expected format for apexJarValue = <apex name>:<jar name> -func GetJarLocationFromApexJarPair(apexJarValue string) string { - apex, jar := android.SplitApexJarPair(apexJarValue) +func GetJarLocationFromApexJarPair(ctx android.PathContext, apexJarValue string) string { + apex, jar := android.SplitApexJarPair(ctx, apexJarValue) return filepath.Join("/apex", apex, "javalib", jar+".jar") } @@ -573,7 +573,7 @@ var nonUpdatableSystemServerJarsKey = android.NewOnceKey("nonUpdatableSystemServ func NonUpdatableSystemServerJars(ctx android.PathContext, global *GlobalConfig) []string { return ctx.Config().Once(nonUpdatableSystemServerJarsKey, func() interface{} { return android.RemoveListFromList(global.SystemServerJars, - android.GetJarsFromApexJarPairs(global.UpdatableSystemServerJars)) + android.GetJarsFromApexJarPairs(ctx, global.UpdatableSystemServerJars)) }).([]string) } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index dffdc248f..90457d07d 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -109,11 +109,11 @@ func (image bootImageConfig) getAnyAndroidVariant() *bootImageVariant { return nil } -func (image bootImageConfig) moduleName(idx int) string { +func (image bootImageConfig) moduleName(ctx android.PathContext, idx int) string { // Dexpreopt on the boot class path produces multiple files. The first dex file // is converted into 'name'.art (to match the legacy assumption that 'name'.art // exists), and the rest are converted to 'name'-<jar>.art. - _, m := android.SplitApexJarPair(image.modules[idx]) + _, m := android.SplitApexJarPair(ctx, image.modules[idx]) name := image.stem if idx != 0 || image.extends != nil { name += "-" + stemOf(m) @@ -121,9 +121,9 @@ func (image bootImageConfig) moduleName(idx int) string { return name } -func (image bootImageConfig) firstModuleNameOrStem() string { +func (image bootImageConfig) firstModuleNameOrStem(ctx android.PathContext) string { if len(image.modules) > 0 { - return image.moduleName(0) + return image.moduleName(ctx, 0) } else { return image.stem } @@ -132,7 +132,7 @@ func (image bootImageConfig) firstModuleNameOrStem() string { func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths { ret := make(android.OutputPaths, 0, len(image.modules)*len(exts)) for i := range image.modules { - name := image.moduleName(i) + name := image.moduleName(ctx, i) for _, ext := range exts { ret = append(ret, dir.Join(ctx, name+ext)) } @@ -261,7 +261,7 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul } name := ctx.ModuleName(module) - index := android.IndexList(name, android.GetJarsFromApexJarPairs(image.modules)) + index := android.IndexList(name, android.GetJarsFromApexJarPairs(ctx, image.modules)) if index == -1 { return -1, nil } @@ -314,7 +314,7 @@ func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootI // Ensure all modules were converted to paths for i := range bootDexJars { if bootDexJars[i] == nil { - _, m := android.SplitApexJarPair(image.modules[i]) + _, m := android.SplitApexJarPair(ctx, image.modules[i]) if ctx.Config().AllowMissingDependencies() { missingDeps = append(missingDeps, m) bootDexJars[i] = android.PathForOutput(ctx, "missing") @@ -614,7 +614,7 @@ func updatableBcpPackagesRule(ctx android.SingletonContext, image *bootImageConf return ctx.Config().Once(updatableBcpPackagesRuleKey, func() interface{} { global := dexpreopt.GetGlobalConfig(ctx) - updatableModules := android.GetJarsFromApexJarPairs(global.UpdatableBootJars) + updatableModules := android.GetJarsFromApexJarPairs(ctx, global.UpdatableBootJars) // Collect `permitted_packages` for updatable boot jars. var updatablePackages []string diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 41a2ca794..f13d9f210 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -39,7 +39,7 @@ func systemServerClasspath(ctx android.MakeVarsContext) []string { // 2) The jars that are from an updatable apex. for _, m := range global.UpdatableSystemServerJars { systemServerClasspathLocations = append(systemServerClasspathLocations, - dexpreopt.GetJarLocationFromApexJarPair(m)) + dexpreopt.GetJarLocationFromApexJarPair(ctx, m)) } if len(systemServerClasspathLocations) != len(global.SystemServerJars)+len(global.UpdatableSystemServerJars) { panic(fmt.Errorf("Wrong number of system server jars, got %d, expected %d", @@ -80,7 +80,7 @@ func stemOf(moduleName string) string { } func getDexLocation(ctx android.PathContext, target android.Target, module string) string { - apex, jar := android.SplitApexJarPair(module) + apex, jar := android.SplitApexJarPair(ctx, module) name := stemOf(jar) + ".jar" @@ -156,7 +156,7 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped") // expands to <stem>.art for primary image and <stem>-<1st module>.art for extension - imageName := c.firstModuleNameOrStem() + ".art" + imageName := c.firstModuleNameOrStem(ctx) + ".art" // The path to bootclasspath dex files needs to be known at module // GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled. @@ -164,7 +164,7 @@ func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { // TODO(b/143682396): use module dependencies instead inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input") for _, m := range c.modules { - _, jar := android.SplitApexJarPair(m) + _, jar := android.SplitApexJarPair(ctx, m) c.dexPaths = append(c.dexPaths, inputDir.Join(ctx, stemOf(jar)+".jar")) } c.dexPathsDeps = c.dexPaths @@ -215,7 +215,7 @@ func defaultBootclasspath(ctx android.PathContext) []string { updatableBootclasspath := make([]string, len(global.UpdatableBootJars)) for i, p := range global.UpdatableBootJars { - updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(p) + updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(ctx, p) } bootclasspath := append(copyOf(image.getAnyAndroidVariant().dexLocationsDeps), updatableBootclasspath...) diff --git a/java/java.go b/java/java.go index d943a3a24..5b1dcd7cf 100644 --- a/java/java.go +++ b/java/java.go @@ -643,13 +643,15 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } } else if sdkDep.useModule { ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) - ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultBootclasspathLibraries...) ctx.AddVariationDependencies(nil, proguardRaiseTag, config.DefaultLibraries...) } } + if sdkDep.systemModules != "" { + ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) + } if ctx.ModuleName() == "android_stubs_current" || ctx.ModuleName() == "android_system_stubs_current" || @@ -1052,19 +1054,10 @@ func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { } func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion { - sdk, err := sdkContext.sdkVersion().effectiveVersion(ctx) - if err != nil { - ctx.PropertyErrorf("sdk_version", "%s", err) - } if javaVersion != "" { return normalizeJavaVersion(ctx, javaVersion) - } else if ctx.Device() && sdk <= 23 { - return JAVA_VERSION_7 - } else if ctx.Device() && sdk <= 29 { - return JAVA_VERSION_8 - } else if ctx.Device() && ctx.Config().UnbundledBuildUsePrebuiltSdks() { - // TODO(b/142896162): once we have prebuilt system modules we can use 1.9 for unbundled builds - return JAVA_VERSION_8 + } else if ctx.Device() { + return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx) } else { return JAVA_VERSION_9 } diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go index 03bc76bf2..999c72f3c 100644 --- a/java/prebuilt_apis.go +++ b/java/prebuilt_apis.go @@ -15,11 +15,12 @@ package java import ( - "android/soong/android" "sort" "strings" "github.com/google/blueprint/proptools" + + "android/soong/android" ) func init() { @@ -69,6 +70,10 @@ func parseApiFilePath(ctx android.LoadHookContext, path string) (module string, return } +func prebuiltApiModuleName(mctx android.LoadHookContext, module string, scope string, apiver string) string { + return mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module +} + func createImport(mctx android.LoadHookContext, module string, scope string, apiver string, path string) { props := struct { Name *string @@ -76,7 +81,7 @@ func createImport(mctx android.LoadHookContext, module string, scope string, api Sdk_version *string Installable *bool }{} - props.Name = proptools.StringPtr(mctx.ModuleName() + "_" + scope + "_" + apiver + "_" + module) + props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, module, scope, apiver)) props.Jars = append(props.Jars, path) // TODO(hansson): change to scope after migration is done. props.Sdk_version = proptools.StringPtr("current") @@ -124,6 +129,27 @@ func prebuiltSdkStubs(mctx android.LoadHookContext) { } } +func createSystemModules(mctx android.LoadHookContext, apiver string) { + props := struct { + Name *string + Libs []string + }{} + props.Name = proptools.StringPtr(prebuiltApiModuleName(mctx, "system_modules", "public", apiver)) + props.Libs = append(props.Libs, prebuiltApiModuleName(mctx, "core-for-system-modules", "public", apiver)) + + mctx.CreateModule(SystemModulesFactory, &props) +} + +func prebuiltSdkSystemModules(mctx android.LoadHookContext) { + for _, apiver := range mctx.Module().(*prebuiltApis).properties.Api_dirs { + jar := android.ExistentPathForSource(mctx, + mctx.ModuleDir(), apiver, "public", "core-for-system-modules.jar") + if jar.Valid() { + createSystemModules(mctx, apiver) + } + } +} + func prebuiltApiFiles(mctx android.LoadHookContext) { mydir := mctx.ModuleDir() + "/" // <apiver>/<scope>/api/<module>.txt @@ -178,6 +204,7 @@ func createPrebuiltApiModules(mctx android.LoadHookContext) { if _, ok := mctx.Module().(*prebuiltApis); ok { prebuiltApiFiles(mctx) prebuiltSdkStubs(mctx) + prebuiltSdkSystemModules(mctx) } } @@ -191,7 +218,9 @@ func createPrebuiltApiModules(mctx android.LoadHookContext) { // Similarly, it generates a java_import for all API .jar files found under the // directory where the Android.bp is located. Specifically, an API file located // at ./<ver>/<scope>/api/<module>.jar generates a java_import module named -// <prebuilt-api-module>.<scope>.<ver>.<module>. +// <prebuilt-api-module>_<scope>_<ver>_<module>, and for SDK versions >= 30 +// a java_system_modules module named +// <prebuilt-api-module>_public_<ver>_system_modules func PrebuiltApisFactory() android.Module { module := &prebuiltApis{} module.AddProperties(&module.properties) diff --git a/java/sdk.go b/java/sdk.go index 690451c60..9310f7846 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -252,6 +252,20 @@ func (s sdkSpec) effectiveVersionString(ctx android.EarlyModuleContext) (string, return ver.String(), err } +func (s sdkSpec) defaultJavaLanguageVersion(ctx android.EarlyModuleContext) javaVersion { + sdk, err := s.effectiveVersion(ctx) + if err != nil { + ctx.PropertyErrorf("sdk_version", "%s", err) + } + if sdk <= 23 { + return JAVA_VERSION_7 + } else if sdk <= 29 { + return JAVA_VERSION_8 + } else { + return JAVA_VERSION_9 + } +} + func sdkSpecFrom(str string) sdkSpec { switch str { // special cases first @@ -370,10 +384,16 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext sdkContext) sdkDep return sdkDep{} } + var systemModules string + if sdkVersion.defaultJavaLanguageVersion(ctx).usesJavaModules() { + systemModules = "sdk_public_" + sdkVersion.version.String() + "_system_modules" + } + return sdkDep{ - useFiles: true, - jars: android.Paths{jarPath.Path(), lambdaStubsPath}, - aidl: android.OptionalPathForPath(aidlPath.Path()), + useFiles: true, + jars: android.Paths{jarPath.Path(), lambdaStubsPath}, + aidl: android.OptionalPathForPath(aidlPath.Path()), + systemModules: systemModules, } } diff --git a/java/sdk_test.go b/java/sdk_test.go index 088db9e70..fb8646313 100644 --- a/java/sdk_test.go +++ b/java/sdk_test.go @@ -83,6 +83,16 @@ func TestClasspath(t *testing.T) { }, { + name: "sdk v30", + properties: `sdk_version: "30",`, + bootclasspath: []string{`""`}, + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", + }, + { + name: "current", properties: `sdk_version: "current",`, bootclasspath: []string{"android_stubs_current", "core-lambda-stubs"}, @@ -110,6 +120,16 @@ func TestClasspath(t *testing.T) { }, { + name: "system_30", + properties: `sdk_version: "system_30",`, + bootclasspath: []string{`""`}, + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/system/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", + }, + { + name: "test_current", properties: `sdk_version: "test_current",`, bootclasspath: []string{"android_test_stubs_current", "core-lambda-stubs"}, @@ -176,12 +196,24 @@ func TestClasspath(t *testing.T) { }, { + name: "unbundled sdk v30", + unbundled: true, + properties: `sdk_version: "30",`, + bootclasspath: []string{`""`}, + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", + }, + { + name: "unbundled current", unbundled: true, properties: `sdk_version: "current",`, bootclasspath: []string{`""`}, - forces8: true, + system: "sdk_public_current_system_modules", java8classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/current/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, aidl: "-pprebuilts/sdk/current/public/framework.aidl", }, @@ -189,27 +221,30 @@ func TestClasspath(t *testing.T) { name: "pdk default", pdk: true, bootclasspath: []string{`""`}, - forces8: true, - java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, - aidl: "-pprebuilts/sdk/29/public/framework.aidl", + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", }, { name: "pdk current", pdk: true, properties: `sdk_version: "current",`, bootclasspath: []string{`""`}, - forces8: true, - java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, - aidl: "-pprebuilts/sdk/29/public/framework.aidl", + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", }, { name: "pdk 29", pdk: true, properties: `sdk_version: "29",`, bootclasspath: []string{`""`}, - forces8: true, - java8classpath: []string{"prebuilts/sdk/29/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, - aidl: "-pprebuilts/sdk/29/public/framework.aidl", + system: "sdk_public_30_system_modules", + java8classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + java9classpath: []string{"prebuilts/sdk/30/public/android.jar", "prebuilts/sdk/tools/core-lambda-stubs.jar"}, + aidl: "-pprebuilts/sdk/30/public/framework.aidl", }, { name: "module_current", @@ -292,12 +327,16 @@ func TestClasspath(t *testing.T) { if testcase.system == "none" { system = "--system=none" } else if testcase.system != "" { - system = "--system=" + filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system") + dir := "" + if strings.HasPrefix(testcase.system, "sdk_public_") { + dir = "prebuilts/sdk" + } + system = "--system=" + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system") // The module-relative parts of these paths are hardcoded in system_modules.go: systemDeps = []string{ - filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "modules"), - filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "lib", "jrt-fs.jar"), - filepath.Join(buildDir, ".intermediates", testcase.system, "android_common", "system", "release"), + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "modules"), + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "lib", "jrt-fs.jar"), + filepath.Join(buildDir, ".intermediates", dir, testcase.system, "android_common", "system", "release"), } } diff --git a/java/testing.go b/java/testing.go index 53181a087..196714852 100644 --- a/java/testing.go +++ b/java/testing.go @@ -55,36 +55,54 @@ func TestConfig(buildDir string, env map[string]string, bp string, fs map[string "assets_a/a": nil, "assets_b/b": nil, - "prebuilts/sdk/14/public/android.jar": nil, - "prebuilts/sdk/14/public/framework.aidl": nil, - "prebuilts/sdk/14/system/android.jar": nil, - "prebuilts/sdk/17/public/android.jar": nil, - "prebuilts/sdk/17/public/framework.aidl": nil, - "prebuilts/sdk/17/system/android.jar": nil, - "prebuilts/sdk/29/public/android.jar": nil, - "prebuilts/sdk/29/public/framework.aidl": nil, - "prebuilts/sdk/29/system/android.jar": nil, - "prebuilts/sdk/29/system/foo.jar": nil, - "prebuilts/sdk/current/core/android.jar": nil, - "prebuilts/sdk/current/public/android.jar": nil, - "prebuilts/sdk/current/public/framework.aidl": nil, - "prebuilts/sdk/current/public/core.jar": nil, - "prebuilts/sdk/current/system/android.jar": nil, - "prebuilts/sdk/current/test/android.jar": nil, - "prebuilts/sdk/28/public/api/foo.txt": nil, - "prebuilts/sdk/28/system/api/foo.txt": nil, - "prebuilts/sdk/28/test/api/foo.txt": nil, - "prebuilts/sdk/28/public/api/foo-removed.txt": nil, - "prebuilts/sdk/28/system/api/foo-removed.txt": nil, - "prebuilts/sdk/28/test/api/foo-removed.txt": nil, - "prebuilts/sdk/28/public/api/bar.txt": nil, - "prebuilts/sdk/28/system/api/bar.txt": nil, - "prebuilts/sdk/28/test/api/bar.txt": nil, - "prebuilts/sdk/28/public/api/bar-removed.txt": nil, - "prebuilts/sdk/28/system/api/bar-removed.txt": nil, - "prebuilts/sdk/28/test/api/bar-removed.txt": nil, - "prebuilts/sdk/tools/core-lambda-stubs.jar": nil, - "prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "current"],}`), + "prebuilts/sdk/14/public/android.jar": nil, + "prebuilts/sdk/14/public/framework.aidl": nil, + "prebuilts/sdk/14/system/android.jar": nil, + "prebuilts/sdk/17/public/android.jar": nil, + "prebuilts/sdk/17/public/framework.aidl": nil, + "prebuilts/sdk/17/system/android.jar": nil, + "prebuilts/sdk/29/public/android.jar": nil, + "prebuilts/sdk/29/public/framework.aidl": nil, + "prebuilts/sdk/29/system/android.jar": nil, + "prebuilts/sdk/29/system/foo.jar": nil, + "prebuilts/sdk/30/public/android.jar": nil, + "prebuilts/sdk/30/public/framework.aidl": nil, + "prebuilts/sdk/30/system/android.jar": nil, + "prebuilts/sdk/30/system/foo.jar": nil, + "prebuilts/sdk/30/public/core-for-system-modules.jar": nil, + "prebuilts/sdk/current/core/android.jar": nil, + "prebuilts/sdk/current/public/android.jar": nil, + "prebuilts/sdk/current/public/framework.aidl": nil, + "prebuilts/sdk/current/public/core.jar": nil, + "prebuilts/sdk/current/public/core-for-system-modules.jar": nil, + "prebuilts/sdk/current/system/android.jar": nil, + "prebuilts/sdk/current/test/android.jar": nil, + "prebuilts/sdk/28/public/api/foo.txt": nil, + "prebuilts/sdk/28/system/api/foo.txt": nil, + "prebuilts/sdk/28/test/api/foo.txt": nil, + "prebuilts/sdk/28/public/api/foo-removed.txt": nil, + "prebuilts/sdk/28/system/api/foo-removed.txt": nil, + "prebuilts/sdk/28/test/api/foo-removed.txt": nil, + "prebuilts/sdk/28/public/api/bar.txt": nil, + "prebuilts/sdk/28/system/api/bar.txt": nil, + "prebuilts/sdk/28/test/api/bar.txt": nil, + "prebuilts/sdk/28/public/api/bar-removed.txt": nil, + "prebuilts/sdk/28/system/api/bar-removed.txt": nil, + "prebuilts/sdk/28/test/api/bar-removed.txt": nil, + "prebuilts/sdk/30/public/api/foo.txt": nil, + "prebuilts/sdk/30/system/api/foo.txt": nil, + "prebuilts/sdk/30/test/api/foo.txt": nil, + "prebuilts/sdk/30/public/api/foo-removed.txt": nil, + "prebuilts/sdk/30/system/api/foo-removed.txt": nil, + "prebuilts/sdk/30/test/api/foo-removed.txt": nil, + "prebuilts/sdk/30/public/api/bar.txt": nil, + "prebuilts/sdk/30/system/api/bar.txt": nil, + "prebuilts/sdk/30/test/api/bar.txt": nil, + "prebuilts/sdk/30/public/api/bar-removed.txt": nil, + "prebuilts/sdk/30/system/api/bar-removed.txt": nil, + "prebuilts/sdk/30/test/api/bar-removed.txt": nil, + "prebuilts/sdk/tools/core-lambda-stubs.jar": nil, + "prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "30", "current"],}`), "prebuilts/apk/app.apk": nil, "prebuilts/apk/app_arm.apk": nil, diff --git a/sdk/update.go b/sdk/update.go index 476a4a5ea..1ba58064d 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -350,6 +350,9 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro bp = newGeneratedFile(ctx, "snapshot", "Android.bp") generateBpContents(&bp.generatedContents, bpFile) + contents := bp.content.String() + syntaxCheckSnapshotBpFile(ctx, contents) + bp.build(pctx, ctx, nil) filesToZip := builder.filesToZip @@ -394,6 +397,36 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro return outputZipFile } +// Check the syntax of the generated Android.bp file contents and if they are +// invalid then log an error with the contents (tagged with line numbers) and the +// errors that were found so that it is easy to see where the problem lies. +func syntaxCheckSnapshotBpFile(ctx android.ModuleContext, contents string) { + errs := android.CheckBlueprintSyntax(ctx, "Android.bp", contents) + if len(errs) != 0 { + message := &strings.Builder{} + _, _ = fmt.Fprint(message, `errors in generated Android.bp snapshot: + +Generated Android.bp contents +======================================================================== +`) + for i, line := range strings.Split(contents, "\n") { + _, _ = fmt.Fprintf(message, "%6d: %s\n", i+1, line) + } + + _, _ = fmt.Fprint(message, ` +======================================================================== + +Errors found: +`) + + for _, err := range errs { + _, _ = fmt.Fprintf(message, "%s\n", err.Error()) + } + + ctx.ModuleErrorf("%s", message.String()) + } +} + func extractCommonProperties(ctx android.ModuleContext, extractor *commonValueExtractor, commonProperties interface{}, inputPropertiesSlice interface{}) { err := extractor.extractCommonProperties(commonProperties, inputPropertiesSlice) if err != nil { diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 1b13e5d36..fa44cb1e6 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -39,6 +39,7 @@ func runNinja(ctx Context, config Config) { args := []string{ "-d", "keepdepfile", "-d", "keeprsp", + "-d", "stats", "--frontend_file", fifo, } diff --git a/ui/build/soong.go b/ui/build/soong.go index 2fbf381b6..6a12add78 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -119,6 +119,7 @@ func runSoong(ctx Context, config Config) { cmd := Command(ctx, config, "soong "+name, config.PrebuiltBuildTool("ninja"), "-d", "keepdepfile", + "-d", "stats", "-o", "usesphonyoutputs=yes", "-o", "preremoveoutputs=yes", "-w", "dupbuild=err", diff --git a/ui/status/ninja.go b/ui/status/ninja.go index 9cf2f6a81..a11774cce 100644 --- a/ui/status/ninja.go +++ b/ui/status/ninja.go @@ -174,6 +174,8 @@ func (n *NinjaReader) run() { n.status.Print("warning: " + message) case ninja_frontend.Status_Message_ERROR: n.status.Error(message) + case ninja_frontend.Status_Message_DEBUG: + n.status.Verbose(message) default: n.status.Print(message) } diff --git a/ui/status/ninja_frontend/frontend.pb.go b/ui/status/ninja_frontend/frontend.pb.go index 7c05eed4b..7ba9de2a9 100644 --- a/ui/status/ninja_frontend/frontend.pb.go +++ b/ui/status/ninja_frontend/frontend.pb.go @@ -3,9 +3,11 @@ package ninja_frontend -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" + proto "github.com/golang/protobuf/proto" + math "math" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -16,7 +18,7 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package type Status_Message_Level int32 @@ -24,17 +26,21 @@ const ( Status_Message_INFO Status_Message_Level = 0 Status_Message_WARNING Status_Message_Level = 1 Status_Message_ERROR Status_Message_Level = 2 + Status_Message_DEBUG Status_Message_Level = 3 ) var Status_Message_Level_name = map[int32]string{ 0: "INFO", 1: "WARNING", 2: "ERROR", + 3: "DEBUG", } + var Status_Message_Level_value = map[string]int32{ "INFO": 0, "WARNING": 1, "ERROR": 2, + "DEBUG": 3, } func (x Status_Message_Level) Enum() *Status_Message_Level { @@ -42,9 +48,11 @@ func (x Status_Message_Level) Enum() *Status_Message_Level { *p = x return p } + func (x Status_Message_Level) String() string { return proto.EnumName(Status_Message_Level_name, int32(x)) } + func (x *Status_Message_Level) UnmarshalJSON(data []byte) error { value, err := proto.UnmarshalJSONEnum(Status_Message_Level_value, data, "Status_Message_Level") if err != nil { @@ -53,8 +61,9 @@ func (x *Status_Message_Level) UnmarshalJSON(data []byte) error { *x = Status_Message_Level(value) return nil } + func (Status_Message_Level) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 5, 0} + return fileDescriptor_eca3873955a29cfe, []int{0, 5, 0} } type Status struct { @@ -73,16 +82,17 @@ func (m *Status) Reset() { *m = Status{} } func (m *Status) String() string { return proto.CompactTextString(m) } func (*Status) ProtoMessage() {} func (*Status) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0} + return fileDescriptor_eca3873955a29cfe, []int{0} } + func (m *Status) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status.Unmarshal(m, b) } func (m *Status) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status.Marshal(b, m, deterministic) } -func (dst *Status) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status.Merge(dst, src) +func (m *Status) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status.Merge(m, src) } func (m *Status) XXX_Size() int { return xxx_messageInfo_Status.Size(m) @@ -147,16 +157,17 @@ func (m *Status_TotalEdges) Reset() { *m = Status_TotalEdges{} } func (m *Status_TotalEdges) String() string { return proto.CompactTextString(m) } func (*Status_TotalEdges) ProtoMessage() {} func (*Status_TotalEdges) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 0} + return fileDescriptor_eca3873955a29cfe, []int{0, 0} } + func (m *Status_TotalEdges) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_TotalEdges.Unmarshal(m, b) } func (m *Status_TotalEdges) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_TotalEdges.Marshal(b, m, deterministic) } -func (dst *Status_TotalEdges) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_TotalEdges.Merge(dst, src) +func (m *Status_TotalEdges) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_TotalEdges.Merge(m, src) } func (m *Status_TotalEdges) XXX_Size() int { return xxx_messageInfo_Status_TotalEdges.Size(m) @@ -188,16 +199,17 @@ func (m *Status_BuildStarted) Reset() { *m = Status_BuildStarted{} } func (m *Status_BuildStarted) String() string { return proto.CompactTextString(m) } func (*Status_BuildStarted) ProtoMessage() {} func (*Status_BuildStarted) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 1} + return fileDescriptor_eca3873955a29cfe, []int{0, 1} } + func (m *Status_BuildStarted) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_BuildStarted.Unmarshal(m, b) } func (m *Status_BuildStarted) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_BuildStarted.Marshal(b, m, deterministic) } -func (dst *Status_BuildStarted) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_BuildStarted.Merge(dst, src) +func (m *Status_BuildStarted) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_BuildStarted.Merge(m, src) } func (m *Status_BuildStarted) XXX_Size() int { return xxx_messageInfo_Status_BuildStarted.Size(m) @@ -232,16 +244,17 @@ func (m *Status_BuildFinished) Reset() { *m = Status_BuildFinished{} } func (m *Status_BuildFinished) String() string { return proto.CompactTextString(m) } func (*Status_BuildFinished) ProtoMessage() {} func (*Status_BuildFinished) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 2} + return fileDescriptor_eca3873955a29cfe, []int{0, 2} } + func (m *Status_BuildFinished) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_BuildFinished.Unmarshal(m, b) } func (m *Status_BuildFinished) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_BuildFinished.Marshal(b, m, deterministic) } -func (dst *Status_BuildFinished) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_BuildFinished.Merge(dst, src) +func (m *Status_BuildFinished) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_BuildFinished.Merge(m, src) } func (m *Status_BuildFinished) XXX_Size() int { return xxx_messageInfo_Status_BuildFinished.Size(m) @@ -276,16 +289,17 @@ func (m *Status_EdgeStarted) Reset() { *m = Status_EdgeStarted{} } func (m *Status_EdgeStarted) String() string { return proto.CompactTextString(m) } func (*Status_EdgeStarted) ProtoMessage() {} func (*Status_EdgeStarted) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 3} + return fileDescriptor_eca3873955a29cfe, []int{0, 3} } + func (m *Status_EdgeStarted) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_EdgeStarted.Unmarshal(m, b) } func (m *Status_EdgeStarted) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_EdgeStarted.Marshal(b, m, deterministic) } -func (dst *Status_EdgeStarted) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_EdgeStarted.Merge(dst, src) +func (m *Status_EdgeStarted) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_EdgeStarted.Merge(m, src) } func (m *Status_EdgeStarted) XXX_Size() int { return xxx_messageInfo_Status_EdgeStarted.Size(m) @@ -353,7 +367,11 @@ type Status_EdgeFinished struct { // Exit status (0 for success). Status *int32 `protobuf:"zigzag32,3,opt,name=status" json:"status,omitempty"` // Edge output, may contain ANSI codes. - Output *string `protobuf:"bytes,4,opt,name=output" json:"output,omitempty"` + Output *string `protobuf:"bytes,4,opt,name=output" json:"output,omitempty"` + // Number of milliseconds spent executing in user mode + UserTime *uint32 `protobuf:"varint,5,opt,name=user_time,json=userTime" json:"user_time,omitempty"` + // Number of milliseconds spent executing in kernel mode + SystemTime *uint32 `protobuf:"varint,6,opt,name=system_time,json=systemTime" json:"system_time,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -363,16 +381,17 @@ func (m *Status_EdgeFinished) Reset() { *m = Status_EdgeFinished{} } func (m *Status_EdgeFinished) String() string { return proto.CompactTextString(m) } func (*Status_EdgeFinished) ProtoMessage() {} func (*Status_EdgeFinished) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 4} + return fileDescriptor_eca3873955a29cfe, []int{0, 4} } + func (m *Status_EdgeFinished) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_EdgeFinished.Unmarshal(m, b) } func (m *Status_EdgeFinished) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_EdgeFinished.Marshal(b, m, deterministic) } -func (dst *Status_EdgeFinished) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_EdgeFinished.Merge(dst, src) +func (m *Status_EdgeFinished) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_EdgeFinished.Merge(m, src) } func (m *Status_EdgeFinished) XXX_Size() int { return xxx_messageInfo_Status_EdgeFinished.Size(m) @@ -411,8 +430,22 @@ func (m *Status_EdgeFinished) GetOutput() string { return "" } +func (m *Status_EdgeFinished) GetUserTime() uint32 { + if m != nil && m.UserTime != nil { + return *m.UserTime + } + return 0 +} + +func (m *Status_EdgeFinished) GetSystemTime() uint32 { + if m != nil && m.SystemTime != nil { + return *m.SystemTime + } + return 0 +} + type Status_Message struct { - // Message priority level (INFO, WARNING, or ERROR). + // Message priority level (DEBUG, INFO, WARNING, ERROR). Level *Status_Message_Level `protobuf:"varint,1,opt,name=level,enum=ninja.Status_Message_Level,def=0" json:"level,omitempty"` // Info/warning/error message from Ninja. Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"` @@ -425,16 +458,17 @@ func (m *Status_Message) Reset() { *m = Status_Message{} } func (m *Status_Message) String() string { return proto.CompactTextString(m) } func (*Status_Message) ProtoMessage() {} func (*Status_Message) Descriptor() ([]byte, []int) { - return fileDescriptor_frontend_5a49d9b15a642005, []int{0, 5} + return fileDescriptor_eca3873955a29cfe, []int{0, 5} } + func (m *Status_Message) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_Status_Message.Unmarshal(m, b) } func (m *Status_Message) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return xxx_messageInfo_Status_Message.Marshal(b, m, deterministic) } -func (dst *Status_Message) XXX_Merge(src proto.Message) { - xxx_messageInfo_Status_Message.Merge(dst, src) +func (m *Status_Message) XXX_Merge(src proto.Message) { + xxx_messageInfo_Status_Message.Merge(m, src) } func (m *Status_Message) XXX_Size() int { return xxx_messageInfo_Status_Message.Size(m) @@ -462,6 +496,7 @@ func (m *Status_Message) GetMessage() string { } func init() { + proto.RegisterEnum("ninja.Status_Message_Level", Status_Message_Level_name, Status_Message_Level_value) proto.RegisterType((*Status)(nil), "ninja.Status") proto.RegisterType((*Status_TotalEdges)(nil), "ninja.Status.TotalEdges") proto.RegisterType((*Status_BuildStarted)(nil), "ninja.Status.BuildStarted") @@ -469,42 +504,46 @@ func init() { proto.RegisterType((*Status_EdgeStarted)(nil), "ninja.Status.EdgeStarted") proto.RegisterType((*Status_EdgeFinished)(nil), "ninja.Status.EdgeFinished") proto.RegisterType((*Status_Message)(nil), "ninja.Status.Message") - proto.RegisterEnum("ninja.Status_Message_Level", Status_Message_Level_name, Status_Message_Level_value) } -func init() { proto.RegisterFile("frontend.proto", fileDescriptor_frontend_5a49d9b15a642005) } - -var fileDescriptor_frontend_5a49d9b15a642005 = []byte{ - // 496 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0xd1, 0x6e, 0xd3, 0x30, - 0x14, 0xa5, 0x69, 0xd3, 0x34, 0x37, 0x6d, 0x28, 0x96, 0x40, 0x59, 0x10, 0xa2, 0xda, 0xd3, 0x78, - 0x20, 0x48, 0xbc, 0x20, 0x10, 0x12, 0xa2, 0xd2, 0x06, 0x43, 0xd0, 0x49, 0xde, 0x24, 0x24, 0x5e, - 0xaa, 0x74, 0xf6, 0x86, 0x51, 0xe2, 0x54, 0xb1, 0xbb, 0x5f, 0xe0, 0x7f, 0x78, 0xe0, 0xfb, 0x90, - 0xaf, 0xed, 0x2c, 0x65, 0x7b, 0xcb, 0xf1, 0x3d, 0xe7, 0xde, 0x73, 0x8f, 0x1d, 0x48, 0xaf, 0xda, - 0x46, 0x6a, 0x2e, 0x59, 0xb1, 0x6d, 0x1b, 0xdd, 0x90, 0x50, 0x0a, 0xf9, 0xab, 0x3c, 0xfc, 0x13, - 0xc1, 0xf8, 0x5c, 0x97, 0x7a, 0xa7, 0xc8, 0x5b, 0x48, 0x74, 0xa3, 0xcb, 0x6a, 0xcd, 0xd9, 0x35, - 0x57, 0xd9, 0x60, 0x31, 0x38, 0x4a, 0x5e, 0x67, 0x05, 0xf2, 0x0a, 0xcb, 0x29, 0x2e, 0x0c, 0xe1, - 0xd8, 0xd4, 0x29, 0xe8, 0xee, 0x9b, 0x7c, 0x80, 0xd9, 0x66, 0x27, 0x2a, 0xb6, 0x56, 0xba, 0x6c, - 0x35, 0x67, 0x59, 0x80, 0xe2, 0x7c, 0x5f, 0xbc, 0x34, 0x94, 0x73, 0xcb, 0xa0, 0xd3, 0x4d, 0x0f, - 0x91, 0x25, 0xa4, 0xb6, 0xc1, 0x95, 0x90, 0x42, 0xfd, 0xe4, 0x2c, 0x1b, 0x62, 0x87, 0xa7, 0xf7, - 0x74, 0x38, 0x71, 0x14, 0x6a, 0x67, 0x7a, 0x48, 0xde, 0xc3, 0xd4, 0x38, 0xef, 0x3c, 0x8c, 0xb0, - 0xc3, 0xc1, 0x7e, 0x07, 0xe3, 0xd7, 0x5b, 0x48, 0xf8, 0x2d, 0x30, 0x2b, 0xa0, 0xba, 0x33, 0x10, - 0xde, 0xb7, 0x82, 0x91, 0x77, 0xf3, 0x71, 0x5c, 0x37, 0xfe, 0x15, 0x44, 0x35, 0x57, 0xaa, 0xbc, - 0xe6, 0xd9, 0x18, 0xa5, 0x8f, 0xf7, 0xa5, 0xdf, 0x6c, 0x91, 0x7a, 0x56, 0xfe, 0x12, 0xe0, 0x36, - 0x4e, 0xf2, 0xfc, 0x6e, 0xfa, 0xb3, 0x7e, 0xc6, 0xf9, 0x17, 0x98, 0xf6, 0x03, 0x24, 0x0b, 0x48, - 0xb6, 0x65, 0x5b, 0x56, 0x15, 0xaf, 0x84, 0xaa, 0x9d, 0xa0, 0x7f, 0x44, 0x32, 0x88, 0x6e, 0x78, - 0xbb, 0x69, 0x14, 0xc7, 0xfb, 0x98, 0x50, 0x0f, 0xf3, 0x87, 0x30, 0xdb, 0x8b, 0x32, 0xff, 0x3b, - 0x80, 0xa4, 0x17, 0x0d, 0x49, 0x21, 0x10, 0xcc, 0xf5, 0x0c, 0x04, 0x23, 0xcf, 0x00, 0x30, 0xd6, - 0xb5, 0x16, 0xb5, 0xed, 0x36, 0xa3, 0x31, 0x9e, 0x5c, 0x88, 0x9a, 0x93, 0x27, 0x30, 0x16, 0x72, - 0xbb, 0xd3, 0x2a, 0x1b, 0x2e, 0x86, 0x47, 0x31, 0x75, 0xc8, 0x38, 0x68, 0x76, 0x1a, 0x0b, 0x23, - 0x2c, 0x78, 0x48, 0x08, 0x8c, 0x18, 0x57, 0x97, 0x98, 0x72, 0x4c, 0xf1, 0xdb, 0xb0, 0x2f, 0x9b, - 0xba, 0x2e, 0x25, 0xc3, 0x04, 0x63, 0xea, 0xa1, 0xad, 0x48, 0xd5, 0x54, 0x3c, 0x8b, 0xec, 0x26, - 0x0e, 0xe6, 0x02, 0xa6, 0xfd, 0x3b, 0xb9, 0x63, 0xfc, 0x00, 0x26, 0x5c, 0xb2, 0xbe, 0xed, 0x88, - 0x4b, 0xe6, 0x4d, 0x2b, 0xbc, 0x1a, 0x7c, 0x6b, 0x8f, 0xa8, 0x43, 0xe6, 0xdc, 0xba, 0xc4, 0x17, - 0x14, 0x53, 0x87, 0xf2, 0xdf, 0x03, 0x88, 0xdc, 0x25, 0x92, 0x37, 0x10, 0x56, 0xfc, 0x86, 0x57, - 0x38, 0x29, 0xfd, 0xff, 0x99, 0x3a, 0x56, 0xf1, 0xd5, 0x50, 0xde, 0x8d, 0x4e, 0x57, 0x27, 0x67, - 0xd4, 0xf2, 0xcd, 0x26, 0xfe, 0x95, 0x04, 0x76, 0x47, 0x07, 0x0f, 0x5f, 0x40, 0x88, 0x7c, 0x32, - 0x01, 0x54, 0xcc, 0x1f, 0x90, 0x04, 0xa2, 0xef, 0x1f, 0xe9, 0xea, 0x74, 0xf5, 0x69, 0x3e, 0x20, - 0x31, 0x84, 0xc7, 0x94, 0x9e, 0xd1, 0x79, 0xb0, 0x24, 0x9f, 0x87, 0x3f, 0x52, 0x9c, 0xb8, 0xf6, - 0x7f, 0xf5, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2e, 0x8c, 0xef, 0xcb, 0xe0, 0x03, 0x00, 0x00, +func init() { + proto.RegisterFile("frontend.proto", fileDescriptor_eca3873955a29cfe) +} + +var fileDescriptor_eca3873955a29cfe = []byte{ + // 539 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x54, 0xd1, 0x6e, 0xd3, 0x4a, + 0x10, 0xbd, 0x4e, 0xe2, 0x38, 0x1e, 0x27, 0xb9, 0x61, 0x25, 0x90, 0xeb, 0x0a, 0x35, 0xea, 0x53, + 0x5f, 0x08, 0x12, 0x42, 0x42, 0x20, 0x24, 0x44, 0x44, 0x5a, 0x8a, 0x20, 0x95, 0xb6, 0x45, 0x48, + 0xbc, 0x44, 0x4e, 0x77, 0x5a, 0x8c, 0xec, 0x75, 0xe4, 0xdd, 0x54, 0xe2, 0x37, 0xf8, 0x09, 0xfe, + 0x80, 0xaf, 0xe3, 0x01, 0xed, 0xec, 0xda, 0x75, 0x68, 0xdf, 0x7c, 0x76, 0xce, 0x9c, 0x39, 0x7b, + 0x76, 0x64, 0x18, 0x5f, 0x55, 0xa5, 0xd4, 0x28, 0xc5, 0x6c, 0x53, 0x95, 0xba, 0x64, 0xbe, 0xcc, + 0xe4, 0xf7, 0xf4, 0xf0, 0x4f, 0x00, 0xfd, 0x73, 0x9d, 0xea, 0xad, 0x62, 0x2f, 0x21, 0xd2, 0xa5, + 0x4e, 0xf3, 0x15, 0x8a, 0x6b, 0x54, 0xb1, 0x37, 0xf5, 0x8e, 0xa2, 0x67, 0xf1, 0x8c, 0x78, 0x33, + 0xcb, 0x99, 0x5d, 0x18, 0xc2, 0xc2, 0xd4, 0x39, 0xe8, 0xe6, 0x9b, 0xbd, 0x81, 0xd1, 0x7a, 0x9b, + 0xe5, 0x62, 0xa5, 0x74, 0x5a, 0x69, 0x14, 0x71, 0x87, 0x9a, 0x93, 0xdd, 0xe6, 0xb9, 0xa1, 0x9c, + 0x5b, 0x06, 0x1f, 0xae, 0x5b, 0x88, 0xcd, 0x61, 0x6c, 0x05, 0xae, 0x32, 0x99, 0xa9, 0x6f, 0x28, + 0xe2, 0x2e, 0x29, 0xec, 0xdf, 0xa3, 0x70, 0xec, 0x28, 0xdc, 0xce, 0xac, 0x21, 0x7b, 0x0d, 0x43, + 0xe3, 0xbc, 0xf1, 0xd0, 0x23, 0x85, 0xbd, 0x5d, 0x05, 0xe3, 0xb7, 0xb6, 0x10, 0xe1, 0x2d, 0x30, + 0x57, 0xa0, 0xee, 0xc6, 0x80, 0x7f, 0xdf, 0x15, 0x4c, 0x7b, 0x33, 0x9f, 0xc6, 0x35, 0xe3, 0x9f, + 0x42, 0x50, 0xa0, 0x52, 0xe9, 0x35, 0xc6, 0x7d, 0x6a, 0x7d, 0xb8, 0xdb, 0xfa, 0xc9, 0x16, 0x79, + 0xcd, 0x4a, 0x9e, 0x00, 0xdc, 0xc6, 0xc9, 0x0e, 0xee, 0xa6, 0x3f, 0x6a, 0x67, 0x9c, 0x7c, 0x80, + 0x61, 0x3b, 0x40, 0x36, 0x85, 0x68, 0x93, 0x56, 0x69, 0x9e, 0x63, 0x9e, 0xa9, 0xc2, 0x35, 0xb4, + 0x8f, 0x58, 0x0c, 0xc1, 0x0d, 0x56, 0xeb, 0x52, 0x21, 0xbd, 0xc7, 0x80, 0xd7, 0x30, 0xf9, 0x1f, + 0x46, 0x3b, 0x51, 0x26, 0xbf, 0x3d, 0x88, 0x5a, 0xd1, 0xb0, 0x31, 0x74, 0x32, 0xe1, 0x34, 0x3b, + 0x99, 0x60, 0x8f, 0x01, 0x28, 0xd6, 0x95, 0xce, 0x0a, 0xab, 0x36, 0xe2, 0x21, 0x9d, 0x5c, 0x64, + 0x05, 0xb2, 0x47, 0xd0, 0xcf, 0xe4, 0x66, 0xab, 0x55, 0xdc, 0x9d, 0x76, 0x8f, 0x42, 0xee, 0x90, + 0x71, 0x50, 0x6e, 0x35, 0x15, 0x7a, 0x54, 0xa8, 0x21, 0x63, 0xd0, 0x13, 0xa8, 0x2e, 0x29, 0xe5, + 0x90, 0xd3, 0xb7, 0x61, 0x5f, 0x96, 0x45, 0x91, 0x4a, 0x41, 0x09, 0x86, 0xbc, 0x86, 0xb6, 0x22, + 0x55, 0x99, 0x63, 0x1c, 0xd8, 0x9b, 0x38, 0x98, 0xfc, 0xf2, 0x60, 0xd8, 0x7e, 0x94, 0x3b, 0xce, + 0xf7, 0x60, 0x80, 0x52, 0xb4, 0x7d, 0x07, 0x28, 0x45, 0xed, 0x5a, 0xd1, 0xdb, 0xd0, 0xb2, 0x3d, + 0xe0, 0x0e, 0x99, 0x73, 0x6b, 0x93, 0x56, 0x28, 0xe4, 0x0e, 0xb1, 0x7d, 0x08, 0xb7, 0x0a, 0x2b, + 0xab, 0xe5, 0x93, 0xd6, 0xc0, 0x1c, 0x90, 0xd8, 0x01, 0x44, 0xea, 0x87, 0xd2, 0x58, 0xd8, 0x72, + 0xdf, 0xbe, 0x9f, 0x3d, 0x32, 0x84, 0xe4, 0xa7, 0x07, 0x81, 0xdb, 0x01, 0xf6, 0x02, 0xfc, 0x1c, + 0x6f, 0x30, 0x27, 0x9f, 0xe3, 0x7f, 0xb7, 0xdc, 0xb1, 0x66, 0x1f, 0x0d, 0xe5, 0x55, 0xef, 0x74, + 0x79, 0x7c, 0xc6, 0x2d, 0xdf, 0x04, 0x51, 0x2f, 0x59, 0xc7, 0x46, 0xe4, 0xe0, 0xe1, 0x73, 0xf0, + 0x89, 0xcf, 0x06, 0x40, 0x1d, 0x93, 0xff, 0x58, 0x04, 0xc1, 0x97, 0xb7, 0x7c, 0x79, 0xba, 0x3c, + 0x99, 0x78, 0x2c, 0x04, 0x7f, 0xc1, 0xf9, 0x19, 0x9f, 0x74, 0xcc, 0xe7, 0xbb, 0xc5, 0xfc, 0xf3, + 0xc9, 0xa4, 0x3b, 0x67, 0xef, 0xbb, 0x5f, 0xc7, 0x34, 0x7c, 0x55, 0xff, 0x1f, 0xfe, 0x06, 0x00, + 0x00, 0xff, 0xff, 0xaf, 0x93, 0x48, 0xcf, 0x2a, 0x04, 0x00, 0x00, } diff --git a/ui/status/ninja_frontend/frontend.proto b/ui/status/ninja_frontend/frontend.proto index 13fd535dc..baa004668 100644 --- a/ui/status/ninja_frontend/frontend.proto +++ b/ui/status/ninja_frontend/frontend.proto @@ -61,6 +61,10 @@ message Status { optional sint32 status = 3; // Edge output, may contain ANSI codes. optional string output = 4; + // Number of milliseconds spent executing in user mode + optional uint32 user_time = 5; + // Number of milliseconds spent executing in kernel mode + optional uint32 system_time = 6; } message Message { @@ -68,8 +72,9 @@ message Status { INFO = 0; WARNING = 1; ERROR = 2; + DEBUG = 3; } - // Message priority level (INFO, WARNING, or ERROR). + // Message priority level (DEBUG, INFO, WARNING, ERROR). optional Level level = 1 [default = INFO]; // Info/warning/error message from Ninja. optional string message = 2; |