Merge "Switch to clang-r365631"
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/module.go b/android/module.go
index 990a893..0ab9be7 100644
--- a/android/module.go
+++ b/android/module.go
@@ -71,6 +71,7 @@
OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
OtherModuleExists(name string) bool
+ OtherModuleType(m blueprint.Module) string
GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
diff --git a/android/paths.go b/android/paths.go
index 0d99918..5110617 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -996,7 +996,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 {
@@ -1009,9 +1009,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 e4fad83..574604b 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.
@@ -740,6 +756,18 @@
return
}
+func getCopyManifestForPrebuiltJavaLibrary(java *java.Import) (fileToCopy android.Path, dirInApex string) {
+ dirInApex = "javalib"
+ // The output is only one, but for some reason, ImplementationJars returns Paths, not Path
+ implJars := java.ImplementationJars()
+ if len(implJars) != 1 {
+ panic(fmt.Errorf("java.ImplementationJars() must return single Path, but got: %s",
+ strings.Join(implJars.Strings(), ", ")))
+ }
+ fileToCopy = implJars[0]
+ return
+}
+
func getCopyManifestForPrebuiltEtc(prebuilt *android.PrebuiltEtc) (fileToCopy android.Path, dirInApex string) {
dirInApex = filepath.Join("etc", prebuilt.SubDir())
fileToCopy = prebuilt.OutputFile()
@@ -833,16 +861,24 @@
ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
- if java, ok := child.(*java.Library); ok {
- fileToCopy, dirInApex := getCopyManifestForJavaLibrary(java)
+ if javaLib, ok := child.(*java.Library); ok {
+ fileToCopy, dirInApex := getCopyManifestForJavaLibrary(javaLib)
if fileToCopy == nil {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
} else {
- filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, javaSharedLib, java, nil})
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, javaSharedLib, javaLib, nil})
+ }
+ return true
+ } else if javaLib, ok := child.(*java.Import); ok {
+ fileToCopy, dirInApex := getCopyManifestForPrebuiltJavaLibrary(javaLib)
+ if fileToCopy == nil {
+ ctx.PropertyErrorf("java_libs", "%q does not have a jar output", depName)
+ } else {
+ filesInfo = append(filesInfo, apexFile{fileToCopy, depName, dirInApex, javaSharedLib, javaLib, nil})
}
return true
} else {
- ctx.PropertyErrorf("java_libs", "%q is not a java_library module", depName)
+ ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
case prebuiltTag:
if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
@@ -1257,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))
@@ -1351,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 f034f2a..e06c193 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -102,6 +102,7 @@
ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory))
ctx.RegisterModuleType("filegroup", android.ModuleFactoryAdaptor(android.FileGroupFactory))
ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
+ ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("prebuilts", android.PrebuiltMutator).Parallel()
@@ -218,6 +219,7 @@
"myprebuilt": nil,
"my_include": nil,
"foo/bar/MyClass.java": nil,
+ "prebuilt.jar": nil,
"vendor/foo/devkeys/test.x509.pem": nil,
"vendor/foo/devkeys/test.pk8": nil,
"testkey.x509.pem": nil,
@@ -301,7 +303,7 @@
binaries: ["foo",],
}
},
- java_libs: ["myjar"],
+ java_libs: ["myjar", "myprebuiltjar"],
}
apex {
@@ -376,6 +378,12 @@
system_modules: "none",
compile_dex: true,
}
+
+ java_import {
+ name: "myprebuiltjar",
+ jars: ["prebuilt.jar"],
+ installable: true,
+ }
`)
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
@@ -393,6 +401,7 @@
// Ensure that apex variant is created for the direct dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_core_shared_myapex")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myprebuiltjar"), "android_common_myapex")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared_myapex")
@@ -402,6 +411,7 @@
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar.jar")
+ ensureContains(t, copyCmds, "image.apex/javalib/myprebuiltjar.jar")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
@@ -410,6 +420,7 @@
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_core_shared")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common")
ensureListContains(t, ctx.ModuleVariantsForTests("myotherjar"), "android_common")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myprebuiltjar"), "android_common")
// Ensure that all symlinks are present.
found_foo_link_64 := false
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 89c418b..3d89770 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -643,9 +643,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 b637d3e..c853e67 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -330,6 +330,7 @@
unstrippedOutputFilePath() android.Path
nativeCoverage() bool
+ coverageOutputFilePath() android.OptionalPath
}
type installer interface {
@@ -464,6 +465,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 c619b5a..c4799e9 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/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 893fc66..0869727 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -432,25 +432,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 {
@@ -815,11 +836,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() {
@@ -857,6 +883,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 9fa0ac9..15272eb 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -119,3 +119,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 80f5f95..192b8d9 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -31,7 +31,10 @@
// 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"}
hwasanCflags = []string{"-fno-omit-frame-pointer", "-Wno-frame-larger-than=",
@@ -443,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 1a5dd79..d7feb6f 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 f0ad33b..e69b774 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/genrule/genrule.go b/genrule/genrule.go
index 411da05..cf0b484 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -40,6 +40,7 @@
)
func init() {
+ pctx.Import("android/soong/android")
pctx.HostBinToolVariable("sboxCmd", "sbox")
}
@@ -425,7 +426,24 @@
for _, outputFile := range task.out {
g.outputFiles = append(g.outputFiles, outputFile)
}
- g.outputDeps = append(g.outputDeps, task.out[0])
+
+ // For <= 6 outputs, just embed those directly in the users. Right now, that covers >90% of
+ // the genrules on AOSP. That will make things simpler to look at the graph in the common
+ // case. For larger sets of outputs, inject a phony target in between to limit ninja file
+ // growth.
+ if len(task.out) <= 6 {
+ g.outputDeps = g.outputFiles
+ } else {
+ phonyFile := android.PathForModuleGen(ctx, "genrule-phony")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Phony,
+ Output: phonyFile,
+ Inputs: g.outputFiles,
+ })
+
+ g.outputDeps = android.Paths{phonyFile}
+ }
}
// Collect information for opening IDE project files in java/jdeps.go.
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",