Merge changes from topic "soong_build_number_file"
* changes:
Add an order-only dependency on the build number file
Add support for order-only dependencies to RuleBuilder
diff --git a/Android.bp b/Android.bp
index 2a4653a..0621475 100644
--- a/Android.bp
+++ b/Android.bp
@@ -207,6 +207,7 @@
"cc/binary_sdk_member.go",
"cc/fuzz.go",
"cc/library.go",
+ "cc/library_headers.go",
"cc/library_sdk_member.go",
"cc/object.go",
"cc/test.go",
@@ -232,6 +233,7 @@
"cc/compiler_test.go",
"cc/gen_test.go",
"cc/genrule_test.go",
+ "cc/library_headers_test.go",
"cc/library_test.go",
"cc/object_test.go",
"cc/prebuilt_test.go",
@@ -534,6 +536,7 @@
"sdk/update.go",
],
testSrcs: [
+ "sdk/bp_test.go",
"sdk/cc_sdk_test.go",
"sdk/exports_test.go",
"sdk/java_sdk_test.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index dbf3aa8..a8153cc 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -236,8 +236,8 @@
}
}
- if amod.noticeFile.Valid() {
- a.SetString("LOCAL_NOTICE_FILE", amod.noticeFile.String())
+ if len(amod.noticeFiles) > 0 {
+ a.SetString("LOCAL_NOTICE_FILE", strings.Join(amod.noticeFiles.Strings(), " "))
}
if host {
diff --git a/android/module.go b/android/module.go
index fd3fec3..1026bdf 100644
--- a/android/module.go
+++ b/android/module.go
@@ -172,6 +172,7 @@
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
+ InstallForceOS() *OsType
RequiredModuleNames() []string
HostRequiredModuleNames() []string
@@ -214,11 +215,12 @@
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
+ InstallForceOS() *OsType
SkipInstall()
ExportedToMake() bool
InitRc() Paths
VintfFragments() Paths
- NoticeFile() OptionalPath
+ NoticeFiles() Paths
AddProperties(props ...interface{})
GetProperties() []interface{}
@@ -242,6 +244,8 @@
RequiredModuleNames() []string
HostRequiredModuleNames() []string
TargetRequiredModuleNames() []string
+
+ filesToInstall() InstallPaths
}
// Qualified id for a module
@@ -643,9 +647,9 @@
primaryVisibilityProperty visibilityProperty
noAddressSanitizer bool
- installFiles Paths
+ installFiles InstallPaths
checkbuildFiles Paths
- noticeFile OptionalPath
+ noticeFiles Paths
// Used by buildTargetSingleton to create checkbuild and per-directory build targets
// Only set on the final variant of each module
@@ -849,22 +853,20 @@
return m.commonProperties.NamespaceExportedToMake
}
-func (m *ModuleBase) computeInstallDeps(
- ctx blueprint.ModuleContext) Paths {
+func (m *ModuleBase) computeInstallDeps(ctx blueprint.ModuleContext) InstallPaths {
- result := Paths{}
+ var result InstallPaths
// TODO(ccross): we need to use WalkDeps and have some way to know which dependencies require installation
- ctx.VisitDepsDepthFirstIf(isFileInstaller,
- func(m blueprint.Module) {
- fileInstaller := m.(fileInstaller)
- files := fileInstaller.filesToInstall()
- result = append(result, files...)
- })
+ ctx.VisitDepsDepthFirst(func(m blueprint.Module) {
+ if a, ok := m.(Module); ok {
+ result = append(result, a.filesToInstall()...)
+ }
+ })
return result
}
-func (m *ModuleBase) filesToInstall() Paths {
+func (m *ModuleBase) filesToInstall() InstallPaths {
return m.installFiles
}
@@ -900,12 +902,16 @@
return false
}
+func (m *ModuleBase) InstallForceOS() *OsType {
+ return nil
+}
+
func (m *ModuleBase) Owner() string {
return String(m.commonProperties.Owner)
}
-func (m *ModuleBase) NoticeFile() OptionalPath {
- return m.noticeFile
+func (m *ModuleBase) NoticeFiles() Paths {
+ return m.noticeFiles
}
func (m *ModuleBase) setImageVariation(variant string) {
@@ -948,8 +954,8 @@
}
func (m *ModuleBase) generateModuleTarget(ctx ModuleContext) {
- allInstalledFiles := Paths{}
- allCheckbuildFiles := Paths{}
+ var allInstalledFiles InstallPaths
+ var allCheckbuildFiles Paths
ctx.VisitAllModuleVariants(func(module Module) {
a := module.base()
allInstalledFiles = append(allInstalledFiles, a.installFiles...)
@@ -968,7 +974,7 @@
ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony,
Output: name,
- Implicits: allInstalledFiles,
+ Implicits: allInstalledFiles.Paths(),
Default: !ctx.Config().EmbeddedInMake(),
})
deps = append(deps, name)
@@ -1151,12 +1157,25 @@
}
})
- notice := proptools.StringDefault(m.commonProperties.Notice, "NOTICE")
+ m.noticeFiles = make([]Path, 0)
+ optPath := OptionalPath{}
+ notice := proptools.StringDefault(m.commonProperties.Notice, "")
if module := SrcIsModule(notice); module != "" {
- m.noticeFile = ctx.ExpandOptionalSource(¬ice, "notice")
- } else {
+ optPath = ctx.ExpandOptionalSource(¬ice, "notice")
+ } else if notice != "" {
noticePath := filepath.Join(ctx.ModuleDir(), notice)
- m.noticeFile = ExistentPathForSource(ctx, noticePath)
+ optPath = ExistentPathForSource(ctx, noticePath)
+ }
+ if optPath.Valid() {
+ m.noticeFiles = append(m.noticeFiles, optPath.Path())
+ } else {
+ for _, notice = range []string{"LICENSE", "LICENCE", "NOTICE"} {
+ noticePath := filepath.Join(ctx.ModuleDir(), notice)
+ optPath = ExistentPathForSource(ctx, noticePath)
+ if optPath.Valid() {
+ m.noticeFiles = append(m.noticeFiles, optPath.Path())
+ }
+ }
}
m.module.GenerateAndroidBuildActions(ctx)
@@ -1281,7 +1300,7 @@
func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string { return b.bp.OtherModuleName(m) }
func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
- b.bp.OtherModuleErrorf(m, fmt, args)
+ b.bp.OtherModuleErrorf(m, fmt, args...)
}
func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
return b.bp.OtherModuleDependencyTag(m)
@@ -1296,8 +1315,8 @@
type moduleContext struct {
bp blueprint.ModuleContext
baseModuleContext
- installDeps Paths
- installFiles Paths
+ installDeps InstallPaths
+ installFiles InstallPaths
checkbuildFiles Paths
module Module
@@ -1703,6 +1722,10 @@
return m.module.InstallBypassMake()
}
+func (m *moduleContext) InstallForceOS() *OsType {
+ return m.module.InstallForceOS()
+}
+
func (m *moduleContext) skipInstall(fullInstallPath InstallPath) bool {
if m.module.base().commonProperties.SkipInstall {
return true
@@ -1746,7 +1769,7 @@
if !m.skipInstall(fullInstallPath) {
- deps = append(deps, m.installDeps...)
+ deps = append(deps, m.installDeps.Paths()...)
var implicitDeps, orderOnlyDeps Paths
@@ -1827,20 +1850,6 @@
m.checkbuildFiles = append(m.checkbuildFiles, srcPath)
}
-type fileInstaller interface {
- filesToInstall() Paths
-}
-
-func isFileInstaller(m blueprint.Module) bool {
- _, ok := m.(fileInstaller)
- return ok
-}
-
-func isAndroidModule(m blueprint.Module) bool {
- _, ok := m.(Module)
- return ok
-}
-
func findStringInSlice(str string, slice []string) int {
for i, s := range slice {
if s == str {
diff --git a/android/paths.go b/android/paths.go
index 66725c6..8b373da 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -53,6 +53,7 @@
InstallInRecovery() bool
InstallInRoot() bool
InstallBypassMake() bool
+ InstallForceOS() *OsType
}
var _ ModuleInstallPathContext = ModuleContext(nil)
@@ -1205,22 +1206,40 @@
// PathForModuleInstall returns a Path representing the install path for the
// module appended with paths...
func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath {
+ os := ctx.Os()
+ if forceOS := ctx.InstallForceOS(); forceOS != nil {
+ os = *forceOS
+ }
+ partition := modulePartition(ctx, os)
+
+ ret := pathForInstall(ctx, os, partition, ctx.Debug(), pathComponents...)
+
+ if ctx.InstallBypassMake() && ctx.Config().EmbeddedInMake() {
+ ret = ret.ToMakePath()
+ }
+
+ return ret
+}
+
+func pathForInstall(ctx PathContext, os OsType, partition string, debug bool,
+ pathComponents ...string) InstallPath {
+
var outPaths []string
- if ctx.Device() {
- partition := modulePartition(ctx)
+
+ if os.Class == Device {
outPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
} else {
- switch ctx.Os() {
+ switch os {
case Linux:
- outPaths = []string{"host", "linux-x86"}
+ outPaths = []string{"host", "linux-x86", partition}
case LinuxBionic:
// TODO: should this be a separate top level, or shared with linux-x86?
- outPaths = []string{"host", "linux_bionic-x86"}
+ outPaths = []string{"host", "linux_bionic-x86", partition}
default:
- outPaths = []string{"host", ctx.Os().String() + "-x86"}
+ outPaths = []string{"host", os.String() + "-x86", partition}
}
}
- if ctx.Debug() {
+ if debug {
outPaths = append([]string{"debug"}, outPaths...)
}
outPaths = append(outPaths, pathComponents...)
@@ -1231,9 +1250,6 @@
}
ret := InstallPath{basePath{path, ctx.Config(), ""}, ""}
- if ctx.InstallBypassMake() && ctx.Config().EmbeddedInMake() {
- ret = ret.ToMakePath()
- }
return ret
}
@@ -1253,47 +1269,76 @@
return "/" + rel
}
-func modulePartition(ctx ModuleInstallPathContext) string {
+func modulePartition(ctx ModuleInstallPathContext, os OsType) string {
var partition string
- if ctx.InstallInData() {
- partition = "data"
- } else if ctx.InstallInTestcases() {
+ if ctx.InstallInTestcases() {
+ // "testcases" install directory can be used for host or device modules.
partition = "testcases"
- } else if ctx.InstallInRamdisk() {
- if ctx.DeviceConfig().BoardUsesRecoveryAsBoot() {
- partition = "recovery/root/first_stage_ramdisk"
+ } else if os.Class == Device {
+ if ctx.InstallInData() {
+ partition = "data"
+ } else if ctx.InstallInRamdisk() {
+ if ctx.DeviceConfig().BoardUsesRecoveryAsBoot() {
+ partition = "recovery/root/first_stage_ramdisk"
+ } else {
+ partition = "ramdisk"
+ }
+ if !ctx.InstallInRoot() {
+ partition += "/system"
+ }
+ } else if ctx.InstallInRecovery() {
+ if ctx.InstallInRoot() {
+ partition = "recovery/root"
+ } else {
+ // the layout of recovery partion is the same as that of system partition
+ partition = "recovery/root/system"
+ }
+ } else if ctx.SocSpecific() {
+ partition = ctx.DeviceConfig().VendorPath()
+ } else if ctx.DeviceSpecific() {
+ partition = ctx.DeviceConfig().OdmPath()
+ } else if ctx.ProductSpecific() {
+ partition = ctx.DeviceConfig().ProductPath()
+ } else if ctx.SystemExtSpecific() {
+ partition = ctx.DeviceConfig().SystemExtPath()
+ } else if ctx.InstallInRoot() {
+ partition = "root"
} else {
- partition = "ramdisk"
+ partition = "system"
}
- if !ctx.InstallInRoot() {
- partition += "/system"
+ if ctx.InstallInSanitizerDir() {
+ partition = "data/asan/" + partition
}
- } else if ctx.InstallInRecovery() {
- if ctx.InstallInRoot() {
- partition = "recovery/root"
- } else {
- // the layout of recovery partion is the same as that of system partition
- partition = "recovery/root/system"
- }
- } else if ctx.SocSpecific() {
- partition = ctx.DeviceConfig().VendorPath()
- } else if ctx.DeviceSpecific() {
- partition = ctx.DeviceConfig().OdmPath()
- } else if ctx.ProductSpecific() {
- partition = ctx.DeviceConfig().ProductPath()
- } else if ctx.SystemExtSpecific() {
- partition = ctx.DeviceConfig().SystemExtPath()
- } else if ctx.InstallInRoot() {
- partition = "root"
- } else {
- partition = "system"
- }
- if ctx.InstallInSanitizerDir() {
- partition = "data/asan/" + partition
}
return partition
}
+type InstallPaths []InstallPath
+
+// Paths returns the InstallPaths as a Paths
+func (p InstallPaths) Paths() Paths {
+ if p == nil {
+ return nil
+ }
+ ret := make(Paths, len(p))
+ for i, path := range p {
+ ret[i] = path
+ }
+ return ret
+}
+
+// Strings returns the string forms of the install paths.
+func (p InstallPaths) Strings() []string {
+ if p == nil {
+ return nil
+ }
+ ret := make([]string, len(p))
+ for i, path := range p {
+ ret[i] = path.String()
+ }
+ return ret
+}
+
// validateSafePath validates a path that we trust (may contain ninja variables).
// Ensures that each path component does not attempt to leave its component.
func validateSafePath(pathComponents ...string) (string, error) {
diff --git a/android/paths_test.go b/android/paths_test.go
index 7a32026..f1908ac 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -205,6 +205,7 @@
inRamdisk bool
inRecovery bool
inRoot bool
+ forceOS *OsType
}
func (m moduleInstallPathContextImpl) Config() Config {
@@ -241,6 +242,10 @@
return false
}
+func (m moduleInstallPathContextImpl) InstallForceOS() *OsType {
+ return m.forceOS
+}
+
func pathTestConfig(buildDir string) Config {
return TestConfig(buildDir, nil, "", nil)
}
@@ -598,6 +603,40 @@
},
in: []string{"nativetest", "my_test"},
out: "target/product/test_device/data/asan/data/nativetest/my_test",
+ }, {
+ name: "device testcases",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ os: deviceTarget.Os,
+ target: deviceTarget,
+ },
+ inTestcases: true,
+ },
+ in: []string{"my_test", "my_test_bin"},
+ out: "target/product/test_device/testcases/my_test/my_test_bin",
+ }, {
+ name: "host testcases",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ os: hostTarget.Os,
+ target: hostTarget,
+ },
+ inTestcases: true,
+ },
+ in: []string{"my_test", "my_test_bin"},
+ out: "host/linux-x86/testcases/my_test/my_test_bin",
+ }, {
+ name: "forced host testcases",
+ ctx: &moduleInstallPathContextImpl{
+ baseModuleContext: baseModuleContext{
+ os: deviceTarget.Os,
+ target: deviceTarget,
+ },
+ inTestcases: true,
+ forceOS: &Linux,
+ },
+ in: []string{"my_test", "my_test_bin"},
+ out: "host/linux-x86/testcases/my_test/my_test_bin",
},
}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 0abec0d..5c15e8e 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -120,8 +120,8 @@
fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
}
- if fi.module != nil && fi.module.NoticeFile().Valid() {
- fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", fi.module.NoticeFile().Path().String())
+ if fi.module != nil && len(fi.module.NoticeFiles()) > 0 {
+ fmt.Fprintln(w, "LOCAL_NOTICE_FILE :=", strings.Join(fi.module.NoticeFiles().Strings(), " "))
}
} else {
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", pathWhenActivated)
@@ -308,7 +308,7 @@
}
if a.installedFilesFile != nil {
- goal := "droidcore"
+ goal := "checkbuild"
distFile := name + "-installed-files.txt"
fmt.Fprintln(w, ".PHONY:", goal)
fmt.Fprintf(w, "$(call dist-for-goals,%s,%s:%s)\n",
diff --git a/apex/apex.go b/apex/apex.go
index 42cc9a6..c791162 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -52,6 +52,7 @@
var (
sharedLibTag = dependencyTag{name: "sharedLib", payload: true}
+ jniLibTag = dependencyTag{name: "jniLib", payload: true}
executableTag = dependencyTag{name: "executable", payload: true}
javaLibTag = dependencyTag{name: "javaLib", payload: true}
prebuiltTag = dependencyTag{name: "prebuilt", payload: true}
@@ -1155,10 +1156,13 @@
})
}
-type apexNativeDependencies struct {
+type ApexNativeDependencies struct {
// List of native libraries
Native_shared_libs []string
+ // List of JNI libraries
+ Jni_libs []string
+
// List of native executables
Binaries []string
@@ -1168,19 +1172,19 @@
type apexMultilibProperties struct {
// Native dependencies whose compile_multilib is "first"
- First apexNativeDependencies
+ First ApexNativeDependencies
// Native dependencies whose compile_multilib is "both"
- Both apexNativeDependencies
+ Both ApexNativeDependencies
// Native dependencies whose compile_multilib is "prefer32"
- Prefer32 apexNativeDependencies
+ Prefer32 ApexNativeDependencies
// Native dependencies whose compile_multilib is "32"
- Lib32 apexNativeDependencies
+ Lib32 ApexNativeDependencies
// Native dependencies whose compile_multilib is "64"
- Lib64 apexNativeDependencies
+ Lib64 ApexNativeDependencies
}
type apexBundleProperties struct {
@@ -1202,11 +1206,7 @@
// Default: /system/sepolicy/apex/<module_name>_file_contexts.
File_contexts *string `android:"path"`
- // List of native shared libs that are embedded inside this APEX bundle
- Native_shared_libs []string
-
- // List of executables that are embedded inside this APEX bundle
- Binaries []string
+ ApexNativeDependencies
// List of java libraries that are embedded inside this APEX bundle
Java_libs []string
@@ -1214,9 +1214,6 @@
// List of prebuilt files that are embedded inside this APEX bundle
Prebuilts []string
- // List of tests that are embedded inside this APEX bundle
- Tests []string
-
// Name of the apex_key module that provides the private key to sign APEX
Key *string
@@ -1280,6 +1277,9 @@
// rules for making sure that the APEX is truely updatable. This will also disable the size optimizations
// like symlinking to the system libs. Default is false.
Updatable *bool
+
+ // The minimum SDK version that this apex must be compatibile with.
+ Min_sdk_version *string
}
type apexTargetBundleProperties struct {
@@ -1410,6 +1410,8 @@
jacocoReportClassesFile android.Path // only for javalibs and apps
certificate java.Certificate // only for apps
+
+ isJniLib bool
}
func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, moduleName string, installDir string, class apexFileClass, module android.Module) apexFile {
@@ -1528,7 +1530,7 @@
}
func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
- native_shared_libs []string, binaries []string, tests []string,
+ nativeModules ApexNativeDependencies,
target android.Target, imageVariation string) {
// Use *FarVariation* to be able to depend on modules having
// conflicting variations with this module. This is required since
@@ -1538,16 +1540,22 @@
{Mutator: "image", Variation: imageVariation},
{Mutator: "link", Variation: "shared"},
{Mutator: "version", Variation: ""}, // "" is the non-stub variant
- }...), sharedLibTag, native_shared_libs...)
+ }...), sharedLibTag, nativeModules.Native_shared_libs...)
+
+ ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
+ {Mutator: "image", Variation: imageVariation},
+ {Mutator: "link", Variation: "shared"},
+ {Mutator: "version", Variation: ""}, // "" is the non-stub variant
+ }...), jniLibTag, nativeModules.Jni_libs...)
ctx.AddFarVariationDependencies(append(target.Variations(),
blueprint.Variation{Mutator: "image", Variation: imageVariation}),
- executableTag, binaries...)
+ executableTag, nativeModules.Binaries...)
ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
{Mutator: "image", Variation: imageVariation},
{Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant
- }...), testTag, tests...)
+ }...), testTag, nativeModules.Tests...)
}
func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -1580,41 +1588,39 @@
}
}
for i, target := range targets {
- // When multilib.* is omitted for native_shared_libs, it implies
- // multilib.both.
- ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
- {Mutator: "image", Variation: a.getImageVariation(config)},
- {Mutator: "link", Variation: "shared"},
- }...), sharedLibTag, a.properties.Native_shared_libs...)
-
- // When multilib.* is omitted for tests, it implies
- // multilib.both.
- ctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
- {Mutator: "image", Variation: a.getImageVariation(config)},
- {Mutator: "test_per_src", Variation: ""}, // "" is the all-tests variant
- }...), testTag, a.properties.Tests...)
+ // When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies
+ // multilib.both
+ addDependenciesForNativeModules(ctx,
+ ApexNativeDependencies{
+ Native_shared_libs: a.properties.Native_shared_libs,
+ Tests: a.properties.Tests,
+ Jni_libs: a.properties.Jni_libs,
+ Binaries: nil,
+ },
+ target, a.getImageVariation(config))
// Add native modules targetting both ABIs
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Both.Native_shared_libs,
- a.properties.Multilib.Both.Binaries,
- a.properties.Multilib.Both.Tests,
+ a.properties.Multilib.Both,
target,
a.getImageVariation(config))
isPrimaryAbi := i == 0
if isPrimaryAbi {
// When multilib.* is omitted for binaries, it implies
- // multilib.first.
- ctx.AddFarVariationDependencies(append(target.Variations(),
- blueprint.Variation{Mutator: "image", Variation: a.getImageVariation(config)}),
- executableTag, a.properties.Binaries...)
+ // multilib.first
+ addDependenciesForNativeModules(ctx,
+ ApexNativeDependencies{
+ Native_shared_libs: nil,
+ Tests: nil,
+ Jni_libs: nil,
+ Binaries: a.properties.Binaries,
+ },
+ target, a.getImageVariation(config))
// Add native modules targetting the first ABI
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.First.Native_shared_libs,
- a.properties.Multilib.First.Binaries,
- a.properties.Multilib.First.Tests,
+ a.properties.Multilib.First,
target,
a.getImageVariation(config))
}
@@ -1623,32 +1629,24 @@
case "lib32":
// Add native modules targetting 32-bit ABI
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Lib32.Native_shared_libs,
- a.properties.Multilib.Lib32.Binaries,
- a.properties.Multilib.Lib32.Tests,
+ a.properties.Multilib.Lib32,
target,
a.getImageVariation(config))
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Prefer32.Native_shared_libs,
- a.properties.Multilib.Prefer32.Binaries,
- a.properties.Multilib.Prefer32.Tests,
+ a.properties.Multilib.Prefer32,
target,
a.getImageVariation(config))
case "lib64":
// Add native modules targetting 64-bit ABI
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Lib64.Native_shared_libs,
- a.properties.Multilib.Lib64.Binaries,
- a.properties.Multilib.Lib64.Tests,
+ a.properties.Multilib.Lib64,
target,
a.getImageVariation(config))
if !has32BitTarget {
addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Prefer32.Native_shared_libs,
- a.properties.Multilib.Prefer32.Binaries,
- a.properties.Multilib.Prefer32.Tests,
+ a.properties.Multilib.Prefer32,
target,
a.getImageVariation(config))
}
@@ -1657,8 +1655,8 @@
for _, sanitizer := range ctx.Config().SanitizeDevice() {
if sanitizer == "hwaddress" {
addDependenciesForNativeModules(ctx,
- []string{"libclang_rt.hwasan-aarch64-android"},
- nil, nil, target, a.getImageVariation(config))
+ ApexNativeDependencies{[]string{"libclang_rt.hwasan-aarch64-android"}, nil, nil, nil},
+ target, a.getImageVariation(config))
break
}
}
@@ -2079,16 +2077,23 @@
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
switch depTag {
- case sharedLibTag:
+ case sharedLibTag, jniLibTag:
+ isJniLib := depTag == jniLibTag
if c, ok := child.(*cc.Module); ok {
// bootstrap bionic libs are treated as provided by system
if c.HasStubsVariants() && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
provideNativeLibs = append(provideNativeLibs, c.OutputFile().Path().Base())
}
- filesInfo = append(filesInfo, apexFileForNativeLibrary(ctx, c, handleSpecialLibs))
+ fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
+ fi.isJniLib = isJniLib
+ filesInfo = append(filesInfo, fi)
return true // track transitive dependencies
} else {
- ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
+ propertyName := "native_shared_libs"
+ if isJniLib {
+ propertyName = "jni_libs"
+ }
+ ctx.PropertyErrorf(propertyName, "%q is not a cc_library or cc_library_shared module", depName)
}
case executableTag:
if cc, ok := child.(*cc.Module); ok {
@@ -2230,7 +2235,8 @@
return true // track transitive dependencies
}
} else if java.IsJniDepTag(depTag) {
- return true
+ // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps
+ return false
} else if java.IsXmlPermissionsFileDepTag(depTag) {
if prebuilt, ok := child.(android.PrebuiltEtcModule); ok {
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
@@ -2323,6 +2329,11 @@
a.linkToSystemLib = false
}
+ // We also don't want the optimization for host APEXes, because it doesn't make sense.
+ if ctx.Host() {
+ a.linkToSystemLib = false
+ }
+
// prepare apex_manifest.json
a.buildManifest(ctx, provideNativeLibs, requireNativeLibs)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index e694435..8c5ca8b 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -226,6 +226,14 @@
os.RemoveAll(buildDir)
}
+// ensure that 'result' equals 'expected'
+func ensureEquals(t *testing.T, result string, expected string) {
+ t.Helper()
+ if result != expected {
+ t.Errorf("%q != %q", expected, result)
+ }
+}
+
// ensure that 'result' contains 'expected'
func ensureContains(t *testing.T, result string, expected string) {
t.Helper()
@@ -1532,13 +1540,17 @@
var surplus []string
filesMatched := make(map[string]bool)
for _, file := range getFiles(t, ctx, moduleName, variant) {
+ mactchFound := false
for _, expected := range files {
if matched, _ := path.Match(expected, file.path); matched {
filesMatched[expected] = true
- return
+ mactchFound = true
+ break
}
}
- surplus = append(surplus, file.path)
+ if !mactchFound {
+ surplus = append(surplus, file.path)
+ }
}
if len(surplus) > 0 {
@@ -1605,8 +1617,10 @@
ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
"lib/libvndk.so",
"lib/libvndksp.so",
+ "lib/libc++.so",
"lib64/libvndk.so",
"lib64/libvndksp.so",
+ "lib64/libc++.so",
"etc/llndk.libraries.VER.txt",
"etc/vndkcore.libraries.VER.txt",
"etc/vndksp.libraries.VER.txt",
@@ -1666,6 +1680,8 @@
"lib/libvndk.so",
"lib/libvndk.arm.so",
"lib64/libvndk.so",
+ "lib/libc++.so",
+ "lib64/libc++.so",
"etc/*",
})
}
@@ -1877,6 +1893,8 @@
ensureExactContents(t, ctx, "myapex", "android_common_image", []string{
"lib/libvndk.so",
"lib64/libvndk.so",
+ "lib/libc++.so",
+ "lib64/libc++.so",
"etc/*",
})
}
@@ -2871,27 +2889,39 @@
android_app {
name: "AppFoo",
srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
+ sdk_version: "current",
system_modules: "none",
jni_libs: ["libjni"],
+ stl: "none",
apex_available: [ "myapex" ],
}
android_app {
name: "AppFooPriv",
srcs: ["foo/bar/MyClass.java"],
- sdk_version: "none",
+ sdk_version: "current",
system_modules: "none",
privileged: true,
+ stl: "none",
apex_available: [ "myapex" ],
}
cc_library_shared {
name: "libjni",
srcs: ["mylib.cpp"],
+ shared_libs: ["libfoo"],
stl: "none",
system_shared_libs: [],
apex_available: [ "myapex" ],
+ sdk_version: "current",
+ }
+
+ cc_library_shared {
+ name: "libfoo",
+ stl: "none",
+ system_shared_libs: [],
+ apex_available: [ "myapex" ],
+ sdk_version: "current",
}
`)
@@ -2902,16 +2932,19 @@
ensureContains(t, copyCmds, "image.apex/app/AppFoo/AppFoo.apk")
ensureContains(t, copyCmds, "image.apex/priv-app/AppFooPriv/AppFooPriv.apk")
- // JNI libraries are embedded inside APK
- appZipRule := ctx.ModuleForTests("AppFoo", "android_common_myapex").Description("zip jni lib")
- libjniOutput := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module).OutputFile()
- ensureListContains(t, appZipRule.Implicits.Strings(), libjniOutput.String())
- // ... uncompressed
+ appZipRule := ctx.ModuleForTests("AppFoo", "android_common_myapex").Description("zip jni libs")
+ // JNI libraries are uncompressed
if args := appZipRule.Args["jarArgs"]; !strings.Contains(args, "-L 0") {
- t.Errorf("jni lib is not uncompressed for AppFoo")
+ t.Errorf("jni libs are not uncompressed for AppFoo")
}
- // ... and not directly inside the APEX
- ensureNotContains(t, copyCmds, "image.apex/lib64/libjni.so")
+ // JNI libraries including transitive deps are
+ for _, jni := range []string{"libjni", "libfoo"} {
+ jniOutput := ctx.ModuleForTests(jni, "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module).OutputFile()
+ // ... embedded inside APK (jnilibs.zip)
+ ensureListContains(t, appZipRule.Implicits.Strings(), jniOutput.String())
+ // ... and not directly inside the APEX
+ ensureNotContains(t, copyCmds, "image.apex/lib64/"+jni+".so")
+ }
}
func TestApexWithAppImports(t *testing.T) {
@@ -3596,6 +3629,70 @@
ensureRealfileExists(t, files, "lib64/myotherlib.so") // this is a real file
}
+func TestApexWithJniLibs(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ jni_libs: ["mylib"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ shared_libs: ["mylib2"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
+ cc_library {
+ name: "mylib2",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+ `)
+
+ rule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
+ // Notice mylib2.so (transitive dep) is not added as a jni_lib
+ ensureEquals(t, rule.Args["opt"], "-a jniLibs mylib.so")
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "lib64/mylib.so",
+ "lib64/mylib2.so",
+ })
+}
+
+func TestApexWithJniLibs_Errors(t *testing.T) {
+ testApexError(t, `jni_libs: "xxx" is not a cc_library`, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ jni_libs: ["xxx"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ prebuilt_etc {
+ name: "xxx",
+ src: "xxx",
+ }
+ `, withFiles(map[string][]byte{
+ "xxx": nil,
+ }))
+}
+
func TestMain(m *testing.M) {
run := func() int {
setUp()
diff --git a/apex/builder.go b/apex/builder.go
index 88c7098..8c81fb4 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -180,6 +180,17 @@
optCommands = append(optCommands, "-v name "+*a.properties.Apex_name)
}
+ // collect jniLibs. Notice that a.filesInfo is already sorted
+ var jniLibs []string
+ for _, fi := range a.filesInfo {
+ if fi.isJniLib {
+ jniLibs = append(jniLibs, fi.builtFile.Base())
+ }
+ }
+ if len(jniLibs) > 0 {
+ optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " "))
+ }
+
ctx.Build(pctx, android.BuildParams{
Rule: apexManifestRule,
Input: manifestSrc,
@@ -215,15 +226,15 @@
noticeFiles := []android.Path{}
for _, f := range a.filesInfo {
if f.module != nil {
- notice := f.module.NoticeFile()
- if notice.Valid() {
- noticeFiles = append(noticeFiles, notice.Path())
+ notices := f.module.NoticeFiles()
+ if len(notices) > 0 {
+ noticeFiles = append(noticeFiles, notices...)
}
}
}
// append the notice file specified in the apex module itself
- if a.NoticeFile().Valid() {
- noticeFiles = append(noticeFiles, a.NoticeFile().Path())
+ if len(a.NoticeFiles()) > 0 {
+ noticeFiles = append(noticeFiles, a.NoticeFiles()...)
}
if len(noticeFiles) == 0 {
@@ -383,6 +394,16 @@
targetSdkVersion := ctx.Config().DefaultAppTargetSdk()
minSdkVersion := ctx.Config().DefaultAppTargetSdk()
+
+ if proptools.Bool(a.properties.Legacy_android10_support) {
+ if !java.UseApiFingerprint(ctx, targetSdkVersion) {
+ targetSdkVersion = "29"
+ }
+ if !java.UseApiFingerprint(ctx, minSdkVersion) {
+ minSdkVersion = "29"
+ }
+ }
+
if java.UseApiFingerprint(ctx, targetSdkVersion) {
targetSdkVersion += fmt.Sprintf(".$$(cat %s)", java.ApiFingerprintPath(ctx).String())
implicitInputs = append(implicitInputs, java.ApiFingerprintPath(ctx))
diff --git a/build_kzip.bash b/build_kzip.bash
index 008030f..0018ea9 100755
--- a/build_kzip.bash
+++ b/build_kzip.bash
@@ -19,16 +19,20 @@
# The extraction might fail for some source files, so run with -k and then check that
# sufficiently many files were generated.
declare -r out="${OUT_DIR:-out}"
+
# Build extraction files for C++ and Java. Build `merge_zips` which we use later.
build/soong/soong_ui.bash --build-mode --all-modules --dir=$PWD -k merge_zips xref_cxx xref_java
-#Build extraction file for Go files in build/soong directory.
+
+# Build extraction file for Go the files in build/{blueprint,soong} directories.
declare -r abspath_out=$(realpath "${out}")
declare -r go_extractor=$(realpath prebuilts/build-tools/linux-x86/bin/go_extractor)
declare -r go_root=$(realpath prebuilts/go/linux-x86)
+declare -r vnames_path=$(realpath build/soong/vnames.go.json)
+declare -r source_root=$PWD
for dir in blueprint soong; do
(cd "build/$dir";
- "$go_extractor" --goroot="$go_root" --rules=vnames.go.json --canonicalize_package_corpus \
- --output "${abspath_out}/soong/build_${dir}.go.kzip" ./...
+ KYTHE_ROOT_DIRECTORY="${source_root}" "$go_extractor" --goroot="$go_root" --rules="${vnames_path}" \
+ --canonicalize_package_corpus --output "${abspath_out}/soong/build_${dir}.go.kzip" ./...
)
done
diff --git a/cc/androidmk.go b/cc/androidmk.go
index a78e455..81004da 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -34,7 +34,7 @@
type AndroidMkContext interface {
Name() string
Target() android.Target
- subAndroidMk(*android.AndroidMkData, interface{})
+ subAndroidMk(*android.AndroidMkEntries, interface{})
Arch() android.Arch
Os() android.OsType
Host() bool
@@ -46,29 +46,29 @@
}
type subAndroidMkProvider interface {
- AndroidMk(AndroidMkContext, *android.AndroidMkData)
+ AndroidMkEntries(AndroidMkContext, *android.AndroidMkEntries)
}
-func (c *Module) subAndroidMk(data *android.AndroidMkData, obj interface{}) {
+func (c *Module) subAndroidMk(entries *android.AndroidMkEntries, obj interface{}) {
if c.subAndroidMkOnce == nil {
c.subAndroidMkOnce = make(map[subAndroidMkProvider]bool)
}
if androidmk, ok := obj.(subAndroidMkProvider); ok {
if !c.subAndroidMkOnce[androidmk] {
c.subAndroidMkOnce[androidmk] = true
- androidmk.AndroidMk(c, data)
+ androidmk.AndroidMkEntries(c, entries)
}
}
}
-func (c *Module) AndroidMk() android.AndroidMkData {
+func (c *Module) AndroidMkEntries() []android.AndroidMkEntries {
if c.Properties.HideFromMake || !c.IsForPlatform() {
- return android.AndroidMkData{
+ return []android.AndroidMkEntries{{
Disabled: true,
- }
+ }}
}
- ret := android.AndroidMkData{
+ entries := android.AndroidMkEntries{
OutputFile: c.outputFile,
// TODO(jiyong): add the APEXes providing shared libs to the required modules
// Currently, adding c.Properties.ApexesProvidingSharedLibs is causing multiple
@@ -77,29 +77,29 @@
Required: c.Properties.AndroidMkRuntimeLibs,
Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- Extra: []android.AndroidMkExtraFunc{
- func(w io.Writer, outputFile android.Path) {
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
if len(c.Properties.Logtags) > 0 {
- fmt.Fprintln(w, "LOCAL_LOGTAGS_FILES :=", strings.Join(c.Properties.Logtags, " "))
+ entries.AddStrings("LOCAL_LOGTAGS_FILES", c.Properties.Logtags...)
}
if len(c.Properties.AndroidMkSharedLibs) > 0 {
- fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
+ entries.AddStrings("LOCAL_SHARED_LIBRARIES", c.Properties.AndroidMkSharedLibs...)
}
if len(c.Properties.AndroidMkStaticLibs) > 0 {
- fmt.Fprintln(w, "LOCAL_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkStaticLibs, " "))
+ entries.AddStrings("LOCAL_STATIC_LIBRARIES", c.Properties.AndroidMkStaticLibs...)
}
if len(c.Properties.AndroidMkWholeStaticLibs) > 0 {
- fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
+ entries.AddStrings("LOCAL_WHOLE_STATIC_LIBRARIES", c.Properties.AndroidMkWholeStaticLibs...)
}
- fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.makeLinkType)
+ entries.SetString("LOCAL_SOONG_LINK_TYPE", c.makeLinkType)
if c.UseVndk() {
- fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
+ entries.SetBool("LOCAL_USE_VNDK", true)
if c.IsVndk() && !c.static() {
- fmt.Fprintln(w, "LOCAL_SOONG_VNDK_VERSION := "+c.VndkVersion())
+ entries.SetString("LOCAL_SOONG_VNDK_VERSION", c.VndkVersion())
// VNDK libraries available to vendor are not installed because
// they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
if !c.isVndkExt() {
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
}
}
}
@@ -108,22 +108,22 @@
}
for _, feature := range c.features {
- c.subAndroidMk(&ret, feature)
+ c.subAndroidMk(&entries, feature)
}
- c.subAndroidMk(&ret, c.compiler)
- c.subAndroidMk(&ret, c.linker)
+ c.subAndroidMk(&entries, c.compiler)
+ c.subAndroidMk(&entries, c.linker)
if c.sanitize != nil {
- c.subAndroidMk(&ret, c.sanitize)
+ c.subAndroidMk(&entries, c.sanitize)
}
- c.subAndroidMk(&ret, c.installer)
+ c.subAndroidMk(&entries, c.installer)
- ret.SubName += c.Properties.SubName
+ entries.SubName += c.Properties.SubName
- return ret
+ return []android.AndroidMkEntries{entries}
}
-func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, ret *android.AndroidMkData) {
+func androidMkWriteTestData(data android.Paths, ctx AndroidMkContext, entries *android.AndroidMkEntries) {
var testFiles []string
for _, d := range data {
rel := d.Rel()
@@ -135,8 +135,8 @@
testFiles = append(testFiles, path+":"+rel)
}
if len(testFiles) > 0 {
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(testFiles, " "))
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.AddStrings("LOCAL_TEST_DATA", testFiles...)
})
}
}
@@ -153,7 +153,7 @@
return overrides
}
-func (library *libraryDecorator) androidMkWriteExportedFlags(w io.Writer) {
+func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.AndroidMkEntries) {
exportedFlags := library.exportedFlags()
for _, dir := range library.exportedDirs() {
exportedFlags = append(exportedFlags, "-I"+dir.String())
@@ -162,75 +162,92 @@
exportedFlags = append(exportedFlags, "-isystem "+dir.String())
}
if len(exportedFlags) > 0 {
- fmt.Fprintln(w, "LOCAL_EXPORT_CFLAGS :=", strings.Join(exportedFlags, " "))
+ entries.AddStrings("LOCAL_EXPORT_CFLAGS", exportedFlags...)
}
exportedDeps := library.exportedDeps()
if len(exportedDeps) > 0 {
- fmt.Fprintln(w, "LOCAL_EXPORT_C_INCLUDE_DEPS :=", strings.Join(exportedDeps.Strings(), " "))
+ entries.AddStrings("LOCAL_EXPORT_C_INCLUDE_DEPS", exportedDeps.Strings()...)
}
}
-func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
+func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
if library.sAbiOutputFile.Valid() {
- fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", library.sAbiOutputFile.String())
+ entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES",
+ "$(LOCAL_ADDITIONAL_DEPENDENCIES) "+library.sAbiOutputFile.String())
if library.sAbiDiff.Valid() && !library.static() {
- fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", library.sAbiDiff.String())
- fmt.Fprintln(w, "HEADER_ABI_DIFFS +=", library.sAbiDiff.String())
+ entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES",
+ "$(LOCAL_ADDITIONAL_DEPENDENCIES) "+library.sAbiDiff.String())
+ entries.SetString("HEADER_ABI_DIFFS",
+ "$(HEADER_ABI_DIFFS) "+library.sAbiDiff.String())
}
}
}
-func (library *libraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
+func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
+ if library.sAbiOutputFile.Valid() {
+ fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_ADDITIONAL_DEPENDENCIES) ",
+ library.sAbiOutputFile.String())
+ if library.sAbiDiff.Valid() && !library.static() {
+ fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_ADDITIONAL_DEPENDENCIES) ",
+ library.sAbiDiff.String())
+ fmt.Fprintln(w, "HEADER_ABI_DIFFS := $(HEADER_ABI_DIFFS) ",
+ library.sAbiDiff.String())
+ }
+ }
+}
+
+func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
if library.static() {
- ret.Class = "STATIC_LIBRARIES"
+ entries.Class = "STATIC_LIBRARIES"
} else if library.shared() {
- ret.Class = "SHARED_LIBRARIES"
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", library.toc().String())
+ entries.Class = "SHARED_LIBRARIES"
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_SOONG_TOC", library.toc().String())
if !library.buildStubs() {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
+ entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", library.unstrippedOutputFile.String())
}
if len(library.Properties.Overrides) > 0 {
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(makeOverrideModuleNames(ctx, library.Properties.Overrides), " "))
+ entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, library.Properties.Overrides), " "))
}
if len(library.post_install_cmds) > 0 {
- fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(library.post_install_cmds, "&& "))
+ entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(library.post_install_cmds, "&& "))
}
})
} else if library.header() {
- ret.Class = "HEADER_LIBRARIES"
+ entries.Class = "HEADER_LIBRARIES"
}
- ret.DistFile = library.distFile
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- library.androidMkWriteExportedFlags(w)
- library.androidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
+ entries.DistFile = library.distFile
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ library.androidMkWriteExportedFlags(entries)
+ library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
- _, _, ext := android.SplitFileExt(outputFile.Base())
+ _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
- fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
if library.coverageOutputFile.Valid() {
- fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", library.coverageOutputFile.String())
+ entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
}
if library.useCoreVariant {
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
- fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
- fmt.Fprintln(w, "LOCAL_VNDK_DEPEND_ON_CORE_VARIANT := true")
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
+ entries.SetBool("LOCAL_VNDK_DEPEND_ON_CORE_VARIANT", true)
}
if library.checkSameCoreVariant {
- fmt.Fprintln(w, "LOCAL_CHECK_SAME_VNDK_VARIANTS := true")
+ entries.SetBool("LOCAL_CHECK_SAME_VNDK_VARIANTS", true)
}
})
if library.shared() && !library.buildStubs() {
- ctx.subAndroidMk(ret, library.baseInstaller)
+ ctx.subAndroidMk(entries, library.baseInstaller)
} else {
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
if library.buildStubs() {
- fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
+ entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
}
})
}
@@ -238,90 +255,91 @@
android.DirectlyInAnyApex(ctx, ctx.Name()) && !ctx.InRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() &&
!ctx.static() {
if !library.buildStubs() {
- ret.SubName = ".bootstrap"
+ entries.SubName = ".bootstrap"
}
}
}
-func (object *objectLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Custom = func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
- out := ret.OutputFile.Path()
- varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, data.SubName)
+func (object *objectLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "STATIC_LIBRARIES"
+ entries.ExtraFooters = append(entries.ExtraFooters,
+ func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+ out := entries.OutputFile.Path()
+ varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName)
- fmt.Fprintf(w, "\n%s := %s\n", varname, out.String())
- fmt.Fprintln(w, ".KATI_READONLY: "+varname)
- }
+ fmt.Fprintf(w, "\n%s := %s\n", varname, out.String())
+ fmt.Fprintln(w, ".KATI_READONLY: "+varname)
+ })
}
-func (binary *binaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, binary.baseInstaller)
+func (binary *binaryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, binary.baseInstaller)
- ret.Class = "EXECUTABLES"
- ret.DistFile = binary.distFile
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String())
+ entries.Class = "EXECUTABLES"
+ entries.DistFile = binary.distFile
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String())
if len(binary.symlinks) > 0 {
- fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(binary.symlinks, " "))
+ entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...)
}
if binary.coverageOutputFile.Valid() {
- fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", binary.coverageOutputFile.String())
+ entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputFile.String())
}
if len(binary.Properties.Overrides) > 0 {
- fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " "))
+ entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " "))
}
if len(binary.post_install_cmds) > 0 {
- fmt.Fprintln(w, "LOCAL_POST_INSTALL_CMD := "+strings.Join(binary.post_install_cmds, "&& "))
+ entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(binary.post_install_cmds, "&& "))
}
})
}
-func (benchmark *benchmarkDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, benchmark.binaryDecorator)
- ret.Class = "NATIVE_TESTS"
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+func (benchmark *benchmarkDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, benchmark.binaryDecorator)
+ entries.Class = "NATIVE_TESTS"
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
if len(benchmark.Properties.Test_suites) > 0 {
- fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
+ entries.SetString("LOCAL_COMPATIBILITY_SUITE",
strings.Join(benchmark.Properties.Test_suites, " "))
}
if benchmark.testConfig != nil {
- fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", benchmark.testConfig.String())
+ entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String())
}
- fmt.Fprintln(w, "LOCAL_NATIVE_BENCHMARK := true")
+ entries.SetBool("LOCAL_NATIVE_BENCHMARK", true)
if !BoolDefault(benchmark.Properties.Auto_gen_config, true) {
- fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
}
})
- androidMkWriteTestData(benchmark.data, ctx, ret)
+ androidMkWriteTestData(benchmark.data, ctx, entries)
}
-func (test *testBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, test.binaryDecorator)
- ret.Class = "NATIVE_TESTS"
+func (test *testBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, test.binaryDecorator)
+ entries.Class = "NATIVE_TESTS"
if Bool(test.Properties.Test_per_src) {
- ret.SubName = "_" + String(test.binaryDecorator.Properties.Stem)
+ entries.SubName = "_" + String(test.binaryDecorator.Properties.Stem)
}
-
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
if len(test.Properties.Test_suites) > 0 {
- fmt.Fprintln(w, "LOCAL_COMPATIBILITY_SUITE :=",
+ entries.SetString("LOCAL_COMPATIBILITY_SUITE",
strings.Join(test.Properties.Test_suites, " "))
}
if test.testConfig != nil {
- fmt.Fprintln(w, "LOCAL_FULL_TEST_CONFIG :=", test.testConfig.String())
+ entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String())
}
if !BoolDefault(test.Properties.Auto_gen_config, true) {
- fmt.Fprintln(w, "LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG := true")
+ entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
}
})
- androidMkWriteTestData(test.data, ctx, ret)
+ androidMkWriteTestData(test.data, ctx, entries)
}
-func (fuzz *fuzzBinary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, fuzz.binaryDecorator)
+func (fuzz *fuzzBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, fuzz.binaryDecorator)
var fuzzFiles []string
for _, d := range fuzz.corpus {
@@ -344,199 +362,198 @@
filepath.Dir(fuzz.config.String())+":config.json")
}
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_IS_FUZZ_TARGET := true")
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_IS_FUZZ_TARGET", true)
if len(fuzzFiles) > 0 {
- fmt.Fprintln(w, "LOCAL_TEST_DATA := "+strings.Join(fuzzFiles, " "))
+ entries.AddStrings("LOCAL_TEST_DATA", fuzzFiles...)
}
if fuzz.installedSharedDeps != nil {
- fmt.Fprintln(w, "LOCAL_FUZZ_INSTALLED_SHARED_DEPS :="+
- strings.Join(fuzz.installedSharedDeps, " "))
+ entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...)
}
})
}
-func (test *testLibrary) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, test.libraryDecorator)
+func (test *testLibrary) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, test.libraryDecorator)
}
-func (library *toolchainLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "STATIC_LIBRARIES"
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- _, suffix, _ := android.SplitFileExt(outputFile.Base())
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
+func (library *toolchainLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "STATIC_LIBRARIES"
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ _, suffix, _ := android.SplitFileExt(entries.OutputFile.Path().Base())
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
})
}
-func (installer *baseInstaller) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+func (installer *baseInstaller) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
// Soong installation is only supported for host modules. Have Make
// installation trigger Soong installation.
if ctx.Target().Os.Class == android.Host {
- ret.OutputFile = android.OptionalPathForPath(installer.path)
+ entries.OutputFile = android.OptionalPathForPath(installer.path)
}
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
path, file := filepath.Split(installer.path.ToMakePath().String())
stem, suffix, _ := android.SplitFileExt(file)
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
- fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+ entries.SetString("LOCAL_MODULE_PATH", path)
+ entries.SetString("LOCAL_MODULE_STEM", stem)
})
}
-func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel
- ret.Class = "SHARED_LIBRARIES"
+func (c *stubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.SubName = ndkLibrarySuffix + "." + c.properties.ApiLevel
+ entries.Class = "SHARED_LIBRARIES"
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
path, file := filepath.Split(c.installPath.String())
stem, suffix, _ := android.SplitFileExt(file)
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
- fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
- fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+ entries.SetString("LOCAL_MODULE_PATH", path)
+ entries.SetString("LOCAL_MODULE_STEM", stem)
+ entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
})
}
-func (c *llndkStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "SHARED_LIBRARIES"
+func (c *llndkStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "SHARED_LIBRARIES"
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- c.libraryDecorator.androidMkWriteExportedFlags(w)
- _, _, ext := android.SplitFileExt(outputFile.Base())
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ c.libraryDecorator.androidMkWriteExportedFlags(entries)
+ _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
- fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
- fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
- fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", c.toc().String())
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
+ entries.SetString("LOCAL_SOONG_TOC", c.toc().String())
})
}
-func (c *vndkPrebuiltLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "SHARED_LIBRARIES"
+func (c *vndkPrebuiltLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "SHARED_LIBRARIES"
- ret.SubName = c.androidMkSuffix
+ entries.SubName = c.androidMkSuffix
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- c.libraryDecorator.androidMkWriteExportedFlags(w)
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ c.libraryDecorator.androidMkWriteExportedFlags(entries)
path, file := filepath.Split(c.path.ToMakePath().String())
stem, suffix, ext := android.SplitFileExt(file)
- fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
- fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+ entries.SetString("LOCAL_MODULE_PATH", path)
+ entries.SetString("LOCAL_MODULE_STEM", stem)
if c.tocFile.Valid() {
- fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String())
+ entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
}
})
}
-func (c *vendorSnapshotLibraryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+func (c *vendorSnapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
// Each vendor snapshot is exported to androidMk only when BOARD_VNDK_VERSION != current
// and the version of the prebuilt is same as BOARD_VNDK_VERSION.
if c.shared() {
- ret.Class = "SHARED_LIBRARIES"
+ entries.Class = "SHARED_LIBRARIES"
} else if c.static() {
- ret.Class = "STATIC_LIBRARIES"
+ entries.Class = "STATIC_LIBRARIES"
} else if c.header() {
- ret.Class = "HEADER_LIBRARIES"
+ entries.Class = "HEADER_LIBRARIES"
}
if c.androidMkVendorSuffix {
- ret.SubName = vendorSuffix
+ entries.SubName = vendorSuffix
} else {
- ret.SubName = ""
+ entries.SubName = ""
}
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- c.libraryDecorator.androidMkWriteExportedFlags(w)
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ c.libraryDecorator.androidMkWriteExportedFlags(entries)
if c.shared() || c.static() {
path, file := filepath.Split(c.path.ToMakePath().String())
stem, suffix, ext := android.SplitFileExt(file)
- fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
- fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
- fmt.Fprintln(w, "LOCAL_MODULE_STEM := "+stem)
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+ entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
+ entries.SetString("LOCAL_MODULE_STEM", stem)
if c.shared() {
- fmt.Fprintln(w, "LOCAL_MODULE_PATH := "+path)
+ entries.SetString("LOCAL_MODULE_PATH", path)
}
if c.tocFile.Valid() {
- fmt.Fprintln(w, "LOCAL_SOONG_TOC := "+c.tocFile.String())
+ entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
}
}
if !c.shared() { // static or header
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
}
})
}
-func (c *vendorSnapshotBinaryDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "EXECUTABLES"
+func (c *vendorSnapshotBinaryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "EXECUTABLES"
if c.androidMkVendorSuffix {
- ret.SubName = vendorSuffix
+ entries.SubName = vendorSuffix
} else {
- ret.SubName = ""
+ entries.SubName = ""
}
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS := "+strings.Join(c.Properties.Symlinks, " "))
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.AddStrings("LOCAL_MODULE_SYMLINKS", c.Properties.Symlinks...)
})
}
-func (c *ndkPrebuiltStlLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "SHARED_LIBRARIES"
+func (c *ndkPrebuiltStlLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "SHARED_LIBRARIES"
}
-func (c *vendorPublicLibraryStubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Class = "SHARED_LIBRARIES"
- ret.SubName = vendorPublicLibrarySuffix
+func (c *vendorPublicLibraryStubDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.Class = "SHARED_LIBRARIES"
+ entries.SubName = vendorPublicLibrarySuffix
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- c.libraryDecorator.androidMkWriteExportedFlags(w)
- _, _, ext := android.SplitFileExt(outputFile.Base())
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ c.libraryDecorator.androidMkWriteExportedFlags(entries)
+ _, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
- fmt.Fprintln(w, "LOCAL_BUILT_MODULE_STEM := $(LOCAL_MODULE)"+ext)
- fmt.Fprintln(w, "LOCAL_UNINSTALLABLE_MODULE := true")
- fmt.Fprintln(w, "LOCAL_NO_NOTICE_FILE := true")
+ entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
+ entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
+ entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
})
}
-func (p *prebuiltLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+func (p *prebuiltLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
if p.properties.Check_elf_files != nil {
- fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES :=", *p.properties.Check_elf_files)
+ entries.SetBool("LOCAL_CHECK_ELF_FILES", *p.properties.Check_elf_files)
} else {
// soong_cc_prebuilt.mk does not include check_elf_file.mk by default
// because cc_library_shared and cc_binary use soong_cc_prebuilt.mk as well.
// In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to
// true if `p.properties.Check_elf_files` is not specified.
- fmt.Fprintln(w, "LOCAL_CHECK_ELF_FILES := true")
+ entries.SetBool("LOCAL_CHECK_ELF_FILES", true)
}
})
}
-func (p *prebuiltLibraryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, p.libraryDecorator)
+func (p *prebuiltLibraryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, p.libraryDecorator)
if p.shared() {
- ctx.subAndroidMk(ret, &p.prebuiltLinker)
- androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret)
+ ctx.subAndroidMk(entries, &p.prebuiltLinker)
+ androidMkWriteAllowUndefinedSymbols(p.baseLinker, entries)
}
}
-func (p *prebuiltBinaryLinker) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
- ctx.subAndroidMk(ret, p.binaryDecorator)
- ctx.subAndroidMk(ret, &p.prebuiltLinker)
- androidMkWriteAllowUndefinedSymbols(p.baseLinker, ret)
+func (p *prebuiltBinaryLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
+ ctx.subAndroidMk(entries, p.binaryDecorator)
+ ctx.subAndroidMk(entries, &p.prebuiltLinker)
+ androidMkWriteAllowUndefinedSymbols(p.baseLinker, entries)
}
-func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, ret *android.AndroidMkData) {
- ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
- allow := linker.Properties.Allow_undefined_symbols
- if allow != nil {
- fmt.Fprintln(w, "LOCAL_ALLOW_UNDEFINED_SYMBOLS :=", *allow)
- }
- })
+func androidMkWriteAllowUndefinedSymbols(linker *baseLinker, entries *android.AndroidMkEntries) {
+ allow := linker.Properties.Allow_undefined_symbols
+ if allow != nil {
+ entries.ExtraEntries = append(entries.ExtraEntries, func(entries *android.AndroidMkEntries) {
+ entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow)
+ })
+ }
}
diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go
index 53bc065..58d6ad0 100644
--- a/cc/binary_sdk_member.go
+++ b/cc/binary_sdk_member.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "strings"
"android/soong/android"
"github.com/google/blueprint"
@@ -98,7 +99,23 @@
func buildSharedNativeBinarySnapshot(info *nativeBinaryInfo, builder android.SnapshotBuilder, member android.SdkMember) {
pbm := builder.AddPrebuiltModule(member, "cc_prebuilt_binary")
- pbm.AddProperty("compile_multilib", "both")
+ archVariantCount := len(info.archVariantProperties)
+
+ // Choose setting for compile_multilib that is appropriate for the arch variants supplied.
+ var multilib string
+ if archVariantCount == 2 {
+ multilib = "both"
+ } else if archVariantCount == 1 {
+ if strings.HasSuffix(info.archVariantProperties[0].archType, "64") {
+ multilib = "64"
+ } else {
+ multilib = "32"
+ }
+ }
+ if multilib != "" {
+ pbm.AddProperty("compile_multilib", multilib)
+ }
+
archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariantProperties {
archTypeProperties := archProperties.AddPropertySet(av.archType)
diff --git a/cc/library.go b/cc/library.go
index bca9a96..6ffb7fc 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -183,7 +183,6 @@
ctx.RegisterModuleType("cc_library", LibraryFactory)
ctx.RegisterModuleType("cc_library_host_static", LibraryHostStaticFactory)
ctx.RegisterModuleType("cc_library_host_shared", LibraryHostSharedFactory)
- ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
}
// cc_library creates both static and/or shared libraries for a device and/or
@@ -233,16 +232,6 @@
return module.Init()
}
-// cc_library_headers contains a set of c/c++ headers which are imported by
-// other soong cc modules using the header_libs property. For best practices,
-// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
-// Make.
-func LibraryHeaderFactory() android.Module {
- module, library := NewLibrary(android.HostAndDeviceSupported)
- library.HeaderOnly()
- return module.Init()
-}
-
type flagExporter struct {
Properties FlagExporterProperties
@@ -1314,22 +1303,28 @@
if cc_prebuilt {
library := mctx.Module().(*Module).linker.(prebuiltLibraryInterface)
- // Always create both the static and shared variants for prebuilt libraries, and then disable the one
- // that is not being used. This allows them to share the name of a cc_library module, which requires that
- // all the variants of the cc_library also exist on the prebuilt.
- modules := mctx.CreateLocalVariations("static", "shared")
- static := modules[0].(*Module)
- shared := modules[1].(*Module)
+ // Differentiate between header only and building an actual static/shared library
+ if library.buildStatic() || library.buildShared() {
+ // Always create both the static and shared variants for prebuilt libraries, and then disable the one
+ // that is not being used. This allows them to share the name of a cc_library module, which requires that
+ // all the variants of the cc_library also exist on the prebuilt.
+ modules := mctx.CreateLocalVariations("static", "shared")
+ static := modules[0].(*Module)
+ shared := modules[1].(*Module)
- static.linker.(prebuiltLibraryInterface).setStatic()
- shared.linker.(prebuiltLibraryInterface).setShared()
+ static.linker.(prebuiltLibraryInterface).setStatic()
+ shared.linker.(prebuiltLibraryInterface).setShared()
- if !library.buildStatic() {
- static.linker.(prebuiltLibraryInterface).disablePrebuilt()
+ if !library.buildStatic() {
+ static.linker.(prebuiltLibraryInterface).disablePrebuilt()
+ }
+ if !library.buildShared() {
+ shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
+ }
+ } else {
+ // Header only
}
- if !library.buildShared() {
- shared.linker.(prebuiltLibraryInterface).disablePrebuilt()
- }
+
} else if library, ok := mctx.Module().(LinkableInterface); ok && library.CcLibraryInterface() {
// Non-cc.Modules may need an empty variant for their mutators.
diff --git a/cc/library_headers.go b/cc/library_headers.go
new file mode 100644
index 0000000..88cf7af
--- /dev/null
+++ b/cc/library_headers.go
@@ -0,0 +1,56 @@
+// Copyright 2020 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.
+
+package cc
+
+import "android/soong/android"
+
+func init() {
+ RegisterLibraryHeadersBuildComponents(android.InitRegistrationContext)
+
+ // Register sdk member types.
+ android.RegisterSdkMemberType(headersLibrarySdkMemberType)
+}
+
+var headersLibrarySdkMemberType = &librarySdkMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "native_header_libs",
+ SupportsSdk: true,
+ },
+ prebuiltModuleType: "cc_prebuilt_library_headers",
+ linkTypes: nil,
+}
+
+func RegisterLibraryHeadersBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("cc_library_headers", LibraryHeaderFactory)
+ ctx.RegisterModuleType("cc_prebuilt_library_headers", prebuiltLibraryHeaderFactory)
+}
+
+// cc_library_headers contains a set of c/c++ headers which are imported by
+// other soong cc modules using the header_libs property. For best practices,
+// use export_include_dirs property or LOCAL_EXPORT_C_INCLUDE_DIRS for
+// Make.
+func LibraryHeaderFactory() android.Module {
+ module, library := NewLibrary(android.HostAndDeviceSupported)
+ library.HeaderOnly()
+ module.sdkMemberTypes = []android.SdkMemberType{headersLibrarySdkMemberType}
+ return module.Init()
+}
+
+// cc_prebuilt_library_headers is a prebuilt version of cc_library_headers
+func prebuiltLibraryHeaderFactory() android.Module {
+ module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported)
+ library.HeaderOnly()
+ return module.Init()
+}
diff --git a/cc/library_headers_test.go b/cc/library_headers_test.go
new file mode 100644
index 0000000..564ef61
--- /dev/null
+++ b/cc/library_headers_test.go
@@ -0,0 +1,62 @@
+// Copyright 2020 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.
+
+package cc
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestLibraryHeaders(t *testing.T) {
+ ctx := testCc(t, `
+ cc_library_headers {
+ name: "headers",
+ export_include_dirs: ["my_include"],
+ }
+ cc_library_static {
+ name: "lib",
+ srcs: ["foo.c"],
+ header_libs: ["headers"],
+ }
+ `)
+
+ // test if header search paths are correctly added
+ cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
+ cflags := cc.Args["cFlags"]
+ if !strings.Contains(cflags, " -Imy_include ") {
+ t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
+ }
+}
+
+func TestPrebuiltLibraryHeaders(t *testing.T) {
+ ctx := testCc(t, `
+ cc_prebuilt_library_headers {
+ name: "headers",
+ export_include_dirs: ["my_include"],
+ }
+ cc_library_static {
+ name: "lib",
+ srcs: ["foo.c"],
+ header_libs: ["headers"],
+ }
+ `)
+
+ // test if header search paths are correctly added
+ cc := ctx.ModuleForTests("lib", "android_arm64_armv8-a_static").Rule("cc")
+ cflags := cc.Args["cFlags"]
+ if !strings.Contains(cflags, " -Imy_include ") {
+ t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
+ }
+}
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index dd097cf..a36917e 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -65,12 +65,19 @@
if version == "" {
version = LatestStubsVersionFor(mctx.Config(), name)
}
- for _, linkType := range mt.linkTypes {
+ if mt.linkTypes == nil {
mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
{Mutator: "image", Variation: android.CoreVariation},
- {Mutator: "link", Variation: linkType},
{Mutator: "version", Variation: version},
}...), dependencyTag, name)
+ } else {
+ for _, linkType := range mt.linkTypes {
+ mctx.AddFarVariationDependencies(append(target.Variations(), []blueprint.Variation{
+ {Mutator: "image", Variation: android.CoreVariation},
+ {Mutator: "link", Variation: linkType},
+ {Mutator: "version", Variation: version},
+ }...), dependencyTag, name)
+ }
}
}
}
@@ -92,7 +99,7 @@
// copy exported header files and stub *.so files
func (mt *librarySdkMemberType) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
info := mt.organizeVariants(member)
- buildSharedNativeLibSnapshot(sdkModuleContext, info, builder, member)
+ info.generatePrebuiltLibrary(sdkModuleContext, builder, member)
}
// Organize the variants by architecture.
@@ -197,85 +204,148 @@
}
}
-func buildSharedNativeLibSnapshot(sdkModuleContext android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder, member android.SdkMember) {
- // a function for emitting include dirs
- addExportedDirCopyCommandsForNativeLibs := func(lib nativeLibInfoProperties) {
- // Do not include exportedGeneratedIncludeDirs in the list of directories whose
- // contents are copied as they are copied from exportedGeneratedHeaders below.
- includeDirs := lib.ExportedIncludeDirs
- includeDirs = append(includeDirs, lib.ExportedSystemIncludeDirs...)
- for _, dir := range includeDirs {
- // lib.ArchType is "" for common properties.
- targetDir := filepath.Join(lib.archType, nativeIncludeDir)
-
- // TODO(jiyong) copy headers having other suffixes
- headers, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.h", nil)
- for _, file := range headers {
- src := android.PathForSource(sdkModuleContext, file)
- dest := filepath.Join(targetDir, file)
- builder.CopyToSnapshot(src, dest)
- }
- }
-
- genHeaders := lib.exportedGeneratedHeaders
- for _, file := range genHeaders {
- // lib.ArchType is "" for common properties.
- targetDir := filepath.Join(lib.archType, nativeGeneratedIncludeDir)
-
- dest := filepath.Join(targetDir, lib.name, file.Rel())
- builder.CopyToSnapshot(file, dest)
- }
- }
-
- addExportedDirCopyCommandsForNativeLibs(info.commonProperties)
-
- // for each architecture
- for _, av := range info.archVariantProperties {
- builder.CopyToSnapshot(av.outputFile, nativeLibraryPathFor(av))
-
- addExportedDirCopyCommandsForNativeLibs(av)
- }
-
- info.generatePrebuiltLibrary(sdkModuleContext, builder, member)
-}
-
func (info *nativeLibInfo) generatePrebuiltLibrary(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember) {
pbm := builder.AddPrebuiltModule(member, info.memberType.prebuiltModuleType)
- addPossiblyArchSpecificProperties(info.commonProperties, pbm)
+ addPossiblyArchSpecificProperties(sdkModuleContext, builder, info.commonProperties, pbm)
archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariantProperties {
archTypeProperties := archProperties.AddPropertySet(av.archType)
- // Add any arch specific properties inside the appropriate arch: {<arch>: {...}} block
- archTypeProperties.AddProperty("srcs", []string{nativeLibraryPathFor(av)})
- addPossiblyArchSpecificProperties(av, archTypeProperties)
+ // If the library has some link types then it produces an output binary file, otherwise it
+ // is header only.
+ if info.memberType.linkTypes != nil {
+ // Copy the generated library to the snapshot and add a reference to it in the .bp module.
+ nativeLibraryPath := nativeLibraryPathFor(av)
+ builder.CopyToSnapshot(av.outputFile, nativeLibraryPath)
+ archTypeProperties.AddProperty("srcs", []string{nativeLibraryPath})
+ }
+
+ // Add any arch specific properties inside the appropriate arch: {<arch>: {...}} block
+ addPossiblyArchSpecificProperties(sdkModuleContext, builder, av, archTypeProperties)
}
pbm.AddProperty("stl", "none")
pbm.AddProperty("system_shared_libs", []string{})
}
-// Add properties that may, or may not, be arch specific.
-func addPossiblyArchSpecificProperties(libInfo nativeLibInfoProperties, outputProperties android.BpPropertySet) {
- addExportedDirsForNativeLibs(libInfo, outputProperties, false /*systemInclude*/)
- addExportedDirsForNativeLibs(libInfo, outputProperties, true /*systemInclude*/)
+type includeDirsProperty struct {
+ // Accessor to retrieve the paths
+ pathsGetter func(libInfo nativeLibInfoProperties) android.Paths
+
+ // The name of the property in the prebuilt library, "" means there is no property.
+ propertyName string
+
+ // The directory within the snapshot directory into which items should be copied.
+ snapshotDir string
+
+ // True if the items on the path should be copied.
+ copy bool
+
+ // True if the paths represent directories, files if they represent files.
+ dirs bool
}
-// a function for emitting include dirs
-func addExportedDirsForNativeLibs(lib nativeLibInfoProperties, properties android.BpPropertySet, systemInclude bool) {
- includeDirs := nativeIncludeDirPathsFor(lib, systemInclude)
- if len(includeDirs) == 0 {
- return
+var includeDirProperties = []includeDirsProperty{
+ {
+ // ExportedIncludeDirs lists directories that contains some header files to be
+ // copied into a directory in the snapshot. The snapshot directories must be added to
+ // the export_include_dirs property in the prebuilt module in the snapshot.
+ pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.ExportedIncludeDirs },
+ propertyName: "export_include_dirs",
+ snapshotDir: nativeIncludeDir,
+ copy: true,
+ dirs: true,
+ },
+ {
+ // ExportedSystemIncludeDirs lists directories that contains some system header files to
+ // be copied into a directory in the snapshot. The snapshot directories must be added to
+ // the export_system_include_dirs property in the prebuilt module in the snapshot.
+ pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.ExportedSystemIncludeDirs },
+ propertyName: "export_system_include_dirs",
+ snapshotDir: nativeIncludeDir,
+ copy: true,
+ dirs: true,
+ },
+ {
+ // exportedGeneratedIncludeDirs lists directories that contains some header files
+ // that are explicitly listed in the exportedGeneratedHeaders property. So, the contents
+ // of these directories do not need to be copied, but these directories do need adding to
+ // the export_include_dirs property in the prebuilt module in the snapshot.
+ pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.exportedGeneratedIncludeDirs },
+ propertyName: "export_include_dirs",
+ snapshotDir: nativeGeneratedIncludeDir,
+ copy: false,
+ dirs: true,
+ },
+ {
+ // exportedGeneratedHeaders lists header files that are in one of the directories
+ // specified in exportedGeneratedIncludeDirs must be copied into the snapshot.
+ // As they are in a directory in exportedGeneratedIncludeDirs they do not need adding to a
+ // property in the prebuilt module in the snapshot.
+ pathsGetter: func(libInfo nativeLibInfoProperties) android.Paths { return libInfo.exportedGeneratedHeaders },
+ propertyName: "",
+ snapshotDir: nativeGeneratedIncludeDir,
+ copy: true,
+ dirs: false,
+ },
+}
+
+// Add properties that may, or may not, be arch specific.
+func addPossiblyArchSpecificProperties(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, libInfo nativeLibInfoProperties, outputProperties android.BpPropertySet) {
+
+ // Map from property name to the include dirs to add to the prebuilt module in the snapshot.
+ includeDirs := make(map[string][]string)
+
+ // Iterate over each include directory property, copying files and collating property
+ // values where necessary.
+ for _, propertyInfo := range includeDirProperties {
+ // Calculate the base directory in the snapshot into which the files will be copied.
+ // lib.ArchType is "" for common properties.
+ targetDir := filepath.Join(libInfo.archType, propertyInfo.snapshotDir)
+
+ propertyName := propertyInfo.propertyName
+
+ // Iterate over each path in one of the include directory properties.
+ for _, path := range propertyInfo.pathsGetter(libInfo) {
+
+ // Copy the files/directories when necessary.
+ if propertyInfo.copy {
+ if propertyInfo.dirs {
+ // When copying a directory glob and copy all the headers within it.
+ // TODO(jiyong) copy headers having other suffixes
+ headers, _ := sdkModuleContext.GlobWithDeps(path.String()+"/**/*.h", nil)
+ for _, file := range headers {
+ src := android.PathForSource(sdkModuleContext, file)
+ dest := filepath.Join(targetDir, file)
+ builder.CopyToSnapshot(src, dest)
+ }
+ } else {
+ // Otherwise, just copy the files.
+ dest := filepath.Join(targetDir, libInfo.name, path.Rel())
+ builder.CopyToSnapshot(path, dest)
+ }
+ }
+
+ // Only directories are added to a property.
+ if propertyInfo.dirs {
+ var snapshotPath string
+ if isGeneratedHeaderDirectory(path) {
+ snapshotPath = filepath.Join(targetDir, libInfo.name)
+ } else {
+ snapshotPath = filepath.Join(targetDir, path.String())
+ }
+
+ includeDirs[propertyName] = append(includeDirs[propertyName], snapshotPath)
+ }
+ }
}
- var propertyName string
- if !systemInclude {
- propertyName = "export_include_dirs"
- } else {
- propertyName = "export_system_include_dirs"
+
+ // Add the collated include dir properties to the output.
+ for property, dirs := range includeDirs {
+ outputProperties.AddProperty(property, dirs)
}
- properties.AddProperty(propertyName, includeDirs)
}
const (
@@ -290,31 +360,6 @@
nativeStubDir, lib.outputFile.Base())
}
-// paths to the include dirs of a native shared library. Relative to <sdk_root>/<api_dir>
-func nativeIncludeDirPathsFor(lib nativeLibInfoProperties, systemInclude bool) []string {
- var result []string
- var includeDirs []android.Path
- if !systemInclude {
- // Include the generated include dirs in the exported include dirs.
- includeDirs = append(lib.ExportedIncludeDirs, lib.exportedGeneratedIncludeDirs...)
- } else {
- includeDirs = lib.ExportedSystemIncludeDirs
- }
- for _, dir := range includeDirs {
- var path string
- if isGeneratedHeaderDirectory(dir) {
- path = filepath.Join(nativeGeneratedIncludeDir, lib.name)
- } else {
- path = filepath.Join(nativeIncludeDir, dir.String())
- }
-
- // lib.ArchType is "" for common properties.
- path = filepath.Join(lib.archType, path)
- result = append(result, path)
- }
- return result
-}
-
// nativeLibInfoProperties represents properties of a native lib
//
// The exported (capitalized) fields will be examined and may be changed during common value extraction.
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index b0cf489..2c18ac3 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -87,15 +87,16 @@
func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
flags Flags, deps PathDeps, objs Objects) android.Path {
+
+ p.libraryDecorator.exportIncludes(ctx)
+ p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
+ p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
+ p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
+ p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
+ p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
+
// TODO(ccross): verify shared library dependencies
if len(p.properties.Srcs) > 0 {
- p.libraryDecorator.exportIncludes(ctx)
- p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
- p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
- p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
- p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
- p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
-
builderFlags := flagsToBuilderFlags(flags)
in := p.Prebuilt.SingleSourcePath(ctx)
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 5ea8ee08..6e809bf 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -609,18 +609,18 @@
return flags
}
-func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+func (sanitize *sanitize) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
// Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
// both the sanitized and non-sanitized variants to make without a name conflict.
- if ret.Class == "STATIC_LIBRARIES" || ret.Class == "HEADER_LIBRARIES" {
+ if entries.Class == "STATIC_LIBRARIES" || entries.Class == "HEADER_LIBRARIES" {
if Bool(sanitize.Properties.Sanitize.Cfi) {
- ret.SubName += ".cfi"
+ entries.SubName += ".cfi"
}
if Bool(sanitize.Properties.Sanitize.Hwaddress) {
- ret.SubName += ".hwasan"
+ entries.SubName += ".hwasan"
}
if Bool(sanitize.Properties.Sanitize.Scs) {
- ret.SubName += ".scs"
+ entries.SubName += ".scs"
}
}
}
diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go
index 8f48f86..73388ce 100644
--- a/cc/snapshot_utils.go
+++ b/cc/snapshot_utils.go
@@ -117,6 +117,17 @@
return outPath
}
+func combineNotices(ctx android.SingletonContext, paths android.Paths, out string) android.OutputPath {
+ outPath := android.PathForOutput(ctx, out)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cat,
+ Inputs: paths,
+ Output: outPath,
+ Description: "combine notices for " + out,
+ })
+ return outPath
+}
+
func writeStringToFile(ctx android.SingletonContext, content, out string) android.OutputPath {
outPath := android.PathForOutput(ctx, out)
ctx.Build(pctx, android.BuildParams{
diff --git a/cc/test.go b/cc/test.go
index 05e6fe5..1085d3a 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -49,7 +49,7 @@
// list of files or filegroup modules that provide data that should be installed alongside
// the test
- Data []string `android:"path"`
+ Data []string `android:"path,arch_variant"`
// list of compatibility suites (for example "cts", "vts") that the module should be
// installed into.
diff --git a/cc/testing.go b/cc/testing.go
index 7b0305f..a22763a 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -25,6 +25,7 @@
RegisterCCBuildComponents(ctx)
RegisterBinaryBuildComponents(ctx)
RegisterLibraryBuildComponents(ctx)
+ RegisterLibraryHeadersBuildComponents(ctx)
ctx.RegisterModuleType("toolchain_library", ToolchainLibraryFactory)
ctx.RegisterModuleType("llndk_library", LlndkLibraryFactory)
@@ -213,6 +214,7 @@
stl: "none",
vendor_available: true,
recovery_available: true,
+ host_supported: true,
}
cc_library {
name: "libc++",
@@ -222,6 +224,7 @@
stl: "none",
vendor_available: true,
recovery_available: true,
+ host_supported: true,
vndk: {
enabled: true,
support_system_process: true,
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index aed7918..20762a8 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -661,14 +661,14 @@
headers = append(headers, exportedHeaders(ctx, l)...)
}
- if m.NoticeFile().Valid() {
+ if len(m.NoticeFiles()) > 0 {
noticeName := ctx.ModuleName(m) + ".txt"
noticeOut := filepath.Join(noticeDir, noticeName)
// skip already copied notice file
if !installedNotices[noticeOut] {
installedNotices[noticeOut] = true
- snapshotOutputs = append(snapshotOutputs, copyFile(
- ctx, m.NoticeFile().Path(), noticeOut))
+ snapshotOutputs = append(snapshotOutputs, combineNotices(
+ ctx, m.NoticeFiles(), noticeOut))
}
}
})
diff --git a/cc/vndk.go b/cc/vndk.go
index 4578a7d..d0492fc 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -644,13 +644,13 @@
moduleNames[stem] = ctx.ModuleName(m)
modulePaths[stem] = ctx.ModuleDir(m)
- if m.NoticeFile().Valid() {
+ if len(m.NoticeFiles()) > 0 {
noticeName := stem + ".txt"
// skip already copied notice file
if _, ok := noticeBuilt[noticeName]; !ok {
noticeBuilt[noticeName] = true
- snapshotOutputs = append(snapshotOutputs, copyFile(
- ctx, m.NoticeFile().Path(), filepath.Join(noticeDir, noticeName)))
+ snapshotOutputs = append(snapshotOutputs, combineNotices(
+ ctx, m.NoticeFiles(), filepath.Join(noticeDir, noticeName)))
}
}
diff --git a/java/app.go b/java/app.go
index bcf08a7..ed4462c 100755
--- a/java/app.go
+++ b/java/app.go
@@ -390,16 +390,20 @@
return false
}
- path := child.(android.Module).NoticeFile()
- if path.Valid() {
- noticePathSet[path.Path()] = true
+ paths := child.(android.Module).NoticeFiles()
+ if len(paths) > 0 {
+ for _, path := range paths {
+ noticePathSet[path] = true
+ }
}
return true
})
// If the app has one, add it too.
- if a.NoticeFile().Valid() {
- noticePathSet[a.NoticeFile().Path()] = true
+ if len(a.NoticeFiles()) > 0 {
+ for _, path := range a.NoticeFiles() {
+ noticePathSet[path] = true
+ }
}
if len(noticePathSet) == 0 {
@@ -491,7 +495,7 @@
dexJarFile := a.dexBuildActions(ctx)
- jniLibs, certificateDeps := collectAppDeps(ctx, a.shouldEmbedJnis(ctx))
+ jniLibs, certificateDeps := collectAppDeps(ctx, a.shouldEmbedJnis(ctx), !Bool(a.appProperties.Jni_uses_platform_apis))
jniJarFile := a.jniBuildActions(jniLibs, ctx)
if ctx.Failed() {
@@ -527,7 +531,8 @@
}
}
-func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps bool) ([]jniLib, []Certificate) {
+func collectAppDeps(ctx android.ModuleContext, shouldCollectRecursiveNativeDeps bool,
+ checkNativeSdkVersion bool) ([]jniLib, []Certificate) {
var jniLibs []jniLib
var certificates []Certificate
seenModulePaths := make(map[string]bool)
@@ -549,6 +554,18 @@
}
seenModulePaths[path.String()] = true
+ if checkNativeSdkVersion {
+ if app, ok := ctx.Module().(interface{ sdkVersion() sdkSpec }); ok {
+ if app.sdkVersion().specified() &&
+ app.sdkVersion().kind != sdkCorePlatform &&
+ dep.SdkVersion() == "" {
+ ctx.PropertyErrorf("jni_libs",
+ "JNI dependency %q uses platform APIs, but this module does not",
+ otherName)
+ }
+ }
+ }
+
if lib.Valid() {
jniLibs = append(jniLibs, jniLib{
name: ctx.OtherModuleName(module),
@@ -1045,7 +1062,7 @@
ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
}
- _, certificates := collectAppDeps(ctx, false)
+ _, certificates := collectAppDeps(ctx, false, false)
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
@@ -1300,7 +1317,7 @@
r.aapt.buildActions(ctx, r, "--no-resource-deduping", "--no-resource-removal")
// Sign the built package
- _, certificates := collectAppDeps(ctx, false)
+ _, certificates := collectAppDeps(ctx, false, false)
certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates)
diff --git a/java/app_test.go b/java/app_test.go
index dfd8571..0c6da7a 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -903,6 +903,7 @@
name: "libjni",
system_shared_libs: [],
stl: "none",
+ sdk_version: "current",
}
android_app {
@@ -2112,6 +2113,7 @@
system_shared_libs: [],
stl: "none",
notice: "LIB_NOTICE",
+ sdk_version: "current",
}
java_library {
diff --git a/java/config/config.go b/java/config/config.go
index 7f446e5..54c89cd 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -48,7 +48,7 @@
// TODO: Could this be all updatable bootclasspath jars?
"updatable-media",
"framework-sdkextensions",
- "ike",
+ "android.net.ipsec.ike",
}
)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 4313964..40cfe4f 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -132,28 +132,28 @@
bootImage = artBootImageConfig(ctx)
}
- var archs []android.ArchType
- for _, a := range ctx.MultiTargets() {
- archs = append(archs, a.Arch.ArchType)
- }
- if len(archs) == 0 {
+ targets := ctx.MultiTargets()
+ if len(targets) == 0 {
// assume this is a java library, dexpreopt for all arches for now
for _, target := range ctx.Config().Targets[android.Android] {
if target.NativeBridge == android.NativeBridgeDisabled {
- archs = append(archs, target.Arch.ArchType)
+ targets = append(targets, target)
}
}
if inList(ctx.ModuleName(), global.SystemServerJars) && !d.isSDKLibrary {
// If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
- archs = archs[:1]
+ targets = targets[:1]
}
}
+ var archs []android.ArchType
var images android.Paths
var imagesDeps []android.OutputPaths
- for _, arch := range archs {
- images = append(images, bootImage.images[arch])
- imagesDeps = append(imagesDeps, bootImage.imagesDeps[arch])
+ for _, target := range targets {
+ archs = append(archs, target.Arch.ArchType)
+ variant := bootImage.getVariant(target)
+ images = append(images, variant.images)
+ imagesDeps = append(imagesDeps, variant.imagesDeps)
}
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 655a476..d7adb40 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,7 +16,6 @@
import (
"path/filepath"
- "sort"
"strings"
"android/soong/android"
@@ -48,6 +47,7 @@
// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
// will then reconstruct the real path, so the rules must have a dependency on the real path.
+// Target-independent description of pre-compiled boot image.
type bootImageConfig struct {
// Whether this image is an extension.
extension bool
@@ -67,9 +67,6 @@
// Subdirectory where the image files are installed.
installSubdir string
- // Targets for which the image is generated.
- targets []android.Target
-
// The names of jars that constitute this image.
modules []string
@@ -84,15 +81,43 @@
// The "locations" of the dependency images and in this image.
imageLocations []string
- // Paths to image files (grouped by target).
- images map[android.ArchType]android.OutputPath // first image file
- imagesDeps map[android.ArchType]android.OutputPaths // all files
-
- // Only for extensions, paths to the primary boot images (grouped by target).
- primaryImages map[android.ArchType]android.OutputPath
-
// File path to a zip archive with all image files (or nil, if not needed).
zip android.WritablePath
+
+ // Rules which should be used in make to install the outputs.
+ profileInstalls android.RuleBuilderInstalls
+
+ // Target-dependent fields.
+ variants []*bootImageVariant
+}
+
+// Target-dependent description of pre-compiled boot image.
+type bootImageVariant struct {
+ *bootImageConfig
+
+ // Target for which the image is generated.
+ target android.Target
+
+ // Paths to image files.
+ images android.OutputPath // first image file
+ imagesDeps android.OutputPaths // all files
+
+ // Only for extensions, paths to the primary boot images.
+ primaryImages android.OutputPath
+
+ // Rules which should be used in make to install the outputs.
+ installs android.RuleBuilderInstalls
+ vdexInstalls android.RuleBuilderInstalls
+ unstrippedInstalls android.RuleBuilderInstalls
+}
+
+func (image bootImageConfig) getVariant(target android.Target) *bootImageVariant {
+ for _, variant := range image.variants {
+ if variant.target.Os == target.Os && variant.target.Arch.ArchType == target.Arch.ArchType {
+ return variant
+ }
+ }
+ return nil
}
func (image bootImageConfig) moduleName(idx int) string {
@@ -126,28 +151,6 @@
return ret
}
-type bootImage struct {
- bootImageConfig
-
- installs map[android.ArchType]android.RuleBuilderInstalls
- vdexInstalls map[android.ArchType]android.RuleBuilderInstalls
- unstrippedInstalls map[android.ArchType]android.RuleBuilderInstalls
-
- profileInstalls android.RuleBuilderInstalls
-}
-
-func newBootImage(ctx android.PathContext, config bootImageConfig) *bootImage {
- image := &bootImage{
- bootImageConfig: config,
-
- installs: make(map[android.ArchType]android.RuleBuilderInstalls),
- vdexInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
- unstrippedInstalls: make(map[android.ArchType]android.RuleBuilderInstalls),
- }
-
- return image
-}
-
func concat(lists ...[]string) []string {
var size int
for _, l := range lists {
@@ -182,8 +185,8 @@
}
type dexpreoptBootJars struct {
- defaultBootImage *bootImage
- otherImages []*bootImage
+ defaultBootImage *bootImageConfig
+ otherImages []*bootImageConfig
dexpreoptConfigForMake android.WritablePath
}
@@ -193,10 +196,11 @@
if skipDexpreoptBootJars(ctx) {
return nil
}
-
// Include dexpreopt files for the primary boot image.
- files := artBootImageConfig(ctx).imagesDeps
-
+ files := map[android.ArchType]android.OutputPaths{}
+ for _, variant := range artBootImageConfig(ctx).variants {
+ files[variant.target.Arch.ArchType] = variant.imagesDeps
+ }
return files
}
@@ -233,10 +237,8 @@
dumpOatRules(ctx, d.defaultBootImage)
}
-// buildBootImage takes a bootImageConfig, creates rules to build it, and returns a *bootImage.
-func buildBootImage(ctx android.SingletonContext, config bootImageConfig) *bootImage {
- image := newBootImage(ctx, config)
-
+// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
+func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
bootDexJars := make(android.Paths, len(image.modules))
ctx.VisitAllModules(func(module android.Module) {
// Collect dex jar paths for the modules listed above.
@@ -277,8 +279,8 @@
bootFrameworkProfileRule(ctx, image, missingDeps)
var allFiles android.Paths
- for _, target := range image.targets {
- files := buildBootImageRuleForArch(ctx, image, target.Arch.ArchType, profile, missingDeps)
+ for _, variant := range image.variants {
+ files := buildBootImageVariant(ctx, variant, profile, missingDeps)
allFiles = append(allFiles, files.Paths()...)
}
@@ -296,12 +298,13 @@
return image
}
-func buildBootImageRuleForArch(ctx android.SingletonContext, image *bootImage,
- arch android.ArchType, profile android.Path, missingDeps []string) android.WritablePaths {
+func buildBootImageVariant(ctx android.SingletonContext, image *bootImageVariant,
+ profile android.Path, missingDeps []string) android.WritablePaths {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
+ arch := image.target.Arch.ArchType
symbolsDir := image.symbolsDir.Join(ctx, image.installSubdir, arch.String())
symbolsFile := symbolsDir.Join(ctx, image.stem+".oat")
outputDir := image.dir.Join(ctx, image.installSubdir, arch.String())
@@ -351,7 +354,7 @@
}
if image.extension {
- artImage := image.primaryImages[arch]
+ artImage := image.primaryImages
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":").
@@ -426,9 +429,9 @@
rule.Build(pctx, ctx, image.name+"JarsDexpreopt_"+arch.String(), "dexpreopt "+image.name+" jars "+arch.String())
// save output and installed files for makevars
- image.installs[arch] = rule.Installs()
- image.vdexInstalls[arch] = vdexInstalls
- image.unstrippedInstalls[arch] = unstrippedInstalls
+ image.installs = rule.Installs()
+ image.vdexInstalls = vdexInstalls
+ image.unstrippedInstalls = unstrippedInstalls
return zipFiles
}
@@ -437,7 +440,7 @@
It is likely that the boot classpath is inconsistent.
Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.`
-func bootImageProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
+func bootImageProfileRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -492,7 +495,7 @@
var bootImageProfileRuleKey = android.NewOnceKey("bootImageProfileRule")
-func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImage, missingDeps []string) android.WritablePath {
+func bootFrameworkProfileRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
globalSoong := dexpreopt.GetCachedGlobalSoongConfig(ctx)
global := dexpreopt.GetGlobalConfig(ctx)
@@ -537,15 +540,10 @@
var bootFrameworkProfileRuleKey = android.NewOnceKey("bootFrameworkProfileRule")
-func dumpOatRules(ctx android.SingletonContext, image *bootImage) {
- var archs []android.ArchType
- for arch := range image.images {
- archs = append(archs, arch)
- }
- sort.Slice(archs, func(i, j int) bool { return archs[i].String() < archs[j].String() })
-
+func dumpOatRules(ctx android.SingletonContext, image *bootImageConfig) {
var allPhonies android.Paths
- for _, arch := range archs {
+ for _, image := range image.variants {
+ arch := image.target.Arch.ArchType
// Create a rule to call oatdump.
output := android.PathForOutput(ctx, "boot."+arch.String()+".oatdump.txt")
rule := android.NewRuleBuilder()
@@ -554,7 +552,7 @@
BuiltTool(ctx, "oatdumpd").
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
- FlagWithArg("--image=", strings.Join(image.imageLocations, ":")).Implicits(image.imagesDeps[arch].Paths()).
+ FlagWithArg("--image=", strings.Join(image.imageLocations, ":")).Implicits(image.imagesDeps.Paths()).
FlagWithOutput("--output=", output).
FlagWithArg("--instruction-set=", arch.String())
rule.Build(pctx, ctx, "dump-oat-boot-"+arch.String(), "dump oat boot "+arch.String())
@@ -609,20 +607,13 @@
var imageNames []string
for _, current := range append(d.otherImages, image) {
imageNames = append(imageNames, current.name)
- var arches []android.ArchType
- for arch, _ := range current.images {
- arches = append(arches, arch)
- }
-
- sort.Slice(arches, func(i, j int) bool { return arches[i].String() < arches[j].String() })
-
- for _, arch := range arches {
- sfx := current.name + "_" + arch.String()
- ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps[arch].Strings(), " "))
- ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs[arch].String())
- ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls[arch].String())
+ for _, current := range current.variants {
+ sfx := current.name + "_" + current.target.Arch.ArchType.String()
+ ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls.String())
+ ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images.String())
+ ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps.Strings(), " "))
+ ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs.String())
+ ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls.String())
}
ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(current.imageLocations, ":"))
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 28f56d2..a06aec4 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -146,8 +146,6 @@
// common to all configs
for _, c := range configs {
- c.targets = targets
-
c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars")
c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped")
@@ -166,14 +164,17 @@
}
c.dexPathsDeps = c.dexPaths
- c.images = make(map[android.ArchType]android.OutputPath)
- c.imagesDeps = make(map[android.ArchType]android.OutputPaths)
-
+ // Create target-specific variants.
for _, target := range targets {
arch := target.Arch.ArchType
imageDir := c.dir.Join(ctx, c.installSubdir, arch.String())
- c.images[arch] = imageDir.Join(ctx, imageName)
- c.imagesDeps[arch] = c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex")
+ variant := &bootImageVariant{
+ bootImageConfig: c,
+ target: target,
+ images: imageDir.Join(ctx, imageName),
+ imagesDeps: c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex"),
+ }
+ c.variants = append(c.variants, variant)
}
c.zip = c.dir.Join(ctx, c.name+".zip")
@@ -181,19 +182,21 @@
// specific to the framework config
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
- frameworkCfg.primaryImages = artCfg.images
+ for i := range targets {
+ frameworkCfg.variants[i].primaryImages = artCfg.variants[i].images
+ }
frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
return configs
}).(map[string]*bootImageConfig)
}
-func artBootImageConfig(ctx android.PathContext) bootImageConfig {
- return *genBootImageConfigs(ctx)[artBootImageName]
+func artBootImageConfig(ctx android.PathContext) *bootImageConfig {
+ return genBootImageConfigs(ctx)[artBootImageName]
}
-func defaultBootImageConfig(ctx android.PathContext) bootImageConfig {
- return *genBootImageConfigs(ctx)[frameworkBootImageName]
+func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig {
+ return genBootImageConfigs(ctx)[frameworkBootImageName]
}
func defaultBootclasspath(ctx android.PathContext) []string {
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 6020aba..884a757 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -28,9 +28,10 @@
}, "outFlag", "stubAPIFlags")
type hiddenAPI struct {
- flagsCSVPath android.Path
- metadataCSVPath android.Path
bootDexJarPath android.Path
+ flagsCSVPath android.Path
+ indexCSVPath android.Path
+ metadataCSVPath android.Path
}
func (h *hiddenAPI) flagsCSV() android.Path {
@@ -45,17 +46,21 @@
return h.bootDexJarPath
}
+func (h *hiddenAPI) indexCSV() android.Path {
+ return h.indexCSVPath
+}
+
type hiddenAPIIntf interface {
- flagsCSV() android.Path
- metadataCSV() android.Path
bootDexJar() android.Path
+ flagsCSV() android.Path
+ indexCSV() android.Path
+ metadataCSV() android.Path
}
var _ hiddenAPIIntf = (*hiddenAPI)(nil)
-func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOutPath, implementationJar android.Path,
- uncompressDex bool) android.ModuleOutPath {
-
+func (h *hiddenAPI) hiddenAPI(ctx android.ModuleContext, dexJar android.ModuleOutPath,
+ implementationJar android.Path, uncompressDex bool) android.ModuleOutPath {
if !ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
name := ctx.ModuleName()
@@ -77,9 +82,8 @@
// Derive the greylist from classes jar.
flagsCSV := android.PathForModuleOut(ctx, "hiddenapi", "flags.csv")
metadataCSV := android.PathForModuleOut(ctx, "hiddenapi", "metadata.csv")
- hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, implementationJar)
- h.flagsCSVPath = flagsCSV
- h.metadataCSVPath = metadataCSV
+ indexCSV := android.PathForModuleOut(ctx, "hiddenapi", "index.csv")
+ h.hiddenAPIGenerateCSV(ctx, flagsCSV, metadataCSV, indexCSV, implementationJar)
// If this module is actually on the boot jars list and not providing
// hiddenapi information for a module on the boot jars list then encode
@@ -96,9 +100,7 @@
return dexJar
}
-func hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV android.WritablePath,
- classesJar android.Path) {
-
+func (h *hiddenAPI) hiddenAPIGenerateCSV(ctx android.ModuleContext, flagsCSV, metadataCSV, indexCSV android.WritablePath, classesJar android.Path) {
stubFlagsCSV := hiddenAPISingletonPaths(ctx).stubFlags
ctx.Build(pctx, android.BuildParams{
@@ -112,6 +114,7 @@
"stubAPIFlags": stubFlagsCSV.String(),
},
})
+ h.flagsCSVPath = flagsCSV
ctx.Build(pctx, android.BuildParams{
Rule: hiddenAPIGenerateCSVRule,
@@ -124,18 +127,26 @@
"stubAPIFlags": stubFlagsCSV.String(),
},
})
+ h.metadataCSVPath = metadataCSV
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ BuiltTool(ctx, "merge_csv").
+ FlagWithInput("--zip_input=", classesJar).
+ FlagWithOutput("--output=", indexCSV)
+ rule.Build(pctx, ctx, "merged-hiddenapi-index", "Merged Hidden API index")
+ h.indexCSVPath = indexCSV
}
var hiddenAPIEncodeDexRule = pctx.AndroidStaticRule("hiddenAPIEncodeDex", blueprint.RuleParams{
- Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output && ` +
- `unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input && ` +
- `for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do ` +
- ` echo "--input-dex=$${INPUT_DEX}"; ` +
- ` echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})"; ` +
- `done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags && ` +
- `${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" && ` +
- `${config.MergeZipsCmd} -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" $out $tmpDir/dex.jar $in`,
+ Command: `rm -rf $tmpDir && mkdir -p $tmpDir && mkdir $tmpDir/dex-input && mkdir $tmpDir/dex-output &&
+ unzip -o -q $in 'classes*.dex' -d $tmpDir/dex-input &&
+ for INPUT_DEX in $$(find $tmpDir/dex-input -maxdepth 1 -name 'classes*.dex' | sort); do
+ echo "--input-dex=$${INPUT_DEX}";
+ echo "--output-dex=$tmpDir/dex-output/$$(basename $${INPUT_DEX})";
+ done | xargs ${config.HiddenAPI} encode --api-flags=$flagsCsv $hiddenapiFlags &&
+ ${config.SoongZipCmd} $soongZipFlags -o $tmpDir/dex.jar -C $tmpDir/dex-output -f "$tmpDir/dex-output/classes*.dex" &&
+ ${config.MergeZipsCmd} -D -zipToNotStrip $tmpDir/dex.jar -stripFile "classes*.dex" -stripFile "**/*.uau" $out $tmpDir/dex.jar $in`,
CommandDeps: []string{
"${config.HiddenAPI}",
"${config.SoongZipCmd}",
@@ -159,9 +170,21 @@
tmpOutput = android.PathForModuleOut(ctx, "hiddenapi", "unaligned", "unaligned.jar")
tmpDir = android.PathForModuleOut(ctx, "hiddenapi", "unaligned")
}
+
+ enforceHiddenApiFlagsToAllMembers := true
// If frameworks/base doesn't exist we must be building with the 'master-art' manifest.
// Disable assertion that all methods/fields have hidden API flags assigned.
if !ctx.Config().FrameworksBaseDirExists(ctx) {
+ enforceHiddenApiFlagsToAllMembers = false
+ }
+ // b/149353192: when a module is instrumented, jacoco adds synthetic members
+ // $jacocoData and $jacocoInit. Since they don't exist when building the hidden API flags,
+ // don't complain when we don't find hidden API flags for the synthetic members.
+ if j, ok := ctx.Module().(*Library); ok && j.shouldInstrument(ctx) {
+ enforceHiddenApiFlagsToAllMembers = false
+ }
+
+ if !enforceHiddenApiFlagsToAllMembers {
hiddenapiFlags = "--no-force-assign-all"
}
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 7850193..7e7e955 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -22,13 +22,15 @@
func init() {
android.RegisterSingletonType("hiddenapi", hiddenAPISingletonFactory)
+ android.RegisterSingletonType("hiddenapi_index", hiddenAPIIndexSingletonFactory)
android.RegisterModuleType("hiddenapi_flags", hiddenAPIFlagsFactory)
}
type hiddenAPISingletonPathsStruct struct {
- stubFlags android.OutputPath
flags android.OutputPath
+ index android.OutputPath
metadata android.OutputPath
+ stubFlags android.OutputPath
}
var hiddenAPISingletonPathsKey = android.NewOnceKey("hiddenAPISingletonPathsKey")
@@ -39,9 +41,10 @@
func hiddenAPISingletonPaths(ctx android.PathContext) hiddenAPISingletonPathsStruct {
return ctx.Config().Once(hiddenAPISingletonPathsKey, func() interface{} {
return hiddenAPISingletonPathsStruct{
- stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
flags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-flags.csv"),
+ index: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-index.csv"),
metadata: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-greylist.csv"),
+ stubFlags: android.PathForOutput(ctx, "hiddenapi", "hiddenapi-stub-flags.txt"),
}
}).(hiddenAPISingletonPathsStruct)
}
@@ -364,3 +367,45 @@
android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommon)
return module
}
+
+func hiddenAPIIndexSingletonFactory() android.Singleton {
+ return &hiddenAPIIndexSingleton{}
+}
+
+type hiddenAPIIndexSingleton struct {
+ index android.Path
+}
+
+func (h *hiddenAPIIndexSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ // Don't run any hiddenapi rules if UNSAFE_DISABLE_HIDDENAPI_FLAGS=true
+ if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ return
+ }
+
+ indexes := android.Paths{}
+ ctx.VisitAllModules(func(module android.Module) {
+ if h, ok := module.(hiddenAPIIntf); ok {
+ if h.indexCSV() != nil {
+ indexes = append(indexes, h.indexCSV())
+ }
+ }
+ })
+
+ rule := android.NewRuleBuilder()
+ rule.Command().
+ BuiltTool(ctx, "merge_csv").
+ FlagWithArg("--header=", "signature,file,startline,startcol,endline,endcol,properties").
+ FlagWithOutput("--output=", hiddenAPISingletonPaths(ctx).index).
+ Inputs(indexes)
+ rule.Build(pctx, ctx, "singleton-merged-hiddenapi-index", "Singleton merged Hidden API index")
+
+ h.index = hiddenAPISingletonPaths(ctx).index
+}
+
+func (h *hiddenAPIIndexSingleton) MakeVars(ctx android.MakeVarsContext) {
+ if ctx.Config().IsEnvTrue("UNSAFE_DISABLE_HIDDENAPI_FLAGS") {
+ return
+ }
+
+ ctx.Strict("INTERNAL_PLATFORM_HIDDENAPI_INDEX", h.index.String())
+}
diff --git a/java/java.go b/java/java.go
index 462dba8..8d58a90 100644
--- a/java/java.go
+++ b/java/java.go
@@ -1323,6 +1323,7 @@
j.compiledSrcJars = srcJars
enable_sharding := false
+ var headerJarFileWithoutJarjar android.Path
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
enable_sharding = true
@@ -1332,7 +1333,8 @@
// allow for the use of annotation processors that do function correctly
// with sharding enabled. See: b/77284273.
}
- j.headerJarFile = j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
+ headerJarFileWithoutJarjar, j.headerJarFile =
+ j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars)
if ctx.Failed() {
return
}
@@ -1351,7 +1353,7 @@
}
if enable_sharding {
- flags.classpath = append(flags.classpath, j.headerJarFile)
+ flags.classpath = append(flags.classpath, headerJarFileWithoutJarjar)
shardSize := int(*(j.properties.Javac_shard_size))
var shardSrcs []android.Paths
if len(uniqueSrcFiles) > 0 {
@@ -1519,6 +1521,14 @@
j.headerJarFile = j.implementationJarFile
}
+ // Force enable the instrumentation for java code that is built for APEXes ...
+ // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent
+ // doesn't make sense)
+ isJacocoAgent := ctx.ModuleName() == "jacocoagent"
+ if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() {
+ j.properties.Instrument = true
+ }
+
if j.shouldInstrument(ctx) {
outputFile = j.instrument(ctx, flags, outputFile, jarName)
}
@@ -1642,7 +1652,8 @@
}
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
- deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) android.Path {
+ deps deps, flags javaBuilderFlags, jarName string,
+ extraJars android.Paths) (headerJar, jarjarHeaderJar android.Path) {
var jars android.Paths
if len(srcFiles) > 0 || len(srcJars) > 0 {
@@ -1650,7 +1661,7 @@
turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
if ctx.Failed() {
- return nil
+ return nil, nil
}
jars = append(jars, turbineJar)
}
@@ -1659,7 +1670,6 @@
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
- var headerJar android.Path
jars = append(jars, deps.staticHeaderJars...)
// we cannot skip the combine step for now if there is only one jar
@@ -1668,18 +1678,19 @@
TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
headerJar = combinedJar
+ jarjarHeaderJar = combinedJar
if j.expandJarjarRules != nil {
// Transform classes.jar into classes-jarjar.jar
jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName)
TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules)
- headerJar = jarjarFile
+ jarjarHeaderJar = jarjarFile
if ctx.Failed() {
- return nil
+ return nil, nil
}
}
- return headerJar
+ return headerJar, jarjarHeaderJar
}
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
diff --git a/scripts/jsonmodify.py b/scripts/jsonmodify.py
index 4b2c3c2..ba1109e 100755
--- a/scripts/jsonmodify.py
+++ b/scripts/jsonmodify.py
@@ -112,9 +112,10 @@
if args.out:
with open(args.out, "w") as f:
- json.dump(obj, f, indent=2)
+ json.dump(obj, f, indent=2, separators=(',', ': '))
+ f.write('\n')
else:
- print(json.dumps(obj, indent=2))
+ print(json.dumps(obj, indent=2, separators=(',', ': ')))
if __name__ == '__main__':
diff --git a/sdk/bp.go b/sdk/bp.go
index 6936daf..c2a75e4 100644
--- a/sdk/bp.go
+++ b/sdk/bp.go
@@ -48,8 +48,7 @@
}
func (s *bpPropertySet) AddPropertySet(name string) android.BpPropertySet {
- set := &bpPropertySet{}
- set.init()
+ set := newPropertySet()
s.AddProperty(name, set)
return set
}
@@ -62,7 +61,7 @@
return s.tags[name]
}
-func (s *bpPropertySet) transform(transformer bpPropertyTransformer) {
+func (s *bpPropertySet) transformContents(transformer bpPropertyTransformer) {
var newOrder []string
for _, name := range s.order {
value := s.properties[name]
@@ -70,7 +69,13 @@
var newValue interface{}
var newTag android.BpPropertyTag
if propertySet, ok := value.(*bpPropertySet); ok {
- newValue, newTag = transformer.transformPropertySet(name, propertySet, tag)
+ var newPropertySet *bpPropertySet
+ newPropertySet, newTag = transformPropertySet(transformer, name, propertySet, tag)
+ if newPropertySet == nil {
+ newValue = nil
+ } else {
+ newValue = newPropertySet
+ }
} else {
newValue, newTag = transformer.transformProperty(name, value, tag)
}
@@ -88,6 +93,16 @@
s.order = newOrder
}
+func transformPropertySet(transformer bpPropertyTransformer, name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+ newPropertySet, newTag := transformer.transformPropertySetBeforeContents(name, propertySet, tag)
+ if newPropertySet != nil {
+ newPropertySet.transformContents(transformer)
+
+ newPropertySet, newTag = transformer.transformPropertySetAfterContents(name, newPropertySet, newTag)
+ }
+ return newPropertySet, newTag
+}
+
func (s *bpPropertySet) setProperty(name string, value interface{}) {
if s.properties[name] == nil {
s.AddProperty(name, value)
@@ -136,7 +151,17 @@
// The name will be "" for the top level property set.
//
// Returning (nil, ...) will cause the property set to be removed.
- transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
+ transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
+
+ // Transform the property set, returning the new property set/tag to insert back into the
+ // parent property set (or module if this is the top level property set).
+ //
+ // This will be called after transforming the properties in the supplied set.
+ //
+ // The name will be "" for the top level property set.
+ //
+ // Returning (nil, ...) will cause the property set to be removed.
+ transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
// Transform a property, return the new value/tag to insert back into the property set.
//
@@ -165,7 +190,11 @@
return module
}
-func (t identityTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t identityTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+ return propertySet, tag
+}
+
+func (t identityTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
return propertySet, tag
}
@@ -180,12 +209,13 @@
func (m *bpModule) transform(transformer bpTransformer) *bpModule {
transformedModule := transformer.transformModule(m)
// Copy the contents of the returned property set into the module and then transform that.
- transformedModule.bpPropertySet, _ = transformer.transformPropertySet("", transformedModule.bpPropertySet, nil)
- transformedModule.bpPropertySet.transform(transformer)
+ transformedModule.bpPropertySet, _ = transformPropertySet(transformer, "", transformedModule.bpPropertySet, nil)
return transformedModule
}
-type deepCopyTransformation struct{}
+type deepCopyTransformation struct {
+ identityTransformation
+}
func (t deepCopyTransformation) transformModule(module *bpModule) *bpModule {
// Take a shallow copy of the module. Any mutable property values will be copied by the
@@ -194,7 +224,7 @@
return &moduleCopy
}
-func (t deepCopyTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t deepCopyTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
// Create a shallow copy of the properties map. Any mutable property values will be copied by the
// transformer.
propertiesCopy := make(map[string]interface{})
@@ -253,10 +283,19 @@
}
func (f *bpFile) newModule(moduleType string) *bpModule {
+ return newModule(moduleType)
+}
+
+func newModule(moduleType string) *bpModule {
module := &bpModule{
moduleType: moduleType,
- bpPropertySet: &bpPropertySet{},
+ bpPropertySet: newPropertySet(),
}
- module.bpPropertySet.init()
return module
}
+
+func newPropertySet() *bpPropertySet {
+ set := &bpPropertySet{}
+ set.init()
+ return set
+}
diff --git a/sdk/bp_test.go b/sdk/bp_test.go
new file mode 100644
index 0000000..f89f38c
--- /dev/null
+++ b/sdk/bp_test.go
@@ -0,0 +1,76 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// 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.
+
+package sdk
+
+import (
+ "testing"
+
+ "android/soong/android"
+)
+
+type removeFredTransformation struct {
+ identityTransformation
+}
+
+func (t removeFredTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
+ if name == "fred" {
+ return nil, nil
+ }
+ return value, tag
+}
+
+func (t removeFredTransformation) transformPropertySetBeforeContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+ if name == "fred" {
+ return nil, nil
+ }
+ return propertySet, tag
+}
+
+func (t removeFredTransformation) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+ if len(propertySet.properties) == 0 {
+ return nil, nil
+ }
+ return propertySet, tag
+}
+
+func TestTransformRemoveProperty(t *testing.T) {
+
+ helper := &TestHelper{t}
+
+ set := newPropertySet()
+ set.AddProperty("name", "name")
+ set.AddProperty("fred", "12")
+
+ set.transformContents(removeFredTransformation{})
+
+ contents := &generatedContents{}
+ outputPropertySet(contents, set)
+ helper.AssertTrimmedStringEquals("removing property failed", "name: \"name\",\\n", contents.content.String())
+}
+
+func TestTransformRemovePropertySet(t *testing.T) {
+
+ helper := &TestHelper{t}
+
+ set := newPropertySet()
+ set.AddProperty("name", "name")
+ set.AddPropertySet("fred")
+
+ set.transformContents(removeFredTransformation{})
+
+ contents := &generatedContents{}
+ outputPropertySet(contents, set)
+ helper.AssertTrimmedStringEquals("removing property set failed", "name: \"name\",\\n", contents.content.String())
+}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 9c8e292..ecb1da0 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -749,3 +749,199 @@
`),
)
}
+
+func TestHostSnapshotWithMultiLib64(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithCc(t, `
+ module_exports {
+ name: "myexports",
+ device_supported: false,
+ host_supported: true,
+ target: {
+ host: {
+ compile_multilib: "64",
+ },
+ },
+ native_static_libs: ["mynativelib"],
+ }
+
+ cc_library_static {
+ name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ srcs: [
+ "Test.cpp",
+ "aidl/foo/bar/Test.aidl",
+ ],
+ export_include_dirs: ["include"],
+ aidl: {
+ export_aidl_headers: true,
+ },
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("myexports", "linux_glibc_common", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_static {
+ name: "myexports_mynativelib@current",
+ sdk_member_name: "mynativelib",
+ device_supported: false,
+ host_supported: true,
+ export_include_dirs: ["include/include"],
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.a"],
+ export_include_dirs: ["x86_64/include_gen/mynativelib"],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_static {
+ name: "mynativelib",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ export_include_dirs: ["include/include"],
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/lib/mynativelib.a"],
+ export_include_dirs: ["x86_64/include_gen/mynativelib"],
+ },
+ },
+ stl: "none",
+ system_shared_libs: [],
+}
+
+module_exports_snapshot {
+ name: "myexports@current",
+ device_supported: false,
+ host_supported: true,
+ target: {
+ host: {
+ compile_multilib: "64",
+ },
+ },
+ native_static_libs: ["myexports_mynativelib@current"],
+}`),
+ checkAllCopyRules(`
+include/Test.h -> include/include/Test.h
+.intermediates/mynativelib/linux_glibc_x86_64_static/mynativelib.a -> x86_64/lib/mynativelib.a
+.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/Test.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/Test.h
+.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BnTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BnTest.h
+.intermediates/mynativelib/linux_glibc_x86_64_static/gen/aidl/aidl/foo/bar/BpTest.h -> x86_64/include_gen/mynativelib/aidl/foo/bar/BpTest.h
+`),
+ )
+}
+
+func TestSnapshotWithCcHeadersLibrary(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_header_libs: ["mynativeheaders"],
+ }
+
+ cc_library_headers {
+ name: "mynativeheaders",
+ export_include_dirs: ["include"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "android_common", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_headers {
+ name: "mysdk_mynativeheaders@current",
+ sdk_member_name: "mynativeheaders",
+ export_include_dirs: ["include/include"],
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_headers {
+ name: "mynativeheaders",
+ prefer: false,
+ export_include_dirs: ["include/include"],
+ stl: "none",
+ system_shared_libs: [],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ native_header_libs: ["mysdk_mynativeheaders@current"],
+}
+`),
+ checkAllCopyRules(`
+include/Test.h -> include/include/Test.h
+`),
+ )
+}
+
+func TestHostSnapshotWithCcHeadersLibrary(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ device_supported: false,
+ host_supported: true,
+ native_header_libs: ["mynativeheaders"],
+ }
+
+ cc_library_headers {
+ name: "mynativeheaders",
+ device_supported: false,
+ host_supported: true,
+ export_include_dirs: ["include"],
+ system_shared_libs: [],
+ stl: "none",
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "linux_glibc_common", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_headers {
+ name: "mysdk_mynativeheaders@current",
+ sdk_member_name: "mynativeheaders",
+ device_supported: false,
+ host_supported: true,
+ export_include_dirs: ["include/include"],
+ stl: "none",
+ system_shared_libs: [],
+}
+
+cc_prebuilt_library_headers {
+ name: "mynativeheaders",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ export_include_dirs: ["include/include"],
+ stl: "none",
+ system_shared_libs: [],
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ device_supported: false,
+ host_supported: true,
+ native_header_libs: ["mysdk_mynativeheaders@current"],
+}
+`),
+ checkAllCopyRules(`
+include/Test.h -> include/include/Test.h
+`),
+ )
+}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 4976dc0..c194ac1 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -323,8 +323,10 @@
if s.Enabled() {
for _, memberListProperty := range s.memberListProperties() {
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
- tag := memberListProperty.dependencyTag
- memberListProperty.memberType.AddDependencies(mctx, tag, names)
+ if len(names) > 0 {
+ tag := memberListProperty.dependencyTag
+ memberListProperty.memberType.AddDependencies(mctx, tag, names)
+ }
}
}
}
diff --git a/sdk/testing.go b/sdk/testing.go
index ae0620d..7352c74 100644
--- a/sdk/testing.go
+++ b/sdk/testing.go
@@ -61,6 +61,12 @@
config := android.TestArchConfig(buildDir, nil, bp, mockFS)
+ // Add windows as a default disable OS to test behavior when some OS variants
+ // are disabled.
+ config.Targets[android.Windows] = []android.Target{
+ {android.Windows, android.Arch{ArchType: android.X86_64}, android.NativeBridgeDisabled, "", ""},
+ }
+
ctx := android.NewTestArchContext()
// from android package
diff --git a/sdk/update.go b/sdk/update.go
index ff567be..d211e80 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -107,10 +107,15 @@
// The members are first grouped by type and then grouped by name. The order of
// the types is the order they are referenced in android.SdkMemberTypesRegistry.
// The names are in the order in which the dependencies were added.
-func (s *sdk) collectMembers(ctx android.ModuleContext) []*sdkMember {
+//
+// Returns the members as well as the multilib setting to use.
+func (s *sdk) collectMembers(ctx android.ModuleContext) ([]*sdkMember, string) {
byType := make(map[android.SdkMemberType][]*sdkMember)
byName := make(map[string]*sdkMember)
+ lib32 := false // True if any of the members have 32 bit version.
+ lib64 := false // True if any of the members have 64 bit version.
+
ctx.WalkDeps(func(child android.Module, parent android.Module) bool {
tag := ctx.OtherModuleDependencyTag(child)
if memberTag, ok := tag.(android.SdkMemberTypeDependencyTag); ok {
@@ -122,7 +127,6 @@
}
name := ctx.OtherModuleName(child)
-
member := byName[name]
if member == nil {
member = &sdkMember{memberType: memberType, name: name}
@@ -130,6 +134,13 @@
byType[memberType] = append(byType[memberType], member)
}
+ multilib := child.Target().Arch.ArchType.Multilib
+ if multilib == "lib32" {
+ lib32 = true
+ } else if multilib == "lib64" {
+ lib64 = true
+ }
+
// Only append new variants to the list. This is needed because a member can be both
// exported by the sdk and also be a transitive sdk member.
member.variants = appendUniqueVariants(member.variants, child.(android.SdkAware))
@@ -148,7 +159,17 @@
members = append(members, membersOfType...)
}
- return members
+ // Compute the setting of multilib.
+ var multilib string
+ if lib32 && lib64 {
+ multilib = "both"
+ } else if lib32 {
+ multilib = "32"
+ } else if lib64 {
+ multilib = "64"
+ }
+
+ return members, multilib
}
func appendUniqueVariants(variants []android.SdkAware, newVariant android.SdkAware) []android.SdkAware {
@@ -207,7 +228,8 @@
}
s.builderForTests = builder
- for _, member := range s.collectMembers(ctx) {
+ members, multilib := s.collectMembers(ctx)
+ for _, member := range members {
member.memberType.BuildSnapshot(ctx, builder, member)
}
@@ -219,6 +241,9 @@
unversionedTransformer := unversionedTransformation{builder: builder}
for _, unversioned := range builder.prebuiltOrder {
+ // Prune any empty property sets.
+ unversioned = unversioned.transform(pruneEmptySetTransformer{})
+
// Copy the unversioned module so it can be modified to make it versioned.
versioned := unversioned.deepCopy()
@@ -249,6 +274,16 @@
}
addHostDeviceSupportedProperties(&s.ModuleBase, snapshotModule)
+
+ // Compile_multilib defaults to both and must always be set to both on the
+ // device and so only needs to be set when targeted at the host and is neither
+ // unspecified or both.
+ if s.HostSupported() && multilib != "" && multilib != "both" {
+ targetSet := snapshotModule.AddPropertySet("target")
+ hostSet := targetSet.AddPropertySet("host")
+ hostSet.AddProperty("compile_multilib", multilib)
+ }
+
for _, memberListProperty := range s.memberListProperties() {
names := memberListProperty.getter(s.dynamicMemberTypeListProperties)
if len(names) > 0 {
@@ -357,6 +392,20 @@
}
}
+type pruneEmptySetTransformer struct {
+ identityTransformation
+}
+
+var _ bpTransformer = (*pruneEmptySetTransformer)(nil)
+
+func (t pruneEmptySetTransformer) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+ if len(propertySet.properties) == 0 {
+ return nil, nil
+ } else {
+ return propertySet, tag
+ }
+}
+
func generateBpContents(contents *generatedContents, bpFile *bpFile) {
contents.Printfln("// This is auto-generated. DO NOT EDIT.")
for _, bpModule := range bpFile.order {
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index ce404f8..65dbb22 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -144,6 +144,9 @@
// list of .sysprop files which defines the properties.
Srcs []string `android:"path"`
+ // If set to true, build a variant of the module for the host. Defaults to false.
+ Host_supported *bool
+
// Whether public stub exists or not.
Public_stub *bool `blueprint:"mutated"`
}
@@ -306,12 +309,20 @@
Sysprop struct {
Platform *bool
}
- Header_libs []string
- Shared_libs []string
+ Target struct {
+ Android struct {
+ Header_libs []string
+ Shared_libs []string
+ }
+ Host struct {
+ Static_libs []string
+ }
+ }
Required []string
Recovery *bool
Recovery_available *bool
Vendor_available *bool
+ Host_supported *bool
}
type javaLibraryProperties struct {
@@ -394,10 +405,12 @@
ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific())
ccProps.Product_specific = proptools.BoolPtr(ctx.ProductSpecific())
ccProps.Sysprop.Platform = proptools.BoolPtr(isOwnerPlatform)
- ccProps.Header_libs = []string{"libbase_headers"}
- ccProps.Shared_libs = []string{"liblog"}
+ ccProps.Target.Android.Header_libs = []string{"libbase_headers"}
+ ccProps.Target.Android.Shared_libs = []string{"liblog"}
+ ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"}
ccProps.Recovery_available = m.properties.Recovery_available
ccProps.Vendor_available = m.properties.Vendor_available
+ ccProps.Host_supported = m.properties.Host_supported
ctx.CreateModule(cc.LibraryFactory, &ccProps)
scope := "internal"
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 7cad3da..51da222 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -161,6 +161,7 @@
api_packages: ["android.sysprop"],
property_owner: "Platform",
vendor_available: true,
+ host_supported: true,
}
sysprop_library {
@@ -244,6 +245,11 @@
static_libs: ["sysprop-platform", "sysprop-vendor"],
}
+ cc_library {
+ name: "libbase",
+ host_supported: true,
+ }
+
cc_library_headers {
name: "libbase_headers",
vendor_available: true,
@@ -256,6 +262,12 @@
nocrt: true,
system_shared_libs: [],
recovery_available: true,
+ host_supported: true,
+ }
+
+ cc_binary_host {
+ name: "hostbin",
+ static_libs: ["sysprop-platform"],
}
llndk_library {
diff --git a/vnames.go.json b/vnames.go.json
index 5842097..7ce2d4b 100644
--- a/vnames.go.json
+++ b/vnames.go.json
@@ -3,7 +3,7 @@
"pattern": "(.*)",
"vname": {
"corpus": "android.googlesource.com/platform/superproject",
- "path": "build/soong/@1@"
+ "path": "@1@"
}
}
]