Optionally embed NOTICE files in apks.
am: 5b425e2e20
Change-Id: I0397838781d5ce7ba20778706d3b0ee4936080e8
diff --git a/apex/apex.go b/apex/apex.go
index 1dfd6dc..70a0bc5 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -145,7 +145,7 @@
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.TopDown("apex_deps", apexDepsMutator)
- ctx.BottomUp("apex", apexMutator)
+ ctx.BottomUp("apex", apexMutator).Parallel()
})
}
diff --git a/cc/cc.go b/cc/cc.go
index 53ec899..1100bac 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -65,7 +65,7 @@
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
- ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
+ ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
ctx.BottomUp("coverage", coverageMutator).Parallel()
diff --git a/cc/gen.go b/cc/gen.go
index 1d30dab..c9f45ee 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -25,6 +25,7 @@
func init() {
pctx.SourcePathVariable("lexCmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/flex")
+ pctx.SourcePathVariable("m4Cmd", "prebuilts/build-tools/${config.HostPrebuiltTag}/bin/m4")
pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
pctx.HostBinToolVariable("syspropCmd", "sysprop_cpp")
@@ -33,8 +34,8 @@
var (
lex = pctx.AndroidStaticRule("lex",
blueprint.RuleParams{
- Command: "$lexCmd -o$out $in",
- CommandDeps: []string{"$lexCmd"},
+ Command: "M4=$m4Cmd $lexCmd -o$out $in",
+ CommandDeps: []string{"$lexCmd", "$m4Cmd"},
})
sysprop = pctx.AndroidStaticRule("sysprop",
diff --git a/cc/makevars.go b/cc/makevars.go
index a71f479..78a32c8 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -161,6 +161,8 @@
ctx.Strict("AIDL_CPP", "${aidlCmd}")
+ ctx.Strict("M4", "${m4Cmd}")
+
ctx.Strict("RS_GLOBAL_INCLUDES", "${config.RsGlobalIncludes}")
ctx.Strict("SOONG_STRIP_PATH", "${stripPath}")
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 0af0659..0eb9a74 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -468,6 +468,10 @@
// TODO(b/131771163): LTO and Fuzzer support is mutually incompatible.
_, flags.LdFlags = removeFromList("-flto", flags.LdFlags)
flags.LdFlags = append(flags.LdFlags, "-fno-lto")
+
+ // TODO(b/133876586): Experimental PM breaks sanitizer coverage.
+ _, flags.CFlags = removeFromList("-fexperimental-new-pass-manager", flags.CFlags)
+ flags.CFlags = append(flags.CFlags, "-fno-experimental-new-pass-manager")
}
if Bool(sanitize.Properties.Sanitize.Cfi) {
@@ -701,8 +705,8 @@
if !isSanitizableDependencyTag(mctx.OtherModuleDependencyTag(child)) {
return false
}
- if d, ok := child.(*Module); ok && d.static() && d.sanitize != nil {
+ if d, ok := child.(*Module); ok && d.static() && d.sanitize != nil {
if enableMinimalRuntime(d.sanitize) {
// If a static dependency is built with the minimal runtime,
// make sure we include the ubsan minimal runtime.
@@ -713,8 +717,17 @@
// make sure we include the ubsan runtime.
c.sanitize.Properties.UbsanRuntimeDep = true
}
+
+ if c.sanitize.Properties.MinimalRuntimeDep &&
+ c.sanitize.Properties.UbsanRuntimeDep {
+ // both flags that this mutator might set are true, so don't bother recursing
+ return false
+ }
+
+ return true
+ } else {
+ return false
}
- return true
})
}
}
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index b909779..d3ef415 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -161,6 +161,7 @@
trace.SetOutput(filepath.Join(logsDir, "build.trace"))
stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, "verbose.log")))
stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, "error.log")))
+ stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, "build_error")))
defer met.Dump(filepath.Join(logsDir, "soong_metrics"))
@@ -337,7 +338,7 @@
}{{
name: "all-modules",
description: "Build action: build from the top of the source tree.",
- action: build.BUILD_MODULES_IN_A_DIRECTORY,
+ action: build.BUILD_MODULES,
buildDependencies: true,
}, {
name: "modules-in-a-dir-no-deps",
diff --git a/finder/finder_test.go b/finder/finder_test.go
index 29711fc..f6d0aa9 100644
--- a/finder/finder_test.go
+++ b/finder/finder_test.go
@@ -891,8 +891,8 @@
IncludeFiles: []string{"findme.txt"},
},
)
- foundPaths := finder.FindNamedAt("/tmp", "findme.txt")
filesystem.Clock.Tick()
+ foundPaths := finder.FindNamedAt("/tmp", "findme.txt")
finder.Shutdown()
// check the response of the first finder
assertSameResponse(t, foundPaths, []string{"/tmp/a/findme.txt"})
@@ -1522,8 +1522,8 @@
IncludeFiles: []string{"hi.txt"},
},
)
- foundPaths := finder.FindAll()
filesystem.Clock.Tick()
+ foundPaths := finder.FindAll()
finder.Shutdown()
// check results
assertSameResponse(t, foundPaths, []string{"/tmp/a/hi.txt"})
@@ -1583,8 +1583,8 @@
IncludeFiles: []string{"hi.txt"},
},
)
- foundPaths := finder.FindAll()
filesystem.Clock.Tick()
+ foundPaths := finder.FindAll()
finder.Shutdown()
allPaths := []string{"/tmp/hi.txt", "/tmp/a/hi.txt", "/tmp/a/a/hi.txt", "/tmp/b/hi.txt"}
// check results
@@ -1629,8 +1629,8 @@
IncludeFiles: []string{"hi.txt"},
},
)
- foundPaths := finder.FindAll()
filesystem.Clock.Tick()
+ foundPaths := finder.FindAll()
finder.Shutdown()
// check results
assertSameResponse(t, foundPaths, []string{"/tmp/hi.txt"})
@@ -1650,8 +1650,8 @@
IncludeFiles: []string{"hi.txt"},
},
)
- foundPaths := finder.FindAll()
filesystem.Clock.Tick()
+ foundPaths := finder.FindAll()
finder.Shutdown()
// check results
assertSameResponse(t, foundPaths, []string{"/tmp/a/hi.txt"})
diff --git a/java/aapt2.go b/java/aapt2.go
index a815160..ad746f7 100644
--- a/java/aapt2.go
+++ b/java/aapt2.go
@@ -60,7 +60,9 @@
},
"outDir", "cFlags")
-func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths) android.WritablePaths {
+func aapt2Compile(ctx android.ModuleContext, dir android.Path, paths android.Paths,
+ flags []string) android.WritablePaths {
+
shards := shardPaths(paths, AAPT2_SHARD_SIZE)
ret := make(android.WritablePaths, 0, len(paths))
@@ -81,9 +83,7 @@
Outputs: outPaths,
Args: map[string]string{
"outDir": android.PathForModuleOut(ctx, "aapt2", dir.String()).String(),
- // Always set --pseudo-localize, it will be stripped out later for release
- // builds that don't want it.
- "cFlags": "--pseudo-localize",
+ "cFlags": strings.Join(flags, " "),
},
})
}
@@ -104,7 +104,9 @@
},
}, "cFlags", "resZipDir", "zipSyncFlags")
-func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string) {
+func aapt2CompileZip(ctx android.ModuleContext, flata android.WritablePath, zip android.Path, zipPrefix string,
+ flags []string) {
+
if zipPrefix != "" {
zipPrefix = "--zip-prefix " + zipPrefix
}
@@ -114,9 +116,7 @@
Input: zip,
Output: flata,
Args: map[string]string{
- // Always set --pseudo-localize, it will be stripped out later for release
- // builds that don't want it.
- "cFlags": "--pseudo-localize",
+ "cFlags": strings.Join(flags, " "),
"resZipDir": android.PathForModuleOut(ctx, "aapt2", "reszip", flata.Base()).String(),
"zipSyncFlags": zipPrefix,
},
diff --git a/java/aar.go b/java/aar.go
index fc0e493..c9306de 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -113,8 +113,9 @@
return a.transitiveManifestPaths
}
-func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext, manifestPath android.Path) (flags []string,
- deps android.Paths, resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
+func (a *aapt) aapt2Flags(ctx android.ModuleContext, sdkContext sdkContext,
+ manifestPath android.Path) (compileFlags, linkFlags []string, linkDeps android.Paths,
+ resDirs, overlayDirs []globbedResourceDir, rroDirs []rroDir, resZips android.Paths) {
hasVersionCode := false
hasVersionName := false
@@ -126,8 +127,6 @@
}
}
- var linkFlags []string
-
// Flags specified in Android.bp
linkFlags = append(linkFlags, a.aaptProperties.Aaptflags...)
@@ -138,8 +137,6 @@
resourceDirs := android.PathsWithOptionalDefaultForModuleSrc(ctx, a.aaptProperties.Resource_dirs, "res")
resourceZips := android.PathsForModuleSrc(ctx, a.aaptProperties.Resource_zips)
- var linkDeps android.Paths
-
// Glob directories into lists of paths
for _, dir := range resourceDirs {
resDirs = append(resDirs, globbedResourceDir{
@@ -193,7 +190,13 @@
linkFlags = append(linkFlags, "--version-name ", versionName)
}
- return linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
+ linkFlags, compileFlags = android.FilterList(linkFlags, []string{"--legacy"})
+
+ // Always set --pseudo-localize, it will be stripped out later for release
+ // builds that don't want it.
+ compileFlags = append(compileFlags, "--pseudo-localize")
+
+ return compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resourceZips
}
func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkDep sdkDep) {
@@ -228,7 +231,7 @@
a.mergedManifestFile = manifestPath
}
- linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
+ compileFlags, linkFlags, linkDeps, resDirs, overlayDirs, rroDirs, resZips := a.aapt2Flags(ctx, sdkContext, manifestPath)
rroDirs = append(rroDirs, staticRRODirs...)
linkFlags = append(linkFlags, libFlags...)
@@ -247,12 +250,12 @@
var compiledResDirs []android.Paths
for _, dir := range resDirs {
- compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files).Paths())
+ compiledResDirs = append(compiledResDirs, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths())
}
for i, zip := range resZips {
flata := android.PathForModuleOut(ctx, fmt.Sprintf("reszip.%d.flata", i))
- aapt2CompileZip(ctx, flata, zip, "")
+ aapt2CompileZip(ctx, flata, zip, "", compileFlags)
compiledResDirs = append(compiledResDirs, android.Paths{flata})
}
@@ -281,7 +284,7 @@
}
for _, dir := range overlayDirs {
- compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files).Paths()...)
+ compiledOverlay = append(compiledOverlay, aapt2Compile(ctx, dir.dir, dir.files, compileFlags).Paths()...)
}
var splitPackages android.WritablePaths
@@ -521,10 +524,6 @@
return a.sdkVersion()
}
-func (a *AARImport) noFrameworkLibs() bool {
- return false
-}
-
var _ AndroidLibraryDependency = (*AARImport)(nil)
func (a *AARImport) ExportPackage() android.Path {
@@ -606,9 +605,12 @@
},
})
+ // Always set --pseudo-localize, it will be stripped out later for release
+ // builds that don't want it.
+ compileFlags := []string{"--pseudo-localize"}
compiledResDir := android.PathForModuleOut(ctx, "flat-res")
flata := compiledResDir.Join(ctx, "gen_res.flata")
- aapt2CompileZip(ctx, flata, aar, "res")
+ aapt2CompileZip(ctx, flata, aar, "res", compileFlags)
a.exportPackage = android.PathForModuleOut(ctx, "package-res.apk")
srcJar := android.PathForModuleGen(ctx, "R.jar")
diff --git a/java/app_test.go b/java/app_test.go
index 06f48fa..2e6d29a 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -546,79 +546,6 @@
}
}
-func TestJNIABI_no_framework_libs_true(t *testing.T) {
- ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- system_shared_libs: [],
- stl: "none",
- }
-
- android_test {
- name: "test",
- no_framework_libs: true,
- jni_libs: ["libjni"],
- }
-
- android_test {
- name: "test_first",
- no_framework_libs: true,
- compile_multilib: "first",
- jni_libs: ["libjni"],
- }
-
- android_test {
- name: "test_both",
- no_framework_libs: true,
- compile_multilib: "both",
- jni_libs: ["libjni"],
- }
-
- android_test {
- name: "test_32",
- no_framework_libs: true,
- compile_multilib: "32",
- jni_libs: ["libjni"],
- }
-
- android_test {
- name: "test_64",
- no_framework_libs: true,
- compile_multilib: "64",
- jni_libs: ["libjni"],
- }
- `)
-
- testCases := []struct {
- name string
- abis []string
- }{
- {"test", []string{"arm64-v8a"}},
- {"test_first", []string{"arm64-v8a"}},
- {"test_both", []string{"arm64-v8a", "armeabi-v7a"}},
- {"test_32", []string{"armeabi-v7a"}},
- {"test_64", []string{"arm64-v8a"}},
- }
-
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.Output("jnilibs.zip")
- var abis []string
- args := strings.Fields(jniLibZip.Args["jarArgs"])
- for i := 0; i < len(args); i++ {
- if args[i] == "-P" {
- abis = append(abis, filepath.Base(args[i+1]))
- i++
- }
- }
- if !reflect.DeepEqual(abis, test.abis) {
- t.Errorf("want abis %v, got %v", test.abis, abis)
- }
- })
- }
-}
-
func TestJNIABI(t *testing.T) {
ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
@@ -692,89 +619,6 @@
}
}
-func TestJNIPackaging_no_framework_libs_true(t *testing.T) {
- ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
- cc_library {
- name: "libjni",
- system_shared_libs: [],
- stl: "none",
- }
-
- android_app {
- name: "app",
- jni_libs: ["libjni"],
- }
-
- android_app {
- name: "app_noembed",
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- }
-
- android_app {
- name: "app_embed",
- jni_libs: ["libjni"],
- use_embedded_native_libs: true,
- }
-
- android_test {
- name: "test",
- no_framework_libs: true,
- jni_libs: ["libjni"],
- }
-
- android_test {
- name: "test_noembed",
- no_framework_libs: true,
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- }
-
- android_test_helper_app {
- name: "test_helper",
- no_framework_libs: true,
- jni_libs: ["libjni"],
- }
-
- android_test_helper_app {
- name: "test_helper_noembed",
- no_framework_libs: true,
- jni_libs: ["libjni"],
- use_embedded_native_libs: false,
- }
- `)
-
- testCases := []struct {
- name string
- packaged bool
- compressed bool
- }{
- {"app", false, false},
- {"app_noembed", false, false},
- {"app_embed", true, false},
- {"test", true, false},
- {"test_noembed", true, true},
- {"test_helper", true, false},
- {"test_helper_noembed", true, true},
- }
-
- for _, test := range testCases {
- t.Run(test.name, func(t *testing.T) {
- app := ctx.ModuleForTests(test.name, "android_common")
- jniLibZip := app.MaybeOutput("jnilibs.zip")
- if g, w := (jniLibZip.Rule != nil), test.packaged; g != w {
- t.Errorf("expected jni packaged %v, got %v", w, g)
- }
-
- if jniLibZip.Rule != nil {
- if g, w := !strings.Contains(jniLibZip.Args["jarArgs"], "-L 0"), test.compressed; g != w {
- t.Errorf("expected jni compressed %v, got %v", w, g)
- }
- }
- })
- }
-}
-
func TestJNIPackaging(t *testing.T) {
ctx := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
diff --git a/java/device_host_converter_test.go b/java/device_host_converter_test.go
index 146bf6f..9b9d0d8 100644
--- a/java/device_host_converter_test.go
+++ b/java/device_host_converter_test.go
@@ -126,7 +126,7 @@
java_library {
name: "device_module",
- no_framework_libs: true,
+ sdk_version: "core_platform",
srcs: ["b.java"],
java_resources: ["java-res/b/b"],
static_libs: ["host_for_device_module"],
diff --git a/java/droiddoc.go b/java/droiddoc.go
index be1b281..734b411 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -171,9 +171,6 @@
// list of java libraries that will be in the classpath.
Libs []string `android:"arch_variant"`
- // don't build against the framework libraries (ext, and framework for device targets)
- No_framework_libs *bool
-
// the java library (in classpath) for documentation that provides java srcs and srcjars.
Srcs_lib *string
@@ -534,10 +531,6 @@
return j.sdkVersion()
}
-func (j *Javadoc) noFrameworkLibs() bool {
- return Bool(j.properties.No_framework_libs)
-}
-
func (j *Javadoc) addDeps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sdkContext(j))
diff --git a/java/java.go b/java/java.go
index a2e9ab0..bf80ced 100644
--- a/java/java.go
+++ b/java/java.go
@@ -82,9 +82,6 @@
// list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"path,arch_variant"`
- // don't build against the framework libraries (ext, and framework for device targets)
- No_framework_libs *bool
-
// list of module-specific flags that will be used for javac compiles
Javacflags []string `android:"arch_variant"`
@@ -482,10 +479,6 @@
return j.sdkVersion()
}
-func (j *Module) noFrameworkLibs() bool {
- return Bool(j.properties.No_framework_libs)
-}
-
func (j *Module) deps(ctx android.BottomUpMutatorContext) {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sdkContext(j))
@@ -506,7 +499,7 @@
}
} else if j.deviceProperties.System_modules == nil {
ctx.PropertyErrorf("sdk_version",
- `system_modules is required to be set when sdk_version is "none", did you mean no_framework_libs?`)
+ `system_modules is required to be set when sdk_version is "none", did you mean "core_platform"`)
} else if *j.deviceProperties.System_modules != "none" {
ctx.AddVariationDependencies(nil, systemModulesTag, *j.deviceProperties.System_modules)
}
diff --git a/java/sdk.go b/java/sdk.go
index 6ffe399..1682a10 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -44,9 +44,6 @@
minSdkVersion() string
// targetSdkVersion returns the target_sdk_version property of the current module, or sdkVersion() if it is not set.
targetSdkVersion() string
-
- // Temporarily provide access to the no_frameworks_libs property (where present).
- noFrameworkLibs() bool
}
func sdkVersionOrDefault(ctx android.BaseModuleContext, v string) string {
@@ -84,6 +81,7 @@
func decodeSdkDep(ctx android.BaseModuleContext, sdkContext sdkContext) sdkDep {
v := sdkContext.sdkVersion()
+
// For PDK builds, use the latest SDK version instead of "current"
if ctx.Config().IsPdkBuild() && (v == "" || v == "current") {
sdkVersions := ctx.Config().Get(sdkVersionsKey).([]int)
@@ -141,9 +139,6 @@
useFiles: true,
jars: android.Paths{jarPath.Path(), lambdaStubsPath},
aidl: android.OptionalPathForPath(aidlPath.Path()),
-
- // Pass value straight through for now to match previous behavior.
- noFrameworksLibs: sdkContext.noFrameworkLibs(),
}
}
@@ -154,9 +149,6 @@
systemModules: m + "_system_modules",
frameworkResModule: r,
aidl: android.OptionalPathForPath(aidl),
-
- // Pass value straight through for now to match previous behavior.
- noFrameworksLibs: sdkContext.noFrameworkLibs(),
}
if m == "core.current.stubs" {
@@ -192,9 +184,6 @@
return sdkDep{
useDefaultLibs: true,
frameworkResModule: "framework-res",
-
- // Pass value straight through for now to match previous behavior.
- noFrameworksLibs: sdkContext.noFrameworkLibs(),
}
case "none":
return sdkDep{
diff --git a/java/sdk_test.go b/java/sdk_test.go
index 953c372..f82a4fb 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -47,14 +47,6 @@
aidl: "-Iframework/aidl",
},
{
- name: "no_framework_libs:true",
- properties: `no_framework_libs:true`,
- bootclasspath: config.DefaultBootclasspathLibraries,
- system: config.DefaultSystemModules,
- classpath: []string{},
- aidl: "",
- },
- {
name: `sdk_version:"core_platform"`,
properties: `sdk_version:"core_platform"`,
bootclasspath: config.DefaultBootclasspathLibraries,
diff --git a/java/system_modules.go b/java/system_modules.go
index f71f452..c616249 100644
--- a/java/system_modules.go
+++ b/java/system_modules.go
@@ -138,7 +138,7 @@
fmt.Fprintln(w, makevar, ":=$=", strings.Join(system.properties.Libs, " "))
fmt.Fprintln(w)
- makevar = "SOONG_SYSTEM_MODULE_DEPS_" + name
+ makevar = "SOONG_SYSTEM_MODULES_DEPS_" + name
fmt.Fprintln(w, makevar, ":=$=", strings.Join(system.outputDeps.Strings(), " "))
fmt.Fprintln(w)
diff --git a/ui/build/config.go b/ui/build/config.go
index 6df9529..4a70f06 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -71,6 +71,9 @@
// Builds all of the modules and their dependencies of a list of specified directories. All specified
// directories are relative to the root directory of the source tree.
BUILD_MODULES_IN_DIRECTORIES
+
+ // Build a list of specified modules. If none was specified, simply build the whole source tree.
+ BUILD_MODULES
)
// checkTopDir validates that the current directory is at the root directory of the source tree.
@@ -290,6 +293,8 @@
var targets []string
switch action {
+ case BUILD_MODULES:
+ // No additional processing is required when building a list of specific modules or all modules.
case BUILD_MODULES_IN_A_DIRECTORY:
// If dir is the root source tree, all the modules are built of the source tree are built so
// no need to find the build file.
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index 1ef5456..856af11 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -763,6 +763,51 @@
}
}
+func TestGetConfigArgsBuildModules(t *testing.T) {
+ tests := []buildActionTestCase{{
+ description: "normal execution from the root source tree directory",
+ dirsInTrees: []string{"0/1/2", "0/2", "0/3"},
+ buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "0/3/Android.mk"},
+ args: []string{"-j", "fake_module", "fake_module2"},
+ curDir: ".",
+ tidyOnly: "",
+ expectedArgs: []string{"-j", "fake_module", "fake_module2"},
+ expectedEnvVars: []envVar{},
+ }, {
+ description: "normal execution in deep directory",
+ dirsInTrees: []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"},
+ buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/Android.mk"},
+ args: []string{"-j", "fake_module", "fake_module2", "-k"},
+ curDir: "1/2/3/4/5/6/7/8/9",
+ tidyOnly: "",
+ expectedArgs: []string{"-j", "fake_module", "fake_module2", "-k"},
+ expectedEnvVars: []envVar{},
+ }, {
+ description: "normal execution in deep directory, no targets",
+ dirsInTrees: []string{"0/1/2", "0/2", "0/3", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6"},
+ buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp", "1/2/3/4/5/6/7/8/9/1/2/3/4/5/6/Android.mk"},
+ args: []string{"-j", "-k"},
+ curDir: "1/2/3/4/5/6/7/8/9",
+ tidyOnly: "",
+ expectedArgs: []string{"-j", "-k"},
+ expectedEnvVars: []envVar{},
+ }, {
+ description: "normal execution in root source tree, no args",
+ dirsInTrees: []string{"0/1/2", "0/2", "0/3"},
+ buildFiles: []string{"0/1/2/Android.mk", "0/2/Android.bp"},
+ args: []string{},
+ curDir: "1/2/3/4/5/6/7/8/9",
+ tidyOnly: "",
+ expectedArgs: []string{},
+ expectedEnvVars: []envVar{},
+ }}
+ for _, tt := range tests {
+ t.Run("build action BUILD_MODULES with dependencies, "+tt.description, func(t *testing.T) {
+ testGetConfigArgs(t, tt, BUILD_MODULES, true)
+ })
+ }
+}
+
// TODO: Remove this test case once mm shell build command has been deprecated.
func TestGetConfigArgsBuildModulesInDirecotoryNoDeps(t *testing.T) {
tests := []buildActionTestCase{{
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index c9946e2..e2c5043 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -88,13 +88,14 @@
"getopt": Allowed,
"git": Allowed,
"grep": Allowed,
+ "gzcat": Allowed,
"gzip": Allowed,
"hexdump": Allowed,
"jar": Allowed,
"java": Allowed,
"javap": Allowed,
"lsof": Allowed,
- "m4": Allowed,
+ "m4": Log,
"openssl": Allowed,
"patch": Allowed,
"pstree": Allowed,
diff --git a/ui/status/Android.bp b/ui/status/Android.bp
index 901a713..34241ee 100644
--- a/ui/status/Android.bp
+++ b/ui/status/Android.bp
@@ -19,6 +19,7 @@
"golang-protobuf-proto",
"soong-ui-logger",
"soong-ui-status-ninja_frontend",
+ "soong-ui-status-build_error_proto",
],
srcs: [
"kati.go",
@@ -41,3 +42,12 @@
"ninja_frontend/frontend.pb.go",
],
}
+
+bootstrap_go_package {
+ name: "soong-ui-status-build_error_proto",
+ pkgPath: "android/soong/ui/status/build_error_proto",
+ deps: ["golang-protobuf-proto"],
+ srcs: [
+ "build_error_proto/build_error.pb.go",
+ ],
+}
diff --git a/ui/status/build_error_proto/build_error.pb.go b/ui/status/build_error_proto/build_error.pb.go
new file mode 100644
index 0000000..d4d0a6e
--- /dev/null
+++ b/ui/status/build_error_proto/build_error.pb.go
@@ -0,0 +1,175 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: build_error.proto
+
+package soong_build_error_proto
+
+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
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// 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.ProtoPackageIsVersion3 // please upgrade the proto package
+
+type BuildError struct {
+ // List of error messages of the overall build. The error messages
+ // are not associated with a build action.
+ ErrorMessages []string `protobuf:"bytes,1,rep,name=error_messages,json=errorMessages" json:"error_messages,omitempty"`
+ // List of build action errors.
+ ActionErrors []*BuildActionError `protobuf:"bytes,2,rep,name=action_errors,json=actionErrors" json:"action_errors,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BuildError) Reset() { *m = BuildError{} }
+func (m *BuildError) String() string { return proto.CompactTextString(m) }
+func (*BuildError) ProtoMessage() {}
+func (*BuildError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_a2e15b05802a5501, []int{0}
+}
+
+func (m *BuildError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BuildError.Unmarshal(m, b)
+}
+func (m *BuildError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BuildError.Marshal(b, m, deterministic)
+}
+func (m *BuildError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BuildError.Merge(m, src)
+}
+func (m *BuildError) XXX_Size() int {
+ return xxx_messageInfo_BuildError.Size(m)
+}
+func (m *BuildError) XXX_DiscardUnknown() {
+ xxx_messageInfo_BuildError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BuildError proto.InternalMessageInfo
+
+func (m *BuildError) GetErrorMessages() []string {
+ if m != nil {
+ return m.ErrorMessages
+ }
+ return nil
+}
+
+func (m *BuildError) GetActionErrors() []*BuildActionError {
+ if m != nil {
+ return m.ActionErrors
+ }
+ return nil
+}
+
+// Build is composed of a list of build action. There can be a set of build
+// actions that can failed.
+type BuildActionError struct {
+ // Description of the command.
+ Description *string `protobuf:"bytes,1,opt,name=description" json:"description,omitempty"`
+ // The command name that raised the error.
+ Command *string `protobuf:"bytes,2,opt,name=command" json:"command,omitempty"`
+ // The command output stream.
+ Output *string `protobuf:"bytes,3,opt,name=output" json:"output,omitempty"`
+ // List of artifacts (i.e. files) that was produced by the command.
+ Artifacts []string `protobuf:"bytes,4,rep,name=artifacts" json:"artifacts,omitempty"`
+ // The error string produced by the build action.
+ Error *string `protobuf:"bytes,5,opt,name=error" json:"error,omitempty"`
+ XXX_NoUnkeyedLiteral struct{} `json:"-"`
+ XXX_unrecognized []byte `json:"-"`
+ XXX_sizecache int32 `json:"-"`
+}
+
+func (m *BuildActionError) Reset() { *m = BuildActionError{} }
+func (m *BuildActionError) String() string { return proto.CompactTextString(m) }
+func (*BuildActionError) ProtoMessage() {}
+func (*BuildActionError) Descriptor() ([]byte, []int) {
+ return fileDescriptor_a2e15b05802a5501, []int{1}
+}
+
+func (m *BuildActionError) XXX_Unmarshal(b []byte) error {
+ return xxx_messageInfo_BuildActionError.Unmarshal(m, b)
+}
+func (m *BuildActionError) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+ return xxx_messageInfo_BuildActionError.Marshal(b, m, deterministic)
+}
+func (m *BuildActionError) XXX_Merge(src proto.Message) {
+ xxx_messageInfo_BuildActionError.Merge(m, src)
+}
+func (m *BuildActionError) XXX_Size() int {
+ return xxx_messageInfo_BuildActionError.Size(m)
+}
+func (m *BuildActionError) XXX_DiscardUnknown() {
+ xxx_messageInfo_BuildActionError.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BuildActionError proto.InternalMessageInfo
+
+func (m *BuildActionError) GetDescription() string {
+ if m != nil && m.Description != nil {
+ return *m.Description
+ }
+ return ""
+}
+
+func (m *BuildActionError) GetCommand() string {
+ if m != nil && m.Command != nil {
+ return *m.Command
+ }
+ return ""
+}
+
+func (m *BuildActionError) GetOutput() string {
+ if m != nil && m.Output != nil {
+ return *m.Output
+ }
+ return ""
+}
+
+func (m *BuildActionError) GetArtifacts() []string {
+ if m != nil {
+ return m.Artifacts
+ }
+ return nil
+}
+
+func (m *BuildActionError) GetError() string {
+ if m != nil && m.Error != nil {
+ return *m.Error
+ }
+ return ""
+}
+
+func init() {
+ proto.RegisterType((*BuildError)(nil), "soong_build_error.BuildError")
+ proto.RegisterType((*BuildActionError)(nil), "soong_build_error.BuildActionError")
+}
+
+func init() { proto.RegisterFile("build_error.proto", fileDescriptor_a2e15b05802a5501) }
+
+var fileDescriptor_a2e15b05802a5501 = []byte{
+ // 229 bytes of a gzipped FileDescriptorProto
+ 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x64, 0x90, 0xc1, 0x4a, 0xc3, 0x40,
+ 0x10, 0x86, 0x49, 0x63, 0x95, 0x4c, 0xad, 0xd8, 0x41, 0x74, 0x04, 0x0f, 0xa1, 0x22, 0xe4, 0x94,
+ 0x83, 0x6f, 0x60, 0x41, 0xf0, 0xe2, 0x25, 0x47, 0x2f, 0x61, 0xdd, 0xac, 0x65, 0xc1, 0x64, 0xc2,
+ 0xce, 0xe6, 0xe8, 0x8b, 0xf8, 0xb4, 0x92, 0x69, 0xa5, 0xa5, 0x39, 0x7e, 0xdf, 0x3f, 0xfb, 0xef,
+ 0xce, 0xc2, 0xea, 0x73, 0xf0, 0xdf, 0x4d, 0xed, 0x42, 0xe0, 0x50, 0xf6, 0x81, 0x23, 0xe3, 0x4a,
+ 0x98, 0xbb, 0x6d, 0x7d, 0x14, 0xac, 0x7f, 0x00, 0x36, 0x23, 0xbe, 0x8e, 0x84, 0x4f, 0x70, 0xa5,
+ 0xba, 0x6e, 0x9d, 0x88, 0xd9, 0x3a, 0xa1, 0x24, 0x4f, 0x8b, 0xac, 0x5a, 0xaa, 0x7d, 0xdf, 0x4b,
+ 0x7c, 0x83, 0xa5, 0xb1, 0xd1, 0x73, 0xb7, 0x2b, 0x11, 0x9a, 0xe5, 0x69, 0xb1, 0x78, 0x7e, 0x2c,
+ 0x27, 0xfd, 0xa5, 0x96, 0xbf, 0xe8, 0xb0, 0x5e, 0x51, 0x5d, 0x9a, 0x03, 0xc8, 0xfa, 0x37, 0x81,
+ 0xeb, 0xd3, 0x11, 0xcc, 0x61, 0xd1, 0x38, 0xb1, 0xc1, 0xf7, 0xa3, 0xa3, 0x24, 0x4f, 0x8a, 0xac,
+ 0x3a, 0x56, 0x48, 0x70, 0x61, 0xb9, 0x6d, 0x4d, 0xd7, 0xd0, 0x4c, 0xd3, 0x7f, 0xc4, 0x5b, 0x38,
+ 0xe7, 0x21, 0xf6, 0x43, 0xa4, 0x54, 0x83, 0x3d, 0xe1, 0x03, 0x64, 0x26, 0x44, 0xff, 0x65, 0x6c,
+ 0x14, 0x3a, 0xd3, 0xa5, 0x0e, 0x02, 0x6f, 0x60, 0xae, 0xcf, 0xa5, 0xb9, 0x1e, 0xda, 0xc1, 0xe6,
+ 0xfe, 0xe3, 0x6e, 0xb2, 0x50, 0xad, 0x3f, 0xf9, 0x17, 0x00, 0x00, 0xff, 0xff, 0xb6, 0x18, 0x9e,
+ 0x17, 0x5d, 0x01, 0x00, 0x00,
+}
diff --git a/ui/status/build_error_proto/build_error.proto b/ui/status/build_error_proto/build_error.proto
new file mode 100644
index 0000000..9c8470d
--- /dev/null
+++ b/ui/status/build_error_proto/build_error.proto
@@ -0,0 +1,46 @@
+// Copyright 2019 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.
+
+syntax = "proto2";
+
+package soong_build_error;
+option go_package = "soong_build_error_proto";
+
+message BuildError {
+ // List of error messages of the overall build. The error messages
+ // are not associated with a build action.
+ repeated string error_messages = 1;
+
+ // List of build action errors.
+ repeated BuildActionError action_errors = 2;
+}
+
+// Build is composed of a list of build action. There can be a set of build
+// actions that can failed.
+message BuildActionError {
+ // Description of the command.
+ optional string description = 1;
+
+ // The command name that raised the error.
+ optional string command = 2;
+
+ // The command output stream.
+ optional string output = 3;
+
+ // List of artifacts (i.e. files) that was produced by the command.
+ repeated string artifacts = 4;
+
+ // The error string produced by the build action.
+ optional string error = 5;
+}
diff --git a/ui/status/build_error_proto/regen.sh b/ui/status/build_error_proto/regen.sh
new file mode 100755
index 0000000..7c3ec8f
--- /dev/null
+++ b/ui/status/build_error_proto/regen.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+aprotoc --go_out=paths=source_relative:. build_error.proto
diff --git a/ui/status/log.go b/ui/status/log.go
index 7badac7..9090f49 100644
--- a/ui/status/log.go
+++ b/ui/status/log.go
@@ -15,11 +15,17 @@
package status
import (
- "android/soong/ui/logger"
"compress/gzip"
+ "errors"
"fmt"
"io"
+ "io/ioutil"
"strings"
+
+ "github.com/golang/protobuf/proto"
+
+ "android/soong/ui/logger"
+ "android/soong/ui/status/build_error_proto"
)
type verboseLog struct {
@@ -77,8 +83,7 @@
}
type errorLog struct {
- w io.WriteCloser
-
+ w io.WriteCloser
empty bool
}
@@ -102,20 +107,17 @@
return
}
- cmd := result.Command
- if cmd == "" {
- cmd = result.Description
- }
-
if !e.empty {
fmt.Fprintf(e.w, "\n\n")
}
e.empty = false
fmt.Fprintf(e.w, "FAILED: %s\n", result.Description)
+
if len(result.Outputs) > 0 {
fmt.Fprintf(e.w, "Outputs: %s\n", strings.Join(result.Outputs, " "))
}
+
fmt.Fprintf(e.w, "Error: %s\n", result.Error)
if result.Command != "" {
fmt.Fprintf(e.w, "Command: %s\n", result.Command)
@@ -144,3 +146,55 @@
fmt.Fprint(e.w, string(p))
return len(p), nil
}
+
+type errorProtoLog struct {
+ errorProto soong_build_error_proto.BuildError
+ filename string
+ log logger.Logger
+}
+
+func NewProtoErrorLog(log logger.Logger, filename string) StatusOutput {
+ return &errorProtoLog{
+ errorProto: soong_build_error_proto.BuildError{},
+ filename: filename,
+ log: log,
+ }
+}
+
+func (e *errorProtoLog) StartAction(action *Action, counts Counts) {}
+
+func (e *errorProtoLog) FinishAction(result ActionResult, counts Counts) {
+ if result.Error == nil {
+ return
+ }
+
+ e.errorProto.ActionErrors = append(e.errorProto.ActionErrors, &soong_build_error_proto.BuildActionError{
+ Description: proto.String(result.Description),
+ Command: proto.String(result.Command),
+ Output: proto.String(result.Output),
+ Artifacts: result.Outputs,
+ Error: proto.String(result.Error.Error()),
+ })
+}
+
+func (e *errorProtoLog) Flush() {
+ data, err := proto.Marshal(&e.errorProto)
+ if err != nil {
+ e.log.Println("Failed to marshal build status proto: %v", err)
+ return
+ }
+ err = ioutil.WriteFile(e.filename, []byte(data), 0644)
+ if err != nil {
+ e.log.Println("Failed to write file %s: %v", e.errorProto, err)
+ }
+}
+
+func (e *errorProtoLog) Message(level MsgLevel, message string) {
+ if level > ErrorLvl {
+ e.errorProto.ErrorMessages = append(e.errorProto.ErrorMessages, message)
+ }
+}
+
+func (e *errorProtoLog) Write(p []byte) (int, error) {
+ return 0, errors.New("not supported")
+}
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index 9638cdf..8659d4d 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -225,9 +225,7 @@
// Limit line width to the terminal width, otherwise we'll wrap onto
// another line and we won't delete the previous line.
- if s.termWidth > 0 {
- str = s.elide(str)
- }
+ str = elide(str, s.termWidth)
// Move to the beginning on the line, turn on bold, print the output,
// turn off bold, then clear the rest of the line.
@@ -237,11 +235,11 @@
s.haveBlankLine = false
}
-func (s *smartStatusOutput) elide(str string) string {
- if len(str) > s.termWidth {
+func elide(str string, width int) string {
+ if width > 0 && len(str) > width {
// TODO: Just do a max. Ninja elides the middle, but that's
// more complicated and these lines aren't that important.
- str = str[:s.termWidth]
+ str = str[:width]
}
return str
@@ -344,9 +342,18 @@
desc = runningAction.action.Command
}
- str := fmt.Sprintf(" %2d:%02d %s", seconds/60, seconds%60, desc)
- str = s.elide(str)
- fmt.Fprint(s.writer, str, ansi.clearToEndOfLine())
+ color := ""
+ if seconds >= 60 {
+ color = ansi.red() + ansi.bold()
+ } else if seconds >= 30 {
+ color = ansi.yellow() + ansi.bold()
+ }
+
+ durationStr := fmt.Sprintf(" %2d:%02d ", seconds/60, seconds%60)
+ desc = elide(desc, s.termWidth-len(durationStr))
+ durationStr = color + durationStr + ansi.regular()
+
+ fmt.Fprint(s.writer, durationStr, desc, ansi.clearToEndOfLine())
if tableLine < s.tableHeight-1 {
fmt.Fprint(s.writer, "\n")
}
@@ -387,6 +394,14 @@
return fmt.Sprintf("\x1b[r")
}
+func (ansiImpl) red() string {
+ return "\x1b[31m"
+}
+
+func (ansiImpl) yellow() string {
+ return "\x1b[33m"
+}
+
func (ansiImpl) bold() string {
return "\x1b[1m"
}