Merge "Add a prebuilt module type for usr/share."
diff --git a/Android.bp b/Android.bp
index 92a6e9d..b407314 100644
--- a/Android.bp
+++ b/Android.bp
@@ -148,6 +148,7 @@
"cc/sabi.go",
"cc/stl.go",
"cc/strip.go",
+ "cc/sysprop.go",
"cc/tidy.go",
"cc/util.go",
"cc/vndk.go",
@@ -178,6 +179,8 @@
"cc/genrule.go",
"cc/vendor_public_library.go",
+
+ "cc/testing.go",
],
testSrcs: [
"cc/cc_test.go",
@@ -378,6 +381,25 @@
pluginFor: ["soong_build"],
}
+bootstrap_go_package {
+ name: "soong-sysprop",
+ pkgPath: "android/soong/sysprop",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-java",
+ ],
+ srcs: [
+ "sysprop/sysprop_library.go",
+ ],
+ testSrcs: [
+ "sysprop/sysprop_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
+
//
// Defaults to enable various configurations of host bionic
//
diff --git a/android/hooks.go b/android/hooks.go
index 57560d2..6b2468d 100644
--- a/android/hooks.go
+++ b/android/hooks.go
@@ -123,7 +123,7 @@
install []func(InstallHookContext)
}
-func loadHookMutator(ctx TopDownMutatorContext) {
+func LoadHookMutator(ctx TopDownMutatorContext) {
if m, ok := ctx.Module().(Module); ok {
// Cast through *androidTopDownMutatorContext because AppendProperties is implemented
// on *androidTopDownMutatorContext but not exposed through TopDownMutatorContext
diff --git a/android/mutator.go b/android/mutator.go
index b77c2f0..e5f742f 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -74,7 +74,7 @@
var preArch = []RegisterMutatorFunc{
func(ctx RegisterMutatorsContext) {
- ctx.TopDown("load_hooks", loadHookMutator).Parallel()
+ ctx.TopDown("load_hooks", LoadHookMutator).Parallel()
},
RegisterNamespaceMutator,
RegisterPrebuiltsPreArchMutators,
diff --git a/android/register.go b/android/register.go
index 10e14fe..19745fe 100644
--- a/android/register.go
+++ b/android/register.go
@@ -20,7 +20,7 @@
type moduleType struct {
name string
- factory blueprint.ModuleFactory
+ factory ModuleFactory
}
var moduleTypes []moduleType
@@ -40,8 +40,6 @@
parallel bool
}
-var mutators []*mutator
-
type ModuleFactory func() Module
// ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
@@ -65,7 +63,7 @@
}
func RegisterModuleType(name string, factory ModuleFactory) {
- moduleTypes = append(moduleTypes, moduleType{name, ModuleFactoryAdaptor(factory)})
+ moduleTypes = append(moduleTypes, moduleType{name, factory})
}
func RegisterSingletonType(name string, factory SingletonFactory) {
@@ -90,7 +88,7 @@
}
for _, t := range moduleTypes {
- ctx.RegisterModuleType(t.name, t.factory)
+ ctx.RegisterModuleType(t.name, ModuleFactoryAdaptor(t.factory))
}
for _, t := range singletons {
@@ -105,3 +103,11 @@
// Register env last so that it can track all used environment variables
ctx.RegisterSingletonType("env", SingletonFactoryAdaptor(EnvSingleton))
}
+
+func ModuleTypeFactories() map[string]ModuleFactory {
+ ret := make(map[string]ModuleFactory)
+ for _, t := range moduleTypes {
+ ret[t.name] = t.factory
+ }
+ return ret
+}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 468b617..3b86947 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -28,7 +28,7 @@
// graph.
type RuleBuilder struct {
commands []*RuleBuilderCommand
- installs []RuleBuilderInstall
+ installs RuleBuilderInstalls
temporariesSet map[string]bool
restat bool
missingDeps []string
@@ -46,6 +46,23 @@
From, To string
}
+type RuleBuilderInstalls []RuleBuilderInstall
+
+// String returns the RuleBuilderInstalls in the form used by $(call copy-many-files) in Make, a space separated
+// list of from:to tuples.
+func (installs RuleBuilderInstalls) String() string {
+ sb := strings.Builder{}
+ for i, install := range installs {
+ if i != 0 {
+ sb.WriteRune(' ')
+ }
+ sb.WriteString(install.From)
+ sb.WriteRune(':')
+ sb.WriteString(install.To)
+ }
+ return sb.String()
+}
+
// MissingDeps adds modules to the list of missing dependencies. If MissingDeps
// is called with a non-empty input, any call to Build will result in a rule
// that will print an error listing the missing dependencies and fail.
@@ -145,8 +162,8 @@
}
// Installs returns the list of tuples passed to Install.
-func (r *RuleBuilder) Installs() []RuleBuilderInstall {
- return append([]RuleBuilderInstall(nil), r.installs...)
+func (r *RuleBuilder) Installs() RuleBuilderInstalls {
+ return append(RuleBuilderInstalls(nil), r.installs...)
}
func (r *RuleBuilder) toolsSet() map[string]bool {
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 53a5b48..f947348 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -84,6 +84,19 @@
// outputs: ["c"]
}
+func ExampleRuleBuilder_Installs() {
+ rule := NewRuleBuilder()
+
+ rule.Command().Tool("ld").Inputs([]string{"a.o", "b.o"}).FlagWithOutput("-o ", "linked")
+ rule.Install("linked", "/bin/linked")
+ rule.Install("linked", "/sbin/linked")
+
+ fmt.Printf("rule.Installs().String() = %q\n", rule.Installs().String())
+
+ // Output:
+ // rule.Installs().String() = "linked:/bin/linked linked:/sbin/linked"
+}
+
func ExampleRuleBuilderCommand() {
rule := NewRuleBuilder()
diff --git a/apex/apex.go b/apex/apex.go
index ef22afb..7633ad2 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -257,18 +257,8 @@
Multilib apexMultilibProperties
- Prefer_sanitize struct {
- // Prefer native libraries with asan if available
- Address *bool
- // Prefer native libraries with hwasan if available
- Hwaddress *bool
- // Prefer native libraries with tsan if available
- Thread *bool
- // Prefer native libraries with integer_overflow if available
- Integer_overflow *bool
- // Prefer native libraries with cfi if available
- Cfi *bool
- }
+ // List of sanitizer names that this APEX is enabled for
+ SanitizerNames []string `blueprint:"mutated"`
}
type apexTargetBundleProperties struct {
@@ -517,12 +507,20 @@
}
ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
- cert := android.SrcIsModule(String(a.properties.Certificate))
+ cert := android.SrcIsModule(a.getCertString(ctx))
if cert != "" {
ctx.AddDependency(ctx.Module(), certificateTag, cert)
}
}
+func (a *apexBundle) getCertString(ctx android.BaseContext) string {
+ certificate, overridden := ctx.DeviceConfig().OverrideCertificateFor(ctx.ModuleName())
+ if overridden {
+ return ":" + certificate
+ }
+ return String(a.properties.Certificate)
+}
+
func (a *apexBundle) Srcs() android.Paths {
if file, ok := a.outputFiles[imageApex]; ok {
return android.Paths{file}
@@ -543,29 +541,15 @@
}
}
+func (a *apexBundle) EnableSanitizer(sanitizerName string) {
+ if !android.InList(sanitizerName, a.properties.SanitizerNames) {
+ a.properties.SanitizerNames = append(a.properties.SanitizerNames, sanitizerName)
+ }
+}
+
func (a *apexBundle) IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool {
- // If this APEX is configured to prefer a sanitizer, use it
- switch sanitizerName {
- case "asan":
- if proptools.Bool(a.properties.Prefer_sanitize.Address) {
- return true
- }
- case "hwasan":
- if proptools.Bool(a.properties.Prefer_sanitize.Hwaddress) {
- return true
- }
- case "tsan":
- if proptools.Bool(a.properties.Prefer_sanitize.Thread) {
- return true
- }
- case "cfi":
- if proptools.Bool(a.properties.Prefer_sanitize.Cfi) {
- return true
- }
- case "integer_overflow":
- if proptools.Bool(a.properties.Prefer_sanitize.Integer_overflow) {
- return true
- }
+ if android.InList(sanitizerName, a.properties.SanitizerNames) {
+ return true
}
// Then follow the global setting
@@ -1021,7 +1005,7 @@
}}
}
-func (a *apexBundle) androidMkForFiles(w io.Writer, name, moduleDir string) []string {
+func (a *apexBundle) androidMkForFiles(w io.Writer, name, moduleDir string, apexType apexPackaging) []string {
moduleNames := []string{}
for _, fi := range a.filesInfo {
@@ -1034,7 +1018,7 @@
fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
- if a.flattened {
+ if a.flattened && apexType.image() {
// /system/apex/<name>/{lib|framework|...}
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)",
a.installDir.RelPathString(), name, fi.installDir))
@@ -1103,7 +1087,7 @@
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
moduleNames := []string{}
if a.installable() {
- moduleNames = a.androidMkForFiles(w, name, moduleDir)
+ moduleNames = a.androidMkForFiles(w, name, moduleDir, apexType)
}
if a.flattened && apexType.image() {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 2c7f285..13ddb55 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -24,6 +24,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/java"
)
func testApex(t *testing.T, bp string) *android.TestContext {
@@ -51,6 +52,7 @@
ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
ctx.RegisterModuleType("prebuilt_etc", android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory))
ctx.RegisterModuleType("sh_binary", android.ModuleFactoryAdaptor(android.ShBinaryFactory))
+ ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory))
ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("image", cc.ImageMutator).Parallel()
ctx.BottomUp("link", cc.LinkageMutator).Parallel()
@@ -138,18 +140,23 @@
`
ctx.MockFileSystem(map[string][]byte{
- "Android.bp": []byte(bp),
- "build/target/product/security": nil,
- "apex_manifest.json": nil,
- "system/sepolicy/apex/myapex-file_contexts": nil,
- "system/sepolicy/apex/otherapex-file_contexts": nil,
- "mylib.cpp": nil,
- "myprebuilt": nil,
- "my_include": nil,
- "vendor/foo/devkeys/test.x509.pem": nil,
- "vendor/foo/devkeys/test.pk8": nil,
- "vendor/foo/devkeys/testkey.avbpubkey": nil,
- "vendor/foo/devkeys/testkey.pem": nil,
+ "Android.bp": []byte(bp),
+ "build/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "system/sepolicy/apex/myapex-file_contexts": nil,
+ "system/sepolicy/apex/myapex_keytest-file_contexts": nil,
+ "system/sepolicy/apex/otherapex-file_contexts": nil,
+ "mylib.cpp": nil,
+ "myprebuilt": nil,
+ "my_include": nil,
+ "vendor/foo/devkeys/test.x509.pem": nil,
+ "vendor/foo/devkeys/test.pk8": nil,
+ "testkey.x509.pem": nil,
+ "testkey.pk8": nil,
+ "testkey.override.x509.pem": nil,
+ "testkey.override.pk8": nil,
+ "vendor/foo/devkeys/testkey.avbpubkey": nil,
+ "vendor/foo/devkeys/testkey.pem": nil,
})
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
android.FailIfErrored(t, errs)
@@ -168,6 +175,7 @@
config = android.TestArchConfig(buildDir, nil)
config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
config.TestProductVariables.DefaultAppCertificate = proptools.StringPtr("vendor/foo/devkeys/test")
+ config.TestProductVariables.CertificateOverrides = []string{"myapex_keytest:myapex.certificate.override"}
return
}
@@ -773,8 +781,9 @@
func TestKeys(t *testing.T) {
ctx := testApex(t, `
apex {
- name: "myapex",
+ name: "myapex_keytest",
key: "myapex.key",
+ certificate: ":myapex.certificate",
native_shared_libs: ["mylib"],
}
@@ -791,6 +800,16 @@
private_key: "testkey.pem",
}
+ android_app_certificate {
+ name: "myapex.certificate",
+ certificate: "testkey",
+ }
+
+ android_app_certificate {
+ name: "myapex.certificate.override",
+ certificate: "testkey.override",
+ }
+
`)
// check the APEX keys
@@ -805,11 +824,11 @@
"vendor/foo/devkeys/testkey.pem")
}
- // check the APK certs
- certs := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("signapk").Args["certificates"]
- if certs != "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8" {
+ // check the APK certs. It should be overridden to myapex.certificate.override
+ certs := ctx.ModuleForTests("myapex_keytest", "android_common_myapex_keytest").Rule("signapk").Args["certificates"]
+ if certs != "testkey.override.x509.pem testkey.override.pk8" {
t.Errorf("cert and private key %q are not %q", certs,
- "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8")
+ "testkey.override.509.pem testkey.override.pk8")
}
}
diff --git a/cc/cc.go b/cc/cc.go
index 01577bc..7b19e98 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -41,6 +41,7 @@
ctx.BottomUp("test_per_src", testPerSrcMutator).Parallel()
ctx.BottomUp("version", VersionMutator).Parallel()
ctx.BottomUp("begin", BeginMutator).Parallel()
+ ctx.BottomUp("sysprop", SyspropMutator).Parallel()
})
android.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
@@ -62,7 +63,7 @@
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator)
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
- ctx.BottomUp("coverage", coverageLinkingMutator).Parallel()
+ ctx.BottomUp("coverage", coverageMutator).Parallel()
ctx.TopDown("vndk_deps", sabiDepsMutator)
ctx.TopDown("lto_deps", ltoDepsMutator)
@@ -257,6 +258,7 @@
baseModuleName() string
getVndkExtendsModuleName() string
isPgoCompile() bool
+ isNDKStubLibrary() bool
useClangLld(actx ModuleContext) bool
apexName() string
hasStubsVariants() bool
@@ -496,6 +498,10 @@
return c.Properties.UseVndk
}
+func (c *Module) isCoverageVariant() bool {
+ return c.coverage.Properties.IsCoverageVariant
+}
+
func (c *Module) isNdk() bool {
return inList(c.Name(), ndkMigratedLibs)
}
@@ -529,6 +535,13 @@
return false
}
+func (c *Module) isNDKStubLibrary() bool {
+ if _, ok := c.compiler.(*stubDecorator); ok {
+ return true
+ }
+ return false
+}
+
func (c *Module) isVndkSp() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndkSp()
@@ -674,6 +687,10 @@
return ctx.mod.isPgoCompile()
}
+func (ctx *moduleContextImpl) isNDKStubLibrary() bool {
+ return ctx.mod.isNDKStubLibrary()
+}
+
func (ctx *moduleContextImpl) isVndkSp() bool {
return ctx.mod.isVndkSp()
}
@@ -955,7 +972,8 @@
// module is marked with 'bootstrap: true').
if c.HasStubsVariants() &&
android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) &&
- !c.inRecovery() && !c.useVndk() && !c.static() && c.IsStubs() {
+ !c.inRecovery() && !c.useVndk() && !c.static() && !c.isCoverageVariant() &&
+ c.IsStubs() {
c.Properties.HideFromMake = false // unhide
// Note: this is still non-installable
}
@@ -1211,11 +1229,18 @@
{Mutator: "link", Variation: "static"},
}, wholeStaticDepTag, deps.WholeStaticLibs...)
+ syspropImplLibraries := syspropImplLibraries(actx.Config())
+
for _, lib := range deps.StaticLibs {
depTag := staticDepTag
if inList(lib, deps.ReexportStaticLibHeaders) {
depTag = staticExportDepTag
}
+
+ if impl, ok := syspropImplLibraries[lib]; ok {
+ lib = impl
+ }
+
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, depTag, lib)
@@ -1253,12 +1278,18 @@
var sharedLibNames []string
for _, lib := range deps.SharedLibs {
- name, version := stubsLibNameAndVersion(lib)
- sharedLibNames = append(sharedLibNames, name)
depTag := sharedDepTag
if inList(lib, deps.ReexportSharedLibHeaders) {
depTag = sharedExportDepTag
}
+
+ if impl, ok := syspropImplLibraries[lib]; ok {
+ lib = impl
+ }
+
+ name, version := stubsLibNameAndVersion(lib)
+ sharedLibNames = append(sharedLibNames, name)
+
addSharedLibDependencies(depTag, name, version)
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 9d370c1..22ac0d9 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -51,165 +51,6 @@
os.Exit(run())
}
-func gatherRequiredDeps(os android.OsType) string {
- ret := `
- toolchain_library {
- name: "libatomic",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libcompiler_rt-extras",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libclang_rt.builtins-arm-android",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libclang_rt.builtins-aarch64-android",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libclang_rt.builtins-i686-android",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libclang_rt.builtins-x86_64-android",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- toolchain_library {
- name: "libgcc",
- vendor_available: true,
- recovery_available: true,
- src: "",
- }
-
- cc_library {
- name: "libc",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- recovery_available: true,
- }
- llndk_library {
- name: "libc",
- symbol_file: "",
- }
- cc_library {
- name: "libm",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- recovery_available: true,
- }
- llndk_library {
- name: "libm",
- symbol_file: "",
- }
- cc_library {
- name: "libdl",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- recovery_available: true,
- }
- llndk_library {
- name: "libdl",
- symbol_file: "",
- }
- cc_library {
- name: "libc++_static",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- stl: "none",
- vendor_available: true,
- recovery_available: true,
- }
- cc_library {
- name: "libc++",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- stl: "none",
- vendor_available: true,
- recovery_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- }
- cc_library {
- name: "libunwind_llvm",
- no_libgcc: true,
- nocrt: true,
- system_shared_libs: [],
- stl: "none",
- vendor_available: true,
- recovery_available: true,
- }
-
- cc_object {
- name: "crtbegin_so",
- recovery_available: true,
- vendor_available: true,
- }
-
- cc_object {
- name: "crtbegin_static",
- recovery_available: true,
- vendor_available: true,
- }
-
- cc_object {
- name: "crtend_so",
- recovery_available: true,
- vendor_available: true,
- }
-
- cc_object {
- name: "crtend_android",
- recovery_available: true,
- vendor_available: true,
- }
-
- cc_library {
- name: "libprotobuf-cpp-lite",
- }
- `
- if os == android.Fuchsia {
- ret += `
- cc_library {
- name: "libbioniccompat",
- stl: "none",
- }
- cc_library {
- name: "libcompiler_rt",
- stl: "none",
- }
- `
- }
- return ret
-}
-
func createTestContext(t *testing.T, config android.Config, bp string, os android.OsType) *android.TestContext {
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("cc_binary", android.ModuleFactoryAdaptor(BinaryFactory))
@@ -233,7 +74,7 @@
ctx.Register()
// add some modules that are required by the compiler and/or linker
- bp = bp + gatherRequiredDeps(os)
+ bp = bp + GatherRequiredDepsForTest(os)
ctx.MockFileSystem(map[string][]byte{
"Android.bp": []byte(bp),
diff --git a/cc/coverage.go b/cc/coverage.go
index 391b118..79f7d7d 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -15,13 +15,16 @@
package cc
import (
+ "strconv"
+
"android/soong/android"
)
type CoverageProperties struct {
Native_coverage *bool
- CoverageEnabled bool `blueprint:"mutated"`
+ CoverageEnabled bool `blueprint:"mutated"`
+ IsCoverageVariant bool `blueprint:"mutated"`
}
type coverage struct {
@@ -93,27 +96,54 @@
return flags
}
-func coverageLinkingMutator(mctx android.BottomUpMutatorContext) {
- if c, ok := mctx.Module().(*Module); ok && c.coverage != nil {
- var enabled bool
+func coverageMutator(mctx android.BottomUpMutatorContext) {
+ // Coverage is disabled globally
+ if !mctx.DeviceConfig().NativeCoverageEnabled() {
+ return
+ }
- if !mctx.DeviceConfig().NativeCoverageEnabled() {
- // Coverage is disabled globally
- } else if mctx.Host() {
+ if c, ok := mctx.Module().(*Module); ok {
+ var needCoverageVariant bool
+ var needCoverageBuild bool
+
+ if mctx.Host() {
// TODO(dwillemsen): because of -nodefaultlibs, we must depend on libclang_rt.profile-*.a
// Just turn off for now.
- } else if c.coverage.Properties.Native_coverage != nil {
- enabled = *c.coverage.Properties.Native_coverage
- } else {
- enabled = mctx.DeviceConfig().CoverageEnabledForPath(mctx.ModuleDir())
+ } else if c.useVndk() || c.hasVendorVariant() {
+ // Do not enable coverage for VNDK libraries
+ } else if c.isNDKStubLibrary() {
+ // Do not enable coverage for NDK stub libraries
+ } else if c.coverage != nil {
+ // Check if Native_coverage is set to false. This property defaults to true.
+ needCoverageVariant = BoolDefault(c.coverage.Properties.Native_coverage, true)
+
+ if sdk_version := String(c.Properties.Sdk_version); sdk_version != "current" {
+ // Native coverage is not supported for SDK versions < 23
+ if fromApi, err := strconv.Atoi(sdk_version); err == nil && fromApi < 23 {
+ needCoverageVariant = false
+ }
+ }
+
+ if needCoverageVariant {
+ // Coverage variant is actually built with coverage if enabled for its module path
+ needCoverageBuild = mctx.DeviceConfig().CoverageEnabledForPath(mctx.ModuleDir())
+ }
}
- if enabled {
- // Create a variation so that we don't need to recompile objects
- // when turning on or off coverage. We'll still relink the necessary
- // binaries, since we don't know which ones those are until later.
- m := mctx.CreateLocalVariations("cov")
- m[0].(*Module).coverage.Properties.CoverageEnabled = true
+ if needCoverageVariant {
+ m := mctx.CreateVariations("", "cov")
+
+ // Setup the non-coverage version and set HideFromMake and
+ // PreventInstall to true.
+ m[0].(*Module).coverage.Properties.CoverageEnabled = false
+ m[0].(*Module).coverage.Properties.IsCoverageVariant = false
+ m[0].(*Module).Properties.HideFromMake = true
+ m[0].(*Module).Properties.PreventInstall = true
+
+ // The coverage-enabled version inherits HideFromMake,
+ // PreventInstall from the original module.
+ m[1].(*Module).coverage.Properties.CoverageEnabled = needCoverageBuild
+ m[1].(*Module).coverage.Properties.IsCoverageVariant = true
}
}
}
diff --git a/cc/gen.go b/cc/gen.go
index c3088f4..0c3d089 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -56,10 +56,11 @@
sysprop = pctx.AndroidStaticRule("sysprop",
blueprint.RuleParams{
- Command: "$syspropCmd --header-output-dir=$headerOutDir --source-output-dir=$srcOutDir --include-name=$includeName $in",
+ Command: "$syspropCmd --header-dir=$headerOutDir --system-header-dir=$systemOutDir " +
+ "--source-dir=$srcOutDir --include-name=$includeName $in",
CommandDeps: []string{"$syspropCmd"},
},
- "headerOutDir", "srcOutDir", "includeName")
+ "headerOutDir", "systemOutDir", "srcOutDir", "includeName")
windmc = pctx.AndroidStaticRule("windmc",
blueprint.RuleParams{
@@ -114,6 +115,7 @@
func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Path) {
headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
+ systemHeaderFile := android.PathForModuleGen(ctx, "sysprop/system", "include", syspropFile.Rel()+".h")
cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")
ctx.Build(pctx, android.BuildParams{
@@ -124,6 +126,7 @@
Input: syspropFile,
Args: map[string]string{
"headerOutDir": filepath.Dir(headerFile.String()),
+ "systemOutDir": filepath.Dir(systemHeaderFile.String()),
"srcOutDir": filepath.Dir(cppFile.String()),
"includeName": syspropFile.Rel() + ".h",
},
diff --git a/cc/library.go b/cc/library.go
index a6c7bc8..a48b45d 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -67,6 +67,11 @@
Export_proto_headers *bool
}
+ Sysprop struct {
+ // Whether platform owns this sysprop library.
+ Platform *bool
+ }
+
Static_ndk_lib *bool
Stubs struct {
@@ -836,9 +841,27 @@
}
if library.baseCompiler.hasSrcExt(".sysprop") {
- flags := []string{
+ internalFlags := []string{
"-I" + android.PathForModuleGen(ctx, "sysprop", "include").String(),
}
+ systemFlags := []string{
+ "-I" + android.PathForModuleGen(ctx, "sysprop/system", "include").String(),
+ }
+
+ flags := internalFlags
+
+ if library.Properties.Sysprop.Platform != nil {
+ isProduct := ctx.ProductSpecific() && !ctx.useVndk()
+ isVendor := ctx.useVndk()
+ isOwnerPlatform := Bool(library.Properties.Sysprop.Platform)
+
+ useSystem := isProduct || (isOwnerPlatform == isVendor)
+
+ if useSystem {
+ flags = systemFlags
+ }
+ }
+
library.reexportFlags(flags)
library.reexportDeps(library.baseCompiler.pathDeps)
library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)
diff --git a/cc/linker.go b/cc/linker.go
index dbdcd57..649185a 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -225,14 +225,9 @@
}
if ctx.toolchain().Bionic() {
- // Allow individual projects to opt out of libcrt,builtins
- // b/117565638
+ // libclang_rt.builtins, libgcc and libatomic have to be last on the command line
if !Bool(linker.Properties.No_libcrt) {
- // libclang_rt.builtins, libgcc and libatomic have to be last on the command line
- // TODO: Also enable for libc and libm
- if ctx.ModuleName() != "libc" && ctx.ModuleName() != "libm" {
- deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
- }
+ deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
}
deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
diff --git a/cc/sanitize.go b/cc/sanitize.go
index fc2ed50..7297718 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -666,6 +666,14 @@
}
return true
})
+ } else if sanitizeable, ok := mctx.Module().(Sanitizeable); ok {
+ // If an APEX module includes a lib which is enabled for a sanitizer T, then
+ // the APEX module is also enabled for the same sanitizer type.
+ mctx.VisitDirectDeps(func(child android.Module) {
+ if c, ok := child.(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
+ sanitizeable.EnableSanitizer(t.name())
+ }
+ })
}
}
}
@@ -848,6 +856,7 @@
type Sanitizeable interface {
android.Module
IsSanitizerEnabled(ctx android.BaseModuleContext, sanitizerName string) bool
+ EnableSanitizer(sanitizerName string)
}
// Create sanitized variants for modules that need them
diff --git a/cc/sysprop.go b/cc/sysprop.go
new file mode 100644
index 0000000..656f79f
--- /dev/null
+++ b/cc/sysprop.go
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 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 cc
+
+import (
+ "sync"
+
+ "android/soong/android"
+)
+
+type syspropLibraryInterface interface {
+ CcModuleName() string
+}
+
+var (
+ syspropImplLibrariesKey = android.NewOnceKey("syspropImplLibirares")
+ syspropImplLibrariesLock sync.Mutex
+)
+
+func syspropImplLibraries(config android.Config) map[string]string {
+ return config.Once(syspropImplLibrariesKey, func() interface{} {
+ return make(map[string]string)
+ }).(map[string]string)
+}
+
+// gather list of sysprop libraries
+func SyspropMutator(mctx android.BottomUpMutatorContext) {
+ if m, ok := mctx.Module().(syspropLibraryInterface); ok {
+ syspropImplLibraries := syspropImplLibraries(mctx.Config())
+ syspropImplLibrariesLock.Lock()
+ defer syspropImplLibrariesLock.Unlock()
+
+ syspropImplLibraries[mctx.ModuleName()] = m.CcModuleName()
+ }
+}
diff --git a/cc/testing.go b/cc/testing.go
new file mode 100644
index 0000000..b3b2756
--- /dev/null
+++ b/cc/testing.go
@@ -0,0 +1,188 @@
+// Copyright (C) 2019 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 cc
+
+import (
+ "android/soong/android"
+)
+
+func GatherRequiredDepsForTest(os android.OsType) string {
+ ret := `
+ toolchain_library {
+ name: "libatomic",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libcompiler_rt-extras",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-arm-android",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-aarch64-android",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-i686-android",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libclang_rt.builtins-x86_64-android",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ toolchain_library {
+ name: "libgcc",
+ vendor_available: true,
+ recovery_available: true,
+ src: "",
+ }
+
+ cc_library {
+ name: "libbase",
+ no_libgcc: true,
+ nocrt: true,
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ }
+ }
+ cc_library {
+ name: "libc",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ recovery_available: true,
+ }
+ llndk_library {
+ name: "libc",
+ symbol_file: "",
+ }
+ cc_library {
+ name: "libm",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ recovery_available: true,
+ }
+ llndk_library {
+ name: "libm",
+ symbol_file: "",
+ }
+ cc_library {
+ name: "libdl",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ recovery_available: true,
+ }
+ llndk_library {
+ name: "libdl",
+ symbol_file: "",
+ }
+ cc_library {
+ name: "libc++_static",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ vendor_available: true,
+ recovery_available: true,
+ }
+ cc_library {
+ name: "libc++",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ vendor_available: true,
+ recovery_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ }
+ cc_library {
+ name: "libunwind_llvm",
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
+ stl: "none",
+ vendor_available: true,
+ recovery_available: true,
+ }
+
+ cc_object {
+ name: "crtbegin_so",
+ recovery_available: true,
+ vendor_available: true,
+ }
+
+ cc_object {
+ name: "crtbegin_static",
+ recovery_available: true,
+ vendor_available: true,
+ }
+
+ cc_object {
+ name: "crtend_so",
+ recovery_available: true,
+ vendor_available: true,
+ }
+
+ cc_object {
+ name: "crtend_android",
+ recovery_available: true,
+ vendor_available: true,
+ }
+
+ cc_library {
+ name: "libprotobuf-cpp-lite",
+ }
+ `
+ if os == android.Fuchsia {
+ ret += `
+ cc_library {
+ name: "libbioniccompat",
+ stl: "none",
+ }
+ cc_library {
+ name: "libcompiler_rt",
+ stl: "none",
+ }
+ `
+ }
+ return ret
+}
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index a4c6898..1f6002e 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -75,6 +75,10 @@
bootstrap.Main(ctx.Context, configuration, configuration.ConfigFileName, configuration.ProductVariablesFileName)
if docFile != "" {
- writeDocs(ctx, docFile)
+ err := writeDocs(ctx, docFile)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
}
}
diff --git a/cmd/soong_build/writedocs.go b/cmd/soong_build/writedocs.go
index a6686c0..8f86b33 100644
--- a/cmd/soong_build/writedocs.go
+++ b/cmd/soong_build/writedocs.go
@@ -19,18 +19,33 @@
"bytes"
"html/template"
"io/ioutil"
+ "reflect"
+ "sort"
"github.com/google/blueprint/bootstrap"
+ "github.com/google/blueprint/bootstrap/bpdoc"
)
func writeDocs(ctx *android.Context, filename string) error {
- moduleTypeList, err := bootstrap.ModuleTypeDocs(ctx.Context)
+ moduleTypeFactories := android.ModuleTypeFactories()
+ bpModuleTypeFactories := make(map[string]reflect.Value)
+ for moduleType, factory := range moduleTypeFactories {
+ bpModuleTypeFactories[moduleType] = reflect.ValueOf(factory)
+ }
+
+ packages, err := bootstrap.ModuleTypeDocs(ctx.Context, bpModuleTypeFactories)
if err != nil {
return err
}
buf := &bytes.Buffer{}
+ var moduleTypeList []*bpdoc.ModuleType
+ for _, pkg := range packages {
+ moduleTypeList = append(moduleTypeList, pkg.ModuleTypes...)
+ }
+ sort.Slice(moduleTypeList, func(i, j int) bool { return moduleTypeList[i].Name < moduleTypeList[j].Name })
+
unique := 0
tmpl, err := template.New("file").Funcs(map[string]interface{}{
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index ecaf876..40c694f 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -100,7 +100,7 @@
t.Error(err)
}
- wantInstalls := []android.RuleBuilderInstall{
+ wantInstalls := android.RuleBuilderInstalls{
{"out/test/oat/arm/package.odex", "/system/app/test/oat/arm/test.odex"},
{"out/test/oat/arm/package.vdex", "/system/app/test/oat/arm/test.vdex"},
}
@@ -141,7 +141,7 @@
t.Error(err)
}
- wantInstalls := []android.RuleBuilderInstall{
+ wantInstalls := android.RuleBuilderInstalls{
{"out/test/oat/arm/package.odex", "/system_other/app/test/oat/arm/test.odex"},
{"out/test/oat/arm/package.vdex", "/system_other/app/test/oat/arm/test.vdex"},
}
@@ -164,7 +164,7 @@
t.Error(err)
}
- wantInstalls := []android.RuleBuilderInstall{
+ wantInstalls := android.RuleBuilderInstalls{
{"out/test/profile.prof", "/system/app/test/test.apk.prof"},
{"out/test/oat/arm/package.art", "/system/app/test/oat/arm/test.art"},
{"out/test/oat/arm/package.odex", "/system/app/test/oat/arm/test.odex"},
diff --git a/java/aar.go b/java/aar.go
index 7495bda..60fbe29 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -367,6 +367,12 @@
a.exportedStaticPackages = android.FirstUniquePaths(a.exportedStaticPackages)
}
+// android_library builds and links sources into a `.jar` file for the device along with Android resources.
+//
+// An android_library has a single variant that produces a `.jar` file containing `.class` files that were
+// compiled against the device bootclasspath, along with a `package-res.apk` file containing Android resources compiled
+// with aapt2. This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
+// an android_app module.
func AndroidLibraryFactory() android.Module {
module := &AndroidLibrary{}
@@ -584,6 +590,10 @@
var _ android.PrebuiltInterface = (*Import)(nil)
+// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
+//
+// This module is not suitable for installing on a device, but can be used as a `static_libs` dependency of
+// an android_app module.
func AARImportFactory() android.Module {
module := &AARImport{}
diff --git a/java/androidmk.go b/java/androidmk.go
index d86e71f..04b328d 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -65,7 +65,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", library.dexJarFile.String())
}
if len(library.dexpreopter.builtInstalled) > 0 {
- fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", strings.Join(library.dexpreopter.builtInstalled, " "))
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", library.dexpreopter.builtInstalled)
}
fmt.Fprintln(w, "LOCAL_SDK_VERSION :=", library.sdkVersion())
fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", library.implementationAndResourcesJar.String())
@@ -166,7 +166,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", binary.dexJarFile.String())
}
if len(binary.dexpreopter.builtInstalled) > 0 {
- fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", strings.Join(binary.dexpreopter.builtInstalled, " "))
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", binary.dexpreopter.builtInstalled)
}
},
},
@@ -260,7 +260,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), "+=", jniLib.name)
}
if len(app.dexpreopter.builtInstalled) > 0 {
- fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", strings.Join(app.dexpreopter.builtInstalled, " "))
+ fmt.Fprintln(w, "LOCAL_SOONG_BUILT_INSTALLED :=", app.dexpreopter.builtInstalled)
}
},
},
diff --git a/java/app.go b/java/app.go
index 05d1927..3cb7e8e 100644
--- a/java/app.go
+++ b/java/app.go
@@ -395,6 +395,7 @@
return String(a.appProperties.Certificate)
}
+// android_app compiles sources and Android resources into an Android application package `.apk` file.
func AndroidAppFactory() android.Module {
module := &AndroidApp{}
@@ -457,6 +458,8 @@
}
}
+// android_test compiles test sources and Android resources into an Android application package `.apk` file and
+// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
func AndroidTestFactory() android.Module {
module := &AndroidTest{}
@@ -494,6 +497,9 @@
appTestHelperAppProperties appTestHelperAppProperties
}
+// android_test_helper_app compiles sources and Android resources into an Android application package `.apk` file that
+// will be used by tests, but does not produce an `AndroidTest.xml` file so the module will not be run directly as a
+// test.
func AndroidTestHelperAppFactory() android.Module {
module := &AndroidTestHelperApp{}
@@ -528,6 +534,8 @@
Certificate *string
}
+// android_app_certificate modules can be referenced by the certificates property of android_app modules to select
+// the signing key.
func AndroidAppCertificateFactory() android.Module {
module := &AndroidAppCertificate{}
module.AddProperties(&module.properties)
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index a89731a..127deab 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -28,7 +28,7 @@
isTest bool
isInstallable bool
- builtInstalled []string
+ builtInstalled string
}
type DexpreoptProperties struct {
@@ -196,9 +196,7 @@
dexpreoptRule.Build(pctx, ctx, "dexpreopt", "dexpreopt")
- for _, install := range dexpreoptRule.Installs() {
- d.builtInstalled = append(d.builtInstalled, install.From+":"+install.To)
- }
+ d.builtInstalled = dexpreoptRule.Installs().String()
stripRule, err := dexpreopt.GenerateStripRule(globalConfig, dexpreoptConfig)
if err != nil {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 787c4d7..85e4797 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -171,12 +171,11 @@
// list of java libraries that will be in the classpath.
Libs []string `android:"arch_variant"`
- // don't build against the default libraries (bootclasspath, legacy-test, core-junit,
- // ext, and framework for device targets)
+ // don't build against the default libraries (bootclasspath, ext, and framework for device
+ // targets)
No_standard_libs *bool
- // don't build against the framework libraries (legacy-test, core-junit,
- // ext, and framework for device targets)
+ // don't build against the framework libraries (ext, and framework for device targets)
No_framework_libs *bool
// the java library (in classpath) for documentation that provides java srcs and srcjars.
@@ -599,6 +598,9 @@
case ".aidl":
javaFile := genAidl(ctx, srcFile, flags.aidlFlags)
outSrcFiles = append(outSrcFiles, javaFile)
+ case ".sysprop":
+ javaFile := genSysprop(ctx, srcFile)
+ outSrcFiles = append(outSrcFiles, javaFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}
diff --git a/java/genrule.go b/java/genrule.go
index 8f29482..25494ec 100644
--- a/java/genrule.go
+++ b/java/genrule.go
@@ -25,8 +25,37 @@
}
// java_genrule is a genrule that can depend on other java_* objects.
-// The cmd may be run multiple times, once for each of the different host/device
-// variations.
+//
+// By default a java_genrule has a single variant that will run against the device variant of its dependencies and
+// produce an output that can be used as an input to a device java rule.
+//
+// Specifying `host_supported: true` will produce two variants, one that uses device dependencie sand one that uses
+// host dependencies. Each variant will run the command.
+//
+// Use a java_genrule instead of a genrule when it needs to depend on or be depended on by other java modules, unless
+// the dependency is for a generated source file.
+//
+// Examples:
+//
+// Use a java_genrule to package generated java resources:
+//
+// java_genrule {
+// name: "generated_resources",
+// tools: [
+// "generator",
+// "soong_zip",
+// ],
+// srcs: ["generator_inputs/**/*"],
+// out: ["generated_android_icu4j_resources.jar"],
+// cmd: "$(location generator) $(in) -o $(genDir) " +
+// "&& $(location soong_zip) -o $(out) -C $(genDir)/res -D $(genDir)/res",
+// }
+//
+// java_library {
+// name: "lib_with_generated_resources",
+// srcs: ["src/**/*.java"],
+// static_libs: ["generated_resources"],
+// }
func genRuleFactory() android.Module {
module := genrule.NewGenRule()
@@ -36,8 +65,9 @@
}
// java_genrule_host is a genrule that can depend on other java_* objects.
-// The cmd may be run multiple times, once for each of the different host/device
-// variations.
+//
+// A java_genrule_host has a single variant that will run against the host variant of its dependencies and
+// produce an output that can be used as an input to a host java rule.
func genRuleFactoryHost() android.Module {
module := genrule.NewGenRule()
diff --git a/java/java.go b/java/java.go
index 76b41ca..880f920 100644
--- a/java/java.go
+++ b/java/java.go
@@ -36,7 +36,7 @@
android.RegisterModuleType("java_defaults", defaultsFactory)
android.RegisterModuleType("java_library", LibraryFactory)
- android.RegisterModuleType("java_library_static", LibraryFactory)
+ android.RegisterModuleType("java_library_static", LibraryStaticFactory)
android.RegisterModuleType("java_library_host", LibraryHostFactory)
android.RegisterModuleType("java_binary", BinaryFactory)
android.RegisterModuleType("java_binary_host", BinaryHostFactory)
@@ -78,12 +78,11 @@
// list of files that should be excluded from java_resources and java_resource_dirs
Exclude_java_resources []string `android:"arch_variant"`
- // don't build against the default libraries (bootclasspath, legacy-test, core-junit,
- // ext, and framework for device targets)
+ // don't build against the default libraries (bootclasspath, ext, and framework for device
+ // targets)
No_standard_libs *bool
- // don't build against the framework libraries (legacy-test, core-junit,
- // ext, and framework for device targets)
+ // don't build against the framework libraries (ext, and framework for device targets)
No_framework_libs *bool
// list of module-specific flags that will be used for javac compiles
@@ -1450,6 +1449,17 @@
j.deps(ctx)
}
+// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well.
+//
+// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were
+// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used
+// as a `static_libs` dependency of another module.
+//
+// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on
+// a device.
+//
+// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
+// compiled against the host bootclasspath.
func LibraryFactory() android.Module {
module := &Library{}
@@ -1463,6 +1473,15 @@
return module
}
+// java_library_static is an obsolete alias for java_library.
+func LibraryStaticFactory() android.Module {
+ return LibraryFactory()
+}
+
+// java_library_host builds and links sources into a `.jar` file for the host.
+//
+// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were
+// compiled against the host bootclasspath.
func LibraryHostFactory() android.Module {
module := &Library{}
@@ -1521,6 +1540,14 @@
android.ExtractSourcesDeps(ctx, j.testProperties.Data)
}
+// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and
+// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file.
+//
+// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were
+// compiled against the device bootclasspath.
+//
+// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
+// compiled against the host bootclasspath.
func TestFactory() android.Module {
module := &Test{}
@@ -1538,6 +1565,11 @@
return module
}
+// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to
+// allow running the test with `atest` or a `TEST_MAPPING` file.
+//
+// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were
+// compiled against the host bootclasspath.
func TestHostFactory() android.Module {
module := &Test{}
@@ -1619,6 +1651,14 @@
}
}
+// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host
+// as well.
+//
+// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were
+// compiled against the device bootclasspath.
+//
+// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one
+// compiled against the host bootclasspath.
func BinaryFactory() android.Module {
module := &Binary{}
@@ -1636,6 +1676,10 @@
return module
}
+// java_binary_host builds a `.jar` file and a shell script that executes it for the host.
+//
+// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were
+// compiled against the host bootclasspath.
func BinaryHostFactory() android.Module {
module := &Binary{}
@@ -1817,6 +1861,13 @@
var _ android.PrebuiltInterface = (*Import)(nil)
+// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module.
+//
+// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were
+// compiled against an Android classpath.
+//
+// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
+// for host modules.
func ImportFactory() android.Module {
module := &Import{}
@@ -1827,6 +1878,11 @@
return module
}
+// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host
+// module.
+//
+// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were
+// compiled against a host bootclasspath.
func ImportFactoryHost() android.Module {
module := &Import{}
@@ -1848,6 +1904,37 @@
func (*Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
+// java_defaults provides a set of properties that can be inherited by other java or android modules.
+//
+// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each
+// property in the defaults module that exists in the depending module will be prepended to the depending module's
+// value for that property.
+//
+// Example:
+//
+// java_defaults {
+// name: "example_defaults",
+// srcs: ["common/**/*.java"],
+// javacflags: ["-Xlint:all"],
+// aaptflags: ["--auto-add-overlay"],
+// }
+//
+// java_library {
+// name: "example",
+// defaults: ["example_defaults"],
+// srcs: ["example/**/*.java"],
+// }
+//
+// is functionally identical to:
+//
+// java_library {
+// name: "example",
+// srcs: [
+// "common/**/*.java",
+// "example/**/*.java",
+// ],
+// javacflags: ["-Xlint:all"],
+// }
func defaultsFactory() android.Module {
return DefaultsFactory()
}
diff --git a/java/java_test.go b/java/java_test.go
index 57b2a59..034e905 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -90,14 +90,14 @@
ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
- ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(sdkLibraryFactory))
- ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(prebuiltApisFactory))
+ ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
+ ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(PrebuiltApisFactory))
ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("prebuilt_apis", prebuiltApisMutator).Parallel()
- ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
+ ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
+ ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
})
ctx.RegisterPreSingletonType("overlay", android.SingletonFactoryAdaptor(OverlaySingletonFactory))
ctx.RegisterPreSingletonType("sdk", android.SingletonFactoryAdaptor(sdkSingletonFactory))
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 0410daf..49cc931 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -30,10 +30,10 @@
// It also creates <module>-api.<scope>.latest for the lastest <ver>.
//
func init() {
- android.RegisterModuleType("prebuilt_apis", prebuiltApisFactory)
+ android.RegisterModuleType("prebuilt_apis", PrebuiltApisFactory)
android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("prebuilt_apis", prebuiltApisMutator).Parallel()
+ ctx.TopDown("prebuilt_apis", PrebuiltApisMutator).Parallel()
})
}
@@ -176,14 +176,14 @@
}
}
-func prebuiltApisMutator(mctx android.TopDownMutatorContext) {
+func PrebuiltApisMutator(mctx android.TopDownMutatorContext) {
if _, ok := mctx.Module().(*prebuiltApis); ok {
prebuiltApiFiles(mctx)
prebuiltSdkStubs(mctx)
}
}
-func prebuiltApisFactory() android.Module {
+func PrebuiltApisFactory() android.Module {
module := &prebuiltApis{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 3623e7c..f2df49b 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -42,6 +42,10 @@
name string
}
+type syspropLibraryInterface interface {
+ SyspropJavaModule() *SdkLibrary
+}
+
var (
publicApiStubsTag = dependencyTag{name: "public"}
systemApiStubsTag = dependencyTag{name: "system"}
@@ -74,10 +78,10 @@
// 2) HTML generation
func init() {
- android.RegisterModuleType("java_sdk_library", sdkLibraryFactory)
+ android.RegisterModuleType("java_sdk_library", SdkLibraryFactory)
android.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("java_sdk_library", sdkLibraryMutator).Parallel()
+ ctx.TopDown("java_sdk_library", SdkLibraryMutator).Parallel()
})
android.RegisterMakeVarsProvider(pctx, func(ctx android.MakeVarsContext) {
@@ -133,7 +137,7 @@
//Html_doc *bool
}
-type sdkLibrary struct {
+type SdkLibrary struct {
Library
sdkLibraryProperties sdkLibraryProperties
@@ -151,10 +155,10 @@
testApiFilePath android.Path
}
-var _ Dependency = (*sdkLibrary)(nil)
-var _ SdkLibraryDependency = (*sdkLibrary)(nil)
+var _ Dependency = (*SdkLibrary)(nil)
+var _ SdkLibraryDependency = (*SdkLibrary)(nil)
-func (module *sdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
+func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
// Add dependencies to the stubs library
ctx.AddVariationDependencies(nil, publicApiStubsTag, module.stubsName(apiScopePublic))
ctx.AddVariationDependencies(nil, publicApiFileTag, module.docsName(apiScopePublic))
@@ -169,7 +173,7 @@
module.Library.deps(ctx)
}
-func (module *sdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
module.Library.GenerateAndroidBuildActions(ctx)
// Record the paths to the header jars of the library (stubs and impl).
@@ -207,7 +211,7 @@
})
}
-func (module *sdkLibrary) AndroidMk() android.AndroidMkData {
+func (module *SdkLibrary) AndroidMk() android.AndroidMkData {
data := module.Library.AndroidMk()
data.Required = append(data.Required, module.xmlFileName())
@@ -267,7 +271,7 @@
}
// Module name of the stubs library
-func (module *sdkLibrary) stubsName(apiScope apiScope) string {
+func (module *SdkLibrary) stubsName(apiScope apiScope) string {
stubsName := module.BaseModuleName() + sdkStubsLibrarySuffix
switch apiScope {
case apiScopeSystem:
@@ -279,7 +283,7 @@
}
// Module name of the docs
-func (module *sdkLibrary) docsName(apiScope apiScope) string {
+func (module *SdkLibrary) docsName(apiScope apiScope) string {
docsName := module.BaseModuleName() + sdkDocsSuffix
switch apiScope {
case apiScopeSystem:
@@ -291,12 +295,12 @@
}
// Module name of the runtime implementation library
-func (module *sdkLibrary) implName() string {
+func (module *SdkLibrary) implName() string {
return module.BaseModuleName()
}
// File path to the runtime implementation library
-func (module *sdkLibrary) implPath() string {
+func (module *SdkLibrary) implPath() string {
partition := "system"
if module.SocSpecific() {
partition = "vendor"
@@ -309,14 +313,14 @@
}
// Module name of the XML file for the lib
-func (module *sdkLibrary) xmlFileName() string {
+func (module *SdkLibrary) xmlFileName() string {
return module.BaseModuleName() + sdkXmlFileSuffix
}
// SDK version that the stubs library is built against. Note that this is always
// *current. Older stubs library built with a numberd SDK version is created from
// the prebuilt jar.
-func (module *sdkLibrary) sdkVersion(apiScope apiScope) string {
+func (module *SdkLibrary) sdkVersion(apiScope apiScope) string {
switch apiScope {
case apiScopePublic:
return "current"
@@ -332,7 +336,7 @@
// $(INTERNAL_PLATFORM_<apiTagName>_API_FILE) points to the generated
// api file for the current source
// TODO: remove this when apicheck is done in soong
-func (module *sdkLibrary) apiTagName(apiScope apiScope) string {
+func (module *SdkLibrary) apiTagName(apiScope apiScope) string {
apiTagName := strings.Replace(strings.ToUpper(module.BaseModuleName()), ".", "_", -1)
switch apiScope {
case apiScopeSystem:
@@ -343,7 +347,7 @@
return apiTagName
}
-func (module *sdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
+func (module *SdkLibrary) latestApiFilegroupName(apiScope apiScope) string {
name := ":" + module.BaseModuleName() + ".api."
switch apiScope {
case apiScopePublic:
@@ -357,7 +361,7 @@
return name
}
-func (module *sdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
+func (module *SdkLibrary) latestRemovedApiFilegroupName(apiScope apiScope) string {
name := ":" + module.BaseModuleName() + "-removed.api."
switch apiScope {
case apiScopePublic:
@@ -372,7 +376,7 @@
}
// Creates a static java library that has API stubs
-func (module *sdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
+func (module *SdkLibrary) createStubsLibrary(mctx android.TopDownMutatorContext, apiScope apiScope) {
props := struct {
Name *string
Srcs []string
@@ -431,7 +435,7 @@
// Creates a droiddoc module that creates stubs source files from the given full source
// files
-func (module *sdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
+func (module *SdkLibrary) createDocs(mctx android.TopDownMutatorContext, apiScope apiScope) {
props := struct {
Name *string
Srcs []string
@@ -528,7 +532,7 @@
}
// Creates the xml file that publicizes the runtime library
-func (module *sdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
+func (module *SdkLibrary) createXmlFile(mctx android.TopDownMutatorContext) {
template := `
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2018 The Android Open Source Project
@@ -587,7 +591,7 @@
mctx.CreateModule(android.ModuleFactoryAdaptor(android.PrebuiltEtcFactory), &etcProps)
}
-func (module *sdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+func (module *SdkLibrary) PrebuiltJars(ctx android.BaseContext, sdkVersion string) android.Paths {
var api, v string
if sdkVersion == "" {
api = "system"
@@ -607,7 +611,7 @@
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+func (module *SdkLibrary) SdkHeaderJars(ctx android.BaseContext, sdkVersion string) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildPrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
@@ -623,7 +627,7 @@
}
// to satisfy SdkLibraryDependency interface
-func (module *sdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
+func (module *SdkLibrary) SdkImplementationJars(ctx android.BaseContext, sdkVersion string) android.Paths {
// This module is just a wrapper for the stubs.
if ctx.Config().UnbundledBuildPrebuiltSdks() {
return module.PrebuiltJars(ctx, sdkVersion)
@@ -649,42 +653,47 @@
// For a java_sdk_library module, create internal modules for stubs, docs,
// runtime libs and xml file. If requested, the stubs and docs are created twice
// once for public API level and once for system API level
-func sdkLibraryMutator(mctx android.TopDownMutatorContext) {
- if module, ok := mctx.Module().(*sdkLibrary); ok {
- if module.Library.Module.properties.Srcs == nil {
- mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
- }
-
- if module.sdkLibraryProperties.Api_packages == nil {
- mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
- }
- // for public API stubs
- module.createStubsLibrary(mctx, apiScopePublic)
- module.createDocs(mctx, apiScopePublic)
-
- if !Bool(module.properties.No_standard_libs) {
- // for system API stubs
- module.createStubsLibrary(mctx, apiScopeSystem)
- module.createDocs(mctx, apiScopeSystem)
-
- // for test API stubs
- module.createStubsLibrary(mctx, apiScopeTest)
- module.createDocs(mctx, apiScopeTest)
-
- // for runtime
- module.createXmlFile(mctx)
- }
-
- // record java_sdk_library modules so that they are exported to make
- javaSdkLibraries := javaSdkLibraries(mctx.Config())
- javaSdkLibrariesLock.Lock()
- defer javaSdkLibrariesLock.Unlock()
- *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
+func SdkLibraryMutator(mctx android.TopDownMutatorContext) {
+ if module, ok := mctx.Module().(*SdkLibrary); ok {
+ module.createInternalModules(mctx)
+ } else if module, ok := mctx.Module().(syspropLibraryInterface); ok {
+ module.SyspropJavaModule().createInternalModules(mctx)
}
}
-func sdkLibraryFactory() android.Module {
- module := &sdkLibrary{}
+func (module *SdkLibrary) createInternalModules(mctx android.TopDownMutatorContext) {
+ if module.Library.Module.properties.Srcs == nil {
+ mctx.PropertyErrorf("srcs", "java_sdk_library must specify srcs")
+ }
+
+ if module.sdkLibraryProperties.Api_packages == nil {
+ mctx.PropertyErrorf("api_packages", "java_sdk_library must specify api_packages")
+ }
+ // for public API stubs
+ module.createStubsLibrary(mctx, apiScopePublic)
+ module.createDocs(mctx, apiScopePublic)
+
+ if !Bool(module.properties.No_standard_libs) {
+ // for system API stubs
+ module.createStubsLibrary(mctx, apiScopeSystem)
+ module.createDocs(mctx, apiScopeSystem)
+
+ // for test API stubs
+ module.createStubsLibrary(mctx, apiScopeTest)
+ module.createDocs(mctx, apiScopeTest)
+
+ // for runtime
+ module.createXmlFile(mctx)
+ }
+
+ // record java_sdk_library modules so that they are exported to make
+ javaSdkLibraries := javaSdkLibraries(mctx.Config())
+ javaSdkLibrariesLock.Lock()
+ defer javaSdkLibrariesLock.Unlock()
+ *javaSdkLibraries = append(*javaSdkLibraries, module.BaseModuleName())
+}
+
+func (module *SdkLibrary) InitSdkLibraryProperties() {
module.AddProperties(
&module.sdkLibraryProperties,
&module.Library.Module.properties,
@@ -695,7 +704,11 @@
module.Library.Module.properties.Installable = proptools.BoolPtr(true)
module.Library.Module.deviceProperties.IsSDKLibrary = true
+}
+func SdkLibraryFactory() android.Module {
+ module := &SdkLibrary{}
+ module.InitSdkLibraryProperties()
InitJavaModule(module, android.HostAndDeviceSupported)
return module
}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
new file mode 100644
index 0000000..4069e78
--- /dev/null
+++ b/sysprop/sysprop_library.go
@@ -0,0 +1,130 @@
+// Copyright (C) 2019 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 sysprop
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/java"
+ "github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
+)
+
+type dependencyTag struct {
+ blueprint.BaseDependencyTag
+ name string
+}
+
+type syspropLibrary struct {
+ java.SdkLibrary
+
+ commonProperties commonProperties
+ syspropLibraryProperties syspropLibraryProperties
+}
+
+type syspropLibraryProperties struct {
+ // Determine who owns this sysprop library. Possible values are
+ // "Platform", "Vendor", or "Odm"
+ Property_owner string
+ Api_packages []string
+}
+
+type commonProperties struct {
+ Srcs []string
+ Recovery *bool
+ Vendor_available *bool
+}
+
+var (
+ Bool = proptools.Bool
+ syspropCcTag = dependencyTag{name: "syspropCc"}
+)
+
+func init() {
+ android.RegisterModuleType("sysprop_library", syspropLibraryFactory)
+}
+
+func (m *syspropLibrary) CcModuleName() string {
+ return "lib" + m.Name()
+}
+
+func (m *syspropLibrary) SyspropJavaModule() *java.SdkLibrary {
+ return &m.SdkLibrary
+}
+
+func syspropLibraryFactory() android.Module {
+ m := &syspropLibrary{}
+
+ m.AddProperties(
+ &m.commonProperties,
+ &m.syspropLibraryProperties,
+ )
+ m.InitSdkLibraryProperties()
+ android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, "common")
+ android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
+
+ return m
+}
+
+func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
+ if m.syspropLibraryProperties.Api_packages == nil {
+ ctx.PropertyErrorf("api_packages", "sysprop_library must specify api_packages")
+ }
+
+ socSpecific := ctx.SocSpecific()
+ deviceSpecific := ctx.DeviceSpecific()
+ productSpecific := ctx.ProductSpecific()
+
+ owner := m.syspropLibraryProperties.Property_owner
+
+ switch owner {
+ case "Platform":
+ // Every partition can access platform-defined properties
+ break
+ case "Vendor":
+ // System can't access vendor's properties
+ if !socSpecific && !deviceSpecific && !productSpecific {
+ ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " +
+ "System can't access sysprop_library owned by Vendor")
+ }
+ case "Odm":
+ // Only vendor can access Odm-defined properties
+ if !socSpecific && !deviceSpecific {
+ ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " +
+ "Odm-defined properties should be accessed only in Vendor or Odm")
+ }
+ default:
+ ctx.PropertyErrorf("property_owner",
+ "Unknown value %s: must be one of Platform, Vendor or Odm", owner)
+ }
+
+ ccProps := struct {
+ Name *string
+ Soc_specific *bool
+ Device_specific *bool
+ Product_specific *bool
+ Sysprop struct {
+ Platform *bool
+ }
+ }{}
+
+ ccProps.Name = proptools.StringPtr(m.CcModuleName())
+ ccProps.Soc_specific = proptools.BoolPtr(socSpecific)
+ ccProps.Device_specific = proptools.BoolPtr(deviceSpecific)
+ ccProps.Product_specific = proptools.BoolPtr(productSpecific)
+ ccProps.Sysprop.Platform = proptools.BoolPtr(owner == "Platform")
+
+ ctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &m.commonProperties, &ccProps)
+}
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
new file mode 100644
index 0000000..92e0af4
--- /dev/null
+++ b/sysprop/sysprop_test.go
@@ -0,0 +1,380 @@
+// Copyright (C) 2019 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 sysprop
+
+import (
+ "android/soong/android"
+ "android/soong/cc"
+ "android/soong/java"
+
+ "fmt"
+ "io/ioutil"
+ "os"
+ "strings"
+ "testing"
+
+ "github.com/google/blueprint/proptools"
+)
+
+var buildDir string
+
+func setUp() {
+ var err error
+ buildDir, err = ioutil.TempDir("", "soong_sysprop_test")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func tearDown() {
+ os.RemoveAll(buildDir)
+}
+
+func TestMain(m *testing.M) {
+ run := func() int {
+ setUp()
+ defer tearDown()
+
+ return m.Run()
+ }
+
+ os.Exit(run())
+}
+
+func testContext(config android.Config, bp string,
+ fs map[string][]byte) *android.TestContext {
+
+ ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("android_app", android.ModuleFactoryAdaptor(java.AndroidAppFactory))
+ ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(java.ExportedDroiddocDirFactory))
+ ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
+ ctx.RegisterModuleType("java_system_modules", android.ModuleFactoryAdaptor(java.SystemModulesFactory))
+ ctx.RegisterModuleType("prebuilt_apis", android.ModuleFactoryAdaptor(java.PrebuiltApisFactory))
+ ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("load_hooks", android.LoadHookMutator).Parallel()
+ })
+ ctx.PreArchMutators(android.RegisterPrebuiltsPreArchMutators)
+ ctx.PreArchMutators(android.RegisterPrebuiltsPostDepsMutators)
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ ctx.PreArchMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("prebuilt_apis", java.PrebuiltApisMutator).Parallel()
+ ctx.TopDown("java_sdk_library", java.SdkLibraryMutator).Parallel()
+ })
+
+ ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
+ ctx.RegisterModuleType("cc_object", android.ModuleFactoryAdaptor(cc.ObjectFactory))
+ ctx.RegisterModuleType("llndk_library", android.ModuleFactoryAdaptor(cc.LlndkLibraryFactory))
+ ctx.RegisterModuleType("toolchain_library", android.ModuleFactoryAdaptor(cc.ToolchainLibraryFactory))
+ ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
+ ctx.BottomUp("image", cc.ImageMutator).Parallel()
+ ctx.BottomUp("link", cc.LinkageMutator).Parallel()
+ ctx.BottomUp("vndk", cc.VndkMutator).Parallel()
+ ctx.BottomUp("version", cc.VersionMutator).Parallel()
+ ctx.BottomUp("begin", cc.BeginMutator).Parallel()
+ ctx.BottomUp("sysprop", cc.SyspropMutator).Parallel()
+ })
+
+ ctx.RegisterModuleType("sysprop_library", android.ModuleFactoryAdaptor(syspropLibraryFactory))
+
+ ctx.Register()
+
+ extraModules := []string{
+ "core-lambda-stubs",
+ "framework",
+ "ext",
+ "updatable_media_stubs",
+
+ "android_stubs_current",
+ "android_system_stubs_current",
+ "android_test_stubs_current",
+ "core.current.stubs",
+ "core.platform.api.stubs",
+ }
+
+ for _, extra := range extraModules {
+ bp += fmt.Sprintf(`
+ java_library {
+ name: "%s",
+ srcs: ["a.java"],
+ no_standard_libs: true,
+ sdk_version: "core_current",
+ system_modules: "core-platform-api-stubs-system-modules",
+ }
+ `, extra)
+ }
+
+ bp += `
+ android_app {
+ name: "framework-res",
+ no_framework_libs: true,
+ }
+ `
+
+ systemModules := []string{
+ "core-system-modules",
+ "core-platform-api-stubs-system-modules",
+ "android_stubs_current_system_modules",
+ "android_system_stubs_current_system_modules",
+ "android_test_stubs_current_system_modules",
+ }
+
+ for _, extra := range systemModules {
+ bp += fmt.Sprintf(`
+ java_system_modules {
+ name: "%s",
+ }
+ `, extra)
+ }
+
+ bp += cc.GatherRequiredDepsForTest(android.Android)
+
+ mockFS := map[string][]byte{
+ "Android.bp": []byte(bp),
+ "a.java": nil,
+ "b.java": nil,
+ "c.java": nil,
+ "d.cpp": nil,
+ "api/current.txt": nil,
+ "api/removed.txt": nil,
+ "api/system-current.txt": nil,
+ "api/system-removed.txt": nil,
+ "api/test-current.txt": nil,
+ "api/test-removed.txt": nil,
+
+ "prebuilts/sdk/current/core/android.jar": nil,
+ "prebuilts/sdk/current/public/android.jar": nil,
+ "prebuilts/sdk/current/public/framework.aidl": nil,
+ "prebuilts/sdk/current/public/core.jar": nil,
+ "prebuilts/sdk/current/system/android.jar": nil,
+ "prebuilts/sdk/current/test/android.jar": nil,
+ "prebuilts/sdk/28/public/api/sysprop-platform.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-platform.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-platform.txt": nil,
+ "prebuilts/sdk/28/public/api/sysprop-platform-removed.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-platform-removed.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-platform-removed.txt": nil,
+ "prebuilts/sdk/28/public/api/sysprop-platform-on-product.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-platform-on-product.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-platform-on-product.txt": nil,
+ "prebuilts/sdk/28/public/api/sysprop-platform-on-product-removed.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-platform-on-product-removed.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-platform-on-product-removed.txt": nil,
+ "prebuilts/sdk/28/public/api/sysprop-vendor.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-vendor.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-vendor.txt": nil,
+ "prebuilts/sdk/28/public/api/sysprop-vendor-removed.txt": nil,
+ "prebuilts/sdk/28/system/api/sysprop-vendor-removed.txt": nil,
+ "prebuilts/sdk/28/test/api/sysprop-vendor-removed.txt": nil,
+ "prebuilts/sdk/tools/core-lambda-stubs.jar": nil,
+ "prebuilts/sdk/Android.bp": []byte(`prebuilt_apis { name: "sdk", api_dirs: ["28", "current"],}`),
+
+ // For framework-res, which is an implicit dependency for framework
+ "AndroidManifest.xml": nil,
+ "build/target/product/security/testkey": nil,
+
+ "build/soong/scripts/jar-wrapper.sh": nil,
+
+ "build/make/core/proguard.flags": nil,
+ "build/make/core/proguard_basic_keeps.flags": nil,
+
+ "jdk8/jre/lib/jce.jar": nil,
+ "jdk8/jre/lib/rt.jar": nil,
+ "jdk8/lib/tools.jar": nil,
+
+ "bar-doc/a.java": nil,
+ "bar-doc/b.java": nil,
+ "bar-doc/IFoo.aidl": nil,
+ "bar-doc/known_oj_tags.txt": nil,
+ "external/doclava/templates-sdk": nil,
+
+ "cert/new_cert.x509.pem": nil,
+ "cert/new_cert.pk8": nil,
+
+ "android/sysprop/PlatformProperties.sysprop": nil,
+ "com/android/VendorProperties.sysprop": nil,
+ }
+
+ for k, v := range fs {
+ mockFS[k] = v
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ return ctx
+}
+
+func run(t *testing.T, ctx *android.TestContext, config android.Config) {
+ t.Helper()
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp", "prebuilts/sdk/Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+}
+
+func testConfig(env map[string]string) android.Config {
+ if env == nil {
+ env = make(map[string]string)
+ }
+ if env["ANDROID_JAVA8_HOME"] == "" {
+ env["ANDROID_JAVA8_HOME"] = "jdk8"
+ }
+ config := android.TestArchConfig(buildDir, env)
+ config.TestProductVariables.DeviceSystemSdkVersions = []string{"28"}
+ config.TestProductVariables.DeviceVndkVersion = proptools.StringPtr("current")
+ config.TestProductVariables.Platform_vndk_version = proptools.StringPtr("VER")
+ return config
+
+}
+
+func test(t *testing.T, bp string) *android.TestContext {
+ t.Helper()
+ config := testConfig(nil)
+ ctx := testContext(config, bp, nil)
+ run(t, ctx, config)
+
+ return ctx
+}
+
+func TestSyspropLibrary(t *testing.T) {
+ ctx := test(t, `
+ sysprop_library {
+ name: "sysprop-platform",
+ srcs: ["android/sysprop/PlatformProperties.sysprop"],
+ api_packages: ["android.sysprop"],
+ property_owner: "Platform",
+ vendor_available: true,
+ }
+
+ sysprop_library {
+ name: "sysprop-platform-on-product",
+ srcs: ["android/sysprop/PlatformProperties.sysprop"],
+ api_packages: ["android.sysprop"],
+ property_owner: "Platform",
+ product_specific: true,
+ }
+
+ sysprop_library {
+ name: "sysprop-vendor",
+ srcs: ["com/android/VendorProperties.sysprop"],
+ api_packages: ["com.android"],
+ property_owner: "Vendor",
+ product_specific: true,
+ vendor_available: true,
+ }
+
+ java_library {
+ name: "java-platform",
+ srcs: ["c.java"],
+ sdk_version: "system_current",
+ libs: ["sysprop-platform"],
+ }
+
+ java_library {
+ name: "java-product",
+ srcs: ["c.java"],
+ sdk_version: "system_current",
+ product_specific: true,
+ libs: ["sysprop-platform", "sysprop-vendor"],
+ }
+
+ java_library {
+ name: "java-vendor",
+ srcs: ["c.java"],
+ sdk_version: "system_current",
+ soc_specific: true,
+ libs: ["sysprop-platform", "sysprop-vendor"],
+ }
+
+ cc_library {
+ name: "cc-client-platform",
+ srcs: ["d.cpp"],
+ static_libs: ["sysprop-platform"],
+ }
+
+ cc_library {
+ name: "cc-client-product",
+ srcs: ["d.cpp"],
+ product_specific: true,
+ static_libs: ["sysprop-platform-on-product", "sysprop-vendor"],
+ }
+
+ cc_library {
+ name: "cc-client-vendor",
+ srcs: ["d.cpp"],
+ soc_specific: true,
+ static_libs: ["sysprop-platform", "sysprop-vendor"],
+ }
+ `)
+
+ for _, variant := range []string{
+ "android_arm_armv7-a-neon_core_shared",
+ "android_arm_armv7-a-neon_core_static",
+ "android_arm_armv7-a-neon_vendor_shared",
+ "android_arm_armv7-a-neon_vendor_static",
+ "android_arm64_armv8-a_core_shared",
+ "android_arm64_armv8-a_core_static",
+ "android_arm64_armv8-a_vendor_shared",
+ "android_arm64_armv8-a_vendor_static",
+ } {
+ // Check for generated cc_library
+ ctx.ModuleForTests("libsysprop-platform", variant)
+ ctx.ModuleForTests("libsysprop-vendor", variant)
+ }
+
+ ctx.ModuleForTests("sysprop-platform", "android_common")
+ ctx.ModuleForTests("sysprop-vendor", "android_common")
+
+ // Check for exported includes
+ coreVariant := "android_arm64_armv8-a_core_static"
+ vendorVariant := "android_arm64_armv8-a_vendor_static"
+
+ platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/include"
+ platformSystemCorePath := "libsysprop-platform/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
+ platformSystemVendorPath := "libsysprop-platform/android_arm64_armv8-a_vendor_static/gen/sysprop/system/include"
+
+ platformOnProductPath := "libsysprop-platform-on-product/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
+
+ vendorInternalPath := "libsysprop-vendor/android_arm64_armv8-a_vendor_static/gen/sysprop/include"
+ vendorSystemPath := "libsysprop-vendor/android_arm64_armv8-a_core_static/gen/sysprop/system/include"
+
+ platformClient := ctx.ModuleForTests("cc-client-platform", coreVariant)
+ platformFlags := platformClient.Rule("cc").Args["cFlags"]
+
+ // Platform should use platform's internal header
+ if !strings.Contains(platformFlags, platformInternalPath) {
+ t.Errorf("flags for platform must contain %#v, but was %#v.",
+ platformInternalPath, platformFlags)
+ }
+
+ productClient := ctx.ModuleForTests("cc-client-product", coreVariant)
+ productFlags := productClient.Rule("cc").Args["cFlags"]
+
+ // Product should use platform's and vendor's system headers
+ if !strings.Contains(productFlags, platformOnProductPath) ||
+ !strings.Contains(productFlags, vendorSystemPath) {
+ t.Errorf("flags for product must contain %#v and %#v, but was %#v.",
+ platformSystemCorePath, vendorSystemPath, productFlags)
+ }
+
+ vendorClient := ctx.ModuleForTests("cc-client-vendor", vendorVariant)
+ vendorFlags := vendorClient.Rule("cc").Args["cFlags"]
+
+ // Vendor should use platform's system header and vendor's internal header
+ if !strings.Contains(vendorFlags, platformSystemVendorPath) ||
+ !strings.Contains(vendorFlags, vendorInternalPath) {
+ t.Errorf("flags for vendor must contain %#v and %#v, but was %#v.",
+ platformSystemVendorPath, vendorInternalPath, vendorFlags)
+ }
+}
diff --git a/ui/build/goma.go b/ui/build/goma.go
index 015a7c7..ff0b40e 100644
--- a/ui/build/goma.go
+++ b/ui/build/goma.go
@@ -73,7 +73,7 @@
cmd := Command(ctx, config, "goma_ctl.py ensure_start", gomaCtl, "ensure_start")
- if err := cmd.Run(); err != nil {
- ctx.Fatalf("goma_ctl.py ensure_start failed with: %v\n", err)
+ if output, err := cmd.CombinedOutput(); err != nil {
+ ctx.Fatalf("goma_ctl.py ensure_start failed with: %v\n%s\n", err, output)
}
}