Merge changes I75b4a761,I779f28c6,If1422372,I26307dd1
* changes:
Introduce inject_bssl_hash library property.
BoringSSL FIPS build - introduce extraLibFlags and use for STL libs.
Allow linker scripts when building objects.
Allow .o files as srcs.
diff --git a/android/arch.go b/android/arch.go
index 44c3f48..907c58b 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -557,6 +557,10 @@
return archType
}
+func ArchTypeList() []ArchType {
+ return append([]ArchType(nil), archTypeList...)
+}
+
func (a ArchType) String() string {
return a.Name
}
diff --git a/android/config.go b/android/config.go
index 72372ef..cb1bdf5 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1077,7 +1077,7 @@
}
func (c *config) FlattenApex() bool {
- return Bool(c.productVariables.FlattenApex)
+ return Bool(c.productVariables.Flatten_apex)
}
func (c *config) EnforceSystemCertificate() bool {
diff --git a/android/paths.go b/android/paths.go
index 1505292..0d64a61 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1000,7 +1000,7 @@
// PathForVndkRefAbiDump returns an OptionalPath representing the path of the
// reference abi dump for the given module. This is not guaranteed to be valid.
func PathForVndkRefAbiDump(ctx ModuleContext, version, fileName string,
- isLlndkOrNdk, isVndk, isGzip bool) OptionalPath {
+ isNdk, isLlndkOrVndk, isGzip bool) OptionalPath {
arches := ctx.DeviceConfig().Arches()
if len(arches) == 0 {
@@ -1013,9 +1013,9 @@
}
var dirName string
- if isLlndkOrNdk {
+ if isNdk {
dirName = "ndk"
- } else if isVndk {
+ } else if isLlndkOrVndk {
dirName = "vndk"
} else {
dirName = "platform" // opt-in libs
diff --git a/android/variable.go b/android/variable.go
index 8886bae..0931db8 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -277,7 +277,7 @@
Ndk_abis *bool `json:",omitempty"`
Exclude_draft_ndk_apis *bool `json:",omitempty"`
- FlattenApex *bool `json:",omitempty"`
+ Flatten_apex *bool `json:",omitempty"`
DexpreoptGlobalConfig *string `json:",omitempty"`
diff --git a/androidmk/cmd/androidmk/android.go b/androidmk/cmd/androidmk/android.go
index 2def179..fcadd03 100644
--- a/androidmk/cmd/androidmk/android.go
+++ b/androidmk/cmd/androidmk/android.go
@@ -173,6 +173,8 @@
// Jacoco filters:
"LOCAL_JACK_COVERAGE_INCLUDE_FILTER": "jacoco.include_filter",
"LOCAL_JACK_COVERAGE_EXCLUDE_FILTER": "jacoco.exclude_filter",
+
+ "LOCAL_FULL_LIBS_MANIFEST_FILES": "additional_manifests",
})
addStandardProperties(bpparser.BoolType,
diff --git a/apex/apex.go b/apex/apex.go
index 58f700b..fdb1cfc 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -293,6 +293,10 @@
// List of sanitizer names that this APEX is enabled for
SanitizerNames []string `blueprint:"mutated"`
+ PreventInstall bool `blueprint:"mutated"`
+
+ HideFromMake bool `blueprint:"mutated"`
+
// Indicates this APEX provides C++ shared libaries to other APEXes. Default: false.
Provide_cpp_shared_libs *bool
@@ -631,7 +635,7 @@
}
func (a *apexBundle) installable() bool {
- return a.properties.Installable == nil || proptools.Bool(a.properties.Installable)
+ return !a.properties.PreventInstall && (a.properties.Installable == nil || proptools.Bool(a.properties.Installable))
}
func (a *apexBundle) getImageVariation(config android.DeviceConfig) string {
@@ -666,6 +670,18 @@
return android.InList(sanitizerName, globalSanitizerNames)
}
+func (a *apexBundle) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+ return ctx.Device() && ctx.DeviceConfig().NativeCoverageEnabled()
+}
+
+func (a *apexBundle) PreventInstall() {
+ a.properties.PreventInstall = true
+}
+
+func (a *apexBundle) HideFromMake() {
+ a.properties.HideFromMake = true
+}
+
func getCopyManifestForNativeLibrary(cc *cc.Module, handleSpecialLibs bool) (fileToCopy android.Path, dirInApex string) {
// Decide the APEX-local directory by the multilib of the library
// In the future, we may query this to the module.
@@ -916,7 +932,7 @@
}
} else {
// indirect dependencies
- if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() && am.IsInstallableToApex() {
+ if am, ok := child.(android.ApexModule); ok {
// 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) {
@@ -956,7 +972,7 @@
filesInfo = append(filesInfo, apexFile{fileToCopy, moduleName, dirInApex, nativeTest, cc, nil})
return true
}
- } else {
+ } else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
}
}
@@ -1277,6 +1293,11 @@
}
func (a *apexBundle) AndroidMk() android.AndroidMkData {
+ if a.properties.HideFromMake {
+ return android.AndroidMkData{
+ Disabled: true,
+ }
+ }
writers := []android.AndroidMkData{}
if a.apexTypes.image() {
writers = append(writers, a.androidMkForType(imageApex))
@@ -1371,6 +1392,9 @@
fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", cc.UnstrippedOutputFile().String())
}
cc.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
+ if cc.CoverageOutputFile().Valid() {
+ fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", cc.CoverageOutputFile().String())
+ }
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
} else {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e06c193..82c5909 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -714,6 +714,58 @@
}
+func TestApexDependencyToLLNDK(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ use_vendor: true,
+ native_shared_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ shared_libs: ["libbar"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libbar",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+
+ llndk_library {
+ name: "libbar",
+ symbol_file: "",
+ }
+
+ `)
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that LLNDK dep is not included
+ ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
+
+ injectRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("injectApexDependency")
+ ensureListEmpty(t, names(injectRule.Args["provideNativeLibs"]))
+
+ // Ensure that LLNDK dep is required
+ ensureListContains(t, names(injectRule.Args["requireNativeLibs"]), "libbar.so")
+
+}
+
func TestApexWithSystemLibsStubs(t *testing.T) {
ctx, _ := testApex(t, `
apex {
diff --git a/build_kzip.bash b/build_kzip.bash
new file mode 100755
index 0000000..5364e7f
--- /dev/null
+++ b/build_kzip.bash
@@ -0,0 +1,25 @@
+# /bin/bash -uv
+#
+# Build kzip files (source files for the indexing pipeline) for the given configuration,
+# merge them and place the resulting all.kzip into $DIST_DIR.
+# It is assumed that the current directory is the top of the source tree.
+# The following enviromnet variables affect the result:
+# TARGET_PRODUCT target device name, e.g., `aosp_blueline`
+# TARGET_BUILD_VARIANT variant, e.g., `userdebug`
+# OUT_DIR where the build is happening (./out if not specified)
+# DIST_DIR where the resulting all.kzip will be placed
+# XREF_CORPUS source code repository URI, e.g.,
+# `android.googlesource.com/platform/superproject`
+
+# The extraction might fail for some source files, so run with -k
+build/soong/soong_ui.bash --build-mode --all-modules --dir=$PWD -k merge_zips xref_cxx xref_java
+
+# We build with -k, so check that we have generated at least 100K files
+# (the actual number is 180K+)
+declare -r kzip_count=$(find $OUT_DIR -name '*.kzip' | wc -l)
+(($kzip_count>100000)) || { printf "Too few kzip files were generated: %d\n" $kzip_count; exit 1; }
+
+# Pack
+# TODO(asmundak): this should be done by soong.
+declare -r allkzip=all.kzip
+"${OUT_DIR:-out}/soong/host/linux-x86/bin/merge_zips" "$DIST_DIR/$allkzip" @<(find $OUT_DIR -name '*.kzip')
diff --git a/cc/binary.go b/cc/binary.go
index 149a92e..fd00060 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -425,6 +425,10 @@
return true
}
+func (binary *binaryDecorator) coverageOutputFilePath() android.OptionalPath {
+ return binary.coverageOutputFile
+}
+
// /system/bin/linker -> /apex/com.android.runtime/bin/linker
func (binary *binaryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
dir := binary.baseInstaller.installDir(ctx)
diff --git a/cc/builder.go b/cc/builder.go
index 0c5692a..00dc742 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -648,9 +648,6 @@
excludedSymbolVersions, excludedSymbolTags []string) android.OptionalPath {
outputFile := android.PathForModuleOut(ctx, baseName+".lsdump")
- sabiLock.Lock()
- lsdumpPaths = append(lsdumpPaths, outputFile.String())
- sabiLock.Unlock()
implicits := android.Paths{soFile}
symbolFilterStr := "-so " + soFile.String()
diff --git a/cc/cc.go b/cc/cc.go
index 457bb8d..0245c6a 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -320,6 +320,7 @@
unstrippedOutputFilePath() android.Path
nativeCoverage() bool
+ coverageOutputFilePath() android.OptionalPath
}
type installer interface {
@@ -454,6 +455,13 @@
return nil
}
+func (c *Module) CoverageOutputFile() android.OptionalPath {
+ if c.linker != nil {
+ return c.linker.coverageOutputFilePath()
+ }
+ return android.OptionalPath{}
+}
+
func (c *Module) RelativeInstallPath() string {
if c.installer != nil {
return c.installer.relativeInstallPath()
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 99a88e9..52234a8 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -1941,13 +1941,13 @@
// Check the shared version of lib2.
variant := "android_arm64_armv8-a_core_shared"
module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
- checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
+ checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
// Check the static version of lib2.
variant = "android_arm64_armv8-a_core_static"
module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
// libc++_static is linked additionally.
- checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
+ checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
}
var compilerFlagsTestCases = []struct {
diff --git a/cc/config/global.go b/cc/config/global.go
index 9ce6896..2150abf 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -122,8 +122,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r353983d"
- ClangDefaultShortVersion = "9.0.4"
+ ClangDefaultVersion = "clang-r365631"
+ ClangDefaultShortVersion = "9.0.6"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/coverage.go b/cc/coverage.go
index 0de0c1c..2e81a9e 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -140,7 +140,6 @@
} else {
// Check if Native_coverage is set to false. This property defaults to true.
needCoverageVariant = BoolDefault(cov.Properties.Native_coverage, true)
-
if sdk_version := ctx.sdkVersion(); ctx.useSdk() && sdk_version != "current" {
// Native coverage is not supported for SDK versions < 23
if fromApi, err := strconv.Atoi(sdk_version); err == nil && fromApi < 23 {
@@ -158,6 +157,14 @@
cov.Properties.NeedCoverageVariant = needCoverageVariant
}
+// Coverage is an interface for non-CC modules to implement to be mutated for coverage
+type Coverage interface {
+ android.Module
+ IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool
+ PreventInstall()
+ HideFromMake()
+}
+
func coverageMutator(mctx android.BottomUpMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
needCoverageVariant := c.coverage.Properties.NeedCoverageVariant
@@ -177,5 +184,14 @@
m[1].(*Module).coverage.Properties.CoverageEnabled = needCoverageBuild
m[1].(*Module).coverage.Properties.IsCoverageVariant = true
}
+ } else if cov, ok := mctx.Module().(Coverage); ok && cov.IsNativeCoverageNeeded(mctx) {
+ // APEX modules fall here
+
+ // Note: variant "" is also created because an APEX can be depended on by another
+ // module which are split into "" and "cov" variants. e.g. when cc_test refers
+ // to an APEX via 'data' property.
+ m := mctx.CreateVariations("", "cov")
+ m[0].(Coverage).PreventInstall()
+ m[0].(Coverage).HideFromMake()
}
}
diff --git a/cc/library.go b/cc/library.go
index 4c2993c..2496712 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -435,25 +435,46 @@
return flags
}
+// Returns a string that represents the class of the ABI dump.
+// Returns an empty string if ABI check is disabled for this library.
+func (library *libraryDecorator) classifySourceAbiDump(ctx ModuleContext) string {
+ enabled := library.Properties.Header_abi_checker.Enabled
+ if enabled != nil && !Bool(enabled) {
+ return ""
+ }
+ // Return NDK if the library is both NDK and LLNDK.
+ if ctx.isNdk() {
+ return "NDK"
+ }
+ if ctx.isLlndkPublic(ctx.Config()) {
+ return "LLNDK"
+ }
+ if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) {
+ if ctx.isVndkSp() {
+ if ctx.isVndkExt() {
+ return "VNDK-SP-ext"
+ } else {
+ return "VNDK-SP"
+ }
+ } else {
+ if ctx.isVndkExt() {
+ return "VNDK-ext"
+ } else {
+ return "VNDK-core"
+ }
+ }
+ }
+ if enabled != nil && Bool(enabled) {
+ return "PLATFORM"
+ }
+ return ""
+}
+
func (library *libraryDecorator) shouldCreateSourceAbiDump(ctx ModuleContext) bool {
if !ctx.shouldCreateSourceAbiDump() {
return false
}
- if library.Properties.Header_abi_checker.Enabled != nil {
- return Bool(library.Properties.Header_abi_checker.Enabled)
- }
- if ctx.isNdk() {
- return true
- }
- if ctx.isLlndkPublic(ctx.Config()) {
- return true
- }
- if ctx.useVndk() && ctx.isVndk() && !ctx.isVndkPrivate(ctx.Config()) {
- // Return true if this is VNDK-core, VNDK-SP, or VNDK-Ext, and not
- // VNDK-private.
- return true
- }
- return false
+ return library.classifySourceAbiDump(ctx) != ""
}
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) Objects {
@@ -830,11 +851,16 @@
return true
}
-func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
- isLlndkOrNdk := inList(ctx.baseModuleName(), *llndkLibraries(ctx.Config())) || inList(ctx.baseModuleName(), ndkMigratedLibs)
+func (library *libraryDecorator) coverageOutputFilePath() android.OptionalPath {
+ return library.coverageOutputFile
+}
- refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isLlndkOrNdk, ctx.isVndk(), false)
- refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isLlndkOrNdk, ctx.isVndk(), true)
+func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
+ isNdk := ctx.isNdk()
+ isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || ctx.isVndk()
+
+ refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false)
+ refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true)
if refAbiDumpTextFile.Valid() {
if refAbiDumpGzipFile.Valid() {
@@ -872,6 +898,8 @@
library.Properties.Header_abi_checker.Exclude_symbol_versions,
library.Properties.Header_abi_checker.Exclude_symbol_tags)
+ addLsdumpPath(library.classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
+
refAbiDumpFile := getRefAbiDumpFile(ctx, vndkVersion, fileName)
if refAbiDumpFile != nil {
library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
diff --git a/cc/linker.go b/cc/linker.go
index 962fcce..563ad04 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -383,6 +383,10 @@
flags.LdFlags = append(flags.LdFlags, "-lfdio", "-lzircon")
}
+ if ctx.toolchain().LibclangRuntimeLibraryArch() != "" {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--exclude-libs="+config.BuiltinsRuntimeLibrary(ctx.toolchain())+".a")
+ }
+
CheckBadLinkerFlags(ctx, "ldflags", linker.Properties.Ldflags)
flags.LdFlags = append(flags.LdFlags, proptools.NinjaAndShellEscapeList(linker.Properties.Ldflags)...)
diff --git a/cc/object.go b/cc/object.go
index 33586a4..1a2711d 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -137,3 +137,7 @@
func (object *objectLinker) nativeCoverage() bool {
return true
}
+
+func (object *objectLinker) coverageOutputFilePath() android.OptionalPath {
+ return android.OptionalPath{}
+}
diff --git a/cc/sabi.go b/cc/sabi.go
index ae7b31d..0999151 100644
--- a/cc/sabi.go
+++ b/cc/sabi.go
@@ -94,3 +94,9 @@
})
}
}
+
+func addLsdumpPath(lsdumpPath string) {
+ sabiLock.Lock()
+ lsdumpPaths = append(lsdumpPaths, lsdumpPath)
+ sabiLock.Unlock()
+}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index a017824..192b8d9 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -31,14 +31,13 @@
// understand also need to be added to ClangLibToolingUnknownCflags in
// cc/config/clang.go
- asanCflags = []string{"-fno-omit-frame-pointer"}
+ asanCflags = []string{
+ "-fno-omit-frame-pointer",
+ "-fno-experimental-new-pass-manager",
+ }
asanLdflags = []string{"-Wl,-u,__asan_preinit"}
- // TODO(pcc): Stop passing -hwasan-allow-ifunc here once it has been made
- // the default.
hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=",
- "-mllvm", "-hwasan-create-frame-descriptions=0",
- "-mllvm", "-hwasan-allow-ifunc",
"-fsanitize-hwaddress-abi=platform",
"-fno-experimental-new-pass-manager"}
@@ -447,6 +446,7 @@
// libraries needed with -fsanitize=address. http://b/18650275 (WAI)
flags.LdFlags = append(flags.LdFlags, "-Wl,--no-as-needed")
} else {
+ flags.CFlags = append(flags.CFlags, "-mllvm", "-asan-globals=0")
if ctx.bootstrap() {
flags.DynamicLinker = "/system/bin/bootstrap/linker_asan"
} else {
diff --git a/cc/stl.go b/cc/stl.go
index bbfe6f8..5578299 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -161,6 +161,15 @@
} else {
deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl)
}
+ if ctx.Device() && !ctx.useSdk() {
+ // __cxa_demangle is not a part of libc++.so on the device since
+ // it's large and most processes don't need it. Statically link
+ // libc++demangle into every process so that users still have it if
+ // needed, but the linker won't include this unless it is actually
+ // called.
+ // http://b/138245375
+ deps.StaticLibs = append(deps.StaticLibs, "libc++demangle")
+ }
if ctx.toolchain().Bionic() {
if ctx.Arch().ArchType == android.Arm {
deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm")
diff --git a/cc/testing.go b/cc/testing.go
index a12b520..5a3993c 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -167,6 +167,16 @@
},
}
cc_library {
+ name: "libc++demangle",
+ no_libcrt: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ host_supported: false,
+ vendor_available: true,
+ recovery_available: true,
+ }
+ cc_library {
name: "libunwind_llvm",
no_libcrt: true,
nocrt: true,
diff --git a/java/aar.go b/java/aar.go
index ce3d126..a4e6f91 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -69,6 +69,9 @@
// path to AndroidManifest.xml. If unset, defaults to "AndroidManifest.xml".
Manifest *string `android:"path"`
+
+ // paths to additional manifest files to merge with main manifest.
+ Additional_manifests []string `android:"path"`
}
type aapt struct {
@@ -220,7 +223,11 @@
a.transitiveManifestPaths = append(android.Paths{manifestPath}, transitiveStaticLibManifests...)
if len(transitiveStaticLibManifests) > 0 {
- a.mergedManifestFile = manifestMerger(ctx, manifestPath, transitiveStaticLibManifests, a.isLibrary)
+ // Merge additional manifest files with app manifest.
+ additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests)
+ additionalManifests = append(additionalManifests, transitiveStaticLibManifests...)
+
+ a.mergedManifestFile = manifestMerger(ctx, manifestPath, additionalManifests, a.isLibrary)
if !a.isLibrary {
// Only use the merged manifest for applications. For libraries, the transitive closure of manifests
// will be propagated to the final application and merged there. The merged manifest for libraries is
diff --git a/java/androidmk.go b/java/androidmk.go
index ad0e171..c00e070 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -609,28 +609,23 @@
}
}
-func (app *AndroidAppImport) AndroidMk() android.AndroidMkData {
- return android.AndroidMkData{
+func (a *AndroidAppImport) AndroidMkEntries() android.AndroidMkEntries {
+ return android.AndroidMkEntries{
Class: "APPS",
- OutputFile: android.OptionalPathForPath(app.outputFile),
+ OutputFile: android.OptionalPathForPath(a.outputFile),
Include: "$(BUILD_SYSTEM)/soong_app_prebuilt.mk",
- Extra: []android.AndroidMkExtraFunc{
- func(w io.Writer, outputFile android.Path) {
- if Bool(app.properties.Privileged) {
- fmt.Fprintln(w, "LOCAL_PRIVILEGED_MODULE := true")
- }
- if app.certificate != nil {
- fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", app.certificate.Pem.String())
- } else {
- fmt.Fprintln(w, "LOCAL_CERTIFICATE := PRESIGNED")
- }
- if len(app.properties.Overrides) > 0 {
- fmt.Fprintln(w, "LOCAL_OVERRIDES_PACKAGES :=", strings.Join(app.properties.Overrides, " "))
- }
- if len(app.dexpreopter.builtInstalled) > 0 {
- fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", app.dexpreopter.builtInstalled)
- }
- },
+ AddCustomEntries: func(name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+ entries.SetBoolIfTrue("LOCAL_PRIVILEGED_MODULE", Bool(a.properties.Privileged))
+ if a.certificate != nil {
+ entries.SetString("LOCAL_CERTIFICATE", a.certificate.Pem.String())
+ } else {
+ entries.SetString("LOCAL_CERTIFICATE", "PRESIGNED")
+ }
+ entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", a.properties.Overrides...)
+ if len(a.dexpreopter.builtInstalled) > 0 {
+ entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", a.dexpreopter.builtInstalled)
+ }
+ entries.AddStrings("LOCAL_INSTALLED_MODULE_STEM", a.installPath.Rel())
},
}
}
diff --git a/java/app.go b/java/app.go
index 674e5ec..31f07d3 100644
--- a/java/app.go
+++ b/java/app.go
@@ -39,6 +39,8 @@
android.RegisterModuleType("android_app_certificate", AndroidAppCertificateFactory)
android.RegisterModuleType("override_android_app", OverrideAndroidAppModuleFactory)
android.RegisterModuleType("android_app_import", AndroidAppImportFactory)
+
+ initAndroidAppImportVariantGroupTypes()
}
// AndroidManifest.xml merging
@@ -731,8 +733,9 @@
android.DefaultableModuleBase
prebuilt android.Prebuilt
- properties AndroidAppImportProperties
- dpiVariants interface{}
+ properties AndroidAppImportProperties
+ dpiVariants interface{}
+ archVariants interface{}
outputFile android.Path
certificate *Certificate
@@ -740,6 +743,8 @@
dexpreopter
usesLibrary usesLibrary
+
+ installPath android.OutputPath
}
type AndroidAppImportProperties struct {
@@ -765,10 +770,13 @@
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
// from PRODUCT_PACKAGES.
Overrides []string
+
+ // Optional name for the installed app. If unspecified, it is derived from the module name.
+ Filename *string
}
-// Chooses a source APK path to use based on the module and product specs.
-func (a *AndroidAppImport) updateSrcApkPath(ctx android.LoadHookContext) {
+// Updates properties with variant-specific values.
+func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
config := ctx.Config()
dpiProps := reflect.ValueOf(a.dpiVariants).Elem().FieldByName("Dpi_variants")
@@ -776,24 +784,22 @@
// overwrites everything else.
// TODO(jungjw): Can we optimize this by making it priority order?
for i := len(config.ProductAAPTPrebuiltDPI()) - 1; i >= 0; i-- {
- dpi := config.ProductAAPTPrebuiltDPI()[i]
- if inList(dpi, supportedDpis) {
- MergePropertiesFromVariant(ctx, &a.properties, dpiProps, dpi, "dpi_variants")
- }
+ MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPrebuiltDPI()[i])
}
if config.ProductAAPTPreferredConfig() != "" {
- dpi := config.ProductAAPTPreferredConfig()
- if inList(dpi, supportedDpis) {
- MergePropertiesFromVariant(ctx, &a.properties, dpiProps, dpi, "dpi_variants")
- }
+ MergePropertiesFromVariant(ctx, &a.properties, dpiProps, config.ProductAAPTPreferredConfig())
}
+
+ archProps := reflect.ValueOf(a.archVariants).Elem().FieldByName("Arch")
+ archType := ctx.Config().Targets[android.Android][0].Arch.ArchType
+ MergePropertiesFromVariant(ctx, &a.properties, archProps, archType.Name)
}
func MergePropertiesFromVariant(ctx android.BaseModuleContext,
- dst interface{}, variantGroup reflect.Value, variant, variantGroupPath string) {
+ dst interface{}, variantGroup reflect.Value, variant string) {
src := variantGroup.FieldByName(proptools.FieldNameForProperty(variant))
if !src.IsValid() {
- ctx.ModuleErrorf("field %q does not exist", variantGroupPath+"."+variant)
+ return
}
err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, proptools.OrderAppend)
@@ -917,7 +923,8 @@
// TODO: Optionally compress the output apk.
- ctx.InstallFile(installDir, a.BaseModuleName()+".apk", a.outputFile)
+ a.installPath = ctx.InstallFile(installDir,
+ proptools.StringDefault(a.properties.Filename, a.BaseModuleName()+".apk"), a.outputFile)
// TODO: androidmk converter jni libs
}
@@ -930,26 +937,46 @@
return a.prebuilt.Name(a.ModuleBase.Name())
}
-// Populates dpi_variants property and its fields at creation time.
-func (a *AndroidAppImport) addDpiVariants() {
- // TODO(jungjw): Do we want to do some filtering here?
- props := reflect.ValueOf(&a.properties).Type()
+var dpiVariantGroupType reflect.Type
+var archVariantGroupType reflect.Type
- dpiFields := make([]reflect.StructField, len(supportedDpis))
- for i, dpi := range supportedDpis {
- dpiFields[i] = reflect.StructField{
- Name: proptools.FieldNameForProperty(dpi),
+func initAndroidAppImportVariantGroupTypes() {
+ dpiVariantGroupType = createVariantGroupType(supportedDpis, "Dpi_variants")
+
+ archNames := make([]string, len(android.ArchTypeList()))
+ for i, archType := range android.ArchTypeList() {
+ archNames[i] = archType.Name
+ }
+ archVariantGroupType = createVariantGroupType(archNames, "Arch")
+}
+
+// Populates all variant struct properties at creation time.
+func (a *AndroidAppImport) populateAllVariantStructs() {
+ a.dpiVariants = reflect.New(dpiVariantGroupType).Interface()
+ a.AddProperties(a.dpiVariants)
+
+ a.archVariants = reflect.New(archVariantGroupType).Interface()
+ a.AddProperties(a.archVariants)
+}
+
+func createVariantGroupType(variants []string, variantGroupName string) reflect.Type {
+ props := reflect.TypeOf((*AndroidAppImportProperties)(nil))
+
+ variantFields := make([]reflect.StructField, len(variants))
+ for i, variant := range variants {
+ variantFields[i] = reflect.StructField{
+ Name: proptools.FieldNameForProperty(variant),
Type: props,
}
}
- dpiStruct := reflect.StructOf(dpiFields)
- a.dpiVariants = reflect.New(reflect.StructOf([]reflect.StructField{
+
+ variantGroupStruct := reflect.StructOf(variantFields)
+ return reflect.StructOf([]reflect.StructField{
{
- Name: "Dpi_variants",
- Type: dpiStruct,
+ Name: variantGroupName,
+ Type: variantGroupStruct,
},
- })).Interface()
- a.AddProperties(a.dpiVariants)
+ })
}
// android_app_import imports a prebuilt apk with additional processing specified in the module.
@@ -973,9 +1000,9 @@
module.AddProperties(&module.properties)
module.AddProperties(&module.dexpreoptProperties)
module.AddProperties(&module.usesLibrary.usesLibraryProperties)
- module.addDpiVariants()
+ module.populateAllVariantStructs()
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
- module.updateSrcApkPath(ctx)
+ module.processVariants(ctx)
})
InitJavaModule(module, android.DeviceSupported)
diff --git a/java/app_test.go b/java/app_test.go
index f6a307e..564211c 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1242,6 +1242,116 @@
}
}
+func TestAndroidAppImport_Filename(t *testing.T) {
+ ctx, config := testJava(t, `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ }
+
+ android_app_import {
+ name: "bar",
+ apk: "prebuilts/apk/app.apk",
+ presigned: true,
+ filename: "bar_sample.apk"
+ }
+ `)
+
+ testCases := []struct {
+ name string
+ expected string
+ }{
+ {
+ name: "foo",
+ expected: "foo.apk",
+ },
+ {
+ name: "bar",
+ expected: "bar_sample.apk",
+ },
+ }
+
+ for _, test := range testCases {
+ variant := ctx.ModuleForTests(test.name, "android_common")
+ if variant.MaybeOutput(test.expected).Rule == nil {
+ t.Errorf("can't find output named %q - all outputs: %v", test.expected, variant.AllOutputs())
+ }
+
+ a := variant.Module().(*AndroidAppImport)
+ expectedValues := []string{test.expected}
+ actualValues := android.AndroidMkEntriesForTest(
+ t, config, "", a).EntryMap["LOCAL_INSTALLED_MODULE_STEM"]
+ if !reflect.DeepEqual(actualValues, expectedValues) {
+ t.Errorf("Incorrect LOCAL_INSTALLED_MODULE_STEM value '%s', expected '%s'",
+ actualValues, expectedValues)
+ }
+ }
+}
+
+func TestAndroidAppImport_ArchVariants(t *testing.T) {
+ // The test config's target arch is ARM64.
+ testCases := []struct {
+ name string
+ bp string
+ expected string
+ }{
+ {
+ name: "matching arch",
+ bp: `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ arch: {
+ arm64: {
+ apk: "prebuilts/apk/app_arm64.apk",
+ },
+ },
+ certificate: "PRESIGNED",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `,
+ expected: "prebuilts/apk/app_arm64.apk",
+ },
+ {
+ name: "no matching arch",
+ bp: `
+ android_app_import {
+ name: "foo",
+ apk: "prebuilts/apk/app.apk",
+ arch: {
+ arm: {
+ apk: "prebuilts/apk/app_arm.apk",
+ },
+ },
+ certificate: "PRESIGNED",
+ dex_preopt: {
+ enabled: true,
+ },
+ }
+ `,
+ expected: "prebuilts/apk/app.apk",
+ },
+ }
+
+ jniRuleRe := regexp.MustCompile("^if \\(zipinfo (\\S+)")
+ for _, test := range testCases {
+ ctx, _ := testJava(t, test.bp)
+
+ variant := ctx.ModuleForTests("foo", "android_common")
+ jniRuleCommand := variant.Output("jnis-uncompressed/foo.apk").RuleParams.Command
+ matches := jniRuleRe.FindStringSubmatch(jniRuleCommand)
+ if len(matches) != 2 {
+ t.Errorf("failed to extract the src apk path from %q", jniRuleCommand)
+ }
+ if test.expected != matches[1] {
+ t.Errorf("wrong src apk, expected: %q got: %q", test.expected, matches[1])
+ }
+ }
+}
+
func TestStl(t *testing.T) {
ctx, _ := testJava(t, cc.GatherRequiredDepsForTest(android.Android)+`
cc_library {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 78bfa80..9956270 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -111,6 +111,9 @@
// :module syntax).
Removed_api_file *string `android:"path"`
+ // If not blank, path to the baseline txt file for approved API check violations.
+ Baseline_file *string `android:"path"`
+
// Arguments to the apicheck tool.
Args *string
}
@@ -1506,6 +1509,8 @@
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Current.Removed_api_file))
+ baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Current.Baseline_file)
+ updatedBaselineOutput := android.PathForModuleOut(ctx, "current_baseline.txt")
d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
@@ -1526,6 +1531,11 @@
d.inclusionAnnotationsFlags(ctx, cmd)
d.mergeAnnoDirFlags(ctx, cmd)
+ if baselineFile.Valid() {
+ cmd.FlagWithInput("--baseline ", baselineFile.Path())
+ cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
+ }
+
zipSyncCleanupCmd(rule, srcJarDir)
msg := fmt.Sprintf(`\n******************************\n`+
@@ -1584,6 +1594,8 @@
apiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Api_file))
removedApiFile := android.PathForModuleSrc(ctx, String(d.properties.Check_api.Last_released.Removed_api_file))
+ baselineFile := android.OptionalPathForModuleSrc(ctx, d.properties.Check_api.Last_released.Baseline_file)
+ updatedBaselineOutput := android.PathForModuleOut(ctx, "last_released_baseline.txt")
d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
@@ -1606,6 +1618,11 @@
d.mergeAnnoDirFlags(ctx, cmd)
+ if baselineFile.Valid() {
+ cmd.FlagWithInput("--baseline ", baselineFile.Path())
+ cmd.FlagWithOutput("--update-baseline ", updatedBaselineOutput)
+ }
+
zipSyncCleanupCmd(rule, srcJarDir)
msg := `\n******************************\n` +
diff --git a/java/java.go b/java/java.go
index 3b789f6..afb1218 100644
--- a/java/java.go
+++ b/java/java.go
@@ -205,8 +205,9 @@
// Defaults to sdk_version if not set.
Target_sdk_version *string
- // It must be true only if sdk_version is empty.
- // This field works in only android_app, otherwise nothing happens.
+ // Whether to compile against the platform APIs instead of an SDK.
+ // If true, then sdk_version must be empty. The value of this field
+ // is ignored when module's type isn't android_app.
Platform_apis *bool
Aidl struct {
diff --git a/java/java_test.go b/java/java_test.go
index 81d1f2c..5fcdf96 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -171,6 +171,8 @@
"prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["14", "28", "current"],}`),
"prebuilts/apk/app.apk": nil,
+ "prebuilts/apk/app_arm.apk": nil,
+ "prebuilts/apk/app_arm64.apk": nil,
"prebuilts/apk/app_xhdpi.apk": nil,
"prebuilts/apk/app_xxhdpi.apk": nil,
diff --git a/java/proto.go b/java/proto.go
index 0ec6499..22a3eed 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -75,9 +75,11 @@
flags.proto = android.GetProtoFlags(ctx, p)
if String(p.Proto.Plugin) == "" {
+ var typeToPlugin string
switch String(p.Proto.Type) {
case "micro":
flags.proto.OutTypeFlag = "--javamicro_out"
+ typeToPlugin = "javamicro"
case "nano":
flags.proto.OutTypeFlag = "--javanano_out"
case "lite":
@@ -89,6 +91,12 @@
ctx.PropertyErrorf("proto.type", "unknown proto type %q",
String(p.Proto.Type))
}
+
+ if typeToPlugin != "" {
+ hostTool := ctx.Config().HostToolPath(ctx, "protoc-gen-"+typeToPlugin)
+ flags.proto.Deps = append(flags.proto.Deps, hostTool)
+ flags.proto.Flags = append(flags.proto.Flags, "--plugin=protoc-gen-"+typeToPlugin+"="+hostTool.String())
+ }
}
flags.proto.OutParams = append(flags.proto.OutParams, j.Proto.Output_params...)
diff --git a/ui/build/config.go b/ui/build/config.go
index 434047b..665d2f0 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -180,6 +180,11 @@
ret.environ.Set("TMPDIR", absPath(ctx, ret.TempDir()))
+ // Always set ASAN_SYMBOLIZER_PATH so that ASAN-based tools can symbolize any crashes
+ symbolizerPath := filepath.Join("prebuilts/clang/host", ret.HostPrebuiltTag(),
+ "llvm-binutils-stable/llvm-symbolizer")
+ ret.environ.Set("ASAN_SYMBOLIZER_PATH", absPath(ctx, symbolizerPath))
+
// Precondition: the current directory is the top of the source tree
checkTopDir(ctx)
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 9ddbbea..a7799ea 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -171,6 +171,7 @@
"TMPDIR",
// Tool configs
+ "ASAN_SYMBOLIZER_PATH",
"JAVA_HOME",
"PYTHONDONTWRITEBYTECODE",