Merge "Fix incorrect Rust installation paths."
diff --git a/README.md b/README.md
index b1bb425..3eac87b 100644
--- a/README.md
+++ b/README.md
@@ -419,7 +419,8 @@
name: "acme_cc_defaults",
module_type: "cc_defaults",
config_namespace: "acme",
- variables: ["board", "feature"],
+ variables: ["board"],
+ bool_variables: ["feature"],
properties: ["cflags", "srcs"],
}
@@ -427,10 +428,6 @@
name: "board",
values: ["soc_a", "soc_b"],
}
-
-soong_config_bool_variable {
- name: "feature",
-}
```
This example describes a new `acme_cc_defaults` module type that extends the
diff --git a/android/apex.go b/android/apex.go
index cbaf1c7..d2fb6a1 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -32,6 +32,14 @@
MinSdkVersion int
}
+// Extracted from ApexModule to make it easier to define custom subsets of the
+// ApexModule interface and improve code navigation within the IDE.
+type DepIsInSameApex interface {
+ // DepIsInSameApex tests if the other module 'dep' is installed to the same
+ // APEX as this module
+ DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
+}
+
// ApexModule is the interface that a module type is expected to implement if
// the module has to be built differently depending on whether the module
// is destined for an apex or not (installed to one of the regular partitions).
@@ -49,6 +57,8 @@
// respectively.
type ApexModule interface {
Module
+ DepIsInSameApex
+
apexModuleBase() *ApexModuleBase
// Marks that this module should be built for the specified APEXes.
@@ -88,10 +98,6 @@
// Tests if this module is available for the specified APEX or ":platform"
AvailableFor(what string) bool
- // DepIsInSameApex tests if the other module 'dep' is installed to the same
- // APEX as this module
- DepIsInSameApex(ctx BaseModuleContext, dep Module) bool
-
// Returns the highest version which is <= maxSdkVersion.
// For example, with maxSdkVersion is 10 and versionList is [9,11]
// it returns 9 as string
diff --git a/android/defs.go b/android/defs.go
index 5c815e6..4552224 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -100,6 +100,9 @@
// Used only when USE_GOMA=true is set, to restrict non-goma jobs to the local parallelism value
localPool = blueprint.NewBuiltinPool("local_pool")
+ // Used only by RuleBuilder to identify remoteable rules. Does not actually get created in ninja.
+ remotePool = blueprint.NewBuiltinPool("remote_pool")
+
// Used for processes that need significant RAM to ensure there are not too many running in parallel.
highmemPool = blueprint.NewBuiltinPool("highmem_pool")
)
diff --git a/android/module.go b/android/module.go
index d57abd1..02b2c89 100644
--- a/android/module.go
+++ b/android/module.go
@@ -128,6 +128,13 @@
// and returns a top-down dependency path from a start module to current child module.
GetWalkPath() []Module
+ // GetTagPath is supposed to be called in visit function passed in WalkDeps()
+ // and returns a top-down dependency tags path from a start module to current child module.
+ // It has one less entry than GetWalkPath() as it contains the dependency tags that
+ // exist between each adjacent pair of modules in the GetWalkPath().
+ // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
+ GetTagPath() []blueprint.DependencyTag
+
AddMissingDependencies(missingDeps []string)
Target() Target
@@ -220,6 +227,7 @@
InstallBypassMake() bool
InstallForceOS() *OsType
SkipInstall()
+ IsSkipInstall() bool
ExportedToMake() bool
InitRc() Paths
VintfFragments() Paths
@@ -908,7 +916,7 @@
// partition at "system/vendor/odm".
if config.OdmPath() == "odm" {
partition = "odm"
- } else if strings.HasPrefix(config.OdmPath (), "vendor/") {
+ } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
partition = "vendor"
}
} else if m.ProductSpecific() {
@@ -943,6 +951,10 @@
m.commonProperties.SkipInstall = true
}
+func (m *ModuleBase) IsSkipInstall() bool {
+ return m.commonProperties.SkipInstall == true
+}
+
func (m *ModuleBase) ExportedToMake() bool {
return m.commonProperties.NamespaceExportedToMake
}
@@ -1400,6 +1412,7 @@
debug bool
walkPath []Module
+ tagPath []blueprint.DependencyTag
strictVisitDeps bool // If true, enforce that all dependencies are enabled
}
@@ -1506,10 +1519,17 @@
func (m *moduleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
- if m.config.UseRemoteBuild() && params.Pool == nil {
- // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
- // jobs to the local parallelism value
- params.Pool = localPool
+ if m.config.UseRemoteBuild() {
+ if params.Pool == nil {
+ // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
+ // jobs to the local parallelism value
+ params.Pool = localPool
+ } else if params.Pool == remotePool {
+ // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
+ // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
+ // parallelism.
+ params.Pool = nil
+ }
}
rule := m.bp.Rule(pctx.PackageContext, name, params, argNames...)
@@ -1689,6 +1709,7 @@
func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
b.walkPath = []Module{b.Module()}
+ b.tagPath = []blueprint.DependencyTag{}
b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
childAndroidModule, _ := child.(Module)
parentAndroidModule, _ := parent.(Module)
@@ -1696,8 +1717,10 @@
// record walkPath before visit
for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
+ b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
}
b.walkPath = append(b.walkPath, childAndroidModule)
+ b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
return visit(childAndroidModule, parentAndroidModule)
} else {
return false
@@ -1709,6 +1732,10 @@
return b.walkPath
}
+func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
+ return b.tagPath
+}
+
func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
m.bp.VisitAllModuleVariants(func(module blueprint.Module) {
visit(module.(Module))
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 9005f07..6226548 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -446,7 +446,8 @@
if ctx.Config().UseGoma() && r.remoteable.Goma {
// When USE_GOMA=true is set and the rule is supported by goma, allow jobs to run outside the local pool.
} else if ctx.Config().UseRBE() && r.remoteable.RBE {
- // When USE_RBE=true is set and the rule is supported by RBE, allow jobs to run outside the local pool.
+ // When USE_RBE=true is set and the rule is supported by RBE, use the remotePool.
+ pool = remotePool
} else if r.highmem {
pool = highmemPool
} else if ctx.Config().UseRemoteBuild() {
diff --git a/android/sdk.go b/android/sdk.go
index 66094cd..6f62f55 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -22,17 +22,30 @@
"github.com/google/blueprint/proptools"
)
+// Extracted from SdkAware to make it easier to define custom subsets of the
+// SdkAware interface and improve code navigation within the IDE.
+//
+// In addition to its use in SdkAware this interface must also be implemented by
+// APEX to specify the SDKs required by that module and its contents. e.g. APEX
+// is expected to implement RequiredSdks() by reading its own properties like
+// `uses_sdks`.
+type RequiredSdks interface {
+ // The set of SDKs required by an APEX and its contents.
+ RequiredSdks() SdkRefs
+}
+
// SdkAware is the interface that must be supported by any module to become a member of SDK or to be
// built with SDK
type SdkAware interface {
Module
+ RequiredSdks
+
sdkBase() *SdkBase
MakeMemberOf(sdk SdkRef)
IsInAnySdk() bool
ContainingSdk() SdkRef
MemberName() string
BuildWithSdks(sdks SdkRefs)
- RequiredSdks() SdkRefs
}
// SdkRef refers to a version of an SDK
diff --git a/android/singleton.go b/android/singleton.go
index 45a9b82..568398c 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -128,10 +128,17 @@
}
func (s *singletonContextAdaptor) Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule {
- if s.Config().UseRemoteBuild() && params.Pool == nil {
- // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
- // jobs to the local parallelism value
- params.Pool = localPool
+ if s.Config().UseRemoteBuild() {
+ if params.Pool == nil {
+ // When USE_GOMA=true or USE_RBE=true are set and the rule is not supported by goma/RBE, restrict
+ // jobs to the local parallelism value
+ params.Pool = localPool
+ } else if params.Pool == remotePool {
+ // remotePool is a fake pool used to identify rule that are supported for remoting. If the rule's
+ // pool is the remotePool, replace with nil so that ninja runs it at NINJA_REMOTE_NUM_JOBS
+ // parallelism.
+ params.Pool = nil
+ }
}
rule := s.SingletonContext.Rule(pctx.PackageContext, name, params, argNames...)
if s.Config().captureBuild {
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 198108d..fa1e204 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -88,7 +88,8 @@
// name: "acme_cc_defaults",
// module_type: "cc_defaults",
// config_namespace: "acme",
-// variables: ["board", "feature"],
+// variables: ["board"],
+// bool_variables: ["feature"],
// properties: ["cflags", "srcs"],
// }
//
@@ -97,10 +98,6 @@
// values: ["soc_a", "soc_b"],
// }
//
-// soong_config_bool_variable {
-// name: "feature",
-// }
-//
// If an acme BoardConfig.mk file contained:
//
// SOONG_CONFIG_NAMESPACES += acme
@@ -149,7 +146,8 @@
// name: "acme_cc_defaults",
// module_type: "cc_defaults",
// config_namespace: "acme",
-// variables: ["board", "feature"],
+// variables: ["board"],
+// bool_variables: ["feature"],
// properties: ["cflags", "srcs"],
// }
//
@@ -158,10 +156,6 @@
// values: ["soc_a", "soc_b"],
// }
//
-// soong_config_bool_variable {
-// name: "feature",
-// }
-//
// acme_cc_defaults {
// name: "acme_defaults",
// cflags: ["-DGENERIC"],
diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go
index 6ad88a2..1cf060d 100644
--- a/android/soong_config_modules_test.go
+++ b/android/soong_config_modules_test.go
@@ -43,7 +43,8 @@
name: "acme_test_defaults",
module_type: "test_defaults",
config_namespace: "acme",
- variables: ["board", "feature1", "feature2", "FEATURE3"],
+ variables: ["board", "feature1", "FEATURE3"],
+ bool_variables: ["feature2"],
properties: ["cflags", "srcs"],
}
@@ -57,10 +58,6 @@
}
soong_config_bool_variable {
- name: "feature2",
- }
-
- soong_config_bool_variable {
name: "FEATURE3",
}
`
diff --git a/android/soongconfig/modules.go b/android/soongconfig/modules.go
index aa4f5c5..2d6063d 100644
--- a/android/soongconfig/modules.go
+++ b/android/soongconfig/modules.go
@@ -109,6 +109,9 @@
// the list of SOONG_CONFIG variables that this module type will read
Variables []string
+ // the list of boolean SOONG_CONFIG variables that this module type will read
+ Bool_variables []string
+
// the list of properties that this module type will extend.
Properties []string
}
@@ -146,6 +149,18 @@
}
v.ModuleTypes[props.Name] = mt
+ for _, name := range props.Bool_variables {
+ if name == "" {
+ return []error{fmt.Errorf("bool_variable name must not be blank")}
+ }
+
+ mt.Variables = append(mt.Variables, &boolVariable{
+ baseVariable: baseVariable{
+ variable: name,
+ },
+ })
+ }
+
return nil
}
diff --git a/android/variable.go b/android/variable.go
index 8357d2f..612d138 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -95,6 +95,9 @@
Sanitize struct {
Address *bool
}
+ Optimize struct {
+ Enabled *bool
+ }
}
Pdk struct {
diff --git a/apex/apex.go b/apex/apex.go
index 3fd4905..9142161 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -18,6 +18,7 @@
"fmt"
"path"
"path/filepath"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -94,16 +95,9 @@
// Module separator
//
m["com.android.adbd"] = []string{
- "adbd",
- "libadbconnection_server",
- "libadbd",
"libadbd_auth",
- "libadbd_core",
- "libadbd_services",
- "libasyncio",
"libbuildversion",
"libcap",
- "libdiagnose_usb",
"libmdnssd",
"libminijail",
"libminijail_gen_constants",
@@ -114,7 +108,6 @@
"libpackagelistparser",
"libpcre2",
"libprocessgroup_headers",
- "libqemu_pipe",
}
//
// Module separator
@@ -819,22 +812,6 @@
"libprofile-extras",
"libprofile-extras_ndk",
"libunwind_llvm",
- "ndk_crtbegin_dynamic.27",
- "ndk_crtbegin_so.16",
- "ndk_crtbegin_so.19",
- "ndk_crtbegin_so.21",
- "ndk_crtbegin_so.24",
- "ndk_crtbegin_so.27",
- "ndk_crtend_android.27",
- "ndk_crtend_so.16",
- "ndk_crtend_so.19",
- "ndk_crtend_so.21",
- "ndk_crtend_so.24",
- "ndk_crtend_so.27",
- "ndk_libandroid_support",
- "ndk_libc++_static",
- "ndk_libc++abi",
- "ndk_libunwind",
}
return m
}
@@ -889,9 +866,7 @@
return
}
- cur := mctx.Module().(interface {
- DepIsInSameApex(android.BaseModuleContext, android.Module) bool
- })
+ cur := mctx.Module().(android.DepIsInSameApex)
mctx.VisitDirectDeps(func(child android.Module) {
depName := mctx.OtherModuleName(child)
@@ -1834,6 +1809,24 @@
return android.FutureApiLevel
}
+// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
+// a dependency tag.
+var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`)
+
+func PrettyPrintTag(tag blueprint.DependencyTag) string {
+ // Use tag's custom String() method if available.
+ if stringer, ok := tag.(fmt.Stringer); ok {
+ return stringer.String()
+ }
+
+ // Otherwise, get a default string representation of the tag's struct.
+ tagString := fmt.Sprintf("%#v", tag)
+
+ // Remove the boilerplate from BaseDependencyTag as it adds no value.
+ tagString = tagCleaner.ReplaceAllString(tagString, "")
+ return tagString
+}
+
// Ensures that the dependencies are marked as available for this APEX
func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
// Let's be practical. Availability for test, host, and the VNDK apex isn't important
@@ -1861,8 +1854,11 @@
return true
}
message := ""
- for _, m := range ctx.GetWalkPath()[1:] {
- message = fmt.Sprintf("%s\n -> %s", message, m.String())
+ tagPath := ctx.GetTagPath()
+ // Skip the first module as that will be added at the start of the error message by ctx.ModuleErrorf().
+ walkPath := ctx.GetWalkPath()[1:]
+ for i, m := range walkPath {
+ message = fmt.Sprintf("%s\n via tag %s\n -> %s", message, PrettyPrintTag(tagPath[i]), m.String())
}
ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
// Visit this module's dependencies to check and report any issues with their availability.
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b97e38d..62c2c42 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -27,6 +27,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/dexpreopt"
"android/soong/java"
)
@@ -3540,11 +3541,17 @@
func TestApexAvailable_IndirectDep(t *testing.T) {
// libbbaz is an indirect dep
testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path:
+.*via tag apex\.dependencyTag.*"sharedLib".*
.*-> libfoo.*link:shared.*
+.*via tag cc\.DependencyTag.*"reuse objects".*
.*-> libfoo.*link:static.*
+.*via tag cc\.DependencyTag.*"shared from static".*
.*-> libbar.*link:shared.*
+.*via tag cc\.DependencyTag.*"reuse objects".*
.*-> libbar.*link:static.*
+.*via tag cc\.DependencyTag.*"shared from static".*
.*-> libbaz.*link:shared.*
+.*via tag cc\.DependencyTag.*"reuse objects".*
.*-> libbaz.*link:static.*`, `
apex {
name: "myapex",
@@ -4192,6 +4199,175 @@
ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
}
+func testNoUpdatableJarsInBootImage(t *testing.T, errmsg, bp string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
+ t.Helper()
+
+ bp = bp + `
+ filegroup {
+ name: "some-updatable-apex-file_contexts",
+ srcs: [
+ "system/sepolicy/apex/some-updatable-apex-file_contexts",
+ ],
+ }
+ `
+ bp += cc.GatherRequiredDepsForTest(android.Android)
+ bp += java.GatherRequiredDepsForTest()
+ bp += dexpreopt.BpToolModulesForTest()
+
+ fs := map[string][]byte{
+ "a.java": nil,
+ "a.jar": nil,
+ "build/make/target/product/security": nil,
+ "apex_manifest.json": nil,
+ "AndroidManifest.xml": nil,
+ "system/sepolicy/apex/some-updatable-apex-file_contexts": nil,
+ "system/sepolicy/apex/com.android.art.something-file_contexts": nil,
+ "framework/aidl/a.aidl": nil,
+ }
+ cc.GatherRequiredFilesForTest(fs)
+
+ ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("apex", BundleFactory)
+ ctx.RegisterModuleType("apex_key", ApexKeyFactory)
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ cc.RegisterRequiredBuildComponentsForTest(ctx)
+ java.RegisterJavaBuildComponents(ctx)
+ java.RegisterSystemModulesBuildComponents(ctx)
+ java.RegisterAppBuildComponents(ctx)
+ java.RegisterDexpreoptBootJarsComponents(ctx)
+ ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
+ ctx.PostDepsMutators(android.RegisterOverridePostDepsMutators)
+ ctx.PreDepsMutators(RegisterPreDepsMutators)
+ ctx.PostDepsMutators(RegisterPostDepsMutators)
+
+ config := android.TestArchConfig(buildDir, nil, bp, fs)
+ ctx.Register(config)
+
+ _ = dexpreopt.GlobalSoongConfigForTests(config)
+ dexpreopt.RegisterToolModulesForTest(ctx)
+ pathCtx := android.PathContextForTesting(config)
+ dexpreoptConfig := dexpreopt.GlobalConfigForTests(pathCtx)
+ transformDexpreoptConfig(dexpreoptConfig)
+ dexpreopt.SetTestGlobalConfig(config, dexpreoptConfig)
+
+ _, errs := ctx.ParseBlueprintsFiles("Android.bp")
+ android.FailIfErrored(t, errs)
+
+ _, errs = ctx.PrepareBuildActions(config)
+ if errmsg == "" {
+ android.FailIfErrored(t, errs)
+ } else if len(errs) > 0 {
+ android.FailIfNoMatchingErrors(t, errmsg, errs)
+ return
+ } else {
+ t.Fatalf("missing expected error %q (0 errors are returned)", errmsg)
+ }
+}
+
+func TestNoUpdatableJarsInBootImage(t *testing.T) {
+ bp := `
+ java_library {
+ name: "some-updatable-apex-lib",
+ srcs: ["a.java"],
+ apex_available: [
+ "some-updatable-apex",
+ ],
+ }
+
+ java_library {
+ name: "some-platform-lib",
+ srcs: ["a.java"],
+ installable: true,
+ }
+
+ java_library {
+ name: "some-art-lib",
+ srcs: ["a.java"],
+ apex_available: [
+ "com.android.art.something",
+ ],
+ hostdex: true,
+ }
+
+ apex {
+ name: "some-updatable-apex",
+ key: "some-updatable-apex.key",
+ java_libs: ["some-updatable-apex-lib"],
+ }
+
+ apex_key {
+ name: "some-updatable-apex.key",
+ }
+
+ apex {
+ name: "com.android.art.something",
+ key: "com.android.art.something.key",
+ java_libs: ["some-art-lib"],
+ }
+
+ apex_key {
+ name: "com.android.art.something.key",
+ }
+ `
+
+ var error string
+ var transform func(*dexpreopt.GlobalConfig)
+
+ // updatable jar from ART apex in the ART boot image => ok
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.ArtApexJars = []string{"some-art-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, "", bp, transform)
+
+ // updatable jar from ART apex in the framework boot image => error
+ error = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.BootJars = []string{"some-art-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // updatable jar from some other apex in the ART boot image => error
+ error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.ArtApexJars = []string{"some-updatable-apex-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // updatable jar from some other apex in the framework boot image => error
+ error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.BootJars = []string{"some-updatable-apex-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // nonexistent jar in the ART boot image => error
+ error = "failed to find a dex jar path for module 'nonexistent'"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.ArtApexJars = []string{"nonexistent"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // nonexistent jar in the framework boot image => error
+ error = "failed to find a dex jar path for module 'nonexistent'"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.BootJars = []string{"nonexistent"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // platform jar in the ART boot image => error
+ error = "module 'some-platform-lib' is part of the platform and not allowed in the ART boot image"
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.ArtApexJars = []string{"some-platform-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, error, bp, transform)
+
+ // platform jar in the framework boot image => ok
+ transform = func(config *dexpreopt.GlobalConfig) {
+ config.BootJars = []string{"some-platform-lib"}
+ }
+ testNoUpdatableJarsInBootImage(t, "", bp, transform)
+}
+
func TestMain(m *testing.M) {
run := func() int {
setUp()
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 0516279..a1c5de1 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -124,6 +124,10 @@
Name: "removeHidlInterfaceTypes",
Fix: removeHidlInterfaceTypes,
},
+ {
+ Name: "removeSoongConfigBoolVariable",
+ Fix: removeSoongConfigBoolVariable,
+ },
}
func NewFixRequest() FixRequest {
@@ -714,6 +718,78 @@
return nil
}
+func removeSoongConfigBoolVariable(f *Fixer) error {
+ found := map[string]bool{}
+ newDefs := make([]parser.Definition, 0, len(f.tree.Defs))
+ for _, def := range f.tree.Defs {
+ if mod, ok := def.(*parser.Module); ok && mod.Type == "soong_config_bool_variable" {
+ if name, ok := getLiteralStringPropertyValue(mod, "name"); ok {
+ found[name] = true
+ } else {
+ return fmt.Errorf("Found soong_config_bool_variable without a name")
+ }
+ } else {
+ newDefs = append(newDefs, def)
+ }
+ }
+ f.tree.Defs = newDefs
+
+ if len(found) == 0 {
+ return nil
+ }
+
+ return runPatchListMod(func(mod *parser.Module, buf []byte, patchList *parser.PatchList) error {
+ if mod.Type != "soong_config_module_type" {
+ return nil
+ }
+
+ variables, ok := getLiteralListProperty(mod, "variables")
+ if !ok {
+ return nil
+ }
+
+ boolValues := strings.Builder{}
+ empty := true
+ for _, item := range variables.Values {
+ nameValue, ok := item.(*parser.String)
+ if !ok {
+ empty = false
+ continue
+ }
+ if found[nameValue.Value] {
+ patchList.Add(item.Pos().Offset, item.End().Offset+2, "")
+
+ boolValues.WriteString(`"`)
+ boolValues.WriteString(nameValue.Value)
+ boolValues.WriteString(`",`)
+ } else {
+ empty = false
+ }
+ }
+ if empty {
+ *patchList = parser.PatchList{}
+
+ prop, _ := mod.GetProperty("variables")
+ patchList.Add(prop.Pos().Offset, prop.End().Offset+2, "")
+ }
+ if boolValues.Len() == 0 {
+ return nil
+ }
+
+ bool_variables, ok := getLiteralListProperty(mod, "bool_variables")
+ if ok {
+ patchList.Add(bool_variables.RBracePos.Offset, bool_variables.RBracePos.Offset, ","+boolValues.String())
+ } else {
+ patchList.Add(variables.RBracePos.Offset+2, variables.RBracePos.Offset+2,
+ fmt.Sprintf(`bool_variables: [%s],`, boolValues.String()))
+ }
+
+ return nil
+ })(f)
+
+ return nil
+}
+
// Converts the default source list property, 'srcs', to a single source property with a given name.
// "LOCAL_MODULE" reference is also resolved during the conversion process.
func convertToSingleSource(mod *parser.Module, srcPropertyName string) {
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 38cefdd..64a7b93 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -918,3 +918,67 @@
})
}
}
+
+func TestRemoveSoongConfigBoolVariable(t *testing.T) {
+ tests := []struct {
+ name string
+ in string
+ out string
+ }{
+ {
+ name: "remove bool",
+ in: `
+ soong_config_module_type {
+ name: "foo",
+ variables: ["bar", "baz"],
+ }
+
+ soong_config_bool_variable {
+ name: "bar",
+ }
+
+ soong_config_string_variable {
+ name: "baz",
+ }
+ `,
+ out: `
+ soong_config_module_type {
+ name: "foo",
+ variables: [
+ "baz"
+ ],
+ bool_variables: ["bar"],
+ }
+
+ soong_config_string_variable {
+ name: "baz",
+ }
+ `,
+ },
+ {
+ name: "existing bool_variables",
+ in: `
+ soong_config_module_type {
+ name: "foo",
+ variables: ["baz"],
+ bool_variables: ["bar"],
+ }
+
+ soong_config_bool_variable {
+ name: "baz",
+ }
+ `,
+ out: `
+ soong_config_module_type {
+ name: "foo",
+ bool_variables: ["bar", "baz"],
+ }
+ `,
+ },
+ }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ runPass(t, test.in, test.out, removeSoongConfigBoolVariable)
+ })
+ }
+}
diff --git a/cc/library.go b/cc/library.go
index b9f448b..439a2c0 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -376,7 +376,7 @@
useCoreVariant bool
checkSameCoreVariant bool
- // Decorated interafaces
+ // Decorated interfaces
*baseCompiler
*baseLinker
*baseInstaller
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 0a11af1..754b96a 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -269,6 +269,11 @@
for property, dirs := range includeDirs {
outputProperties.AddProperty(property, dirs)
}
+
+ if len(libInfo.StubsVersion) > 0 {
+ stubsSet := outputProperties.AddPropertySet("stubs")
+ stubsSet.AddProperty("versions", []string{libInfo.StubsVersion})
+ }
}
const (
@@ -335,6 +340,10 @@
// This field is exported as its contents may not be arch specific.
SystemSharedLibs []string
+ // The specific stubs version for the lib variant, or empty string if stubs
+ // are not in use.
+ StubsVersion string
+
// outputFile is not exported as it is always arch specific.
outputFile android.Path
}
@@ -370,6 +379,10 @@
p.SystemSharedLibs = specifiedDeps.systemSharedLibs
}
p.exportedGeneratedHeaders = ccModule.ExportedGeneratedHeaders()
+
+ if ccModule.HasStubsVariants() {
+ p.StubsVersion = ccModule.StubsVersion()
+ }
}
func (p *nativeLibInfoProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index e849aee..3a630d2 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -90,6 +90,11 @@
return ndkPrebuiltModuleToPath(ctx, flags.Toolchain, objectExtension, ctx.sdkVersion())
}
+func (*ndkPrebuiltObjectLinker) availableFor(what string) bool {
+ // ndk prebuilt objects are available to everywhere
+ return true
+}
+
type ndkPrebuiltStlLinker struct {
*libraryDecorator
}
@@ -103,6 +108,11 @@
return deps
}
+func (*ndkPrebuiltStlLinker) availableFor(what string) bool {
+ // ndk prebuilt objects are available to everywhere
+ return true
+}
+
// ndk_prebuilt_shared_stl exports a precompiled ndk shared standard template
// library (stl) library for linking operation. The soong's module name format
// is ndk_<NAME>.so where the library is located under
diff --git a/cc/prebuilt_test.go b/cc/prebuilt_test.go
index 242d835..0b018c1 100644
--- a/cc/prebuilt_test.go
+++ b/cc/prebuilt_test.go
@@ -22,6 +22,25 @@
"github.com/google/blueprint"
)
+func testPrebuilt(t *testing.T, bp string, fs map[string][]byte) *android.TestContext {
+ config := TestConfig(buildDir, android.Android, nil, bp, fs)
+ ctx := CreateTestContext()
+
+ // Enable androidmk support.
+ // * Register the singleton
+ // * Configure that we are inside make
+ // * Add CommonOS to ensure that androidmk processing works.
+ android.RegisterAndroidMkBuildComponents(ctx)
+ android.SetInMakeForTests(config)
+
+ ctx.Register(config)
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ android.FailIfErrored(t, errs)
+ _, errs = ctx.PrepareBuildActions(config)
+ android.FailIfErrored(t, errs)
+ return ctx
+}
+
func TestPrebuilt(t *testing.T) {
bp := `
cc_library {
@@ -84,7 +103,15 @@
}
`
- ctx := testPrebuilt(t, bp)
+ ctx := testPrebuilt(t, bp, map[string][]byte{
+ "liba.so": nil,
+ "libb.a": nil,
+ "libd.so": nil,
+ "libe.a": nil,
+ "libf.a": nil,
+ "libf.so": nil,
+ "crtx.o": nil,
+ })
// Verify that all the modules exist and that their dependencies were connected correctly
liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module()
@@ -143,35 +170,6 @@
}
}
-func testPrebuilt(t *testing.T, bp string) *android.TestContext {
-
- fs := map[string][]byte{
- "liba.so": nil,
- "libb.a": nil,
- "libd.so": nil,
- "libe.a": nil,
- "libf.a": nil,
- "libf.so": nil,
- "crtx.o": nil,
- }
- config := TestConfig(buildDir, android.Android, nil, bp, fs)
- ctx := CreateTestContext()
-
- // Enable androidmk support.
- // * Register the singleton
- // * Configure that we are inside make
- // * Add CommonOS to ensure that androidmk processing works.
- android.RegisterAndroidMkBuildComponents(ctx)
- android.SetInMakeForTests(config)
-
- ctx.Register(config)
- _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
- android.FailIfErrored(t, errs)
- _, errs = ctx.PrepareBuildActions(config)
- android.FailIfErrored(t, errs)
- return ctx
-}
-
func TestPrebuiltLibraryShared(t *testing.T) {
ctx := testPrebuilt(t, `
cc_prebuilt_library_shared {
@@ -181,7 +179,9 @@
none: true,
},
}
- `)
+ `, map[string][]byte{
+ "libf.so": nil,
+ })
shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().String(), "libf.so")
@@ -193,7 +193,9 @@
name: "libtest",
srcs: ["libf.a"],
}
- `)
+ `, map[string][]byte{
+ "libf.a": nil,
+ })
static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module)
assertString(t, static.OutputFile().String(), "libf.a")
@@ -213,7 +215,10 @@
none: true,
},
}
- `)
+ `, map[string][]byte{
+ "libf.a": nil,
+ "libf.so": nil,
+ })
shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module)
assertString(t, shared.OutputFile().String(), "libf.so")
diff --git a/cmd/zipsync/zipsync.go b/cmd/zipsync/zipsync.go
index a6023d3..294e5ef 100644
--- a/cmd/zipsync/zipsync.go
+++ b/cmd/zipsync/zipsync.go
@@ -115,7 +115,7 @@
filename := filepath.Join(*outputDir, name)
if f.FileInfo().IsDir() {
- must(os.MkdirAll(filename, f.FileInfo().Mode()))
+ must(os.MkdirAll(filename, 0777))
} else {
must(os.MkdirAll(filepath.Dir(filename), 0777))
in, err := f.Open()
diff --git a/java/app.go b/java/app.go
index 3f6c1d9..0a4d9e4 100755
--- a/java/app.go
+++ b/java/app.go
@@ -529,14 +529,28 @@
// Build a final signed app package.
packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
- CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps)
+ v4SigningRequested := Bool(a.Module.deviceProperties.V4_signature)
+ var v4SignatureFile android.WritablePath = nil
+ if v4SigningRequested {
+ v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+".apk.idsig")
+ }
+ CreateAndSignAppPackage(ctx, packageFile, a.exportPackage, jniJarFile, dexJarFile, certificates, apkDeps, v4SignatureFile)
a.outputFile = packageFile
+ if v4SigningRequested {
+ a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
+ }
for _, split := range a.aapt.splits {
// Sign the split APKs
packageFile := android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk")
- CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps)
+ if v4SigningRequested {
+ v4SignatureFile = android.PathForModuleOut(ctx, a.installApkName+"_"+split.suffix+".apk.idsig")
+ }
+ CreateAndSignAppPackage(ctx, packageFile, split.path, nil, nil, certificates, apkDeps, v4SignatureFile)
a.extraOutputFiles = append(a.extraOutputFiles, packageFile)
+ if v4SigningRequested {
+ a.extraOutputFiles = append(a.extraOutputFiles, v4SignatureFile)
+ }
}
// Build an app bundle.
@@ -1156,7 +1170,7 @@
}
a.certificate = certificates[0]
signed := android.PathForModuleOut(ctx, "signed", ctx.ModuleName()+".apk")
- SignAppPackage(ctx, signed, dexOutput, certificates)
+ SignAppPackage(ctx, signed, dexOutput, certificates, nil)
a.outputFile = signed
} else {
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", ctx.ModuleName()+".apk")
@@ -1361,7 +1375,7 @@
_, 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)
+ SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil)
r.certificate = certificates[0]
r.outputFile = signed
diff --git a/java/app_builder.go b/java/app_builder.go
index 5e7fbe6..b2780bc 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -45,7 +45,7 @@
})
func CreateAndSignAppPackage(ctx android.ModuleContext, outputFile android.WritablePath,
- packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths) {
+ packageFile, jniJarFile, dexJarFile android.Path, certificates []Certificate, deps android.Paths, v4SignatureFile android.WritablePath) {
unsignedApkName := strings.TrimSuffix(outputFile.Base(), ".apk") + "-unsigned.apk"
unsignedApk := android.PathForModuleOut(ctx, unsignedApkName)
@@ -66,10 +66,10 @@
Implicits: deps,
})
- SignAppPackage(ctx, outputFile, unsignedApk, certificates)
+ SignAppPackage(ctx, outputFile, unsignedApk, certificates, v4SignatureFile)
}
-func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate) {
+func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, unsignedApk android.Path, certificates []Certificate, v4SignatureFile android.WritablePath) {
var certificateArgs []string
var deps android.Paths
@@ -78,14 +78,22 @@
deps = append(deps, c.Pem, c.Key)
}
+ outputFiles := android.WritablePaths{signedApk}
+ var flag string = ""
+ if v4SignatureFile != nil {
+ outputFiles = append(outputFiles, v4SignatureFile)
+ flag = "--enable-v4"
+ }
+
ctx.Build(pctx, android.BuildParams{
Rule: Signapk,
Description: "signapk",
- Output: signedApk,
+ Outputs: outputFiles,
Input: unsignedApk,
Implicits: deps,
Args: map[string]string{
"certificates": strings.Join(certificateArgs, " "),
+ "flags": flag,
},
})
}
diff --git a/java/app_test.go b/java/app_test.go
index 0c6da7a..f3cd070 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1074,6 +1074,66 @@
}
}
+func TestRequestV4SigningFlag(t *testing.T) {
+ testCases := []struct {
+ name string
+ bp string
+ expected string
+ }{
+ {
+ name: "default",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+ `,
+ expected: "",
+ },
+ {
+ name: "default",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ v4_signature: false,
+ }
+ `,
+ expected: "",
+ },
+ {
+ name: "module certificate property",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ v4_signature: true,
+ }
+ `,
+ expected: "--enable-v4",
+ },
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ config := testAppConfig(nil, test.bp, nil)
+ ctx := testContext()
+
+ run(t, ctx, config)
+ foo := ctx.ModuleForTests("foo", "android_common")
+
+ signapk := foo.Output("foo.apk")
+ signFlags := signapk.Args["flags"]
+ if test.expected != signFlags {
+ t.Errorf("Incorrect signing flags, expected: %q, got: %q", test.expected, signFlags)
+ }
+ })
+ }
+}
+
func TestPackageNameOverride(t *testing.T) {
testCases := []struct {
name string
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index d00864d..d53022f 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -26,7 +26,7 @@
)
func init() {
- android.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
+ RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext)
}
// Target-independent description of pre-compiled boot image.
@@ -174,6 +174,10 @@
return &dexpreoptBootJars{}
}
+func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
+}
+
func skipDexpreoptBootJars(ctx android.PathContext) bool {
if dexpreopt.GetGlobalConfig(ctx).DisablePreopt {
return true
@@ -242,16 +246,63 @@
dumpOatRules(ctx, d.defaultBootImage)
}
+// Inspect this module to see if it contains a bootclasspath dex jar.
+// Note that the same jar may occur in multiple modules.
+// This logic is tested in the apex package to avoid import cycle apex <-> java.
+func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, module android.Module) (int, android.Path) {
+ // All apex Java libraries have non-installable platform variants, skip them.
+ if module.IsSkipInstall() {
+ return -1, nil
+ }
+
+ jar, hasJar := module.(interface{ DexJar() android.Path })
+ if !hasJar {
+ return -1, nil
+ }
+
+ name := ctx.ModuleName(module)
+ index := android.IndexList(name, image.modules)
+ if index == -1 {
+ return -1, nil
+ }
+
+ // Check that this module satisfies constraints for a particular boot image.
+ apex, isApexModule := module.(android.ApexModule)
+ if image.name == artBootImageName {
+ if isApexModule && strings.HasPrefix(apex.ApexName(), "com.android.art.") {
+ // ok, found the jar in the ART apex
+ } else if isApexModule && !apex.IsForPlatform() {
+ // this jar is part of an updatable apex other than ART, fail immediately
+ ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the ART boot image", name, apex.ApexName())
+ } else if isApexModule && apex.IsForPlatform() && Bool(module.(*Library).deviceProperties.Hostdex) {
+ // this is a special "hostdex" variant, skip it and resume search
+ return -1, nil
+ } else {
+ // this (installable) jar is part of the platform, fail immediately
+ ctx.Errorf("module '%s' is part of the platform and not allowed in the ART boot image", name)
+ }
+ } else if image.name == frameworkBootImageName {
+ if !isApexModule || apex.IsForPlatform() {
+ // ok, this jar is part of the platform
+ } else {
+ // this jar is part of an updatable apex, fail immediately
+ ctx.Errorf("module '%s' from updatable apex '%s' is not allowed in the framework boot image", name, apex.ApexName())
+ }
+ } else {
+ panic("unknown boot image: " + image.name)
+ }
+
+ return index, jar.DexJar()
+}
+
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
func buildBootImage(ctx android.SingletonContext, image *bootImageConfig) *bootImageConfig {
+ // Collect dex jar paths for the boot image modules.
+ // This logic is tested in the apex package to avoid import cycle apex <-> java.
bootDexJars := make(android.Paths, len(image.modules))
ctx.VisitAllModules(func(module android.Module) {
- // Collect dex jar paths for the modules listed above.
- if j, ok := module.(interface{ DexJar() android.Path }); ok {
- name := ctx.ModuleName(module)
- if i := android.IndexList(name, image.modules); i != -1 {
- bootDexJars[i] = j.DexJar()
- }
+ if i, j := getBootImageJar(ctx, image, module); i != -1 {
+ bootDexJars[i] = j
}
})
@@ -263,7 +314,8 @@
missingDeps = append(missingDeps, image.modules[i])
bootDexJars[i] = android.PathForOutput(ctx, "missing")
} else {
- ctx.Errorf("failed to find dex jar path for module %q",
+ ctx.Errorf("failed to find a dex jar path for module '%s'"+
+ ", note that some jars may be filtered out by module constraints",
image.modules[i])
}
}
diff --git a/java/dexpreopt_bootjars_test.go b/java/dexpreopt_bootjars_test.go
index 94ca8bb..127c201 100644
--- a/java/dexpreopt_bootjars_test.go
+++ b/java/dexpreopt_bootjars_test.go
@@ -53,7 +53,7 @@
ctx := testContext()
- ctx.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
+ RegisterDexpreoptBootJarsComponents(ctx)
run(t, ctx, config)
diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go
index 1315aba..066694c 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -81,7 +81,7 @@
func getDexLocation(ctx android.PathContext, target android.Target, subdir string, name string) string {
if target.Os.Class == android.Host {
- return filepath.Join("out", "host", ctx.Config().PrebuiltOS(), subdir, name)
+ return filepath.Join(ctx.Config().Getenv("OUT_DIR"), "host", ctx.Config().PrebuiltOS(), subdir, name)
} else {
return filepath.Join("/", subdir, name)
}
diff --git a/java/java.go b/java/java.go
index 9a9a02f..c81b781 100644
--- a/java/java.go
+++ b/java/java.go
@@ -325,6 +325,10 @@
UncompressDex bool `blueprint:"mutated"`
IsSDKLibrary bool `blueprint:"mutated"`
+
+ // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file.
+ // Defaults to false.
+ V4_signature *bool
}
func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 52c9004..efee7da 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -86,6 +86,9 @@
// *current. Older stubs library built with a numbered SDK version is created from
// the prebuilt jar.
sdkVersion string
+
+ // Extra arguments to pass to droidstubs for this scope.
+ droidstubsArgs []string
}
// Initialize a scope, creating and adding appropriate dependency tags
@@ -131,6 +134,7 @@
moduleSuffix: sdkSystemApiSuffix,
apiFileMakeVariableSuffix: "_SYSTEM",
sdkVersion: "system_current",
+ droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi"},
})
apiScopeTest = initApiScope(&apiScope{
name: "test",
@@ -138,6 +142,7 @@
moduleSuffix: sdkTestApiSuffix,
apiFileMakeVariableSuffix: "_TEST",
sdkVersion: "test_current",
+ droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
})
allApiScopes = apiScopes{
apiScopePublic,
@@ -458,7 +463,7 @@
mctx.CreateModule(LibraryFactory, &props)
}
-// Creates a droiddoc module that creates stubs source files from the given full source
+// Creates a droidstubs module that creates stubs source files from the given full source
// files
func (module *SdkLibrary) createStubsSources(mctx android.LoadHookContext, apiScope *apiScope) {
props := struct {
@@ -516,15 +521,15 @@
props.Merge_annotations_dirs = module.sdkLibraryProperties.Merge_annotations_dirs
props.Merge_inclusion_annotations_dirs = module.sdkLibraryProperties.Merge_inclusion_annotations_dirs
- droiddocArgs := []string{}
+ droidstubsArgs := []string{}
if len(module.sdkLibraryProperties.Api_packages) != 0 {
- droiddocArgs = append(droiddocArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
+ droidstubsArgs = append(droidstubsArgs, "--stub-packages "+strings.Join(module.sdkLibraryProperties.Api_packages, ":"))
}
if len(module.sdkLibraryProperties.Hidden_api_packages) != 0 {
- droiddocArgs = append(droiddocArgs,
+ droidstubsArgs = append(droidstubsArgs,
android.JoinWithPrefix(module.sdkLibraryProperties.Hidden_api_packages, " --hide-package "))
}
- droiddocArgs = append(droiddocArgs, module.sdkLibraryProperties.Droiddoc_options...)
+ droidstubsArgs = append(droidstubsArgs, module.sdkLibraryProperties.Droiddoc_options...)
disabledWarnings := []string{
"MissingPermission",
"BroadcastBehavior",
@@ -536,16 +541,12 @@
"Todo",
"Typo",
}
- droiddocArgs = append(droiddocArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
+ droidstubsArgs = append(droidstubsArgs, android.JoinWithPrefix(disabledWarnings, "--hide "))
- switch apiScope {
- case apiScopeSystem:
- droiddocArgs = append(droiddocArgs, "-showAnnotation android.annotation.SystemApi")
- case apiScopeTest:
- droiddocArgs = append(droiddocArgs, " -showAnnotation android.annotation.TestApi")
- }
+ // Add in scope specific arguments.
+ droidstubsArgs = append(droidstubsArgs, apiScope.droidstubsArgs...)
props.Arg_files = module.sdkLibraryProperties.Droiddoc_option_files
- props.Args = proptools.StringPtr(strings.Join(droiddocArgs, " "))
+ props.Args = proptools.StringPtr(strings.Join(droidstubsArgs, " "))
// List of APIs identified from the provided source files are created. They are later
// compared against to the not-yet-released (a.k.a current) list of APIs and to the
diff --git a/rust/library.go b/rust/library.go
index 0cf2dd0..bf863bb 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -318,6 +318,8 @@
if ctx.toolchain().Bionic() && (library.dylib() || library.shared()) {
deps = library.baseCompiler.bionicDeps(ctx, deps)
+ deps.CrtBegin = "crtbegin_so"
+ deps.CrtEnd = "crtend_so"
}
return deps
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index eb64bcc..780da9f 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -32,6 +32,7 @@
"arm64/include/Arm64Test.h": nil,
"libfoo.so": nil,
"aidl/foo/bar/Test.aidl": nil,
+ "some/where/stubslib.map.txt": nil,
}
return testSdkWithFs(t, bp, fs)
}
@@ -1739,3 +1740,63 @@
}
`))
}
+
+func TestStubsLibrary(t *testing.T) {
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["stubslib"],
+ }
+
+ cc_library {
+ name: "stubslib",
+ stubs: {
+ symbol_file: "some/where/stubslib.map.txt",
+ versions: ["1", "2", "3"],
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_stubslib@current",
+ sdk_member_name: "stubslib",
+ installable: false,
+ stubs: {
+ versions: ["3"],
+ },
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/stubslib.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/stubslib.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "stubslib",
+ prefer: false,
+ stubs: {
+ versions: ["3"],
+ },
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/stubslib.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/stubslib.so"],
+ },
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ native_shared_libs: ["mysdk_stubslib@current"],
+}
+`))
+}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index dabdf85..a5709ac 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -434,8 +434,8 @@
// Step 6: ensure that the dependencies from outside of the APEX are all from the required SDKs
func sdkRequirementsMutator(mctx android.TopDownMutatorContext) {
if m, ok := mctx.Module().(interface {
- DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool
- RequiredSdks() android.SdkRefs
+ android.DepIsInSameApex
+ android.RequiredSdks
}); ok {
requiredSdks := m.RequiredSdks()
if len(requiredSdks) == 0 {
diff --git a/ui/build/sandbox_linux.go b/ui/build/sandbox_linux.go
index 2de772b..4c3bac3 100644
--- a/ui/build/sandbox_linux.go
+++ b/ui/build/sandbox_linux.go
@@ -54,6 +54,9 @@
working bool
group string
+ srcDir string
+ outDir string
+ distDir string
}
func (c *Cmd) sandboxSupported() bool {
@@ -72,15 +75,34 @@
sandboxConfig.group = "nobody"
}
- cmd := exec.CommandContext(c.ctx.Context, nsjailPath,
+ sandboxConfig.srcDir = absPath(c.ctx, ".")
+ sandboxConfig.outDir = absPath(c.ctx, c.config.OutDir())
+ sandboxConfig.distDir = absPath(c.ctx, c.config.DistDir())
+
+ sandboxArgs := []string{
"-H", "android-build",
"-e",
"-u", "nobody",
"-g", sandboxConfig.group,
- "-B", "/",
+ "-R", "/",
+ "-B", sandboxConfig.srcDir,
+ "-B", "/tmp",
+ "-B", sandboxConfig.outDir,
+ }
+
+ if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) {
+ //Mount dist dir as read-write if it already exists
+ sandboxArgs = append(sandboxArgs, "-B",
+ sandboxConfig.distDir)
+ }
+
+ sandboxArgs = append(sandboxArgs,
"--disable_clone_newcgroup",
"--",
"/bin/bash", "-c", `if [ $(hostname) == "android-build" ]; then echo "Android" "Success"; else echo Failure; fi`)
+
+ cmd := exec.CommandContext(c.ctx.Context, nsjailPath, sandboxArgs...)
+
cmd.Env = c.config.Environment().Environ()
c.ctx.Verboseln(cmd.Args)
@@ -144,8 +166,17 @@
"--rlimit_fsize", "soft",
"--rlimit_nofile", "soft",
- // For now, just map everything. Eventually we should limit this, especially to make most things readonly.
- "-B", "/",
+ // For now, just map everything. Make most things readonly.
+ "-R", "/",
+
+ // Mount source are read-write
+ "-B", sandboxConfig.srcDir,
+
+ //Mount out dir as read-write
+ "-B", sandboxConfig.outDir,
+
+ // Mount a writable tmp dir
+ "-B", "/tmp",
// Disable newcgroup for now, since it may require newer kernels
// TODO: try out cgroups
@@ -155,6 +186,11 @@
"-q",
}
+ if _, err := os.Stat(sandboxConfig.distDir); !os.IsNotExist(err) {
+ //Mount dist dir as read-write if it already exists
+ sandboxArgs = append(sandboxArgs, "-B", sandboxConfig.distDir)
+ }
+
if c.Sandbox.AllowBuildBrokenUsesNetwork && c.config.BuildBrokenUsesNetwork() {
c.ctx.Printf("AllowBuildBrokenUsesNetwork: %v", c.Sandbox.AllowBuildBrokenUsesNetwork)
c.ctx.Printf("BuildBrokenUsesNetwork: %v", c.config.BuildBrokenUsesNetwork())