Merge "Only package gcno files for gcov coverage builds."
diff --git a/apex/apex.go b/apex/apex.go
index 3542c6a..8463ac1 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1741,15 +1741,16 @@
func apexFileForAndroidApp(ctx android.BaseModuleContext, aapp interface {
android.Module
Privileged() bool
+ InstallApkName() string
OutputFile() android.Path
JacocoReportClassesFile() android.Path
Certificate() java.Certificate
-}, pkgName string) apexFile {
+}) apexFile {
appDir := "app"
if aapp.Privileged() {
appDir = "priv-app"
}
- dirInApex := filepath.Join(appDir, pkgName)
+ dirInApex := filepath.Join(appDir, aapp.InstallApkName())
fileToCopy := aapp.OutputFile()
af := newApexFile(ctx, fileToCopy, aapp.Name(), dirInApex, app, aapp)
af.jacocoReportClassesFile = aapp.JacocoReportClassesFile()
@@ -2040,14 +2041,13 @@
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
case androidAppTag:
- pkgName := ctx.DeviceConfig().OverridePackageNameFor(depName)
if ap, ok := child.(*java.AndroidApp); ok {
- filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
+ filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
return true // track transitive dependencies
} else if ap, ok := child.(*java.AndroidAppImport); ok {
- filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
+ filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
- filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap, pkgName))
+ filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
} else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index cbff0f1..9f55728 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3438,6 +3438,7 @@
dex_preopt: {
enabled: false,
},
+ filename: "AwesomePrebuiltAppFooPriv.apk",
}
`)
@@ -3446,7 +3447,47 @@
copyCmds := apexRule.Args["copy_commands"]
ensureContains(t, copyCmds, "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk")
- ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AppFooPrivPrebuilt.apk")
+ ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk")
+}
+
+func TestApexWithAppImportsPrefer(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apps: [
+ "AppFoo",
+ ],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ android_app {
+ name: "AppFoo",
+ srcs: ["foo/bar/MyClass.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ apex_available: [ "myapex" ],
+ }
+
+ android_app_import {
+ name: "AppFoo",
+ apk: "AppFooPrebuilt.apk",
+ filename: "AppFooPrebuilt.apk",
+ presigned: true,
+ prefer: true,
+ }
+ `, withFiles(map[string][]byte{
+ "AppFooPrebuilt.apk": nil,
+ }))
+
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "app/AppFoo/AppFooPrebuilt.apk",
+ })
}
func TestApexWithTestHelperApp(t *testing.T) {
@@ -3779,7 +3820,7 @@
copyCmds := apexRule.Args["copy_commands"]
ensureNotContains(t, copyCmds, "image.apex/app/app/app.apk")
- ensureContains(t, copyCmds, "image.apex/app/app/override_app.apk")
+ ensureContains(t, copyCmds, "image.apex/app/override_app/override_app.apk")
apexBundle := module.Module().(*apexBundle)
name := apexBundle.Name()
diff --git a/cc/cc.go b/cc/cc.go
index 731f288..63aab95 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -213,6 +213,9 @@
// two variants to be built, one for the platform and one for apps.
Sdk_version *string
+ // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ Min_sdk_version *string
+
// If true, always create an sdk variant and don't create a platform variant.
Sdk_variant_only *bool
@@ -1195,6 +1198,11 @@
return false
}
+ // Coverage builds have extra symbols.
+ if ctx.mod.isCoverageVariant() {
+ return false
+ }
+
if ctx.ctx.Fuchsia() {
return false
}
diff --git a/java/androidmk.go b/java/androidmk.go
index d37eac8..7d57525 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -472,34 +472,6 @@
if ddoc.Javadoc.stubsSrcJar != nil {
entries.SetPath("LOCAL_DROIDDOC_STUBS_SRCJAR", ddoc.Javadoc.stubsSrcJar)
}
- apiFilePrefix := "INTERNAL_PLATFORM_"
- if String(ddoc.properties.Api_tag_name) != "" {
- apiFilePrefix += String(ddoc.properties.Api_tag_name) + "_"
- }
- if ddoc.apiFile != nil {
- entries.SetPath(apiFilePrefix+"API_FILE", ddoc.apiFile)
- }
- if ddoc.dexApiFile != nil {
- entries.SetPath(apiFilePrefix+"DEX_API_FILE", ddoc.dexApiFile)
- }
- if ddoc.privateApiFile != nil {
- entries.SetPath(apiFilePrefix+"PRIVATE_API_FILE", ddoc.privateApiFile)
- }
- if ddoc.privateDexApiFile != nil {
- entries.SetPath(apiFilePrefix+"PRIVATE_DEX_API_FILE", ddoc.privateDexApiFile)
- }
- if ddoc.removedApiFile != nil {
- entries.SetPath(apiFilePrefix+"REMOVED_API_FILE", ddoc.removedApiFile)
- }
- if ddoc.removedDexApiFile != nil {
- entries.SetPath(apiFilePrefix+"REMOVED_DEX_API_FILE", ddoc.removedDexApiFile)
- }
- if ddoc.exactApiFile != nil {
- entries.SetPath(apiFilePrefix+"EXACT_API_FILE", ddoc.exactApiFile)
- }
- if ddoc.proguardFile != nil {
- entries.SetPath(apiFilePrefix+"PROGUARD_FILE", ddoc.proguardFile)
- }
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
@@ -578,35 +550,18 @@
if dstubs.metadataZip != nil {
entries.SetPath("LOCAL_DROIDDOC_METADATA_ZIP", dstubs.metadataZip)
}
- apiFilePrefix := "INTERNAL_PLATFORM_"
- if String(dstubs.properties.Api_tag_name) != "" {
- apiFilePrefix += String(dstubs.properties.Api_tag_name) + "_"
- }
- if dstubs.apiFile != nil {
- entries.SetPath(apiFilePrefix+"API_FILE", dstubs.apiFile)
- }
- if dstubs.dexApiFile != nil {
- entries.SetPath(apiFilePrefix+"DEX_API_FILE", dstubs.dexApiFile)
- }
- if dstubs.privateApiFile != nil {
- entries.SetPath(apiFilePrefix+"PRIVATE_API_FILE", dstubs.privateApiFile)
- }
- if dstubs.privateDexApiFile != nil {
- entries.SetPath(apiFilePrefix+"PRIVATE_DEX_API_FILE", dstubs.privateDexApiFile)
- }
- if dstubs.removedApiFile != nil {
- entries.SetPath(apiFilePrefix+"REMOVED_API_FILE", dstubs.removedApiFile)
- }
- if dstubs.removedDexApiFile != nil {
- entries.SetPath(apiFilePrefix+"REMOVED_DEX_API_FILE", dstubs.removedDexApiFile)
- }
- if dstubs.exactApiFile != nil {
- entries.SetPath(apiFilePrefix+"EXACT_API_FILE", dstubs.exactApiFile)
- }
},
},
ExtraFooters: []android.AndroidMkExtraFootersFunc{
func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+ if dstubs.apiFile != nil {
+ fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
+ fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.apiFile)
+ }
+ if dstubs.removedApiFile != nil {
+ fmt.Fprintf(w, ".PHONY: %s %s.txt\n", dstubs.Name(), dstubs.Name())
+ fmt.Fprintf(w, "%s %s.txt: %s\n", dstubs.Name(), dstubs.Name(), dstubs.removedApiFile)
+ }
if dstubs.checkCurrentApiTimestamp != nil {
fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-check-current-api")
fmt.Fprintln(w, dstubs.Name()+"-check-current-api:",
@@ -633,14 +588,12 @@
fmt.Fprintln(w, dstubs.Name()+"-check-last-released-api:",
dstubs.checkLastReleasedApiTimestamp.String())
- if dstubs.Name() != "android.car-system-stubs-docs" {
- fmt.Fprintln(w, ".PHONY: checkapi")
- fmt.Fprintln(w, "checkapi:",
- dstubs.checkLastReleasedApiTimestamp.String())
+ fmt.Fprintln(w, ".PHONY: checkapi")
+ fmt.Fprintln(w, "checkapi:",
+ dstubs.checkLastReleasedApiTimestamp.String())
- fmt.Fprintln(w, ".PHONY: droidcore")
- fmt.Fprintln(w, "droidcore: checkapi")
- }
+ fmt.Fprintln(w, ".PHONY: droidcore")
+ fmt.Fprintln(w, "droidcore: checkapi")
}
if dstubs.apiLintTimestamp != nil {
fmt.Fprintln(w, ".PHONY:", dstubs.Name()+"-api-lint")
diff --git a/java/app.go b/java/app.go
index ac5121a..7d509ee 100755
--- a/java/app.go
+++ b/java/app.go
@@ -511,6 +511,10 @@
return certificates
}
+func (a *AndroidApp) InstallApkName() string {
+ return a.installApkName
+}
+
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
var apkDeps android.Paths
@@ -1134,6 +1138,10 @@
a.generateAndroidBuildActions(ctx)
}
+func (a *AndroidAppImport) InstallApkName() string {
+ return a.BaseModuleName()
+}
+
func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) {
numCertPropsSet := 0
if String(a.properties.Certificate) != "" {
@@ -1191,6 +1199,8 @@
dexOutput = dexUncompressed
}
+ apkFilename := proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk")
+
// Sign or align the package
// TODO: Handle EXTERNAL
if !Bool(a.properties.Presigned) {
@@ -1201,11 +1211,11 @@
ctx.ModuleErrorf("Unexpected number of certificates were extracted: %q", certificates)
}
a.certificate = certificates[0]
- signed := android.PathForModuleOut(ctx, "signed", ctx.ModuleName()+".apk")
+ signed := android.PathForModuleOut(ctx, "signed", apkFilename)
SignAppPackage(ctx, signed, dexOutput, certificates, nil)
a.outputFile = signed
} else {
- alignedApk := android.PathForModuleOut(ctx, "zip-aligned", ctx.ModuleName()+".apk")
+ alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
TransformZipAlign(ctx, alignedApk, dexOutput)
a.outputFile = alignedApk
a.certificate = presignedCertificate
@@ -1213,8 +1223,7 @@
// TODO: Optionally compress the output apk.
- a.installPath = ctx.InstallFile(installDir,
- proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk"), a.outputFile)
+ a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile)
// TODO: androidmk converter jni libs
}
diff --git a/java/builder.go b/java/builder.go
index 3a0247d..98f70cd 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -147,7 +147,12 @@
jarjar = pctx.AndroidStaticRule("jarjar",
blueprint.RuleParams{
- Command: "${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.JarjarCmd} process $rulesFile $in $out",
+ Command: "${config.JavaCmd} ${config.JavaVmFlags}" +
+ // b/146418363 Enable Android specific jarjar transformer to drop compat annotations
+ // for newly repackaged classes. Dropping @UnsupportedAppUsage on repackaged classes
+ // avoids adding new hiddenapis after jarjar'ing.
+ " -DremoveAndroidCompatAnnotations=true" +
+ " -jar ${config.JarjarCmd} process $rulesFile $in $out",
CommandDeps: []string{"${config.JavaCmd}", "${config.JarjarCmd}", "$rulesFile"},
},
"rulesFile")
diff --git a/java/sdk_library.go b/java/sdk_library.go
index ff80d63..51e680b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -394,13 +394,6 @@
}
}
-// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
-// api file for the current source
-// TODO: remove this when apicheck is done in soong
-func (module *SdkLibrary) apiTagName(apiScope *apiScope) string {
- return strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1) + apiScope.apiFileMakeVariableSuffix
-}
-
func (module *SdkLibrary) latestApiFilegroupName(apiScope *apiScope) string {
return ":" + module.BaseModuleName() + ".api." + apiScope.name + ".latest"
}
@@ -491,9 +484,6 @@
Libs []string
Arg_files []string
Args *string
- Api_tag_name *string
- Api_filename *string
- Removed_api_filename *string
Java_version *string
Merge_annotations_dirs []string
Merge_inclusion_annotations_dirs []string
@@ -572,10 +562,6 @@
apiDir := module.getApiDir()
currentApiFileName = path.Join(apiDir, currentApiFileName)
removedApiFileName = path.Join(apiDir, removedApiFileName)
- // TODO(jiyong): remove these three props
- props.Api_tag_name = proptools.StringPtr(module.apiTagName(apiScope))
- props.Api_filename = proptools.StringPtr(currentApiFileName)
- props.Removed_api_filename = proptools.StringPtr(removedApiFileName)
// check against the not-yet-release API
props.Check_api.Current.Api_file = proptools.StringPtr(currentApiFileName)
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index a2e35d9..0932873 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -151,6 +151,12 @@
// Whether public stub exists or not.
Public_stub *bool `blueprint:"mutated"`
+
+ Cpp struct {
+ // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
+ // Forwarded to cc_library.min_sdk_version
+ Min_sdk_version *string
+ }
}
var (
@@ -344,6 +350,7 @@
Vendor_available *bool
Host_supported *bool
Apex_available []string
+ Min_sdk_version *string
}
type javaLibraryProperties struct {
@@ -433,6 +440,7 @@
ccProps.Vendor_available = m.properties.Vendor_available
ccProps.Host_supported = m.properties.Host_supported
ccProps.Apex_available = m.ApexProperties.Apex_available
+ ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
ctx.CreateModule(cc.LibraryFactory, &ccProps)
scope := "internal"
diff --git a/ui/build/build.go b/ui/build/build.go
index f3feac2..1122733 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -53,7 +53,6 @@
{{end -}}
pool highmem_pool
depth = {{.HighmemParallel}}
-build _kati_always_build_: phony
{{if .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
subninja {{.KatiPackageNinjaFile}}
{{end -}}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index a3234e3..a559330 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -229,8 +229,6 @@
"DEFAULT_ERROR_BUILD_MODULE_TYPES",
"BUILD_BROKEN_PREBUILT_ELF_FILES",
"BUILD_BROKEN_TREBLE_SYSPROP_NEVERALLOW",
- "BUILD_BROKEN_USES_BUILD_AUX_EXECUTABLE",
- "BUILD_BROKEN_USES_BUILD_AUX_STATIC_LIBRARY",
"BUILD_BROKEN_USES_BUILD_COPY_HEADERS",
"BUILD_BROKEN_USES_BUILD_EXECUTABLE",
"BUILD_BROKEN_USES_BUILD_FUZZ_TEST",
@@ -238,17 +236,12 @@
"BUILD_BROKEN_USES_BUILD_HOST_DALVIK_JAVA_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_EXECUTABLE",
- "BUILD_BROKEN_USES_BUILD_HOST_FUZZ_TEST",
"BUILD_BROKEN_USES_BUILD_HOST_JAVA_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_HOST_NATIVE_TEST",
"BUILD_BROKEN_USES_BUILD_HOST_PREBUILT",
"BUILD_BROKEN_USES_BUILD_HOST_SHARED_LIBRARY",
"BUILD_BROKEN_USES_BUILD_HOST_STATIC_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_HOST_STATIC_TEST_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_HOST_TEST_CONFIG",
"BUILD_BROKEN_USES_BUILD_JAVA_LIBRARY",
"BUILD_BROKEN_USES_BUILD_MULTI_PREBUILT",
- "BUILD_BROKEN_USES_BUILD_NATIVE_BENCHMARK",
"BUILD_BROKEN_USES_BUILD_NATIVE_TEST",
"BUILD_BROKEN_USES_BUILD_NOTICE_FILE",
"BUILD_BROKEN_USES_BUILD_PACKAGE",
@@ -258,8 +251,6 @@
"BUILD_BROKEN_USES_BUILD_SHARED_LIBRARY",
"BUILD_BROKEN_USES_BUILD_STATIC_JAVA_LIBRARY",
"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_STATIC_TEST_LIBRARY",
- "BUILD_BROKEN_USES_BUILD_TARGET_TEST_CONFIG",
}, exportEnvVars...), BannerVars...)
make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
diff --git a/ui/build/exec.go b/ui/build/exec.go
index e435c53..053bbae 100644
--- a/ui/build/exec.go
+++ b/ui/build/exec.go
@@ -19,6 +19,8 @@
"io"
"os/exec"
"strings"
+ "syscall"
+ "time"
)
// Cmd is a wrapper of os/exec.Cmd that integrates with the build context for
@@ -33,6 +35,8 @@
ctx Context
config Config
name string
+
+ started time.Time
}
func Command(ctx Context, config Config, name string, executable string, args ...string) *Cmd {
@@ -57,7 +61,20 @@
c.wrapSandbox()
}
- c.ctx.Verboseln(c.Path, c.Args)
+ c.ctx.Verbosef("%q executing %q %v\n", c.name, c.Path, c.Args)
+ c.started = time.Now()
+}
+
+func (c *Cmd) report() {
+ if c.Cmd.ProcessState != nil {
+ rusage := c.Cmd.ProcessState.SysUsage().(*syscall.Rusage)
+ c.ctx.Verbosef("%q finished with exit code %d (%s real, %s user, %s system, %dMB maxrss)",
+ c.name, c.Cmd.ProcessState.ExitCode(),
+ time.Since(c.started).Round(time.Millisecond),
+ c.Cmd.ProcessState.UserTime().Round(time.Millisecond),
+ c.Cmd.ProcessState.SystemTime().Round(time.Millisecond),
+ rusage.Maxrss/1024)
+ }
}
func (c *Cmd) Start() error {
@@ -68,21 +85,30 @@
func (c *Cmd) Run() error {
c.prepare()
err := c.Cmd.Run()
+ c.report()
return err
}
func (c *Cmd) Output() ([]byte, error) {
c.prepare()
bytes, err := c.Cmd.Output()
+ c.report()
return bytes, err
}
func (c *Cmd) CombinedOutput() ([]byte, error) {
c.prepare()
bytes, err := c.Cmd.CombinedOutput()
+ c.report()
return bytes, err
}
+func (c *Cmd) Wait() error {
+ err := c.Cmd.Wait()
+ c.report()
+ return err
+}
+
// StartOrFatal is equivalent to Start, but handles the error with a call to ctx.Fatal
func (c *Cmd) StartOrFatal() {
if err := c.Start(); err != nil {
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 8796a4f..2eb7850 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -67,6 +67,7 @@
"--ninja_dir=" + config.OutDir(),
"--ninja_suffix=" + config.KatiSuffix() + extraSuffix,
"--no_ninja_prelude",
+ "--use_ninja_phony_output",
"--regen",
"--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
"--detect_android_echo",
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index dfc3be1..1b13e5d 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -58,6 +58,7 @@
args = append(args, "-f", config.CombinedNinjaFile())
args = append(args,
+ "-o", "usesphonyoutputs=yes",
"-w", "dupbuild=err",
"-w", "missingdepfile=err")
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 9b8d648..2fbf381 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -119,7 +119,11 @@
cmd := Command(ctx, config, "soong "+name,
config.PrebuiltBuildTool("ninja"),
"-d", "keepdepfile",
+ "-o", "usesphonyoutputs=yes",
+ "-o", "preremoveoutputs=yes",
"-w", "dupbuild=err",
+ "-w", "outputdir=err",
+ "-w", "missingoutfile=err",
"-j", strconv.Itoa(config.Parallel()),
"--frontend_file", fifo,
"-f", filepath.Join(config.SoongOutDir(), file))
diff --git a/ui/build/test_build.go b/ui/build/test_build.go
index 5109465..4ff9483 100644
--- a/ui/build/test_build.go
+++ b/ui/build/test_build.go
@@ -50,10 +50,10 @@
// Get a list of leaf nodes in the dependency graph from ninja
executable := config.PrebuiltBuildTool("ninja")
- args := []string{}
- args = append(args, config.NinjaArgs()...)
- args = append(args, "-f", config.CombinedNinjaFile())
- args = append(args, "-t", "targets", "rule")
+ common_args := []string{}
+ common_args = append(common_args, config.NinjaArgs()...)
+ common_args = append(common_args, "-f", config.CombinedNinjaFile())
+ args := append(common_args, "-t", "targets", "rule")
cmd := Command(ctx, config, "ninja", executable, args...)
stdout, err := cmd.StdoutPipe()
@@ -96,9 +96,31 @@
sb := &strings.Builder{}
title := "Dependencies in out found with no rule to create them:"
fmt.Fprintln(sb, title)
- for _, dep := range danglingRulesList {
- fmt.Fprintln(sb, " ", dep)
+
+ report_lines := 1
+ for i, dep := range danglingRulesList {
+ if report_lines > 20 {
+ fmt.Fprintf(sb, " ... and %d more\n", len(danglingRulesList)-i)
+ break
+ }
+ // It's helpful to see the reverse dependencies. ninja -t query is the
+ // best tool we got for that. Its output starts with the dependency
+ // itself.
+ query_cmd := Command(ctx, config, "ninja", executable,
+ append(common_args, "-t", "query", dep)...)
+ query_stdout, err := query_cmd.StdoutPipe()
+ if err != nil {
+ ctx.Fatal(err)
+ }
+ query_cmd.StartOrFatal()
+ scanner := bufio.NewScanner(query_stdout)
+ for scanner.Scan() {
+ report_lines++
+ fmt.Fprintln(sb, " ", scanner.Text())
+ }
+ query_cmd.WaitOrFatal()
}
+
ts.FinishAction(status.ActionResult{
Action: action,
Error: fmt.Errorf(title),