Merge "Delete prebuilt APEXes when installing source-built APEXes"
diff --git a/android/config.go b/android/config.go
index 556ddcc..074dfc7 100644
--- a/android/config.go
+++ b/android/config.go
@@ -756,6 +756,14 @@
return c.IsEnvTrue("RUN_ERROR_PRONE")
}
+func (c *config) XrefCorpusName() string {
+ return c.Getenv("XREF_CORPUS")
+}
+
+func (c *config) EmitXrefRules() bool {
+ return c.XrefCorpusName() != ""
+}
+
// Returns true if -source 1.9 -target 1.9 is being passed to javac
func (c *config) TargetOpenJDK9() bool {
return c.targetOpenJDK9
diff --git a/apex/apex.go b/apex/apex.go
index de9ce0d..4729e0f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -696,12 +696,6 @@
return
}
-func getCopyManifestForTestPerSrcExecutables(cc *cc.Module) (filesToCopy []android.Path, dirInApex string) {
- dirInApex = filepath.Join("bin", cc.RelativeInstallPath())
- filesToCopy = cc.TestPerSrcOutputFiles()
- return
-}
-
func getCopyManifestForPyBinary(py *python.Module) (fileToCopy android.Path, dirInApex string) {
dirInApex = "bin"
fileToCopy = py.HostToolPath().Path()
@@ -782,10 +776,10 @@
})
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
+ depTag := ctx.OtherModuleDependencyTag(child)
+ depName := ctx.OtherModuleName(child)
if _, ok := parent.(*apexBundle); ok {
// direct dependencies
- depTag := ctx.OtherModuleDependencyTag(child)
- depName := ctx.OtherModuleName(child)
switch depTag {
case sharedLibTag:
if cc, ok := child.(*cc.Module); ok {
@@ -836,22 +830,19 @@
ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
}
case testTag:
- if cc, ok := child.(*cc.Module); ok {
- if cc.TestPerSrcOutputFiles() != nil {
- // Multiple-output test module (using `test_per_src`).
- filesToCopy, dirInApex := getCopyManifestForTestPerSrcExecutables(cc)
- for _, fileToCopy := range filesToCopy {
- // Handle modules created as `test_per_src` variations of a single test module:
- // replace the name of the original test module (`depName`, shared by all
- // `test_per_src` variants of that module) with the name of the generated test
- // binary.
- moduleName := filepath.Base(fileToCopy.String())
- filesInfo = append(filesInfo, apexFile{fileToCopy, moduleName, dirInApex, nativeTest, cc, nil})
- }
+ if ccTest, ok := child.(*cc.Module); ok {
+ if ccTest.IsTestPerSrcAllTestsVariation() {
+ // Multiple-output test module (where `test_per_src: true`).
+ //
+ // `ccTest` is the "" ("all tests") variation of a `test_per_src` module.
+ // We do not add this variation to `filesInfo`, as it has no output;
+ // however, we do add the other variations of this module as indirect
+ // dependencies (see below).
+ return true
} else {
- // Single-output test module (not using `test_per_src`).
- fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
- filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeTest, cc, nil})
+ // Single-output test module (where `test_per_src: false`).
+ fileToCopy, dirInApex := getCopyManifestForExecutable(ccTest)
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeTest, ccTest, nil})
}
return true
} else {
@@ -883,30 +874,46 @@
} else {
// indirect dependencies
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() && am.IsInstallableToApex() {
- if cc, ok := child.(*cc.Module); ok {
- if android.InList(cc.Name(), providedNativeSharedLibs) {
- // If we're using a shared library which is provided from other APEX,
- // don't include it in this APEX
- return false
- }
- if !a.Host() && (cc.IsStubs() || cc.HasStubsVariants()) {
- // If the dependency is a stubs lib, don't include it in this APEX,
- // but make sure that the lib is installed on the device.
- // In case no APEX is having the lib, the lib is installed to the system
- // partition.
- //
- // Always include if we are a host-apex however since those won't have any
- // system libraries.
- if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
- a.externalDeps = append(a.externalDeps, cc.Name())
+ // We cannot use a switch statement on `depTag` here as the checked
+ // tags used below are private (e.g. `cc.sharedDepTag`).
+ if cc.IsSharedDepTag(depTag) || cc.IsRuntimeDepTag(depTag) {
+ if cc, ok := child.(*cc.Module); ok {
+ if android.InList(cc.Name(), providedNativeSharedLibs) {
+ // If we're using a shared library which is provided from other APEX,
+ // don't include it in this APEX
+ return false
}
- // Don't track further
- return false
+ if !a.Host() && (cc.IsStubs() || cc.HasStubsVariants()) {
+ // If the dependency is a stubs lib, don't include it in this APEX,
+ // but make sure that the lib is installed on the device.
+ // In case no APEX is having the lib, the lib is installed to the system
+ // partition.
+ //
+ // Always include if we are a host-apex however since those won't have any
+ // system libraries.
+ if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
+ a.externalDeps = append(a.externalDeps, cc.Name())
+ }
+ // Don't track further
+ return false
+ }
+ fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
+ return true
}
- depName := ctx.OtherModuleName(child)
- fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc, handleSpecialLibs)
- filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, nativeSharedLib, cc, nil})
- return true
+ } else if cc.IsTestPerSrcDepTag(depTag) {
+ if cc, ok := child.(*cc.Module); ok {
+ fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
+ // Handle modules created as `test_per_src` variations of a single test module:
+ // use the name of the generated test binary (`fileToCopy`) instead of the name
+ // of the original test module (`depName`, shared by all `test_per_src`
+ // variations of that module).
+ moduleName := filepath.Base(fileToCopy.String())
+ filesInfo = append(filesInfo, apexFile{fileToCopy, moduleName, dirInApex, nativeTest, cc, nil})
+ return true
+ }
+ } else {
+ ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
}
}
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e44163e..cecdaaf 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -1393,7 +1393,7 @@
}
func TestApexWithTests(t *testing.T) {
- ctx, _ := testApex(t, `
+ ctx, config := testApex(t, `
apex_test {
name: "myapex",
key: "myapex.key",
@@ -1445,6 +1445,22 @@
ensureContains(t, copyCmds, "image.apex/bin/test/mytest1")
ensureContains(t, copyCmds, "image.apex/bin/test/mytest2")
ensureContains(t, copyCmds, "image.apex/bin/test/mytest3")
+
+ // Ensure the module is correctly translated.
+ apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, config, "", apexBundle)
+ name := apexBundle.BaseModuleName()
+ prefix := "TARGET_"
+ var builder strings.Builder
+ data.Custom(&builder, name, prefix, "", data)
+ androidMk := builder.String()
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest1\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest2\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.mytest3\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_manifest.json\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex.apex_pubkey\n")
+ ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
}
func TestApexUsesOtherApex(t *testing.T) {
diff --git a/cc/builder.go b/cc/builder.go
index cbe2c88..2909d51 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -221,6 +221,17 @@
Rspfile: "$out.rsp",
RspfileContent: "$in",
})
+
+ _ = pctx.SourcePathVariable("cxxExtractor",
+ "prebuilts/clang-tools/${config.HostPrebuiltTag}/bin/cxx_extractor")
+ _ = pctx.VariableFunc("kytheCorpus",
+ func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+ kytheExtract = pctx.StaticRule("kythe",
+ blueprint.RuleParams{
+ Command: "rm -f $out && KYTHE_CORPUS=${kytheCorpus} KYTHE_OUTPUT_FILE=$out $cxxExtractor $cFlags $in ",
+ CommandDeps: []string{"$cxxExtractor"},
+ },
+ "cFlags")
)
func init() {
@@ -257,6 +268,7 @@
tidy bool
coverage bool
sAbiDump bool
+ emitXrefs bool
systemIncludeFlags string
@@ -281,6 +293,7 @@
tidyFiles android.Paths
coverageFiles android.Paths
sAbiDumpFiles android.Paths
+ kytheFiles android.Paths
}
func (a Objects) Copy() Objects {
@@ -289,6 +302,7 @@
tidyFiles: append(android.Paths{}, a.tidyFiles...),
coverageFiles: append(android.Paths{}, a.coverageFiles...),
sAbiDumpFiles: append(android.Paths{}, a.sAbiDumpFiles...),
+ kytheFiles: append(android.Paths{}, a.kytheFiles...),
}
}
@@ -298,6 +312,7 @@
tidyFiles: append(a.tidyFiles, b.tidyFiles...),
coverageFiles: append(a.coverageFiles, b.coverageFiles...),
sAbiDumpFiles: append(a.sAbiDumpFiles, b.sAbiDumpFiles...),
+ kytheFiles: append(a.kytheFiles, b.kytheFiles...),
}
}
@@ -314,6 +329,10 @@
if flags.coverage {
coverageFiles = make(android.Paths, 0, len(srcFiles))
}
+ var kytheFiles android.Paths
+ if flags.emitXrefs {
+ kytheFiles = make(android.Paths, 0, len(srcFiles))
+ }
commonFlags := strings.Join([]string{
flags.globalFlags,
@@ -401,6 +420,7 @@
coverage := flags.coverage
dump := flags.sAbiDump
rule := cc
+ emitXref := flags.emitXrefs
switch srcFile.Ext() {
case ".s":
@@ -412,6 +432,7 @@
tidy = false
coverage = false
dump = false
+ emitXref = false
case ".c":
ccCmd = "clang"
moduleCflags = cflags
@@ -450,6 +471,22 @@
},
})
+ if emitXref {
+ kytheFile := android.ObjPathWithExt(ctx, subdir, srcFile, "kzip")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: kytheExtract,
+ Description: "Xref C++ extractor " + srcFile.Rel(),
+ Output: kytheFile,
+ Input: srcFile,
+ Implicits: cFlagsDeps,
+ OrderOnly: pathDeps,
+ Args: map[string]string{
+ "cFlags": moduleCflags,
+ },
+ })
+ kytheFiles = append(kytheFiles, kytheFile)
+ }
+
if tidy {
tidyFile := android.ObjPathWithExt(ctx, subdir, srcFile, "tidy")
tidyFiles = append(tidyFiles, tidyFile)
@@ -493,6 +530,7 @@
tidyFiles: tidyFiles,
coverageFiles: coverageFiles,
sAbiDumpFiles: sAbiDumpFiles,
+ kytheFiles: kytheFiles,
}
}
diff --git a/cc/cc.go b/cc/cc.go
index 2cee807..cc2e65f 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -77,6 +77,7 @@
ctx.TopDown("double_loadable", checkDoubleLoadableLibraries).Parallel()
})
+ android.RegisterSingletonType("kythe_extract_all", kytheExtractAllFactory)
pctx.Import("android/soong/cc/config")
}
@@ -162,6 +163,7 @@
Tidy bool
Coverage bool
SAbiDump bool
+ EmitXrefs bool // If true, generate Ninja rules to generate emitXrefs input files for Kythe
RequiredInstructionSet string
DynamicLinker string
@@ -340,17 +342,22 @@
blueprint.BaseDependencyTag
name string
library bool
+ shared bool
reexportFlags bool
explicitlyVersioned bool
}
+type xref interface {
+ XrefCcFiles() android.Paths
+}
+
var (
- sharedDepTag = dependencyTag{name: "shared", library: true}
- sharedExportDepTag = dependencyTag{name: "shared", library: true, reexportFlags: true}
- earlySharedDepTag = dependencyTag{name: "early_shared", library: true}
- lateSharedDepTag = dependencyTag{name: "late shared", library: true}
+ sharedDepTag = dependencyTag{name: "shared", library: true, shared: true}
+ sharedExportDepTag = dependencyTag{name: "shared", library: true, shared: true, reexportFlags: true}
+ earlySharedDepTag = dependencyTag{name: "early_shared", library: true, shared: true}
+ lateSharedDepTag = dependencyTag{name: "late shared", library: true, shared: true}
staticDepTag = dependencyTag{name: "static", library: true}
staticExportDepTag = dependencyTag{name: "static", library: true, reexportFlags: true}
lateStaticDepTag = dependencyTag{name: "late static", library: true}
@@ -375,6 +382,21 @@
testPerSrcDepTag = dependencyTag{name: "test_per_src"}
)
+func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag.shared
+}
+
+func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag == runtimeDepTag
+}
+
+func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool {
+ ccDepTag, ok := depTag.(dependencyTag)
+ return ok && ccDepTag == testPerSrcDepTag
+}
+
// Module contains the properties and members used by all C/C++ module types, and implements
// the blueprint.Module interface. It delegates to compiler, linker, and installer interfaces
// to construct the output file. Behavior can be customized with a Customizer interface
@@ -408,9 +430,6 @@
outputFile android.OptionalPath
- // Test output files, in the case of a test module using `test_per_src`.
- testPerSrcOutputFiles []android.Path
-
cachedToolchain config.Toolchain
subAndroidMkOnce map[subAndroidMkProvider]bool
@@ -427,16 +446,14 @@
staticVariant *Module
makeLinkType string
+ // Kythe (source file indexer) paths for this compilation module
+ kytheFiles android.Paths
}
func (c *Module) OutputFile() android.OptionalPath {
return c.outputFile
}
-func (c *Module) TestPerSrcOutputFiles() []android.Path {
- return c.testPerSrcOutputFiles
-}
-
func (c *Module) UnstrippedOutputFile() android.Path {
if c.linker != nil {
return c.linker.unstrippedOutputFilePath()
@@ -657,6 +674,10 @@
return isBionic(name)
}
+func (c *Module) XrefCcFiles() android.Paths {
+ return c.kytheFiles
+}
+
type baseModuleContext struct {
android.BaseModuleContext
moduleContextImpl
@@ -950,28 +971,20 @@
return results
}
+func (c *Module) IsTestPerSrcAllTestsVariation() bool {
+ test, ok := c.linker.(testPerSrc)
+ return ok && test.isAllTestsVariation()
+}
+
func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
// Handle the case of a test module split by `test_per_src` mutator.
- if test, ok := c.linker.(testPerSrc); ok {
- // The `test_per_src` mutator adds an extra variant named "", depending on all the
- // other `test_per_src` variants of the test module. Collect the output files of
- // these dependencies and record them in the `testPerSrcOutputFiles` for later use
- // (see e.g. `apexBundle.GenerateAndroidBuildActions`).
- if test.isAllTestsVariation() {
- var testPerSrcOutputFiles []android.Path
- for _, dep := range actx.GetDirectDepsWithTag(testPerSrcDepTag) {
- if ccDep, ok := dep.(*Module); ok {
- depOutputFile := ccDep.OutputFile().Path()
- testPerSrcOutputFiles =
- append(testPerSrcOutputFiles, depOutputFile)
- }
- }
- c.testPerSrcOutputFiles = testPerSrcOutputFiles
- // Set outputFile to an empty path, as this module does not produce an
- // output file per se.
- c.outputFile = android.OptionalPath{}
- return
- }
+ //
+ // The `test_per_src` mutator adds an extra variation named "", depending on all the other
+ // `test_per_src` variations of the test module. Set `outputFile` to an empty path for this
+ // module and return early, as this module does not produce an output file per se.
+ if c.IsTestPerSrcAllTestsVariation() {
+ c.outputFile = android.OptionalPath{}
+ return
}
c.makeLinkType = c.getMakeLinkType(actx)
@@ -995,6 +1008,7 @@
flags := Flags{
Toolchain: c.toolchain(ctx),
+ EmitXrefs: ctx.Config().EmitXrefRules(),
}
if c.compiler != nil {
flags = c.compiler.compilerFlags(ctx, flags, deps)
@@ -1060,6 +1074,7 @@
if ctx.Failed() {
return
}
+ c.kytheFiles = objs.kytheFiles
}
if c.linker != nil {
@@ -2050,12 +2065,14 @@
}
// Overrides ApexModule.IsInstallabeToApex()
-// Only shared libraries are installable to APEX.
+// Only shared/runtime libraries and "test_per_src" tests are installable to APEX.
func (c *Module) IsInstallableToApex() bool {
if shared, ok := c.linker.(interface {
shared() bool
}); ok {
return shared.shared()
+ } else if _, ok := c.linker.(testPerSrc); ok {
+ return true
}
return false
}
@@ -2366,6 +2383,31 @@
return ctx.Config().PlatformSdkVersion()
}
+func kytheExtractAllFactory() android.Singleton {
+ return &kytheExtractAllSingleton{}
+}
+
+type kytheExtractAllSingleton struct {
+}
+
+func (ks *kytheExtractAllSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var xrefTargets android.Paths
+ ctx.VisitAllModules(func(module android.Module) {
+ if ccModule, ok := module.(xref); ok {
+ xrefTargets = append(xrefTargets, ccModule.XrefCcFiles()...)
+ }
+ })
+ // TODO(asmundak): Perhaps emit a rule to output a warning if there were no xrefTargets
+ if len(xrefTargets) > 0 {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: blueprint.Phony,
+ Output: android.PathForPhony(ctx, "xref_cxx"),
+ Inputs: xrefTargets,
+ //Default: true,
+ })
+ }
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var BoolPtr = proptools.BoolPtr
diff --git a/cc/compiler.go b/cc/compiler.go
index 0f9599e..ffb6ad2 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -17,6 +17,7 @@
import (
"fmt"
"path/filepath"
+ "strconv"
"strings"
"github.com/google/blueprint/proptools"
@@ -308,27 +309,10 @@
flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
"-isystem "+getCurrentIncludePath(ctx).String(),
"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
-
- // TODO: Migrate to API suffixed triple?
- // Traditionally this has come from android/api-level.h, but with the
- // libc headers unified it must be set by the build system since we
- // don't have per-API level copies of that header now.
- version := ctx.sdkVersion()
- if version == "current" {
- version = "__ANDROID_API_FUTURE__"
- }
- flags.GlobalFlags = append(flags.GlobalFlags,
- "-D__ANDROID_API__="+version)
}
if ctx.useVndk() {
- // sdkVersion() returns VNDK version for vendor modules.
- version := ctx.sdkVersion()
- if version == "current" {
- version = "__ANDROID_API_FUTURE__"
- }
- flags.GlobalFlags = append(flags.GlobalFlags,
- "-D__ANDROID_API__="+version, "-D__ANDROID_VNDK__")
+ flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_VNDK__")
}
if ctx.inRecovery() {
@@ -364,6 +348,15 @@
flags.LdFlags = config.ClangFilterUnknownCflags(flags.LdFlags)
target := "-target " + tc.ClangTriple()
+ if ctx.Os().Class == android.Device {
+ version := ctx.sdkVersion()
+ if version == "" || version == "current" {
+ target += strconv.Itoa(android.FutureApiLevel)
+ } else {
+ target += version
+ }
+ }
+
gccPrefix := "-B" + config.ToolPath(tc)
flags.CFlags = append(flags.CFlags, target, gccPrefix)
diff --git a/cc/library.go b/cc/library.go
index 7cbfdb5..2b7c9a1 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -110,6 +110,9 @@
// Symbol tags that should be ignored from the symbol file
Exclude_symbol_tags []string
}
+
+ // Order symbols in .bss section by their sizes. Only useful for shared libraries.
+ Sort_bss_symbols_by_size *bool
}
type LibraryMutatedProperties struct {
@@ -758,6 +761,18 @@
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
+ if Bool(library.Properties.Sort_bss_symbols_by_size) {
+ unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName)
+ TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
+ deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
+ linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, unsortedOutputFile, implicitOutputs)
+
+ symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order")
+ symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags)
+ builderFlags.ldFlags += " " + symbolOrderingFlag
+ linkerDeps = append(linkerDeps, symbolOrderingFile)
+ }
+
TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs,
deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs,
linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs)
diff --git a/cc/linker.go b/cc/linker.go
index fa3b0a6..daacec1 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -147,9 +147,6 @@
// local file name to pass to the linker as --version_script
Version_script *string `android:"path,arch_variant"`
-
- // Local file name to pass to the linker as --symbol-ordering-file
- Symbol_ordering_file *string `android:"arch_variant"`
}
func NewBaseLinker(sanitize *sanitize) *baseLinker {
@@ -442,16 +439,6 @@
}
}
- if !linker.dynamicProperties.BuildStubs {
- symbolOrderingFile := ctx.ExpandOptionalSource(
- linker.Properties.Symbol_ordering_file, "Symbol_ordering_file")
- if symbolOrderingFile.Valid() {
- flags.LdFlags = append(flags.LdFlags,
- "-Wl,--symbol-ordering-file,"+symbolOrderingFile.String())
- flags.LdFlagsDeps = append(flags.LdFlagsDeps, symbolOrderingFile.Path())
- }
- }
-
return flags
}
@@ -487,3 +474,29 @@
},
})
}
+
+// Rule to generate .bss symbol ordering file.
+
+var (
+ _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh")
+ gen_sorted_bss_symbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols",
+ blueprint.RuleParams{
+ Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}",
+ CommandDeps: []string{"$genSortedBssSymbolsPath"},
+ },
+ "crossCompile")
+)
+
+func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string {
+ crossCompile := gccCmd(flags.toolchain, "")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: gen_sorted_bss_symbols,
+ Description: "generate bss symbol order " + symbolOrderingFile.Base(),
+ Output: symbolOrderingFile,
+ Input: in,
+ Args: map[string]string{
+ "crossCompile": crossCompile,
+ },
+ })
+ return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String()
+}
diff --git a/cc/makevars.go b/cc/makevars.go
index a42429f..f9c58b9 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -266,9 +266,9 @@
}
clangPrefix := secondPrefix + "CLANG_" + typePrefix
- clangExtras := "-target " + toolchain.ClangTriple()
- clangExtras += " -B" + config.ToolPath(toolchain)
+ clangExtras := "-B" + config.ToolPath(toolchain)
+ ctx.Strict(clangPrefix+"TRIPLE", toolchain.ClangTriple())
ctx.Strict(clangPrefix+"GLOBAL_CFLAGS", strings.Join([]string{
toolchain.ClangCflags(),
"${config.CommonClangGlobalCflags}",
diff --git a/cc/util.go b/cc/util.go
index 2e1bb25..0d1b2f0 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -74,6 +74,7 @@
coverage: in.Coverage,
tidy: in.Tidy,
sAbiDump: in.SAbiDump,
+ emitXrefs: in.EmitXrefs,
systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 0eaed76..0bc3606 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -416,7 +416,26 @@
fmt.Fprintln(writer, "!")
fmt.Fprintln(writer, "! Older versions are saved in verbose.log.#.gz files")
fmt.Fprintln(writer, "")
- time.Sleep(5 * time.Second)
+ select {
+ case <-time.After(5 * time.Second):
+ case <-ctx.Done():
+ return
+ }
+ }
+
+ if _, ok := config.Environment().Get("ONE_SHOT_MAKEFILE"); ok {
+ writer := ctx.Writer
+ fmt.Fprintln(writer, "! The variable `ONE_SHOT_MAKEFILE` is deprecated, and will be removed shortly.")
+ fmt.Fprintln(writer, "!")
+ fmt.Fprintln(writer, "! If you're using `mm`, you'll need to run `source build/envsetup.sh` to update.")
+ fmt.Fprintln(writer, "!")
+ fmt.Fprintln(writer, "! Otherwise, either specify a module name with m, or use mma / MODULES-IN-...")
+ fmt.Fprintln(writer, "")
+ select {
+ case <-time.After(30 * time.Second):
+ case <-ctx.Done():
+ return
+ }
}
toBuild := build.BuildAll
diff --git a/java/app.go b/java/app.go
index a679e88..674e5ec 100644
--- a/java/app.go
+++ b/java/app.go
@@ -191,9 +191,12 @@
}
}
+func (a *AndroidTestHelperApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ a.generateAndroidBuildActions(ctx)
+}
+
func (a *AndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
- a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
+ a.checkPlatformAPI(ctx)
a.generateAndroidBuildActions(ctx)
}
@@ -422,6 +425,9 @@
func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) {
var apkDeps android.Paths
+ a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
+ a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
+
// Check if the install APK name needs to be overridden.
a.installApkName = ctx.DeviceConfig().OverridePackageNameFor(a.Name())
@@ -584,8 +590,6 @@
a.additionalAaptFlags = append(a.additionalAaptFlags, "--rename-instrumentation-target-package "+manifestPackageName)
}
}
- a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx)
- a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex)
a.generateAndroidBuildActions(ctx)
a.testConfig = tradefed.AutoGenInstrumentationTestConfig(ctx, a.testProperties.Test_config, a.testProperties.Test_config_template, a.manifestPath, a.testProperties.Test_suites)
diff --git a/java/app_test.go b/java/app_test.go
index 32de019..f6a307e 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -72,6 +72,7 @@
ctx := testApp(t, moduleType+` {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current"
}
`)
@@ -117,6 +118,7 @@
name: "foo",
srcs: ["a.java"],
package_splits: ["v4", "v7,hdpi"],
+ sdk_version: "current"
}`)
foo := ctx.ModuleForTests("foo", "android_common")
@@ -139,6 +141,40 @@
}
}
+func TestPlatformAPIs(t *testing.T) {
+ testJava(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ platform_apis: true,
+ }
+ `)
+
+ testJava(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+ `)
+
+ testJavaError(t, "platform_apis must be true when sdk_version is empty.", `
+ android_app {
+ name: "bar",
+ srcs: ["b.java"],
+ }
+ `)
+
+ testJavaError(t, "platform_apis must be false when sdk_version is not empty.", `
+ android_app {
+ name: "bar",
+ srcs: ["b.java"],
+ sdk_version: "system_current",
+ platform_apis: true,
+ }
+ `)
+}
+
func TestResourceDirs(t *testing.T) {
testCases := []struct {
name string
@@ -169,6 +205,7 @@
bp := `
android_app {
name: "foo",
+ sdk_version: "current",
%s
}
`
@@ -349,12 +386,14 @@
bp := `
android_app {
name: "foo",
+ sdk_version: "current",
resource_dirs: ["foo/res"],
static_libs: ["lib", "lib3"],
}
android_app {
name: "bar",
+ sdk_version: "current",
resource_dirs: ["bar/res"],
}
@@ -461,6 +500,7 @@
platformSdkCodename string
platformSdkFinal bool
expectedMinSdkVersion string
+ platformApis bool
}{
{
name: "current final SDK",
@@ -481,6 +521,7 @@
{
name: "default final SDK",
sdkVersion: "",
+ platformApis: true,
platformSdkInt: 27,
platformSdkCodename: "REL",
platformSdkFinal: true,
@@ -489,6 +530,7 @@
{
name: "default non-final SDK",
sdkVersion: "",
+ platformApis: true,
platformSdkInt: 27,
platformSdkCodename: "OMR1",
platformSdkFinal: false,
@@ -504,11 +546,16 @@
for _, moduleType := range []string{"android_app", "android_library"} {
for _, test := range testCases {
t.Run(moduleType+" "+test.name, func(t *testing.T) {
+ platformApiProp := ""
+ if test.platformApis {
+ platformApiProp = "platform_apis: true,"
+ }
bp := fmt.Sprintf(`%s {
name: "foo",
srcs: ["a.java"],
sdk_version: "%s",
- }`, moduleType, test.sdkVersion)
+ %s
+ }`, moduleType, test.sdkVersion, platformApiProp)
config := testConfig(nil)
config.TestProductVariables.Platform_sdk_version = &test.platformSdkInt
@@ -630,18 +677,21 @@
android_app {
name: "app",
jni_libs: ["libjni"],
+ sdk_version: "current",
}
android_app {
name: "app_noembed",
jni_libs: ["libjni"],
use_embedded_native_libs: false,
+ sdk_version: "current",
}
android_app {
name: "app_embed",
jni_libs: ["libjni"],
use_embedded_native_libs: true,
+ sdk_version: "current",
}
android_test {
@@ -715,6 +765,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
certificateOverride: "",
@@ -726,7 +777,8 @@
android_app {
name: "foo",
srcs: ["a.java"],
- certificate: ":new_certificate"
+ certificate: ":new_certificate",
+ sdk_version: "current",
}
android_app_certificate {
@@ -743,7 +795,8 @@
android_app {
name: "foo",
srcs: ["a.java"],
- certificate: "expiredkey"
+ certificate: "expiredkey",
+ sdk_version: "current",
}
`,
certificateOverride: "",
@@ -755,7 +808,8 @@
android_app {
name: "foo",
srcs: ["a.java"],
- certificate: "expiredkey"
+ certificate: "expiredkey",
+ sdk_version: "current",
}
android_app_certificate {
@@ -801,6 +855,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
packageNameOverride: "",
@@ -815,6 +870,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
packageNameOverride: "foo:bar",
@@ -856,11 +912,13 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
android_test {
name: "bar",
instrumentation_for: "foo",
+ sdk_version: "current",
}
`
config := testConfig(nil)
@@ -885,6 +943,7 @@
srcs: ["a.java"],
certificate: "expiredkey",
overrides: ["qux"],
+ sdk_version: "current",
}
override_android_app {
@@ -984,6 +1043,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
override_android_app {
@@ -1253,18 +1313,21 @@
name: "foo",
srcs: ["a.java"],
api_packages: ["foo"],
+ sdk_version: "current",
}
java_sdk_library {
name: "bar",
srcs: ["a.java"],
api_packages: ["bar"],
+ sdk_version: "current",
}
android_app {
name: "app",
srcs: ["a.java"],
uses_libs: ["foo"],
+ sdk_version: "current",
optional_uses_libs: [
"bar",
"baz",
@@ -1339,6 +1402,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
noCode: false,
@@ -1348,6 +1412,7 @@
bp: `
android_app {
name: "foo",
+ sdk_version: "current",
}
`,
noCode: true,
@@ -1358,11 +1423,13 @@
android_app {
name: "foo",
static_libs: ["lib"],
+ sdk_version: "current",
}
java_library {
name: "lib",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
noCode: false,
@@ -1373,10 +1440,12 @@
android_app {
name: "foo",
static_libs: ["lib"],
+ sdk_version: "current",
}
java_library {
name: "lib",
+ sdk_version: "current",
}
`,
// TODO(jungjw): this should probably be true
@@ -1406,6 +1475,7 @@
jni_libs: ["libjni"],
notice: "APP_NOTICE",
embed_notices: true,
+ sdk_version: "current",
}
// No embed_notice flag
@@ -1414,6 +1484,7 @@
srcs: ["a.java"],
jni_libs: ["libjni"],
notice: "APP_NOTICE",
+ sdk_version: "current",
}
// No NOTICE files
@@ -1421,6 +1492,7 @@
name: "baz",
srcs: ["a.java"],
embed_notices: true,
+ sdk_version: "current",
}
cc_library {
@@ -1435,6 +1507,7 @@
srcs: [
":gen",
],
+ sdk_version: "current",
}
genrule {
@@ -1510,6 +1583,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
uncompressedPlatform: true,
@@ -1522,6 +1596,7 @@
name: "foo",
use_embedded_dex: true,
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
uncompressedPlatform: true,
@@ -1534,6 +1609,7 @@
name: "foo",
privileged: true,
srcs: ["a.java"],
+ sdk_version: "current",
}
`,
uncompressedPlatform: true,
diff --git a/java/builder.go b/java/builder.go
index 22eff7c..f174cf0 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -62,6 +62,37 @@
"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
"outDir", "annoDir", "javaVersion")
+ _ = pctx.VariableFunc("kytheCorpus",
+ func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
+ // Run it with -add-opens=java.base/java.nio=ALL-UNNAMED to avoid JDK9's warning about
+ // "Illegal reflective access by com.google.protobuf.Utf8$UnsafeProcessor ...
+ // to field java.nio.Buffer.address"
+ kytheExtract = pctx.AndroidStaticRule("kythe",
+ blueprint.RuleParams{
+ Command: `${config.ZipSyncCmd} -d $srcJarDir ` +
+ `-l $srcJarDir/list -f "*.java" $srcJars && ` +
+ `( [ ! -s $srcJarDir/list -a ! -s $out.rsp ] || ` +
+ `KYTHE_ROOT_DIRECTORY=. KYTHE_OUTPUT_FILE=$out ` +
+ `KYTHE_CORPUS=${kytheCorpus} ` +
+ `${config.SoongJavacWrapper} ${config.JavaCmd} ` +
+ `--add-opens=java.base/java.nio=ALL-UNNAMED ` +
+ `-jar ${config.JavaKytheExtractorJar} ` +
+ `${config.JavacHeapFlags} ${config.CommonJdkFlags} ` +
+ `$processorpath $processor $javacFlags $bootClasspath $classpath ` +
+ `-source $javaVersion -target $javaVersion ` +
+ `-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list)`,
+ CommandDeps: []string{
+ "${config.JavaCmd}",
+ "${config.JavaKytheExtractorJar}",
+ "${config.ZipSyncCmd}",
+ },
+ CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
+ Rspfile: "$out.rsp",
+ RspfileContent: "$in",
+ },
+ "javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
+ "outDir", "annoDir", "javaVersion")
+
turbine = pctx.AndroidStaticRule("turbine",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
@@ -196,6 +227,61 @@
"errorprone", "errorprone")
}
+// Emits the rule to generate Xref input file (.kzip file) for the given set of source files and source jars
+// to compile with given set of builder flags, etc.
+func emitXrefRule(ctx android.ModuleContext, xrefFile android.WritablePath,
+ srcFiles, srcJars android.Paths,
+ flags javaBuilderFlags, deps android.Paths,
+ intermediatesDir string) {
+
+ deps = append(deps, srcJars...)
+
+ var bootClasspath string
+ if flags.javaVersion == "1.9" {
+ var systemModuleDeps android.Paths
+ bootClasspath, systemModuleDeps = flags.systemModules.FormJavaSystemModulesPath(ctx.Device())
+ deps = append(deps, systemModuleDeps...)
+ } else {
+ deps = append(deps, flags.bootClasspath...)
+ if len(flags.bootClasspath) == 0 && ctx.Device() {
+ // explicitly specify -bootclasspath "" if the bootclasspath is empty to
+ // ensure java does not fall back to the default bootclasspath.
+ bootClasspath = `-bootclasspath ""`
+ } else {
+ bootClasspath = flags.bootClasspath.FormJavaClassPath("-bootclasspath")
+ }
+ }
+
+ deps = append(deps, flags.classpath...)
+ deps = append(deps, flags.processorPath...)
+
+ processor := "-proc:none"
+ if flags.processor != "" {
+ processor = "-processor " + flags.processor
+ }
+
+ ctx.Build(pctx,
+ android.BuildParams{
+ Rule: kytheExtract,
+ Description: "Xref Java extractor",
+ Output: xrefFile,
+ Inputs: srcFiles,
+ Implicits: deps,
+ Args: map[string]string{
+ "annoDir": android.PathForModuleOut(ctx, intermediatesDir, "anno").String(),
+ "bootClasspath": bootClasspath,
+ "classpath": flags.classpath.FormJavaClassPath("-classpath"),
+ "javacFlags": flags.javacFlags,
+ "javaVersion": flags.javaVersion,
+ "outDir": android.PathForModuleOut(ctx, "javac", "classes.xref").String(),
+ "processorpath": flags.processorPath.FormJavaClassPath("-processorpath"),
+ "processor": processor,
+ "srcJarDir": android.PathForModuleOut(ctx, intermediatesDir, "srcjars.xref").String(),
+ "srcJars": strings.Join(srcJars.Strings(), " "),
+ },
+ })
+}
+
func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android.WritablePath,
srcFiles, srcJars android.Paths, flags javaBuilderFlags) {
diff --git a/java/config/config.go b/java/config/config.go
index 6a0a10a..cb13744 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -94,6 +94,7 @@
pctx.SourcePathVariable("JlinkCmd", "${JavaToolchain}/jlink")
pctx.SourcePathVariable("JmodCmd", "${JavaToolchain}/jmod")
pctx.SourcePathVariable("JrtFsJar", "${JavaHome}/lib/jrt-fs.jar")
+ pctx.SourcePathVariable("JavaKytheExtractorJar", "prebuilts/build-tools/common/framework/javac_extractor.jar")
pctx.SourcePathVariable("Ziptime", "prebuilts/build-tools/${hostPrebuiltTag}/bin/ziptime")
pctx.SourcePathVariable("GenKotlinBuildFileCmd", "build/soong/scripts/gen-kotlin-build-file.sh")
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 19e92b7..2a142ba 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -298,6 +298,7 @@
FlagForEachArg("--dex-location=", image.dexLocations).
Flag("--generate-debug-info").
Flag("--generate-build-id").
+ Flag("--image-format=lz4hc").
FlagWithOutput("--oat-symbols=", symbolsFile).
Flag("--strip").
FlagWithOutput("--oat-file=", outputPath.ReplaceExtension(ctx, "oat")).
diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go
index 22b7bb9..5550a4c 100644
--- a/java/dexpreopt_test.go
+++ b/java/dexpreopt_test.go
@@ -30,6 +30,7 @@
android_app {
name: "foo",
srcs: ["a.java"],
+ sdk_version: "current",
}`,
enabled: true,
},
@@ -57,6 +58,7 @@
bp: `
android_app {
name: "foo",
+ sdk_version: "current",
}`,
enabled: false,
},
@@ -66,11 +68,13 @@
android_app {
name: "foo",
static_libs: ["lib"],
+ sdk_version: "current",
}
java_library {
name: "lib",
srcs: ["a.java"],
+ sdk_version: "current",
}`,
enabled: true,
},
diff --git a/java/java.go b/java/java.go
index 5f4a090..fea38b5 100644
--- a/java/java.go
+++ b/java/java.go
@@ -50,6 +50,21 @@
android.RegisterModuleType("dex_import", DexImportFactory)
android.RegisterSingletonType("logtags", LogtagsSingleton)
+ android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory)
+}
+
+func (j *Module) checkPlatformAPI(ctx android.ModuleContext) {
+ if sc, ok := ctx.Module().(sdkContext); ok {
+ usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis)
+ if usePlatformAPI != (sc.sdkVersion() == "") {
+ if usePlatformAPI {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.")
+ } else {
+ ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.")
+ }
+ }
+
+ }
}
// TODO:
@@ -178,8 +193,8 @@
// list of module-specific flags that will be used for dex compiles
Dxflags []string `android:"arch_variant"`
- // if not blank, set to the version of the sdk to compile against. Defaults to compiling against the current
- // sdk if platform_apis is not set.
+ // if not blank, set to the version of the sdk to compile against.
+ // Defaults to compiling against the current platform.
Sdk_version *string
// if not blank, set the minimum version of the sdk that the compiled artifacts will run against.
@@ -190,7 +205,8 @@
// Defaults to sdk_version if not set.
Target_sdk_version *string
- // if true, compile against the platform APIs instead of an SDK.
+ // It must be true only if sdk_version is empty.
+ // This field works in only android_app, otherwise nothing happens.
Platform_apis *bool
Aidl struct {
@@ -343,6 +359,9 @@
hiddenAPI
dexpreopter
+
+ // list of the xref extraction files
+ kytheFiles android.Paths
}
func (j *Module) OutputFiles(tag string) (android.Paths, error) {
@@ -383,6 +402,10 @@
CompiledSrcJars() android.Paths
}
+type xref interface {
+ XrefJavaFiles() android.Paths
+}
+
func (j *Module) CompiledSrcs() android.Paths {
return j.compiledJavaSrcs
}
@@ -391,6 +414,10 @@
return j.compiledSrcJars
}
+func (j *Module) XrefJavaFiles() android.Paths {
+ return j.kytheFiles
+}
+
var _ SrcDependency = (*Module)(nil)
func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) {
@@ -1139,6 +1166,12 @@
TransformJavaToClasses(ctx, classes, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps)
jars = append(jars, classes)
}
+ if ctx.Config().EmitXrefRules() {
+ extractionFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".kzip")
+ emitXrefRule(ctx, extractionFile, uniqueSrcFiles, srcJars, flags, extraJarDeps, "xref")
+ j.kytheFiles = append(j.kytheFiles, extractionFile)
+
+ }
if ctx.Failed() {
return
}
@@ -2213,6 +2246,30 @@
return module
}
+func kytheExtractJavaFactory() android.Singleton {
+ return &kytheExtractJavaSingleton{}
+}
+
+type kytheExtractJavaSingleton struct {
+}
+
+func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ var xrefTargets android.Paths
+ ctx.VisitAllModules(func(module android.Module) {
+ if javaModule, ok := module.(xref); ok {
+ xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...)
+ }
+ })
+ // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets
+ if len(xrefTargets) > 0 {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: blueprint.Phony,
+ Output: android.PathForPhony(ctx, "xref_java"),
+ Inputs: xrefTargets,
+ })
+ }
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/java/java_test.go b/java/java_test.go
index f95f88b..81d1f2c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -222,6 +222,29 @@
android.FailIfErrored(t, errs)
}
+func testJavaError(t *testing.T, pattern string, bp string) {
+ t.Helper()
+ config := testConfig(nil)
+ ctx := testContext(bp, nil)
+
+ pathCtx := android.PathContextForTesting(config, nil)
+ setDexpreoptTestGlobalConfig(config, dexpreopt.GlobalConfigForTests(pathCtx))
+
+ ctx.Register()
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+ if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+ _, errs = ctx.PrepareBuildActions(config)
+ if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+
+ t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
+}
+
func testJava(t *testing.T, bp string) (*android.TestContext, android.Config) {
t.Helper()
config := testConfig(nil)
diff --git a/scripts/gen_sorted_bss_symbols.sh b/scripts/gen_sorted_bss_symbols.sh
new file mode 100755
index 0000000..244ed0d
--- /dev/null
+++ b/scripts/gen_sorted_bss_symbols.sh
@@ -0,0 +1,28 @@
+#!/bin/bash -e
+
+# 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.
+
+# Script to generate a symbol ordering file that sorts bss section symbols by
+# their sizes.
+# Inputs:
+# Environment:
+# CROSS_COMPILE: prefix added to nm tools
+# Arguments:
+# $1: Input ELF file
+# $2: Output symbol ordering file
+
+set -o pipefail
+
+${CROSS_COMPILE}nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index 266130f..6b9eac1 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -169,7 +169,7 @@
// Variables to export into the environment of Kati/Ninja
exportEnvVars := []string{
// So that we can use the correct TARGET_PRODUCT if it's been
- // modified by PRODUCT-*/APP-* arguments
+ // modified by a buildspec.mk
"TARGET_PRODUCT",
"TARGET_BUILD_VARIANT",
"TARGET_BUILD_APPS",
diff --git a/ui/terminal/smart_status.go b/ui/terminal/smart_status.go
index 8659d4d..57f71ab 100644
--- a/ui/terminal/smart_status.go
+++ b/ui/terminal/smart_status.go
@@ -59,21 +59,24 @@
// current build status similarly to Ninja's built-in terminal
// output.
func NewSmartStatusOutput(w io.Writer, formatter formatter) status.StatusOutput {
- tableHeight, _ := strconv.Atoi(os.Getenv(tableHeightEnVar))
-
s := &smartStatusOutput{
writer: w,
formatter: formatter,
haveBlankLine: true,
- tableMode: tableHeight > 0,
- requestedTableHeight: tableHeight,
+ tableMode: true,
done: make(chan bool),
sigwinch: make(chan os.Signal),
}
+ if env, ok := os.LookupEnv(tableHeightEnVar); ok {
+ h, _ := strconv.Atoi(env)
+ s.tableMode = h > 0
+ s.requestedTableHeight = h
+ }
+
s.updateTermSize()
if s.tableMode {
@@ -297,6 +300,14 @@
if s.tableMode {
tableHeight := s.requestedTableHeight
+ if tableHeight == 0 {
+ tableHeight = s.termHeight / 4
+ if tableHeight < 1 {
+ tableHeight = 1
+ } else if tableHeight > 10 {
+ tableHeight = 10
+ }
+ }
if tableHeight > s.termHeight-1 {
tableHeight = s.termHeight - 1
}