Merge "Revert^2 "Add sdk mutator for native modules""
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 eabe059..9bf6fc7 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -19,6 +19,8 @@
"sort"
"strconv"
"sync"
+
+ "github.com/google/blueprint"
)
const (
@@ -32,6 +34,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 +59,8 @@
// respectively.
type ApexModule interface {
Module
+ DepIsInSameApex
+
apexModuleBase() *ApexModuleBase
// Marks that this module should be built for the specified APEXes.
@@ -88,16 +100,10 @@
// 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 <= min_sdk_version.
- // For example, with min_sdk_version is 10 and versionList is [9,11]
- // it returns 9.
- ChooseSdkVersion(versionList []string, useLatest bool) (string, error)
-
- ShouldSupportAndroid10() bool
+ // Returns the highest version which is <= maxSdkVersion.
+ // For example, with maxSdkVersion is 10 and versionList is [9,11]
+ // it returns 9 as string
+ ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error)
}
type ApexProperties struct {
@@ -113,6 +119,15 @@
Info ApexInfo `blueprint:"mutated"`
}
+// Marker interface that identifies dependencies that are excluded from APEX
+// contents.
+type ExcludeFromApexContentsTag interface {
+ blueprint.DependencyTag
+
+ // Method that differentiates this interface from others.
+ ExcludeFromApexContents()
+}
+
// Provides default implementation for the ApexModule interface. APEX-aware
// modules are expected to include this struct and call InitApexModule().
type ApexModuleBase struct {
@@ -193,22 +208,14 @@
return true
}
-func (m *ApexModuleBase) ChooseSdkVersion(versionList []string, useLatest bool) (string, error) {
- if useLatest {
- return versionList[len(versionList)-1], nil
- }
- minSdkVersion := m.ApexProperties.Info.MinSdkVersion
+func (m *ApexModuleBase) ChooseSdkVersion(versionList []string, maxSdkVersion int) (string, error) {
for i := range versionList {
ver, _ := strconv.Atoi(versionList[len(versionList)-i-1])
- if ver <= minSdkVersion {
+ if ver <= maxSdkVersion {
return versionList[len(versionList)-i-1], nil
}
}
- return "", fmt.Errorf("min_sdk_version is set %v, but not found in %v", minSdkVersion, versionList)
-}
-
-func (m *ApexModuleBase) ShouldSupportAndroid10() bool {
- return !m.IsForPlatform() && (m.ApexProperties.Info.MinSdkVersion <= SdkVersion_Android10)
+ return "", fmt.Errorf("not found a version(<=%d) in versionList: %v", maxSdkVersion, versionList)
}
func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) {
diff --git a/android/config.go b/android/config.go
index 7953170..558c828 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1032,6 +1032,10 @@
return c.config.productVariables.DeviceKernelHeaders
}
+func (c *deviceConfig) SamplingPGO() bool {
+ return Bool(c.config.productVariables.SamplingPGO)
+}
+
func (c *config) NativeLineCoverage() bool {
return Bool(c.productVariables.NativeLineCoverage)
}
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 057a5c7..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
@@ -894,6 +902,40 @@
return Bool(m.commonProperties.System_ext_specific)
}
+func (m *ModuleBase) PartitionTag(config DeviceConfig) string {
+ partition := "system"
+ if m.SocSpecific() {
+ // A SoC-specific module could be on the vendor partition at
+ // "vendor" or the system partition at "system/vendor".
+ if config.VendorPath() == "vendor" {
+ partition = "vendor"
+ }
+ } else if m.DeviceSpecific() {
+ // A device-specific module could be on the odm partition at
+ // "odm", the vendor partition at "vendor/odm", or the system
+ // partition at "system/vendor/odm".
+ if config.OdmPath() == "odm" {
+ partition = "odm"
+ } else if strings.HasPrefix(config.OdmPath(), "vendor/") {
+ partition = "vendor"
+ }
+ } else if m.ProductSpecific() {
+ // A product-specific module could be on the product partition
+ // at "product" or the system partition at "system/product".
+ if config.ProductPath() == "product" {
+ partition = "product"
+ }
+ } else if m.SystemExtSpecific() {
+ // A system_ext-specific module could be on the system_ext
+ // partition at "system_ext" or the system partition at
+ // "system/system_ext".
+ if config.SystemExtPath() == "system_ext" {
+ partition = "system_ext"
+ }
+ }
+ return partition
+}
+
func (m *ModuleBase) Enabled() bool {
if m.commonProperties.Enabled == nil {
return !m.Os().DefaultDisabled
@@ -909,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
}
@@ -1366,6 +1412,7 @@
debug bool
walkPath []Module
+ tagPath []blueprint.DependencyTag
strictVisitDeps bool // If true, enforce that all dependencies are enabled
}
@@ -1472,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...)
@@ -1655,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)
@@ -1662,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
@@ -1675,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/prebuilt.go b/android/prebuilt.go
index c902ec8..82745a4 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -39,6 +39,12 @@
// Mark this tag so dependencies that use it are excluded from visibility enforcement.
func (t prebuiltDependencyTag) ExcludeFromVisibilityEnforcement() {}
+// Mark this tag so dependencies that use it are excluded from APEX contents.
+func (t prebuiltDependencyTag) ExcludeFromApexContents() {}
+
+var _ ExcludeFromVisibilityEnforcementTag = PrebuiltDepTag
+var _ ExcludeFromApexContentsTag = PrebuiltDepTag
+
type PrebuiltProperties struct {
// When prefer is set to true the prebuilt will be used instead of any source module with
// a matching name.
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..6ce609a 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
@@ -125,7 +122,10 @@
}
func (m *soongConfigModuleTypeImport) Name() string {
- return "soong_config_module_type_import_" + soongconfig.CanonicalizeToProperty(m.properties.From)
+ // The generated name is non-deterministic, but it does not
+ // matter because this module does not emit any rules.
+ return soongconfig.CanonicalizeToProperty(m.properties.From) +
+ "soong_config_module_type_import_" + fmt.Sprintf("%p", m)
}
func (*soongConfigModuleTypeImport) Nameless() {}
@@ -149,7 +149,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 +159,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 91de956..612d138 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -95,6 +95,9 @@
Sanitize struct {
Address *bool
}
+ Optimize struct {
+ Enabled *bool
+ }
}
Pdk struct {
@@ -252,6 +255,8 @@
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
+ SamplingPGO *bool `json:",omitempty"`
+
NativeLineCoverage *bool `json:",omitempty"`
Native_coverage *bool `json:",omitempty"`
ClangCoverage *bool `json:",omitempty"`
diff --git a/android/vts_config.go b/android/vts_config.go
index 9a1df7c..77fb9fe 100644
--- a/android/vts_config.go
+++ b/android/vts_config.go
@@ -53,7 +53,7 @@
fmt.Fprintf(w, "LOCAL_TEST_CONFIG := %s\n",
*me.properties.Test_config)
}
- fmt.Fprintf(w, "LOCAL_COMPATIBILITY_SUITE := vts %s\n",
+ fmt.Fprintf(w, "LOCAL_COMPATIBILITY_SUITE := vts10 %s\n",
strings.Join(me.properties.Test_suites, " "))
},
}
@@ -64,7 +64,7 @@
me.AddProperties(&me.properties)
}
-// vts_config generates a Vendor Test Suite (VTS) configuration file from the
+// vts_config generates a Vendor Test Suite (VTS10) configuration file from the
// <test_config> xml file and stores it in a subdirectory of $(HOST_OUT).
func VtsConfigFactory() Module {
module := &VtsConfig{}
diff --git a/apex/androidmk.go b/apex/androidmk.go
index 5c15e8e..db1048e 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -22,6 +22,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/java"
"github.com/google/blueprint/proptools"
)
@@ -181,6 +182,9 @@
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
// we will have foo.apk.apk
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".apk"))
+ if app, ok := fi.module.(*java.AndroidApp); ok && len(app.JniCoverageOutputs()) > 0 {
+ fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", strings.Join(app.JniCoverageOutputs().Strings(), " "))
+ }
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
} else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
diff --git a/apex/apex.go b/apex/apex.go
index 46aaa8b..5a56185 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -18,6 +18,7 @@
"fmt"
"path"
"path/filepath"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -94,27 +95,9 @@
// Module separator
//
m["com.android.adbd"] = []string{
- "adbd",
- "bcm_object",
- "fmtlib",
- "libadbconnection_server",
- "libadbd",
"libadbd_auth",
- "libadbd_core",
- "libadbd_services",
- "libasyncio",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
"libbuildversion",
- "libc++",
"libcap",
- "libcrypto",
- "libcrypto_utils",
- "libcutils",
- "libcutils_headers",
- "libdiagnose_usb",
- "liblog_headers",
"libmdnssd",
"libminijail",
"libminijail_gen_constants",
@@ -125,9 +108,6 @@
"libpackagelistparser",
"libpcre2",
"libprocessgroup_headers",
- "libqemu_pipe",
- "libsystem_headers",
- "libutils_headers",
}
//
// Module separator
@@ -136,7 +116,6 @@
"art_cmdlineparser_headers",
"art_disassembler_headers",
"art_libartbase_headers",
- "bcm_object",
"bionic_libc_platform_headers",
"core-repackaged-icu4j",
"cpp-define-generator-asm-support",
@@ -148,9 +127,7 @@
"conscrypt.module.intra.core.api.stubs",
"dex2oat_headers",
"dt_fd_forward_export",
- "fmtlib",
"icu4c_extra_headers",
- "jacocoagent",
"javavm_headers",
"jni_platform_headers",
"libPlatformProperties",
@@ -160,15 +137,6 @@
"libart_runtime_headers_ndk",
"libartd-disassembler",
"libasync_safe",
- "libbacktrace",
- "libbase",
- "libbase_headers",
- "libc++",
- "libc++_static",
- "libc++abi",
- "libc++demangle",
- "libc_headers",
- "libcrypto",
"libdexfile_all_headers",
"libdexfile_external_headers",
"libdexfile_support",
@@ -181,7 +149,6 @@
"libicuuc_headers",
"libicuuc_stubdata",
"libjdwp_headers",
- "liblog_headers",
"liblz4",
"liblzma",
"libmeminfo",
@@ -192,7 +159,6 @@
"libopenjdkjvmti_headers",
"libperfetto_client_experimental",
"libprocinfo",
- "libprotobuf-cpp-lite",
"libunwind_llvm",
"libunwindstack",
"libv8",
@@ -229,13 +195,10 @@
"android.hidl.token@1.0-utils",
"avrcp-target-service",
"avrcp_headers",
- "bcm_object",
"bluetooth-protos-lite",
"bluetooth.mapsapi",
"com.android.vcard",
"dnsresolver_aidl_interface-V2-java",
- "fmtlib",
- "guava",
"ipmemorystore-aidl-interfaces-V5-java",
"ipmemorystore-aidl-interfaces-java",
"internal_include_headers",
@@ -245,9 +208,6 @@
"libFraunhoferAAC",
"libaudio-a2dp-hw-utils",
"libaudio-hearing-aid-hw-utils",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
"libbinder_headers",
"libbluetooth",
"libbluetooth-types",
@@ -269,38 +229,23 @@
"libbtdevice",
"libbte",
"libbtif",
- "libc++",
"libchrome",
- "libcrypto",
- "libcutils",
- "libcutils_headers",
"libevent",
"libfmq",
"libg722codec",
"libgtest_prod",
"libgui_headers",
- "libhidlbase",
- "libhidlbase-impl-internal",
- "libhidltransport-impl-internal",
- "libhwbinder-impl-internal",
- "libjsoncpp",
- "liblog_headers",
"libmedia_headers",
"libmodpb64",
"libosi",
"libprocessgroup",
"libprocessgroup_headers",
- "libprotobuf-cpp-lite",
- "libprotobuf-java-lite",
- "libprotobuf-java-micro",
"libstagefright_foundation_headers",
"libstagefright_headers",
"libstatslog",
"libstatssocket",
- "libsystem_headers",
"libtinyxml2",
"libudrv-uipc",
- "libutils_headers",
"libz",
"media_plugin_headers",
"net-utils-services-common",
@@ -320,12 +265,8 @@
// Module separator
//
m["com.android.conscrypt"] = []string{
- "bcm_object",
"boringssl_self_test",
- "libc++",
- "libcrypto",
"libnativehelper_header_only",
- "libssl",
"unsupportedappusage",
}
//
@@ -365,28 +306,11 @@
"android.hidl.memory.token@1.0",
"android.hidl.memory@1.0",
"android.hidl.safe_union@1.0",
- "bcm_object",
- "fmtlib",
"gemmlowp_headers",
"libarect",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
"libbuildversion",
- "libc++",
- "libcrypto",
- "libcrypto_static",
- "libcutils",
- "libcutils_headers",
"libeigen",
"libfmq",
- "libhidlbase",
- "libhidlbase-impl-internal",
- "libhidlmemory",
- "libhidltransport-impl-internal",
- "libhwbinder-impl-internal",
- "libjsoncpp",
- "liblog_headers",
"libmath",
"libneuralnetworks_common",
"libneuralnetworks_headers",
@@ -394,12 +318,10 @@
"libprocessgroup_headers",
"libprocpartition",
"libsync",
- "libsystem_headers",
"libtextclassifier_hash",
"libtextclassifier_hash_headers",
"libtextclassifier_hash_static",
"libtflite_kernel_utils",
- "libutils_headers",
"philox_random",
"philox_random_headers",
"tensorflow_headers",
@@ -431,9 +353,7 @@
"android.hidl.memory@1.0",
"android.hidl.token@1.0",
"android.hidl.token@1.0-utils",
- "bcm_object",
"bionic_libc_platform_headers",
- "fmtlib",
"gl_headers",
"libEGL",
"libEGL_blobCache",
@@ -455,23 +375,14 @@
"libaudiopolicy",
"libaudioutils",
"libaudioutils_fixedfft",
- "libbacktrace",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
"libbinder_headers",
"libbluetooth-types-header",
"libbufferhub",
"libbufferhub_headers",
"libbufferhubqueue",
- "libc++",
- "libc_headers",
"libc_malloc_debug_backtrace",
"libcamera_client",
"libcamera_metadata",
- "libcrypto",
- "libcutils",
- "libcutils_headers",
"libdexfile_external_headers",
"libdexfile_support",
"libdvr_headers",
@@ -483,14 +394,7 @@
"libgui",
"libgui_headers",
"libhardware_headers",
- "libhidlbase",
- "libhidlbase-impl-internal",
- "libhidlmemory",
- "libhidltransport-impl-internal",
- "libhwbinder-impl-internal",
"libinput",
- "libjsoncpp",
- "liblog_headers",
"liblzma",
"libmath",
"libmedia",
@@ -538,11 +442,9 @@
"libstagefright_mpeg2extractor",
"libstagefright_mpeg2support",
"libsync",
- "libsystem_headers",
"libui",
"libui_headers",
"libunwindstack",
- "libutils_headers",
"libvibrator",
"libvorbisidec",
"libwavextractor",
@@ -582,7 +484,6 @@
"android.hidl.safe_union@1.0",
"android.hidl.token@1.0",
"android.hidl.token@1.0-utils",
- "fmtlib",
"libEGL",
"libFLAC",
"libFLAC-config",
@@ -599,15 +500,10 @@
"libavcenc",
"libavservices_minijail",
"libavservices_minijail",
- "libbacktrace",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
"libbinder_headers",
"libbinderthreadstateutils",
"libbluetooth-types-header",
"libbufferhub_headers",
- "libc++",
"libc_scudo",
"libcap",
"libcodec2",
@@ -647,8 +543,6 @@
"libcodec2_soft_vp9dec",
"libcodec2_soft_vp9enc",
"libcodec2_vndk",
- "libcutils",
- "libcutils_headers",
"libdexfile_support",
"libdvr_headers",
"libfmq",
@@ -664,15 +558,8 @@
"libhardware_headers",
"libhevcdec",
"libhevcenc",
- "libhidlbase",
- "libhidlbase-impl-internal",
- "libhidlmemory",
- "libhidltransport-impl-internal",
- "libhwbinder-impl-internal",
"libion",
"libjpeg",
- "libjsoncpp",
- "liblog_headers",
"liblzma",
"libmath",
"libmedia_codecserviceregistrant",
@@ -710,11 +597,9 @@
"libstagefright_m4vh263enc",
"libstagefright_mp3dec",
"libsync",
- "libsystem_headers",
"libui",
"libui_headers",
"libunwindstack",
- "libutils_headers",
"libvorbisidec",
"libvpx",
"libyuv",
@@ -730,7 +615,6 @@
"MediaProvider",
"MediaProviderGoogle",
"fmtlib_ndk",
- "guava",
"libbase_ndk",
"libfuse",
"libfuse_jni",
@@ -754,7 +638,6 @@
"kotlinx-coroutines-android-nodeps",
"kotlinx-coroutines-core",
"kotlinx-coroutines-core-nodeps",
- "libprotobuf-java-lite",
"permissioncontroller-statsd",
}
//
@@ -762,14 +645,9 @@
//
m["com.android.runtime"] = []string{
"bionic_libc_platform_headers",
- "fmtlib",
"libarm-optimized-routines-math",
"libasync_safe",
"libasync_safe_headers",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
- "libc++",
"libc_aeabi",
"libc_bionic",
"libc_bionic_ndk",
@@ -783,7 +661,6 @@
"libc_freebsd",
"libc_freebsd_large_stack",
"libc_gdtoa",
- "libc_headers",
"libc_init_dynamic",
"libc_init_static",
"libc_jemalloc_wrapper",
@@ -798,8 +675,6 @@
"libc_syscalls",
"libc_tzcode",
"libc_unwind_static",
- "libcutils",
- "libcutils_headers",
"libdebuggerd",
"libdebuggerd_common_headers",
"libdebuggerd_handler_core",
@@ -812,7 +687,6 @@
"libjemalloc5",
"liblinker_main",
"liblinker_malloc",
- "liblog_headers",
"liblz4",
"liblzma",
"libprocessgroup_headers",
@@ -820,11 +694,9 @@
"libpropertyinfoparser",
"libscudo",
"libstdc++",
- "libsystem_headers",
"libsystemproperties",
"libtombstoned_client_static",
"libunwindstack",
- "libutils_headers",
"libz",
"libziparchive",
}
@@ -832,34 +704,19 @@
// Module separator
//
m["com.android.resolv"] = []string{
- "bcm_object",
"dnsresolver_aidl_interface-unstable-ndk_platform",
- "fmtlib",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
- "libc++",
- "libcrypto",
- "libcutils",
- "libcutils_headers",
"libgtest_prod",
- "libjsoncpp",
- "liblog_headers",
"libnativehelper_header_only",
"libnetd_client_headers",
"libnetd_resolv",
"libnetdutils",
"libprocessgroup",
"libprocessgroup_headers",
- "libprotobuf-cpp-lite",
- "libssl",
"libstatslog_resolv",
"libstatspush_compat",
"libstatssocket",
"libstatssocket_headers",
- "libsystem_headers",
"libsysutils",
- "libutils_headers",
"netd_event_listener_interface-ndk_platform",
"server_configurable_flags",
"stats_proto",
@@ -868,28 +725,13 @@
// Module separator
//
m["com.android.tethering"] = []string{
- "libbase",
- "libc++",
"libnativehelper_compat_libc++",
"android.hardware.tetheroffload.config@1.0",
- "fmtlib",
- "libbacktrace_headers",
- "libbase_headers",
"libcgrouprc",
"libcgrouprc_format",
- "libcutils",
- "libcutils_headers",
- "libhidlbase",
- "libhidlbase-impl-internal",
- "libhidltransport-impl-internal",
- "libhwbinder-impl-internal",
- "libjsoncpp",
- "liblog_headers",
"libprocessgroup",
"libprocessgroup_headers",
- "libsystem_headers",
"libtetherutilsjni",
- "libutils_headers",
"libvndksupport",
"tethering-aidl-interfaces-java",
}
@@ -925,20 +767,9 @@
"ipmemorystore-aidl-interfaces-V3-java",
"ipmemorystore-aidl-interfaces-java",
"ksoap2",
- "libbacktrace_headers",
- "libbase",
- "libbase_headers",
- "libc++",
- "libcutils",
- "libcutils_headers",
- "liblog_headers",
"libnanohttpd",
"libprocessgroup",
"libprocessgroup_headers",
- "libprotobuf-java-lite",
- "libprotobuf-java-nano",
- "libsystem_headers",
- "libutils_headers",
"libwifi-jni",
"net-utils-services-common",
"netd_aidl_interface-V2-java",
@@ -966,34 +797,14 @@
// Module separator
//
m["com.android.os.statsd"] = []string{
- "libbacktrace_headers",
- "libbase_headers",
- "libc++",
- "libcutils",
- "libcutils_headers",
- "liblog_headers",
"libprocessgroup_headers",
"libstatssocket",
- "libsystem_headers",
- "libutils_headers",
}
//
// Module separator
//
m[android.AvailableToAnyApex] = []string{
- "crtbegin_dynamic",
- "crtbegin_dynamic1",
- "crtbegin_so",
- "crtbegin_so1",
- "crtbegin_static",
- "crtbrand",
- "crtend_android",
- "crtend_so",
"libatomic",
- "libc++_static",
- "libc++abi",
- "libc++demangle",
- "libc_headers",
"libclang_rt",
"libgcc_stripped",
"libprofile-clang-extras",
@@ -1001,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
}
@@ -1071,20 +866,28 @@
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)
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() &&
- cur.DepIsInSameApex(mctx, child) {
+ (cur.DepIsInSameApex(mctx, child) || inAnySdk(child)) {
android.UpdateApexDependency(apexBundles, depName, directDep)
am.BuildForApexes(apexBundles)
}
})
}
+// If a module in an APEX depends on a module from an SDK then it needs an APEX
+// specific variant created for it. Refer to sdk.sdkDepsReplaceMutator.
+func inAnySdk(module android.Module) bool {
+ if sa, ok := module.(android.SdkAware); ok {
+ return sa.IsInAnySdk()
+ }
+
+ return false
+}
+
// Create apex variations if a module is included in APEX(s).
func apexMutator(mctx android.BottomUpMutatorContext) {
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
@@ -1973,10 +1776,14 @@
return true
}
+// Function called while walking an APEX's payload dependencies.
+//
+// Return true if the `to` module should be visited, false otherwise.
+type payloadDepsCallback func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool
+
// Visit dependencies that contributes to the payload of this APEX
-func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext,
- do func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool)) {
- ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
+func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext, do payloadDepsCallback) {
+ ctx.WalkDeps(func(child, parent android.Module) bool {
am, ok := child.(android.ApexModule)
if !ok || !am.CanHaveApexVariants() {
return false
@@ -1985,22 +1792,18 @@
// Check for the direct dependencies that contribute to the payload
if dt, ok := ctx.OtherModuleDependencyTag(child).(dependencyTag); ok {
if dt.payload {
- do(ctx, parent, am, false /* externalDep */)
- return true
+ return do(ctx, parent, am, false /* externalDep */)
}
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
return false
}
// Check for the indirect dependencies if it is considered as part of the APEX
if am.ApexName() != "" {
- do(ctx, parent, am, false /* externalDep */)
- return true
+ return do(ctx, parent, am, false /* externalDep */)
}
- do(ctx, parent, am, true /* externalDep */)
-
- // As soon as the dependency graph crosses the APEX boundary, don't go further.
- return false
+ return do(ctx, parent, am, true /* externalDep */)
})
}
@@ -2016,6 +1819,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
@@ -2023,24 +1844,54 @@
return
}
- a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
+ // Coverage build adds additional dependencies for the coverage-only runtime libraries.
+ // Requiring them and their transitive depencies with apex_available is not right
+ // because they just add noise.
+ if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") || a.IsNativeCoverageNeeded(ctx) {
+ return
+ }
+
+ a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
+ if externalDep {
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
+ return false
+ }
+
apexName := ctx.ModuleName()
fromName := ctx.OtherModuleName(from)
toName := ctx.OtherModuleName(to)
- if externalDep || to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
- return
+
+ // If `to` is not actually in the same APEX as `from` then it does not need apex_available and neither
+ // do any of its dependencies.
+ if am, ok := from.(android.DepIsInSameApex); ok && !am.DepIsInSameApex(ctx, to) {
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
+ return false
}
- ctx.ModuleErrorf("%q requires %q that is not available for the APEX.", fromName, toName)
+
+ if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
+ return true
+ }
+ message := ""
+ 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.
+ return true
})
}
// Collects the list of module names that directly or indirectly contributes to the payload of this APEX
func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
a.depInfos = make(map[string]depInfo)
- a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
+ a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if from.Name() == to.Name() {
// This can happen for cc.reuseObjTag. We are not interested in tracking this.
- return
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
+ return !externalDep
}
if info, exists := a.depInfos[to.Name()]; exists {
@@ -2056,6 +1907,9 @@
isExternal: externalDep,
}
}
+
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
+ return !externalDep
})
}
@@ -2132,6 +1986,9 @@
// TODO(jiyong) do this using walkPayloadDeps
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
depTag := ctx.OtherModuleDependencyTag(child)
+ if _, ok := depTag.(android.ExcludeFromApexContentsTag); ok {
+ return false
+ }
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
switch depTag {
@@ -2300,7 +2157,7 @@
filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName))
}
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
- ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
+ ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", PrettyPrintTag(depTag), depName)
}
}
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index dbccb92..0c8937e 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"
)
@@ -158,6 +159,7 @@
"my_include": nil,
"foo/bar/MyClass.java": nil,
"prebuilt.jar": nil,
+ "prebuilt.so": nil,
"vendor/foo/devkeys/test.x509.pem": nil,
"vendor/foo/devkeys/test.pk8": nil,
"testkey.x509.pem": nil,
@@ -367,7 +369,7 @@
apex_available: [ "myapex" ],
}
- cc_library {
+ cc_library_shared {
name: "mylib2",
srcs: ["mylib.cpp"],
system_shared_libs: [],
@@ -381,6 +383,16 @@
],
}
+ cc_prebuilt_library_shared {
+ name: "mylib2",
+ srcs: ["prebuilt.so"],
+ // TODO: remove //apex_available:platform
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
cc_library_static {
name: "libstatic",
srcs: ["mylib.cpp"],
@@ -874,58 +886,89 @@
}
-func TestApexDependencyToLLNDK(t *testing.T) {
- ctx, _ := testApex(t, `
- apex {
- name: "myapex",
- key: "myapex.key",
- use_vendor: true,
- native_shared_libs: ["mylib"],
- }
+func TestApexDependsOnLLNDKTransitively(t *testing.T) {
+ testcases := []struct {
+ name string
+ minSdkVersion string
+ shouldLink string
+ shouldNotLink []string
+ }{
+ {
+ name: "should link to the latest",
+ minSdkVersion: "current",
+ shouldLink: "30",
+ shouldNotLink: []string{"29"},
+ },
+ {
+ name: "should link to llndk#29",
+ minSdkVersion: "29",
+ shouldLink: "29",
+ shouldNotLink: []string{"30"},
+ },
+ }
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ use_vendor: true,
+ native_shared_libs: ["mylib"],
+ min_sdk_version: "`+tc.minSdkVersion+`",
+ }
- apex_key {
- name: "myapex.key",
- public_key: "testkey.avbpubkey",
- private_key: "testkey.pem",
- }
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
- cc_library {
- name: "mylib",
- srcs: ["mylib.cpp"],
- vendor_available: true,
- shared_libs: ["libbar"],
- system_shared_libs: [],
- stl: "none",
- apex_available: [ "myapex" ],
- }
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ vendor_available: true,
+ shared_libs: ["libbar"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
- cc_library {
- name: "libbar",
- srcs: ["mylib.cpp"],
- system_shared_libs: [],
- stl: "none",
- }
+ cc_library {
+ name: "libbar",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ stubs: { versions: ["29","30"] },
+ }
- llndk_library {
- name: "libbar",
- symbol_file: "",
- }
- `, func(fs map[string][]byte, config android.Config) {
- setUseVendorWhitelistForTest(config, []string{"myapex"})
- })
+ llndk_library {
+ name: "libbar",
+ symbol_file: "",
+ }
+ `, func(fs map[string][]byte, config android.Config) {
+ setUseVendorWhitelistForTest(config, []string{"myapex"})
+ }, withUnbundledBuild)
- apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
- copyCmds := apexRule.Args["copy_commands"]
+ // Ensure that LLNDK dep is not included
+ ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ "lib64/mylib.so",
+ })
- // Ensure that LLNDK dep is not included
- ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
+ // Ensure that LLNDK dep is required
+ apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
+ ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
+ ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
- ensureListEmpty(t, names(apexManifestRule.Args["provideNativeLibs"]))
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
+ ensureContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+tc.shouldLink+"/libbar.so")
+ for _, ver := range tc.shouldNotLink {
+ ensureNotContains(t, mylibLdFlags, "libbar.llndk/android_vendor.VER_arm64_armv8-a_shared_"+ver+"/libbar.so")
+ }
- // Ensure that LLNDK dep is required
- ensureListContains(t, names(apexManifestRule.Args["requireNativeLibs"]), "libbar.so")
-
+ mylibCFlags := ctx.ModuleForTests("mylib", "android_vendor.VER_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
+ ensureContains(t, mylibCFlags, "__LIBBAR_API__="+tc.shouldLink)
+ })
+ }
}
func TestApexWithSystemLibsStubs(t *testing.T) {
@@ -1191,7 +1234,7 @@
expectNoLink("libz", "shared", "libz", "shared")
}
-func TestQApexesUseLatestStubsInBundledBuilds(t *testing.T) {
+func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
@@ -1218,16 +1261,18 @@
versions: ["29", "30"],
},
}
- `)
+ `, func(fs map[string][]byte, config android.Config) {
+ config.TestProductVariables.SanitizeDevice = []string{"hwaddress"}
+ })
expectLink := func(from, from_variant, to, to_variant string) {
ld := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld")
libFlags := ld.Args["libFlags"]
ensureContains(t, libFlags, "android_arm64_armv8-a_"+to_variant+"/"+to+".so")
}
- expectLink("libx", "shared_myapex", "libbar", "shared_30")
+ expectLink("libx", "shared_hwasan_myapex", "libbar", "shared_30")
}
-func TestQTargetApexUseStaticUnwinder(t *testing.T) {
+func TestQTargetApexUsesStaticUnwinder(t *testing.T) {
ctx, _ := testApex(t, `
apex {
name: "myapex",
@@ -1246,8 +1291,7 @@
name: "libx",
apex_available: [ "myapex" ],
}
-
- `, withUnbundledBuild)
+ `)
// ensure apex variant of c++ is linked with static unwinder
cm := ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared_myapex").Module().(*cc.Module)
@@ -1255,14 +1299,10 @@
// note that platform variant is not.
cm = ctx.ModuleForTests("libc++", "android_arm64_armv8-a_shared").Module().(*cc.Module)
ensureListNotContains(t, cm.Properties.AndroidMkStaticLibs, "libgcc_stripped")
-
- libFlags := ctx.ModuleForTests("libx", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
- ensureContains(t, libFlags, "android_arm64_armv8-a_shared_myapex/libc++.so")
- ensureContains(t, libFlags, "android_arm64_armv8-a_shared_29/libc.so") // min_sdk_version applied
}
func TestInvalidMinSdkVersion(t *testing.T) {
- testApexError(t, `"libz" .*: min_sdk_version is set 29.*`, `
+ testApexError(t, `"libz" .*: not found a version\(<=29\)`, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1292,9 +1332,9 @@
versions: ["30"],
},
}
- `, withUnbundledBuild)
+ `)
- testApexError(t, `"myapex" .*: min_sdk_version: should be .*`, `
+ testApexError(t, `"myapex" .*: min_sdk_version: should be "current" or <number>`, `
apex {
name: "myapex",
key: "myapex.key",
@@ -1797,6 +1837,7 @@
"myapex",
"otherapex",
],
+ recovery_available: true,
}
cc_library {
name: "mylib2",
@@ -1814,7 +1855,7 @@
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
- ensureContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__=10000")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_myapex").Rule("cc").Args["cFlags"]
@@ -1846,6 +1887,11 @@
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__")
ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MYAPEX__")
ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_OTHERAPEX__")
+
+ // recovery variant does not set __ANDROID_SDK_VERSION__
+ mylibCFlags = ctx.ModuleForTests("mylib", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__")
+ ensureNotContains(t, mylibCFlags, "-D__ANDROID_SDK_VERSION__")
}
func TestHeaderLibsDependency(t *testing.T) {
@@ -3468,7 +3514,7 @@
}`)
}
-func TestApexAvailable(t *testing.T) {
+func TestApexAvailable_DirectDep(t *testing.T) {
// libfoo is not available to myapex, but only to otherapex
testApexError(t, "requires \"libfoo\" that is not available for the APEX", `
apex {
@@ -3501,9 +3547,17 @@
system_shared_libs: [],
apex_available: ["otherapex"],
}`)
+}
+func TestApexAvailable_IndirectDep(t *testing.T) {
// libbbaz is an indirect dep
- testApexError(t, "requires \"libbaz\" that is not available for the APEX", `
+ 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.*"shared".*
+.*-> libbar.*link:shared.*
+.*via tag cc\.DependencyTag.*"shared".*
+.*-> libbaz.*link:shared.*`, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3537,7 +3591,9 @@
stl: "none",
system_shared_libs: [],
}`)
+}
+func TestApexAvailable_InvalidApexName(t *testing.T) {
testApexError(t, "\"otherapex\" is not a valid module name", `
apex {
name: "myapex",
@@ -3558,7 +3614,7 @@
apex_available: ["otherapex"],
}`)
- ctx, _ := testApex(t, `
+ testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3594,7 +3650,9 @@
versions: ["10", "20", "30"],
},
}`)
+}
+func TestApexAvailable_CreatedForPlatform(t *testing.T) {
// check that libfoo and libbar are created only for myapex, but not for the platform
// TODO(jiyong) the checks for the platform variant are removed because we now create
// the platform variant regardless of the apex_availability. Instead, we will make sure that
@@ -3606,7 +3664,7 @@
// ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_myapex")
// ensureListNotContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared")
- ctx, _ = testApex(t, `
+ ctx, _ := testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -3628,8 +3686,10 @@
// check that libfoo is created only for the platform
ensureListNotContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared_myapex")
ensureListContains(t, ctx.ModuleVariantsForTests("libfoo"), "android_arm64_armv8-a_shared")
+}
- ctx, _ = testApex(t, `
+func TestApexAvailable_CreatedForApex(t *testing.T) {
+ testApex(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -4144,6 +4204,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/apex/builder.go b/apex/builder.go
index 67bc206..5a2134a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -230,12 +230,16 @@
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
var noticeFiles android.Paths
- a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
+ a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if externalDep {
- return
+ // As soon as the dependency graph crosses the APEX boundary, don't go further.
+ return false
}
+
notices := to.NoticeFiles()
noticeFiles = append(noticeFiles, notices...)
+
+ return true
})
if len(noticeFiles) == 0 {
diff --git a/apex/key.go b/apex/key.go
index ffde315..607cac5 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -133,17 +133,18 @@
module := apexModulesMap[key]
if m, ok := module.(*apexBundle); ok {
fmt.Fprintf(&filecontent,
- "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q\\n",
+ "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\\n",
m.Name()+".apex",
m.public_key_file.String(),
m.private_key_file.String(),
m.container_certificate_file.String(),
- m.container_private_key_file.String())
+ m.container_private_key_file.String(),
+ m.PartitionTag(ctx.DeviceConfig()))
} else if m, ok := module.(*Prebuilt); ok {
fmt.Fprintf(&filecontent,
- "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q\\n",
+ "name=%q public_key=%q private_key=%q container_certificate=%q container_private_key=%q partition=%q\\n",
m.InstallFilename(),
- "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED")
+ "PRESIGNED", "PRESIGNED", "PRESIGNED", "PRESIGNED", m.PartitionTag(ctx.DeviceConfig()))
}
}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 59d1502..4cdfb31 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -60,6 +60,10 @@
func (bpf *bpf) GenerateAndroidBuildActions(ctx android.ModuleContext) {
cflags := []string{
"-nostdlibinc",
+
+ // Make paths in deps files relative
+ "-no-canonical-prefixes",
+
"-O2",
"-isystem bionic/libc/include",
"-isystem bionic/libc/kernel/uapi",
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/binary_sdk_member.go b/cc/binary_sdk_member.go
index 9b3235c..1d9cc54 100644
--- a/cc/binary_sdk_member.go
+++ b/cc/binary_sdk_member.go
@@ -18,6 +18,7 @@
"path/filepath"
"android/soong/android"
+
"github.com/google/blueprint"
)
@@ -137,7 +138,9 @@
propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false))
}
- if len(p.SystemSharedLibs) > 0 {
+ // SystemSharedLibs needs to be propagated if it's a list, even if it's empty,
+ // so check for non-nil instead of nonzero length.
+ if p.SystemSharedLibs != nil {
propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false))
}
}
diff --git a/cc/cc.go b/cc/cc.go
index 794adf1..4667a3d 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -393,7 +393,7 @@
type specifiedDeps struct {
sharedLibs []string
- systemSharedLibs []string
+ systemSharedLibs []string // Note nil and [] are semantically distinct.
}
type installer interface {
@@ -503,6 +503,9 @@
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
kytheFiles android.Paths
+
+ // For apex variants, this is set as apex.min_sdk_version
+ apexSdkVersion int
}
func (c *Module) Toc() android.OptionalPath {
@@ -644,6 +647,10 @@
c.Properties.PreventInstall = true
return
}
+ if _, ok := c.linker.(*llndkStubDecorator); ok {
+ c.Properties.HideFromMake = true
+ return
+ }
}
panic(fmt.Errorf("SetBuildStubs called on non-library module: %q", c.BaseModuleName()))
}
@@ -663,6 +670,10 @@
library.MutatedProperties.StubsVersion = version
return
}
+ if llndk, ok := c.linker.(*llndkStubDecorator); ok {
+ llndk.libraryDecorator.MutatedProperties.StubsVersion = version
+ return
+ }
}
panic(fmt.Errorf("SetStubsVersions called on non-library module: %q", c.BaseModuleName()))
}
@@ -672,6 +683,9 @@
if library, ok := c.linker.(*libraryDecorator); ok {
return library.MutatedProperties.StubsVersion
}
+ if llndk, ok := c.linker.(*llndkStubDecorator); ok {
+ return llndk.libraryDecorator.MutatedProperties.StubsVersion
+ }
}
panic(fmt.Errorf("StubsVersion called on non-library module: %q", c.BaseModuleName()))
}
@@ -1228,7 +1242,7 @@
}
func (ctx *moduleContextImpl) apexSdkVersion() int {
- return ctx.mod.ApexProperties.Info.MinSdkVersion
+ return ctx.mod.apexSdkVersion
}
func (ctx *moduleContextImpl) hasStubsVariants() bool {
@@ -1868,7 +1882,10 @@
}, depTag, lib)
}
- if deps.StaticUnwinderIfLegacy && ctx.Config().UnbundledBuild() {
+ // staticUnwinderDep is treated as staticDep for Q apexes
+ // so that native libraries/binaries are linked with static unwinder
+ // because Q libc doesn't have unwinder APIs
+ if deps.StaticUnwinderIfLegacy {
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
}, staticUnwinderDepTag, staticUnwinder(actx))
@@ -1883,7 +1900,7 @@
addSharedLibDependencies := func(depTag DependencyTag, name string, version string) {
var variations []blueprint.Variation
variations = append(variations, blueprint.Variation{Mutator: "link", Variation: "shared"})
- versionVariantAvail := !ctx.useVndk() && !c.InRecovery() && !c.InRamdisk()
+ versionVariantAvail := !c.InRecovery() && !c.InRamdisk()
if version != "" && versionVariantAvail {
// Version is explicitly specified. i.e. libFoo#30
variations = append(variations, blueprint.Variation{Mutator: "version", Variation: version})
@@ -2218,13 +2235,17 @@
if depTag == android.ProtoPluginDepTag {
return
}
+ if depTag == llndkImplDep {
+ return
+ }
if dep.Target().Os != ctx.Os() {
ctx.ModuleErrorf("OS mismatch between %q and %q", ctx.ModuleName(), depName)
return
}
if dep.Target().Arch.ArchType != ctx.Arch().ArchType {
- ctx.ModuleErrorf("Arch mismatch between %q and %q", ctx.ModuleName(), depName)
+ ctx.ModuleErrorf("Arch mismatch between %q(%v) and %q(%v)",
+ ctx.ModuleName(), ctx.Arch().ArchType, depName, dep.Target().Arch.ArchType)
return
}
@@ -2248,9 +2269,22 @@
}
}
+ // For the dependency from platform to apex, use the latest stubs
+ c.apexSdkVersion = android.FutureApiLevel
+ if !c.IsForPlatform() {
+ c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion
+ }
+
+ if android.InList("hwaddress", ctx.Config().SanitizeDevice()) {
+ // In hwasan build, we override apexSdkVersion to the FutureApiLevel(10000)
+ // so that even Q(29/Android10) apexes could use the dynamic unwinder by linking the newer stubs(e.g libc(R+)).
+ // (b/144430859)
+ c.apexSdkVersion = android.FutureApiLevel
+ }
+
if depTag == staticUnwinderDepTag {
- // Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
- if c.ShouldSupportAndroid10() {
+ // Use static unwinder for legacy (min_sdk_version = 29) apexes (b/144430859)
+ if c.apexSdkVersion <= android.SdkVersion_Android10 {
depTag = StaticDepTag
} else {
return
@@ -2304,8 +2338,7 @@
// when to use (unspecified) stubs, check min_sdk_version and choose the right one
if useThisDep && depIsStubs && !explicitlyVersioned {
- useLatest := c.IsForPlatform() || (c.ShouldSupportAndroid10() && !ctx.Config().UnbundledBuild())
- versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), useLatest)
+ versionToUse, err := c.ChooseSdkVersion(ccDep.StubsVersions(), c.apexSdkVersion)
if err != nil {
ctx.OtherModuleErrorf(dep, err.Error())
return
@@ -2319,6 +2352,26 @@
return // stop processing this dep
}
}
+ if c.UseVndk() {
+ if m, ok := ccDep.(*Module); ok && m.IsStubs() { // LLNDK
+ // by default, use current version of LLNDK
+ versionToUse := ""
+ versions := stubsVersionsFor(ctx.Config())[depName]
+ if c.ApexName() != "" && len(versions) > 0 {
+ // if this is for use_vendor apex && dep has stubsVersions
+ // apply the same rule of apex sdk enforcement to choose right version
+ var err error
+ versionToUse, err = c.ChooseSdkVersion(versions, c.apexSdkVersion)
+ if err != nil {
+ ctx.OtherModuleErrorf(dep, err.Error())
+ return
+ }
+ }
+ if versionToUse != ccDep.StubsVersion() {
+ return
+ }
+ }
+ }
depPaths.IncludeDirs = append(depPaths.IncludeDirs, ccDep.IncludeDirs()...)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 9a9678f..67eb248 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -2398,6 +2398,34 @@
}
}
+func TestLlndkLibrary(t *testing.T) {
+ ctx := testCc(t, `
+ cc_library {
+ name: "libllndk",
+ stubs: { versions: ["1", "2"] },
+ }
+ llndk_library {
+ name: "libllndk",
+ }
+ `)
+ actual := ctx.ModuleVariantsForTests("libllndk.llndk")
+ expected := []string{
+ "android_vendor.VER_arm64_armv8-a_shared",
+ "android_vendor.VER_arm64_armv8-a_shared_1",
+ "android_vendor.VER_arm64_armv8-a_shared_2",
+ "android_vendor.VER_arm_armv7-a-neon_shared",
+ "android_vendor.VER_arm_armv7-a-neon_shared_1",
+ "android_vendor.VER_arm_armv7-a-neon_shared_2",
+ }
+ checkEquals(t, "variants for llndk stubs", expected, actual)
+
+ params := ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub")
+ checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
+
+ params = ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub")
+ checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
+}
+
func TestLlndkHeaders(t *testing.T) {
ctx := testCc(t, `
llndk_headers {
diff --git a/cc/compiler.go b/cc/compiler.go
index fe81bd0..681b1ab 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -315,18 +315,6 @@
"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
}
- if ctx.canUseSdk() {
- sdkVersion := ctx.sdkVersion()
- if sdkVersion == "" || sdkVersion == "current" {
- if ctx.isForPlatform() {
- sdkVersion = strconv.Itoa(android.FutureApiLevel)
- } else {
- sdkVersion = strconv.Itoa(ctx.apexSdkVersion())
- }
- }
- flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_SDK_VERSION__="+sdkVersion)
- }
-
if ctx.useVndk() {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_VNDK__")
}
@@ -340,6 +328,9 @@
if Bool(compiler.Properties.Use_apex_name_macro) {
flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX_"+makeDefineString(ctx.apexName())+"__")
}
+ if ctx.Device() {
+ flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_SDK_VERSION__="+strconv.Itoa(ctx.apexSdkVersion()))
+ }
}
instructionSet := String(compiler.Properties.Instruction_set)
diff --git a/cc/config/global.go b/cc/config/global.go
index 29020ab..5611a96 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -127,8 +127,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r377782c"
- ClangDefaultShortVersion = "10.0.5"
+ ClangDefaultVersion = "clang-r377782d"
+ ClangDefaultShortVersion = "10.0.6"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go
index 25225b5..8eb79e3 100644
--- a/cc/config/x86_darwin_host.go
+++ b/cc/config/x86_darwin_host.go
@@ -15,9 +15,11 @@
package config
import (
+ "fmt"
"os/exec"
"path/filepath"
"strings"
+ "sync"
"android/soong/android"
)
@@ -89,28 +91,20 @@
)
func init() {
- pctx.VariableFunc("macSdkPath", func(ctx android.PackageVarContext) string {
- xcodeselect := ctx.Config().HostSystemTool("xcode-select")
- bytes, err := exec.Command(xcodeselect, "--print-path").Output()
- if err != nil {
- ctx.Errorf("xcode-select failed with: %q", err.Error())
- }
- return strings.TrimSpace(string(bytes))
- })
pctx.VariableFunc("macSdkRoot", func(ctx android.PackageVarContext) string {
- return xcrunSdk(ctx, "--show-sdk-path")
+ return getMacTools(ctx).sdkRoot
})
pctx.StaticVariable("macMinVersion", "10.10")
pctx.VariableFunc("MacArPath", func(ctx android.PackageVarContext) string {
- return xcrun(ctx, "--find", "ar")
+ return getMacTools(ctx).arPath
})
pctx.VariableFunc("MacStripPath", func(ctx android.PackageVarContext) string {
- return xcrun(ctx, "--find", "strip")
+ return getMacTools(ctx).stripPath
})
pctx.VariableFunc("MacToolPath", func(ctx android.PackageVarContext) string {
- return filepath.Dir(xcrun(ctx, "--find", "ld"))
+ return getMacTools(ctx).toolPath
})
pctx.StaticVariable("DarwinGccVersion", darwinGccVersion)
@@ -126,38 +120,66 @@
pctx.StaticVariable("DarwinYasmFlags", "-f macho -m amd64")
}
-func xcrun(ctx android.PackageVarContext, args ...string) string {
- xcrun := ctx.Config().HostSystemTool("xcrun")
- bytes, err := exec.Command(xcrun, args...).Output()
- if err != nil {
- ctx.Errorf("xcrun failed with: %q", err.Error())
- }
- return strings.TrimSpace(string(bytes))
+type macPlatformTools struct {
+ once sync.Once
+ err error
+
+ sdkRoot string
+ arPath string
+ stripPath string
+ toolPath string
}
-func xcrunSdk(ctx android.PackageVarContext, arg string) string {
- xcrun := ctx.Config().HostSystemTool("xcrun")
- if selected := ctx.Config().Getenv("MAC_SDK_VERSION"); selected != "" {
- if !inList(selected, darwinSupportedSdkVersions) {
- ctx.Errorf("MAC_SDK_VERSION %s isn't supported: %q", selected, darwinSupportedSdkVersions)
+var macTools = &macPlatformTools{}
+
+func getMacTools(ctx android.PackageVarContext) *macPlatformTools {
+ macTools.once.Do(func() {
+ xcrunTool := ctx.Config().HostSystemTool("xcrun")
+
+ xcrun := func(args ...string) string {
+ if macTools.err != nil {
+ return ""
+ }
+
+ bytes, err := exec.Command(xcrunTool, args...).Output()
+ if err != nil {
+ macTools.err = fmt.Errorf("xcrun %q failed with: %q", args, err)
+ return ""
+ }
+
+ return strings.TrimSpace(string(bytes))
+ }
+
+ xcrunSdk := func(arg string) string {
+ if selected := ctx.Config().Getenv("MAC_SDK_VERSION"); selected != "" {
+ if !inList(selected, darwinSupportedSdkVersions) {
+ macTools.err = fmt.Errorf("MAC_SDK_VERSION %s isn't supported: %q", selected, darwinSupportedSdkVersions)
+ return ""
+ }
+
+ return xcrun("--sdk", "macosx"+selected, arg)
+ }
+
+ for _, sdk := range darwinSupportedSdkVersions {
+ bytes, err := exec.Command(xcrunTool, "--sdk", "macosx"+sdk, arg).Output()
+ if err == nil {
+ return strings.TrimSpace(string(bytes))
+ }
+ }
+ macTools.err = fmt.Errorf("Could not find a supported mac sdk: %q", darwinSupportedSdkVersions)
return ""
}
- bytes, err := exec.Command(xcrun, "--sdk", "macosx"+selected, arg).Output()
- if err != nil {
- ctx.Errorf("MAC_SDK_VERSION %s is not installed", selected)
- }
- return strings.TrimSpace(string(bytes))
- }
+ macTools.sdkRoot = xcrunSdk("--show-sdk-path")
- for _, sdk := range darwinSupportedSdkVersions {
- bytes, err := exec.Command(xcrun, "--sdk", "macosx"+sdk, arg).Output()
- if err == nil {
- return strings.TrimSpace(string(bytes))
- }
+ macTools.arPath = xcrun("--find", "ar")
+ macTools.stripPath = xcrun("--find", "strip")
+ macTools.toolPath = filepath.Dir(xcrun("--find", "ld"))
+ })
+ if macTools.err != nil {
+ ctx.Errorf("%q", macTools.err)
}
- ctx.Errorf("Could not find a supported mac sdk: %q", darwinSupportedSdkVersions)
- return ""
+ return macTools
}
type toolchainDarwin struct {
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 6a9b709..b7173a3 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -198,6 +198,11 @@
return installLocation
}
+// Get the device-only shared library symbols install directory.
+func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, archString string) string {
+ return filepath.Join("$(PRODUCT_OUT)/symbols/data/fuzz/", archString, "/lib/", libraryPath.Base())
+}
+
func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
fuzz.binaryDecorator.baseInstaller.dir = filepath.Join(
"fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
@@ -269,6 +274,12 @@
fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
sharedLibraryInstallLocation(
lib, ctx.Host(), ctx.Arch().ArchType.String()))
+
+ // Also add the dependency on the shared library symbols dir.
+ if !ctx.Host() {
+ fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
+ sharedLibrarySymbolsInstallLocation(lib, ctx.Arch().ArchType.String()))
+ }
}
}
@@ -419,12 +430,24 @@
continue
}
sharedLibraryInstalled[installDestination] = true
+
// Escape all the variables, as the install destination here will be called
// via. $(eval) in Make.
installDestination = strings.ReplaceAll(
installDestination, "$", "$$")
s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
library.String()+":"+installDestination)
+
+ // Ensure that on device, the library is also reinstalled to the /symbols/
+ // dir. Symbolized DSO's are always installed to the device when fuzzing, but
+ // we want symbolization tools (like `stack`) to be able to find the symbols
+ // in $ANDROID_PRODUCT_OUT/symbols automagically.
+ if !ccModule.Host() {
+ symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
+ symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
+ s.sharedLibInstallStrings = append(s.sharedLibInstallStrings,
+ library.String()+":"+symbolsInstallDestination)
+ }
}
// The executable.
diff --git a/cc/library.go b/cc/library.go
index 5ce854e..140f87a 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -376,7 +376,7 @@
useCoreVariant bool
checkSameCoreVariant bool
- // Decorated interafaces
+ // Decorated interfaces
*baseCompiler
*baseLinker
*baseInstaller
@@ -749,10 +749,12 @@
func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
if library.static() {
+ // Compare with nil because an empty list needs to be propagated.
if library.StaticProperties.Static.System_shared_libs != nil {
library.baseLinker.Properties.System_shared_libs = library.StaticProperties.Static.System_shared_libs
}
} else if library.shared() {
+ // Compare with nil because an empty list needs to be propagated.
if library.SharedProperties.Shared.System_shared_libs != nil {
library.baseLinker.Properties.System_shared_libs = library.SharedProperties.Shared.System_shared_libs
}
@@ -828,10 +830,21 @@
}
specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...)
- specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...)
+
+ // Must distinguish nil and [] in system_shared_libs - ensure that [] in
+ // either input list doesn't come out as nil.
+ if specifiedDeps.systemSharedLibs == nil {
+ specifiedDeps.systemSharedLibs = properties.System_shared_libs
+ } else {
+ specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...)
+ }
specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs)
- specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs)
+ if len(specifiedDeps.systemSharedLibs) > 0 {
+ // Skip this if systemSharedLibs is either nil or [], to ensure they are
+ // retained.
+ specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs)
+ }
return specifiedDeps
}
@@ -1011,8 +1024,9 @@
}
func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
+ // The logic must be consistent with classifySourceAbiDump.
isNdk := ctx.isNdk()
- isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || ctx.isVndk()
+ isLlndkOrVndk := ctx.isLlndkPublic(ctx.Config()) || (ctx.useVndk() && ctx.isVndk())
refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false)
refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true)
@@ -1371,6 +1385,8 @@
len(sharedCompiler.SharedProperties.Shared.Static_libs) == 0 &&
len(staticCompiler.StaticProperties.Static.Shared_libs) == 0 &&
len(sharedCompiler.SharedProperties.Shared.Shared_libs) == 0 &&
+ // Compare System_shared_libs properties with nil because empty lists are
+ // semantically significant for them.
staticCompiler.StaticProperties.Static.System_shared_libs == nil &&
sharedCompiler.SharedProperties.Shared.System_shared_libs == nil {
@@ -1487,6 +1503,19 @@
}
}
+func createVersionVariations(mctx android.BottomUpMutatorContext, versions []string) {
+ // "" is for the non-stubs variant
+ versions = append([]string{""}, versions...)
+
+ modules := mctx.CreateVariations(versions...)
+ for i, m := range modules {
+ if versions[i] != "" {
+ m.(LinkableInterface).SetBuildStubs()
+ m.(LinkableInterface).SetStubsVersions(versions[i])
+ }
+ }
+}
+
// Version mutator splits a module into the mandatory non-stubs variant
// (which is unnamed) and zero or more stubs variants.
func VersionMutator(mctx android.BottomUpMutatorContext) {
@@ -1498,24 +1527,30 @@
return
}
- // save the list of versions for later use
stubsVersionsLock.Lock()
defer stubsVersionsLock.Unlock()
+ // save the list of versions for later use
stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
- // "" is for the non-stubs variant
- versions = append([]string{""}, versions...)
-
- modules := mctx.CreateVariations(versions...)
- for i, m := range modules {
- if versions[i] != "" {
- m.(LinkableInterface).SetBuildStubs()
- m.(LinkableInterface).SetStubsVersions(versions[i])
- }
- }
- } else {
- mctx.CreateVariations("")
+ createVersionVariations(mctx, versions)
+ return
}
+
+ if c, ok := library.(*Module); ok && c.IsStubs() {
+ stubsVersionsLock.Lock()
+ defer stubsVersionsLock.Unlock()
+ // For LLNDK llndk_library, we borrow vstubs.ersions from its implementation library.
+ // Since llndk_library has dependency to its implementation library,
+ // we can safely access stubsVersionsFor() with its baseModuleName.
+ versions := stubsVersionsFor(mctx.Config())[c.BaseModuleName()]
+ // save the list of versions for later use
+ stubsVersionsFor(mctx.Config())[mctx.ModuleName()] = versions
+
+ createVersionVariations(mctx, versions)
+ return
+ }
+
+ mctx.CreateVariations("")
return
}
if genrule, ok := mctx.Module().(*genrule.Module); ok {
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 4967455..754b96a 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -212,7 +212,9 @@
outputProperties.AddPropertyWithTag("shared_libs", libInfo.SharedLibs, builder.SdkMemberReferencePropertyTag(false))
}
- if len(libInfo.SystemSharedLibs) > 0 {
+ // SystemSharedLibs needs to be propagated if it's a list, even if it's empty,
+ // so check for non-nil instead of nonzero length.
+ if libInfo.SystemSharedLibs != nil {
outputProperties.AddPropertyWithTag("system_shared_libs", libInfo.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false))
}
@@ -267,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 (
@@ -327,11 +334,16 @@
// This field is exported as its contents may not be arch specific.
SharedLibs []string
- // The set of system shared libraries
+ // The set of system shared libraries. Note nil and [] are semantically
+ // distinct - see BaseLinkerProperties.System_shared_libs.
//
// 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
}
@@ -367,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/linker.go b/cc/linker.go
index 385e04e..57a0c01 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -502,7 +502,15 @@
func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps {
specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs...)
- specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...)
+
+ // Must distinguish nil and [] in system_shared_libs - ensure that [] in
+ // either input list doesn't come out as nil.
+ if specifiedDeps.systemSharedLibs == nil {
+ specifiedDeps.systemSharedLibs = linker.Properties.System_shared_libs
+ } else {
+ specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...)
+ }
+
return specifiedDeps
}
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 3dee692..09050aa 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -19,8 +19,14 @@
"strings"
"android/soong/android"
+
+ "github.com/google/blueprint"
)
+var llndkImplDep = struct {
+ blueprint.DependencyTag
+}{}
+
var (
llndkLibrarySuffix = ".llndk"
llndkHeadersSuffix = ".llndk"
@@ -81,6 +87,9 @@
// For non-enforcing devices, vndkVer is empty. Use "current" in that case, too.
vndkVer = "current"
}
+ if stub.stubsVersion() != "" {
+ vndkVer = stub.stubsVersion()
+ }
objs, versionScript := compileStubLibrary(ctx, flags, String(stub.Properties.Symbol_file), vndkVer, "--llndk")
stub.versionScriptPath = versionScript
return objs
@@ -154,6 +163,10 @@
stub.libraryDecorator.flagExporter.Properties.Export_include_dirs = []string{}
}
+ if stub.stubsVersion() != "" {
+ stub.reexportFlags("-D" + versioningMacroName(ctx.baseModuleName()) + "=" + stub.stubsVersion())
+ }
+
return stub.libraryDecorator.link(ctx, flags, deps, objs)
}
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index f909add..c4d7708 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -92,6 +92,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
}
@@ -105,6 +110,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/pgo.go b/cc/pgo.go
index d5c4b87..88903bb 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -88,20 +88,21 @@
return []interface{}{&pgo.Properties}
}
-func (props *PgoProperties) addProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
+func (props *PgoProperties) addInstrumentationProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
- if props.isInstrumentation() {
- flags.Local.CFlags = append(flags.Local.CFlags, profileInstrumentFlag)
- // The profile runtime is added below in deps(). Add the below
- // flag, which is the only other link-time action performed by
- // the Clang driver during link.
- flags.Local.LdFlags = append(flags.Local.LdFlags, "-u__llvm_profile_runtime")
- }
- if props.isSampling() {
- flags.Local.CFlags = append(flags.Local.CFlags, profileSamplingFlag)
- flags.Local.LdFlags = append(flags.Local.LdFlags, profileSamplingFlag)
- }
+ flags.Local.CFlags = append(flags.Local.CFlags, profileInstrumentFlag)
+ // The profile runtime is added below in deps(). Add the below
+ // flag, which is the only other link-time action performed by
+ // the Clang driver during link.
+ flags.Local.LdFlags = append(flags.Local.LdFlags, "-u__llvm_profile_runtime")
+ return flags
+}
+func (props *PgoProperties) addSamplingProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
+ flags.Local.CFlags = append(flags.Local.CFlags, props.Pgo.Cflags...)
+
+ flags.Local.CFlags = append(flags.Local.CFlags, profileSamplingFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, profileSamplingFlag)
return flags
}
@@ -286,8 +287,12 @@
props := pgo.Properties
// Add flags to profile this module based on its profile_kind
- if props.ShouldProfileModule {
- return props.addProfileGatherFlags(ctx, flags)
+ if props.ShouldProfileModule && props.isInstrumentation() {
+ return props.addInstrumentationProfileGatherFlags(ctx, flags)
+ } else if props.ShouldProfileModule && props.isSampling() {
+ return props.addSamplingProfileGatherFlags(ctx, flags)
+ } else if ctx.DeviceConfig().SamplingPGO() {
+ return props.addSamplingProfileGatherFlags(ctx, flags)
}
if !ctx.Config().IsEnvTrue("ANDROID_PGO_NO_PROFILE_USE") {
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/cc/testing.go b/cc/testing.go
index 89a9c36..53f0995 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -67,6 +67,20 @@
src: "",
}
+ cc_prebuilt_library_shared {
+ name: "libclang_rt.hwasan-aarch64-android",
+ nocrt: true,
+ vendor_available: true,
+ recovery_available: true,
+ system_shared_libs: [],
+ stl: "none",
+ srcs: [""],
+ check_elf_files: false,
+ sanitize: {
+ never: true,
+ },
+ }
+
toolchain_library {
name: "libclang_rt.builtins-i686-android",
vendor_available: true,
@@ -220,6 +234,10 @@
vendor_available: true,
recovery_available: true,
host_supported: true,
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
}
cc_library {
name: "libc++",
@@ -248,6 +266,10 @@
host_supported: false,
vendor_available: true,
recovery_available: true,
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
}
cc_library {
name: "libunwind_llvm",
@@ -259,8 +281,21 @@
recovery_available: true,
}
+ cc_defaults {
+ name: "crt_defaults",
+ recovery_available: true,
+ vendor_available: true,
+ native_bridge_supported: true,
+ stl: "none",
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ }
+
cc_object {
name: "crtbegin_so",
+ defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
@@ -269,6 +304,7 @@
cc_object {
name: "crtbegin_dynamic",
+ defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
@@ -277,6 +313,7 @@
cc_object {
name: "crtbegin_static",
+ defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
@@ -285,6 +322,7 @@
cc_object {
name: "crtend_so",
+ defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
@@ -293,6 +331,7 @@
cc_object {
name: "crtend_android",
+ defaults: ["crt_defaults"],
recovery_available: true,
vendor_available: true,
native_bridge_supported: true,
diff --git a/cc/vndk.go b/cc/vndk.go
index e02e7b5..4888dcf 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -297,6 +297,9 @@
if !Bool(lib.Properties.Vendor_available) {
vndkPrivateLibraries(mctx.Config())[name] = filename
}
+ if mctx.OtherModuleExists(name) {
+ mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name)
+ }
}
func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
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/cuj/cuj.go b/cuj/cuj.go
index c7ff8ff..3333012 100644
--- a/cuj/cuj.go
+++ b/cuj/cuj.go
@@ -33,8 +33,9 @@
)
type Test struct {
- name string
- args []string
+ name string
+ args []string
+ before func() error
results TestResults
}
@@ -119,6 +120,15 @@
t.results.metrics = met
}
+// Touch the Intent.java file to cause a rebuild of the frameworks to monitor the
+// incremental build speed as mentioned b/152046247. Intent.java file was chosen
+// as it is a key component of the framework and is often modified.
+func touchIntentFile() error {
+ const intentFileName = "frameworks/base/core/java/android/content/Intent.java"
+ currentTime := time.Now().Local()
+ return os.Chtimes(intentFileName, currentTime, currentTime)
+}
+
func main() {
outDir := os.Getenv("OUT_DIR")
if outDir == "" {
@@ -170,6 +180,36 @@
name: "framework_rebuild_twice",
args: []string{"framework"},
},
+ {
+ // Scenario major_inc_build (b/152046247): tracking build speed of major incremental build.
+ name: "major_inc_build_droid",
+ args: []string{"droid"},
+ },
+ {
+ name: "major_inc_build_framework_minus_apex_after_droid_build",
+ args: []string{"framework-minus-apex"},
+ before: touchIntentFile,
+ },
+ {
+ name: "major_inc_build_framework_after_droid_build",
+ args: []string{"framework"},
+ before: touchIntentFile,
+ },
+ {
+ name: "major_inc_build_sync_after_droid_build",
+ args: []string{"sync"},
+ before: touchIntentFile,
+ },
+ {
+ name: "major_inc_build_droid_rebuild",
+ args: []string{"droid"},
+ before: touchIntentFile,
+ },
+ {
+ name: "major_inc_build_update_api_after_droid_rebuild",
+ args: []string{"update-api"},
+ before: touchIntentFile,
+ },
}
cujMetrics := metrics.NewCriticalUserJourneysMetrics()
@@ -178,6 +218,12 @@
for i, t := range tests {
logsSubDir := fmt.Sprintf("%02d_%s", i, t.name)
logsDir := filepath.Join(cujDir, "logs", logsSubDir)
+ if t.before != nil {
+ if err := t.before(); err != nil {
+ fmt.Printf("error running before function on test %q: %v\n", t.name, err)
+ break
+ }
+ }
t.Run(logsDir)
if t.results.err != nil {
fmt.Printf("error running test %q: %s\n", t.name, t.results.err)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 02e54b3..0e1bfc6 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -589,7 +589,7 @@
// at that time (Soong processes the jars in dependency order, which may be different from the
// the system server classpath order).
func SystemServerDexJarHostPath(ctx android.PathContext, jar string) android.OutputPath {
- return android.PathForOutput(ctx, ctx.Config().BuildDir(), "system_server_dexjars", jar+".jar")
+ return android.PathForOutput(ctx, "system_server_dexjars", jar+".jar")
}
func contains(l []string, s string) bool {
diff --git a/java/androidmk.go b/java/androidmk.go
index d76e29b..136bb36 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -72,6 +72,7 @@
if !hideFromMake {
mainEntries = android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
+ DistFile: android.OptionalPathForPath(library.distFile),
OutputFile: android.OptionalPathForPath(library.outputFile),
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
@@ -275,7 +276,7 @@
}
func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries {
- if !app.IsForPlatform() {
+ if !app.IsForPlatform() || app.appProperties.HideFromMake {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Disabled: true,
}}
@@ -288,6 +289,7 @@
func(entries *android.AndroidMkEntries) {
// App module names can be overridden.
entries.SetString("LOCAL_MODULE", app.installApkName)
+ entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", app.appProperties.PreventInstall)
entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", app.exportPackage)
if app.dexJarFile != nil {
entries.SetPath("LOCAL_SOONG_DEX_JAR", app.dexJarFile)
@@ -347,6 +349,9 @@
for _, jniLib := range app.installJniLibs {
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
}
+ if len(app.jniCoverageOutputs) > 0 {
+ entries.AddStrings("LOCAL_PREBUILT_COVERAGE_ARCHIVE", app.jniCoverageOutputs.Strings()...)
+ }
if len(app.dexpreopter.builtInstalled) > 0 {
entries.SetString("LOCAL_SOONG_BUILT_INSTALLED", app.dexpreopter.builtInstalled)
}
@@ -542,6 +547,7 @@
func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "JAVA_LIBRARIES",
+ DistFile: android.OptionalPathForPath(dstubs.apiFile),
OutputFile: android.OptionalPathForPath(dstubs.stubsSrcJar),
Include: "$(BUILD_SYSTEM)/soong_droiddoc_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index acc6bf0..7daa624 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -16,6 +16,7 @@
import (
"reflect"
+ "strings"
"testing"
"android/soong/android"
@@ -133,3 +134,38 @@
t.Errorf("Unexpected required modules - expected: %q, actual: %q", expected, actual)
}
}
+
+func TestDistWithTag(t *testing.T) {
+ ctx, config := testJava(t, `
+ java_library {
+ name: "foo_without_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["hi"],
+ },
+ }
+ java_library {
+ name: "foo_with_tag",
+ srcs: ["a.java"],
+ compile_dex: true,
+ dist: {
+ targets: ["hi"],
+ tag: ".jar",
+ },
+ }
+ `)
+
+ without_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_without_tag", "android_common").Module())
+ with_tag_entries := android.AndroidMkEntriesForTest(t, config, "", ctx.ModuleForTests("foo_with_tag", "android_common").Module())
+
+ if len(without_tag_entries) != 2 || len(with_tag_entries) != 2 {
+ t.Errorf("two mk entries per module expected, got %d and %d", len(without_tag_entries), len(with_tag_entries))
+ }
+ if !with_tag_entries[0].DistFile.Valid() || !strings.Contains(with_tag_entries[0].DistFile.String(), "/javac/foo_with_tag.jar") {
+ t.Errorf("expected classes.jar DistFile, got %v", with_tag_entries[0].DistFile)
+ }
+ if without_tag_entries[0].DistFile.Valid() {
+ t.Errorf("did not expect explicit DistFile, got %v", without_tag_entries[0].DistFile)
+ }
+}
diff --git a/java/app.go b/java/app.go
index 346f155..6a0aa8f 100755
--- a/java/app.go
+++ b/java/app.go
@@ -105,6 +105,11 @@
// If set, find and merge all NOTICE files that this module and its dependencies have and store
// it in the APK as an asset.
Embed_notices *bool
+
+ // cc.Coverage related properties
+ PreventInstall bool `blueprint:"mutated"`
+ HideFromMake bool `blueprint:"mutated"`
+ IsCoverageVariant bool `blueprint:"mutated"`
}
// android_app properties that can be overridden by override_android_app
@@ -133,7 +138,8 @@
overridableAppProperties overridableAppProperties
- installJniLibs []jniLib
+ installJniLibs []jniLib
+ jniCoverageOutputs android.Paths
bundleFile android.Path
@@ -171,6 +177,10 @@
return a.certificate
}
+func (a *AndroidApp) JniCoverageOutputs() android.Paths {
+ return a.jniCoverageOutputs
+}
+
var _ AndroidLibraryDependency = (*AndroidApp)(nil)
type Certificate struct {
@@ -380,6 +390,11 @@
if a.shouldEmbedJnis(ctx) {
jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx))
+ for _, jni := range jniLibs {
+ if jni.coverageFile.Valid() {
+ a.jniCoverageOutputs = append(a.jniCoverageOutputs, jni.coverageFile.Path())
+ }
+ }
} else {
a.installJniLibs = jniLibs
}
@@ -521,14 +536,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.
@@ -582,9 +611,10 @@
if lib.Valid() {
jniLibs = append(jniLibs, jniLib{
- name: ctx.OtherModuleName(module),
- path: path,
- target: module.Target(),
+ name: ctx.OtherModuleName(module),
+ path: path,
+ target: module.Target(),
+ coverageFile: dep.CoverageOutputFile(),
})
} else {
ctx.ModuleErrorf("dependency %q missing output file", otherName)
@@ -638,6 +668,24 @@
return Bool(a.appProperties.Privileged)
}
+func (a *AndroidApp) IsNativeCoverageNeeded(ctx android.BaseModuleContext) bool {
+ return ctx.Device() && (ctx.DeviceConfig().NativeCoverageEnabled() || ctx.DeviceConfig().ClangCoverageEnabled())
+}
+
+func (a *AndroidApp) PreventInstall() {
+ a.appProperties.PreventInstall = true
+}
+
+func (a *AndroidApp) HideFromMake() {
+ a.appProperties.HideFromMake = true
+}
+
+func (a *AndroidApp) MarkAsCoverageVariant(coverage bool) {
+ a.appProperties.IsCoverageVariant = coverage
+}
+
+var _ cc.Coverage = (*AndroidApp)(nil)
+
// android_app compiles sources and Android resources into an Android application package `.apk` file.
func AndroidAppFactory() android.Module {
module := &AndroidApp{}
@@ -1129,7 +1177,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")
@@ -1334,7 +1382,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 fa18e9d..f2ec483 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -1079,6 +1079,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.go b/java/dexpreopt.go
index 40cfe4f..fba0b97 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -127,7 +127,8 @@
global := dexpreopt.GetGlobalConfig(ctx)
bootImage := defaultBootImageConfig(ctx)
dexFiles := bootImage.dexPathsDeps.Paths()
- dexLocations := bootImage.dexLocationsDeps
+ // The dex locations for all Android variants are identical.
+ dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps
if global.UseArtImage {
bootImage = artBootImageConfig(ctx)
}
@@ -155,6 +156,8 @@
images = append(images, variant.images)
imagesDeps = append(imagesDeps, variant.imagesDeps)
}
+ // The image locations for all Android variants are identical.
+ imageLocations := bootImage.getAnyAndroidVariant().imageLocations()
dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath)
@@ -198,7 +201,7 @@
Archs: archs,
DexPreoptImages: images,
DexPreoptImagesDeps: imagesDeps,
- DexPreoptImageLocations: bootImage.imageLocations,
+ DexPreoptImageLocations: imageLocations,
PreoptBootClassPathDexFiles: dexFiles,
PreoptBootClassPathDexLocations: dexLocations,
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index a3b264e..543b233 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -16,6 +16,7 @@
import (
"path/filepath"
+ "sort"
"strings"
"android/soong/android"
@@ -25,31 +26,13 @@
)
func init() {
- android.RegisterSingletonType("dex_bootjars", dexpreoptBootJarsFactory)
+ RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext)
}
-// The image "location" is a symbolic path that with multiarchitecture
-// support doesn't really exist on the device. Typically it is
-// /system/framework/boot.art and should be the same for all supported
-// architectures on the device. The concrete architecture specific
-// content actually ends up in a "filename" that contains an
-// architecture specific directory name such as arm, arm64, x86, x86_64.
-//
-// Here are some example values for an x86_64 / x86 configuration:
-//
-// bootImages["x86_64"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art"
-// dexpreopt.PathToLocation(bootImages["x86_64"], "x86_64") = "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
-//
-// bootImages["x86"] = "out/soong/generic_x86_64/dex_bootjars/system/framework/x86/boot.art"
-// dexpreopt.PathToLocation(bootImages["x86"])= "out/soong/generic_x86_64/dex_bootjars/system/framework/boot.art"
-//
-// The location is passed as an argument to the ART tools like dex2oat instead of the real path. The ART tools
-// will then reconstruct the real path, so the rules must have a dependency on the real path.
-
// Target-independent description of pre-compiled boot image.
type bootImageConfig struct {
- // Whether this image is an extension.
- extension bool
+ // If this image is an extension, the image that it extends.
+ extends *bootImageConfig
// Image name (used in directory names and ninja rule names).
name string
@@ -69,17 +52,10 @@
// The names of jars that constitute this image.
modules []string
- // The "locations" of jars.
- dexLocations []string // for this image
- dexLocationsDeps []string // for the dependency images and in this image
-
// File paths to jars.
dexPaths android.WritablePaths // for this image
dexPathsDeps android.WritablePaths // for the dependency images and in this image
- // The "locations" of the dependency images and in this image.
- imageLocations []string
-
// File path to a zip archive with all image files (or nil, if not needed).
zip android.WritablePath
@@ -97,6 +73,10 @@
// Target for which the image is generated.
target android.Target
+ // The "locations" of jars.
+ dexLocations []string // for this image
+ dexLocationsDeps []string // for the dependency images and in this image
+
// Paths to image files.
images android.OutputPath // first image file
imagesDeps android.OutputPaths // all files
@@ -119,13 +99,23 @@
return nil
}
+// Return any (the first) variant which is for the device (as opposed to for the host)
+func (image bootImageConfig) getAnyAndroidVariant() *bootImageVariant {
+ for _, variant := range image.variants {
+ if variant.target.Os == android.Android {
+ return variant
+ }
+ }
+ return nil
+}
+
func (image bootImageConfig) moduleName(idx int) string {
// Dexpreopt on the boot class path produces multiple files. The first dex file
// is converted into 'name'.art (to match the legacy assumption that 'name'.art
// exists), and the rest are converted to 'name'-<jar>.art.
m := image.modules[idx]
name := image.stem
- if idx != 0 || image.extension {
+ if idx != 0 || image.extends != nil {
name += "-" + stemOf(m)
}
return name
@@ -150,6 +140,24 @@
return ret
}
+// The image "location" is a symbolic path that, with multiarchitecture support, doesn't really
+// exist on the device. Typically it is /apex/com.android.art/javalib/boot.art and should be the
+// same for all supported architectures on the device. The concrete architecture specific files
+// actually end up in architecture-specific sub-directory such as arm, arm64, x86, or x86_64.
+//
+// For example a physical file
+// "/apex/com.android.art/javalib/x86/boot.art" has "image location"
+// "/apex/com.android.art/javalib/boot.art" (which is not an actual file).
+//
+// The location is passed as an argument to the ART tools like dex2oat instead of the real path.
+// ART tools will then reconstruct the architecture-specific real path.
+func (image *bootImageVariant) imageLocations() (imageLocations []string) {
+ if image.extends != nil {
+ imageLocations = image.extends.getVariant(image.target).imageLocations()
+ }
+ return append(imageLocations, dexpreopt.PathToLocation(image.images, image.target.Arch.ArchType))
+}
+
func concat(lists ...[]string) []string {
var size int
for _, l := range lists {
@@ -166,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
@@ -234,16 +246,66 @@
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 if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ // this is Jacoco platform variant for a coverage build, 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
}
})
@@ -255,7 +317,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])
}
}
@@ -274,6 +337,7 @@
profile := bootImageProfileRule(ctx, image, missingDeps)
bootFrameworkProfileRule(ctx, image, missingDeps)
+ updatableBcpPackagesRule(ctx, image, missingDeps)
var allFiles android.Paths
for _, variant := range image.variants {
@@ -351,7 +415,7 @@
cmd.FlagWithInput("--dirty-image-objects=", global.DirtyImageObjects.Path())
}
- if image.extension {
+ if image.extends != nil {
artImage := image.primaryImages
cmd.
Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
@@ -478,7 +542,7 @@
Tool(globalSoong.Profman).
FlagWithInput("--create-profile-from=", bootImageProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocationsDeps).
+ FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.prof")
@@ -529,7 +593,7 @@
Flag("--generate-boot-profile").
FlagWithInput("--create-profile-from=", bootFrameworkProfile).
FlagForEachInput("--apk=", image.dexPathsDeps.Paths()).
- FlagForEachArg("--dex-location=", image.dexLocationsDeps).
+ FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps).
FlagWithOutput("--reference-profile-file=", profile)
rule.Install(profile, "/system/etc/boot-image.bprof")
@@ -542,6 +606,61 @@
var bootFrameworkProfileRuleKey = android.NewOnceKey("bootFrameworkProfileRule")
+func updatableBcpPackagesRule(ctx android.SingletonContext, image *bootImageConfig, missingDeps []string) android.WritablePath {
+ if ctx.Config().IsPdkBuild() || ctx.Config().UnbundledBuild() {
+ return nil
+ }
+
+ return ctx.Config().Once(updatableBcpPackagesRuleKey, func() interface{} {
+ global := dexpreopt.GetGlobalConfig(ctx)
+ updatableModules := dexpreopt.GetJarsFromApexJarPairs(global.UpdatableBootJars)
+
+ // Collect `permitted_packages` for updatable boot jars.
+ var updatablePackages []string
+ ctx.VisitAllModules(func(module android.Module) {
+ if j, ok := module.(*Library); ok {
+ name := ctx.ModuleName(module)
+ if i := android.IndexList(name, updatableModules); i != -1 {
+ pp := j.properties.Permitted_packages
+ if len(pp) > 0 {
+ updatablePackages = append(updatablePackages, pp...)
+ } else {
+ ctx.Errorf("Missing permitted_packages for %s", name)
+ }
+ // Do not match the same library repeatedly.
+ updatableModules = append(updatableModules[:i], updatableModules[i+1:]...)
+ }
+ }
+ })
+
+ // Sort updatable packages to ensure deterministic ordering.
+ sort.Strings(updatablePackages)
+
+ updatableBcpPackagesName := "updatable-bcp-packages.txt"
+ updatableBcpPackages := image.dir.Join(ctx, updatableBcpPackagesName)
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.WriteFile,
+ Output: updatableBcpPackages,
+ Args: map[string]string{
+ // WriteFile automatically adds the last end-of-line.
+ "content": strings.Join(updatablePackages, "\\n"),
+ },
+ })
+
+ rule := android.NewRuleBuilder()
+ rule.MissingDeps(missingDeps)
+ rule.Install(updatableBcpPackages, "/system/etc/"+updatableBcpPackagesName)
+ // TODO: Rename `profileInstalls` to `extraInstalls`?
+ // Maybe even move the field out of the bootImageConfig into some higher level type?
+ image.profileInstalls = append(image.profileInstalls, rule.Installs()...)
+
+ return updatableBcpPackages
+ }).(android.WritablePath)
+}
+
+var updatableBcpPackagesRuleKey = android.NewOnceKey("updatableBcpPackagesRule")
+
func dumpOatRules(ctx android.SingletonContext, image *bootImageConfig) {
var allPhonies android.Paths
for _, image := range image.variants {
@@ -559,7 +678,7 @@
BuiltTool(ctx, "oatdumpd").
FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
- FlagWithArg("--image=", strings.Join(image.imageLocations, ":")).Implicits(image.imagesDeps.Paths()).
+ FlagWithArg("--image=", strings.Join(image.imageLocations(), ":")).Implicits(image.imagesDeps.Paths()).
FlagWithOutput("--output=", output).
FlagWithArg("--instruction-set=", arch.String())
rule.Build(pctx, ctx, "dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
@@ -573,10 +692,7 @@
Text("echo").FlagWithArg("Output in ", output.String())
rule.Build(pctx, ctx, "phony-dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
- // TODO: We need to make imageLocations per-variant to make oatdump work on host.
- if image.target.Os == android.Android {
- allPhonies = append(allPhonies, phony)
- }
+ allPhonies = append(allPhonies, phony)
}
phony := android.PathForPhony(ctx, "dump-oat-boot")
@@ -612,25 +728,25 @@
if image != nil {
ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String())
ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(image.dexPathsDeps.Strings(), " "))
- ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.dexLocationsDeps, " "))
+ ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(image.getAnyAndroidVariant().dexLocationsDeps, " "))
var imageNames []string
for _, current := range append(d.otherImages, image) {
imageNames = append(imageNames, current.name)
- for _, current := range current.variants {
+ for _, variant := range current.variants {
suffix := ""
- if current.target.Os.Class == android.Host {
+ if variant.target.Os.Class == android.Host {
suffix = "_host"
}
- sfx := current.name + suffix + "_" + current.target.Arch.ArchType.String()
- ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, current.vdexInstalls.String())
- ctx.Strict("DEXPREOPT_IMAGE_"+sfx, current.images.String())
- ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(current.imagesDeps.Strings(), " "))
- ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, current.installs.String())
- ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, current.unstrippedInstalls.String())
+ sfx := variant.name + suffix + "_" + variant.target.Arch.ArchType.String()
+ ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, variant.vdexInstalls.String())
+ ctx.Strict("DEXPREOPT_IMAGE_"+sfx, variant.images.String())
+ ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(variant.imagesDeps.Strings(), " "))
+ ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, variant.installs.String())
+ ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, variant.unstrippedInstalls.String())
}
-
- ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(current.imageLocations, ":"))
+ imageLocations := current.getAnyAndroidVariant().imageLocations()
+ ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(imageLocations, ":"))
ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
}
ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
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 ffce2a9..066694c 100644
--- a/java/dexpreopt_config.go
+++ b/java/dexpreopt_config.go
@@ -79,6 +79,14 @@
return moduleName
}
+func getDexLocation(ctx android.PathContext, target android.Target, subdir string, name string) string {
+ if target.Os.Class == android.Host {
+ return filepath.Join(ctx.Config().Getenv("OUT_DIR"), "host", ctx.Config().PrebuiltOS(), subdir, name)
+ } else {
+ return filepath.Join("/", subdir, name)
+ }
+}
+
var (
bootImageConfigKey = android.NewOnceKey("bootImageConfig")
artBootImageName = "art"
@@ -104,36 +112,23 @@
artSubdir := "apex/com.android.art/javalib"
frameworkSubdir := "system/framework"
- var artLocations, frameworkLocations []string
- for _, m := range artModules {
- artLocations = append(artLocations, filepath.Join("/"+artSubdir, stemOf(m)+".jar"))
- }
- for _, m := range frameworkModules {
- frameworkLocations = append(frameworkLocations, filepath.Join("/"+frameworkSubdir, stemOf(m)+".jar"))
- }
-
// ART config for the primary boot image in the ART apex.
// It includes the Core Libraries.
artCfg := bootImageConfig{
- extension: false,
- name: artBootImageName,
- stem: "boot",
- installSubdir: artSubdir,
- modules: artModules,
- dexLocations: artLocations,
- dexLocationsDeps: artLocations,
+ name: artBootImageName,
+ stem: "boot",
+ installSubdir: artSubdir,
+ modules: artModules,
}
// Framework config for the boot image extension.
// It includes framework libraries and depends on the ART config.
frameworkCfg := bootImageConfig{
- extension: true,
- name: frameworkBootImageName,
- stem: "boot",
- installSubdir: frameworkSubdir,
- modules: frameworkModules,
- dexLocations: frameworkLocations,
- dexLocationsDeps: append(artLocations, frameworkLocations...),
+ extends: &artCfg,
+ name: frameworkBootImageName,
+ stem: "boot",
+ installSubdir: frameworkSubdir,
+ modules: frameworkModules,
}
configs := map[string]*bootImageConfig{
@@ -149,8 +144,6 @@
// expands to <stem>.art for primary image and <stem>-<1st module>.art for extension
imageName := c.firstModuleNameOrStem() + ".art"
- c.imageLocations = []string{c.dir.Join(ctx, "android", c.installSubdir, imageName).String()}
-
// The path to bootclasspath dex files needs to be known at module
// GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled.
// Set up known paths for them, the singleton rules will copy them there.
@@ -171,6 +164,10 @@
images: imageDir.Join(ctx, imageName),
imagesDeps: c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex"),
}
+ for _, m := range c.modules {
+ variant.dexLocations = append(variant.dexLocations, getDexLocation(ctx, target, c.installSubdir, stemOf(m)+".jar"))
+ }
+ variant.dexLocationsDeps = variant.dexLocations
c.variants = append(c.variants, variant)
}
@@ -181,8 +178,8 @@
frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...)
for i := range targets {
frameworkCfg.variants[i].primaryImages = artCfg.variants[i].images
+ frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...)
}
- frameworkCfg.imageLocations = append(artCfg.imageLocations, frameworkCfg.imageLocations...)
return configs
}).(map[string]*bootImageConfig)
@@ -206,7 +203,7 @@
updatableBootclasspath[i] = dexpreopt.GetJarLocationFromApexJarPair(p)
}
- bootclasspath := append(copyOf(image.dexLocationsDeps), updatableBootclasspath...)
+ bootclasspath := append(copyOf(image.getAnyAndroidVariant().dexLocationsDeps), updatableBootclasspath...)
return bootclasspath
})
}
@@ -221,7 +218,7 @@
func dexpreoptConfigMakevars(ctx android.MakeVarsContext) {
ctx.Strict("PRODUCT_BOOTCLASSPATH", strings.Join(defaultBootclasspath(ctx), ":"))
- ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).dexLocationsDeps, ":"))
+ ctx.Strict("PRODUCT_DEX2OAT_BOOTCLASSPATH", strings.Join(defaultBootImageConfig(ctx).getAnyAndroidVariant().dexLocationsDeps, ":"))
ctx.Strict("PRODUCT_SYSTEM_SERVER_CLASSPATH", strings.Join(systemServerClasspath(ctx), ":"))
ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules, ":"))
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index 7e7e955..c7f7cbd 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -211,23 +211,30 @@
// the greylists.
func flagsRule(ctx android.SingletonContext) android.Path {
var flagsCSV android.Paths
-
- var greylistIgnoreConflicts android.Path
+ var greylistRemovedApis android.Paths
ctx.VisitAllModules(func(module android.Module) {
if h, ok := module.(hiddenAPIIntf); ok {
if csv := h.flagsCSV(); csv != nil {
flagsCSV = append(flagsCSV, csv)
}
- } else if ds, ok := module.(*Droidstubs); ok && ctx.ModuleName(module) == "hiddenapi-lists-docs" {
- greylistIgnoreConflicts = ds.removedDexApiFile
+ } else if ds, ok := module.(*Droidstubs); ok {
+ // Track @removed public and system APIs via corresponding droidstubs targets.
+ // These APIs are not present in the stubs, however, we have to keep allowing access
+ // to them at runtime.
+ if m := ctx.ModuleName(module); m == "api-stubs-docs" || m == "system-api-stubs-docs" {
+ greylistRemovedApis = append(greylistRemovedApis, ds.removedDexApiFile)
+ }
}
})
- if greylistIgnoreConflicts == nil {
- ctx.Errorf("failed to find removed_dex_api_filename from hiddenapi-lists-docs module")
- return nil
- }
+ combinedRemovedApis := android.PathForOutput(ctx, "hiddenapi", "combined-removed-dex.txt")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cat,
+ Inputs: greylistRemovedApis,
+ Output: combinedRemovedApis,
+ Description: "Combine removed apis for " + combinedRemovedApis.String(),
+ })
rule := android.NewRuleBuilder()
@@ -242,8 +249,7 @@
Inputs(flagsCSV).
FlagWithInput("--greylist ",
android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist.txt")).
- FlagWithInput("--greylist-ignore-conflicts ",
- greylistIgnoreConflicts).
+ FlagWithInput("--greylist-ignore-conflicts ", combinedRemovedApis).
FlagWithInput("--greylist-max-q ",
android.PathForSource(ctx, "frameworks/base/config/hiddenapi-greylist-max-q.txt")).
FlagWithInput("--greylist-max-p ",
diff --git a/java/java.go b/java/java.go
index 22d14ec..a8ca3ff 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 {
@@ -421,6 +425,8 @@
// list of the xref extraction files
kytheFiles android.Paths
+
+ distFile android.Path
}
func (j *Module) OutputFiles(tag string) (android.Paths, error) {
@@ -540,9 +546,10 @@
}
type jniLib struct {
- name string
- path android.Path
- target android.Target
+ name string
+ path android.Path
+ target android.Target
+ coverageFile android.OptionalPath
}
func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool {
@@ -800,7 +807,7 @@
return javaModule, true
case ver.kind == sdkModule:
return javaModule, false
- case name == "services-stubs":
+ case name == "android_system_server_stubs_current":
return javaSystemServer, true
case ver.kind == sdkSystemServer:
return javaSystemServer, false
@@ -1753,11 +1760,6 @@
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
return true
}
- // Also, a dependency to an sdk member is also considered as such. This is required because
- // sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
- if sa, ok := dep.(android.SdkAware); ok && sa.IsInAnySdk() {
- return true
- }
return false
}
@@ -1777,9 +1779,18 @@
// Java libraries (.jar file)
//
+type LibraryProperties struct {
+ Dist struct {
+ // The tag of the output of this module that should be output.
+ Tag *string `android:"arch_variant"`
+ } `android:"arch_variant"`
+}
+
type Library struct {
Module
+ libraryProperties LibraryProperties
+
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
}
@@ -1823,6 +1834,15 @@
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
ctx.ModuleName()+".jar", j.outputFile, extraInstallDeps...)
}
+
+ // Verify Dist.Tag is set to a supported output
+ if j.libraryProperties.Dist.Tag != nil {
+ distFiles, err := j.OutputFiles(*j.libraryProperties.Dist.Tag)
+ if err != nil {
+ ctx.PropertyErrorf("dist.tag", "%s", err.Error())
+ }
+ j.distFile = distFiles[0]
+ }
}
func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -1943,7 +1963,8 @@
&module.Module.properties,
&module.Module.deviceProperties,
&module.Module.dexpreoptProperties,
- &module.Module.protoProperties)
+ &module.Module.protoProperties,
+ &module.libraryProperties)
android.InitApexModule(module)
android.InitSdkAwareModule(module)
@@ -2338,6 +2359,12 @@
// set the name of the output
Stem *string
+
+ Aidl struct {
+ // directories that should be added as include directories for any aidl sources of modules
+ // that depend on this module, as well as to aidl for this module.
+ Export_include_dirs []string
+ }
}
type Import struct {
@@ -2351,6 +2378,7 @@
combinedClasspathFile android.Path
exportedSdkLibs []string
+ exportAidlIncludeDirs android.Paths
}
func (j *Import) sdkVersion() sdkSpec {
@@ -2424,6 +2452,8 @@
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
jarName, outputFile)
}
+
+ j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
}
var _ Dependency = (*Import)(nil)
@@ -2458,7 +2488,7 @@
}
func (j *Import) AidlIncludeDirs() android.Paths {
- return nil
+ return j.exportAidlIncludeDirs
}
func (j *Import) ExportedSdkLibs() []string {
@@ -2478,11 +2508,6 @@
if staticLibTag == ctx.OtherModuleDependencyTag(dep) {
return true
}
- // Also, a dependency to an sdk member is also considered as such. This is required because
- // sdk members should be mutated into APEXes. Refer to sdk.sdkDepsReplaceMutator.
- if sa, ok := dep.(android.SdkAware); ok && sa.IsInAnySdk() {
- return true
- }
return false
}
diff --git a/java/java_test.go b/java/java_test.go
index 6d972be..e8a1a7c 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1491,3 +1491,27 @@
t.Errorf("bootclasspath of %q must start with --system and end with %q, but was %#v.", moduleName, expectedSuffix, bootClasspath)
}
}
+
+func TestAidlExportIncludeDirsFromImports(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "foo",
+ srcs: ["aidl/foo/IFoo.aidl"],
+ libs: ["bar"],
+ }
+
+ java_import {
+ name: "bar",
+ jars: ["a.jar"],
+ aidl: {
+ export_include_dirs: ["aidl/bar"],
+ },
+ }
+ `)
+
+ aidlCommand := ctx.ModuleForTests("foo", "android_common").Rule("aidl").RuleParams.Command
+ expectedAidlFlag := "-Iaidl/bar"
+ if !strings.Contains(aidlCommand, expectedAidlFlag) {
+ t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
+ }
+}
diff --git a/java/sdk.go b/java/sdk.go
index ded2a06..0e132d3 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -406,7 +406,7 @@
return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
case sdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return toModule([]string{"android_module_lib_stubs_current", "services-stubs"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule([]string{"android_system_server_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
default:
panic(fmt.Errorf("invalid sdk %q", sdkVersion.raw))
}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 6921114..efee7da 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -18,7 +18,6 @@
"android/soong/android"
"fmt"
- "io"
"path"
"path/filepath"
"sort"
@@ -87,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
@@ -132,6 +134,7 @@
moduleSuffix: sdkSystemApiSuffix,
apiFileMakeVariableSuffix: "_SYSTEM",
sdkVersion: "system_current",
+ droidstubsArgs: []string{"-showAnnotation android.annotation.SystemApi"},
})
apiScopeTest = initApiScope(&apiScope{
name: "test",
@@ -139,6 +142,7 @@
moduleSuffix: sdkTestApiSuffix,
apiFileMakeVariableSuffix: "_TEST",
sdkVersion: "test_current",
+ droidstubsArgs: []string{"-showAnnotation android.annotation.TestApi"},
})
allApiScopes = apiScopes{
apiScopePublic,
@@ -328,41 +332,6 @@
entriesList := module.Library.AndroidMkEntries()
entries := &entriesList[0]
entries.Required = append(entries.Required, module.xmlFileName())
-
- entries.ExtraFooters = []android.AndroidMkExtraFootersFunc{
- func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
- if !Bool(module.sdkLibraryProperties.No_dist) {
- // Create a phony module that installs the impl library, for the case when this lib is
- // in PRODUCT_PACKAGES.
- owner := module.ModuleBase.Owner()
- if owner == "" {
- if Bool(module.sdkLibraryProperties.Core_lib) {
- owner = "core"
- } else {
- owner = "android"
- }
- }
-
- // Create dist rules to install the stubs libs and api files to the dist dir
- for _, apiScope := range module.getActiveApiScopes() {
- if scopePaths, ok := module.scopePaths[apiScope]; ok {
- if len(scopePaths.stubsHeaderPath) == 1 {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- scopePaths.stubsImplPath.Strings()[0]+
- ":"+path.Join("apistubs", owner, apiScope.name,
- module.BaseModuleName()+".jar")+")")
- }
- if scopePaths.apiFilePath != nil {
- fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
- scopePaths.apiFilePath.String()+
- ":"+path.Join("apistubs", owner, apiScope.name, "api",
- module.BaseModuleName()+".txt")+")")
- }
- }
- }
- }
- },
- }
return entriesList
}
@@ -386,6 +355,17 @@
return module.BaseModuleName() + sdkXmlFileSuffix
}
+// The dist path of the stub artifacts
+func (module *SdkLibrary) apiDistPath(apiScope *apiScope) string {
+ if module.ModuleBase.Owner() != "" {
+ return path.Join("apistubs", module.ModuleBase.Owner(), apiScope.name)
+ } else if Bool(module.sdkLibraryProperties.Core_lib) {
+ return path.Join("apistubs", "core", apiScope.name)
+ } else {
+ return path.Join("apistubs", "android", apiScope.name)
+ }
+}
+
// Get the sdk version for use when compiling the stubs library.
func (module *SdkLibrary) sdkVersionForStubsLibrary(mctx android.LoadHookContext, apiScope *apiScope) string {
sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
@@ -438,6 +418,12 @@
Srcs []string
Javacflags []string
}
+ Dist struct {
+ Targets []string
+ Dest *string
+ Dir *string
+ Tag *string
+ }
}{}
props.Name = proptools.StringPtr(module.stubsName(apiScope))
@@ -466,11 +452,18 @@
} else if module.SystemExtSpecific() {
props.System_ext_specific = proptools.BoolPtr(true)
}
+ // Dist the class jar artifact for sdk builds.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.BaseModuleName()))
+ props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
+ props.Dist.Tag = proptools.StringPtr(".jar")
+ }
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 {
@@ -497,6 +490,11 @@
Include_dirs []string
Local_include_dirs []string
}
+ Dist struct {
+ Targets []string
+ Dest *string
+ Dir *string
+ }
}{}
sdkDep := decodeSdkDep(mctx, sdkContext(&module.Library))
@@ -523,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",
@@ -543,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
@@ -578,6 +572,13 @@
module.latestRemovedApiFilegroupName(apiScope))
props.Check_api.Ignore_missing_latest_api = proptools.BoolPtr(true)
+ // Dist the api txt artifact for sdk builds.
+ if !Bool(module.sdkLibraryProperties.No_dist) {
+ props.Dist.Targets = []string{"sdk", "win_sdk"}
+ props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.txt", module.BaseModuleName()))
+ props.Dist.Dir = proptools.StringPtr(path.Join(module.apiDistPath(apiScope), "api"))
+ }
+
mctx.CreateModule(DroidstubsFactory, &props)
}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index ea6733d..088db9e 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -222,9 +222,9 @@
{
name: "system_server_current",
properties: `sdk_version: "system_server_current",`,
- bootclasspath: []string{"android_module_lib_stubs_current", "services-stubs", "core-lambda-stubs"},
+ bootclasspath: []string{"android_system_server_stubs_current", "core-lambda-stubs"},
system: "core-current-stubs-system-modules",
- java9classpath: []string{"android_module_lib_stubs_current", "services-stubs"},
+ java9classpath: []string{"android_system_server_stubs_current"},
aidl: "-p" + buildDir + "/framework.aidl",
},
}
diff --git a/java/testing.go b/java/testing.go
index 5b6a39b..6929bb7 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -50,6 +50,8 @@
"api/test-current.txt": nil,
"api/test-removed.txt": nil,
"framework/aidl/a.aidl": nil,
+ "aidl/foo/IFoo.aidl": nil,
+ "aidl/bar/IBar.aidl": nil,
"assets_a/a": nil,
"assets_b/b": nil,
@@ -148,7 +150,7 @@
"android_system_stubs_current",
"android_test_stubs_current",
"android_module_lib_stubs_current",
- "services-stubs",
+ "android_system_server_stubs_current",
"core.current.stubs",
"core.platform.api.stubs",
"kotlin-stdlib",
diff --git a/rust/compiler.go b/rust/compiler.go
index 4593165..81b258c 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -222,7 +222,10 @@
if ctx.toolchain().Is64Bit() && compiler.dir64 != "" {
dir = compiler.dir64
}
- if !ctx.Host() || ctx.Target().NativeBridge == android.NativeBridgeEnabled {
+ if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
+ dir = filepath.Join(dir, ctx.Target().NativeBridgeRelativePath)
+ }
+ if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
dir = filepath.Join(dir, ctx.Arch().ArchType.String())
}
return android.PathForModuleInstall(ctx, dir, compiler.subDir,
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/scripts/OWNERS b/scripts/OWNERS
index 9e97a60..dd0966f 100644
--- a/scripts/OWNERS
+++ b/scripts/OWNERS
@@ -1,2 +1,3 @@
per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
+per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
diff --git a/scripts/build-aml-prebuilts.sh b/scripts/build-aml-prebuilts.sh
index 7e3a82c..35a6ff3 100755
--- a/scripts/build-aml-prebuilts.sh
+++ b/scripts/build-aml-prebuilts.sh
@@ -58,6 +58,7 @@
"DeviceName": "generic_arm64",
"HostArch": "x86_64",
+ "HostSecondaryArch": "x86",
"Aml_abis": true,
"UseGoma": ${USE_GOMA}
diff --git a/scripts/transitive-deps.sh b/scripts/transitive-deps.sh
index 23121c6..c6f8b76 100755
--- a/scripts/transitive-deps.sh
+++ b/scripts/transitive-deps.sh
@@ -469,7 +469,9 @@
fi
readonly hashedNotice="${tmpFiles}/hashednotices"
( # md5sum outputs checksum space indicator(space or *) filename newline
+ set +e
sort -u "${allNotice}" | tr '\n' '\0' | xargs -0 -r md5sum 2>/dev/null
+ set -e
# use sed to replace space and indicator with separator
) > "${hashedNotice}"
if ${showProgress}; then
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index ca40afd..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)
}
@@ -48,7 +49,6 @@
cc_library_shared {
name: "sdkmember",
srcs: ["Test.cpp"],
- system_shared_libs: [],
stl: "none",
}
`)
@@ -178,13 +178,11 @@
cc_library_host_shared {
name: "sdkshared",
- system_shared_libs: [],
stl: "none",
}
cc_library_host_static {
name: "sdkstatic",
- system_shared_libs: [],
stl: "none",
}
`)
@@ -201,25 +199,21 @@
cc_library_shared {
name: "sdkshared",
- system_shared_libs: [],
stl: "none",
}
cc_library_static {
name: "sdkstatic",
- system_shared_libs: [],
stl: "none",
}
cc_library {
name: "sdkboth1",
- system_shared_libs: [],
stl: "none",
}
cc_library {
name: "sdkboth2",
- system_shared_libs: [],
stl: "none",
}
`)
@@ -295,7 +289,6 @@
"Test.cpp",
],
export_include_dirs: ["include"],
- system_shared_libs: [],
stl: "none",
}
@@ -305,7 +298,6 @@
"Test.cpp",
],
export_include_dirs: ["include"],
- system_shared_libs: [],
stl: "none",
}
`)
@@ -342,7 +334,6 @@
export_system_include_dirs: ["arm64/include"],
},
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -410,7 +401,6 @@
"Test.cpp",
],
compile_multilib: "both",
- system_shared_libs: [],
stl: "none",
}
`)
@@ -485,7 +475,6 @@
"Test.cpp",
],
compile_multilib: "both",
- system_shared_libs: [],
stl: "none",
target: {
windows: {
@@ -586,7 +575,6 @@
aidl: {
export_aidl_headers: true,
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -673,7 +661,6 @@
srcs: [
"Test.cpp",
],
- system_shared_libs: [],
stl: "none",
}
@@ -714,7 +701,6 @@
},
},
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -864,7 +850,6 @@
aidl: {
export_aidl_headers: true,
},
- system_shared_libs: [],
stl: "none",
sdk_version: "minimum",
}
@@ -960,7 +945,6 @@
srcs: [
"Test.cpp",
],
- system_shared_libs: [],
stl: "none",
target: {
windows: {
@@ -1050,7 +1034,6 @@
aidl: {
export_aidl_headers: true,
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1137,7 +1120,6 @@
aidl: {
export_aidl_headers: true,
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1219,7 +1201,6 @@
"Test.cpp",
],
export_include_dirs: ["include"],
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1322,7 +1303,6 @@
aidl: {
export_aidl_headers: true,
},
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1393,7 +1373,6 @@
cc_library_headers {
name: "mynativeheaders",
export_include_dirs: ["include"],
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1444,7 +1423,6 @@
device_supported: false,
host_supported: true,
export_include_dirs: ["include"],
- system_shared_libs: [],
stl: "none",
}
`)
@@ -1498,7 +1476,6 @@
cc_library_headers {
name: "mynativeheaders",
host_supported: true,
- system_shared_libs: [],
stl: "none",
export_system_include_dirs: ["include"],
target: {
@@ -1561,3 +1538,265 @@
`),
)
}
+
+func TestSystemSharedLibPropagation(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ native_shared_libs: ["sslnil", "sslempty", "sslnonempty"],
+ }
+
+ cc_library {
+ name: "sslnil",
+ host_supported: true,
+ }
+
+ cc_library {
+ name: "sslempty",
+ system_shared_libs: [],
+ }
+
+ cc_library {
+ name: "sslnonempty",
+ system_shared_libs: ["sslnil"],
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_sslnil@current",
+ sdk_member_name: "sslnil",
+ installable: false,
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslnil.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslnil.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "sslnil",
+ prefer: false,
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslnil.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslnil.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "mysdk_sslempty@current",
+ sdk_member_name: "sslempty",
+ installable: false,
+ system_shared_libs: [],
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslempty.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslempty.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "sslempty",
+ prefer: false,
+ system_shared_libs: [],
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslempty.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslempty.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "mysdk_sslnonempty@current",
+ sdk_member_name: "sslnonempty",
+ installable: false,
+ system_shared_libs: ["mysdk_sslnil@current"],
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslnonempty.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslnonempty.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "sslnonempty",
+ prefer: false,
+ system_shared_libs: ["sslnil"],
+ arch: {
+ arm64: {
+ srcs: ["arm64/lib/sslnonempty.so"],
+ },
+ arm: {
+ srcs: ["arm/lib/sslnonempty.so"],
+ },
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ native_shared_libs: [
+ "mysdk_sslnil@current",
+ "mysdk_sslempty@current",
+ "mysdk_sslnonempty@current",
+ ],
+}
+`))
+
+ result = testSdkWithCc(t, `
+ sdk {
+ name: "mysdk",
+ host_supported: true,
+ native_shared_libs: ["sslvariants"],
+ }
+
+ cc_library {
+ name: "sslvariants",
+ host_supported: true,
+ target: {
+ android: {
+ system_shared_libs: [],
+ },
+ },
+ }
+ `)
+
+ result.CheckSnapshot("mysdk", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_shared {
+ name: "mysdk_sslvariants@current",
+ sdk_member_name: "sslvariants",
+ host_supported: true,
+ installable: false,
+ target: {
+ android: {
+ system_shared_libs: [],
+ },
+ android_arm64: {
+ srcs: ["android/arm64/lib/sslvariants.so"],
+ },
+ android_arm: {
+ srcs: ["android/arm/lib/sslvariants.so"],
+ },
+ linux_glibc_x86_64: {
+ srcs: ["linux_glibc/x86_64/lib/sslvariants.so"],
+ },
+ linux_glibc_x86: {
+ srcs: ["linux_glibc/x86/lib/sslvariants.so"],
+ },
+ },
+}
+
+cc_prebuilt_library_shared {
+ name: "sslvariants",
+ prefer: false,
+ host_supported: true,
+ target: {
+ android: {
+ system_shared_libs: [],
+ },
+ android_arm64: {
+ srcs: ["android/arm64/lib/sslvariants.so"],
+ },
+ android_arm: {
+ srcs: ["android/arm/lib/sslvariants.so"],
+ },
+ linux_glibc_x86_64: {
+ srcs: ["linux_glibc/x86_64/lib/sslvariants.so"],
+ },
+ linux_glibc_x86: {
+ srcs: ["linux_glibc/x86/lib/sslvariants.so"],
+ },
+ },
+}
+
+sdk_snapshot {
+ name: "mysdk@current",
+ host_supported: true,
+ native_shared_libs: ["mysdk_sslvariants@current"],
+}
+`))
+}
+
+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/java_sdk_test.go b/sdk/java_sdk_test.go
index cbffb50..4a2c053 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -53,30 +53,18 @@
system_modules: "none",
sdk_version: "none",
host_supported: true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
}
java_import {
name: "sdkmember_mysdk_1",
sdk_member_name: "sdkmember",
host_supported: true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
}
java_import {
name: "sdkmember_mysdk_2",
sdk_member_name: "sdkmember",
host_supported: true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
}
java_library {
diff --git a/sdk/sdk.go b/sdk/sdk.go
index dabdf85..cb5a605 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -312,7 +312,7 @@
ctx.BottomUp("SdkMemberInterVersion", memberInterVersionMutator).Parallel()
}
-// RegisterPostDepshMutators registers post-deps mutators to support modules implementing SdkAware
+// RegisterPostDepsMutators registers post-deps mutators to support modules implementing SdkAware
// interface and the sdk module type. This function has been made public to be called by tests
// outside of the sdk package
func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
@@ -431,23 +431,31 @@
}
}
-// Step 6: ensure that the dependencies from outside of the APEX are all from the required SDKs
+// Step 6: ensure that the dependencies 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 {
return
}
mctx.VisitDirectDeps(func(dep android.Module) {
- if mctx.OtherModuleDependencyTag(dep) == android.DefaultsDepTag {
+ tag := mctx.OtherModuleDependencyTag(dep)
+ if tag == android.DefaultsDepTag {
// dependency to defaults is always okay
return
}
- // If the dep is from outside of the APEX, but is not in any of the
+ // Ignore the dependency from the unversioned member to any versioned members as an
+ // apex that depends on the unversioned member will not also be depending on a versioned
+ // member.
+ if _, ok := tag.(sdkMemberVersionedDepTag); ok {
+ return
+ }
+
+ // If the dep is outside of the APEX, but is not in any of the
// required SDKs, we know that the dep is a violation.
if sa, ok := dep.(android.SdkAware); ok {
if !m.DepIsInSameApex(mctx, dep) && !requiredSdks.Contains(sa.ContainingSdk()) {
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index 65dbb22..a2e35d9 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -18,6 +18,7 @@
"fmt"
"io"
"path"
+ "sync"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -115,6 +116,7 @@
type syspropLibrary struct {
android.ModuleBase
+ android.ApexModuleBase
properties syspropLibraryProperties
@@ -154,8 +156,21 @@
var (
pctx = android.NewPackageContext("android/soong/sysprop")
syspropCcTag = dependencyTag{name: "syspropCc"}
+
+ syspropLibrariesKey = android.NewOnceKey("syspropLibraries")
+ syspropLibrariesLock sync.Mutex
)
+func syspropLibraries(config android.Config) *[]string {
+ return config.Once(syspropLibrariesKey, func() interface{} {
+ return &[]string{}
+ }).(*[]string)
+}
+
+func SyspropLibraries(config android.Config) []string {
+ return append([]string{}, *syspropLibraries(config)...)
+}
+
func init() {
android.RegisterModuleType("sysprop_library", syspropLibraryFactory)
}
@@ -195,6 +210,10 @@
return proptools.Bool(m.properties.Public_stub)
}
+func (m *syspropLibrary) CurrentSyspropApiFile() android.Path {
+ return m.currentApiFile
+}
+
func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
baseModuleName := m.BaseModuleName()
@@ -296,6 +315,7 @@
&m.properties,
)
android.InitAndroidModule(m)
+ android.InitApexModule(m)
android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
return m
}
@@ -323,6 +343,7 @@
Recovery_available *bool
Vendor_available *bool
Host_supported *bool
+ Apex_available []string
}
type javaLibraryProperties struct {
@@ -411,6 +432,7 @@
ccProps.Recovery_available = m.properties.Recovery_available
ccProps.Vendor_available = m.properties.Vendor_available
ccProps.Host_supported = m.properties.Host_supported
+ ccProps.Apex_available = m.ApexProperties.Apex_available
ctx.CreateModule(cc.LibraryFactory, &ccProps)
scope := "internal"
@@ -463,6 +485,12 @@
Stem: proptools.StringPtr(m.BaseModuleName()),
})
}
+
+ syspropLibrariesLock.Lock()
+ defer syspropLibrariesLock.Unlock()
+
+ libraries := syspropLibraries(ctx.Config())
+ *libraries = append(*libraries, ctx.ModuleName())
}
func syspropDepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 51da222..8503386 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -15,6 +15,8 @@
package sysprop
import (
+ "reflect"
+
"android/soong/android"
"android/soong/cc"
"android/soong/java"
@@ -157,6 +159,7 @@
ctx := test(t, `
sysprop_library {
name: "sysprop-platform",
+ apex_available: ["//apex_available:platform"],
srcs: ["android/sysprop/PlatformProperties.sysprop"],
api_packages: ["android.sysprop"],
property_owner: "Platform",
@@ -305,7 +308,12 @@
"android_arm64_armv8-a_shared",
"android_arm64_armv8-a_static",
} {
- ctx.ModuleForTests("libsysprop-platform", variant)
+ library := ctx.ModuleForTests("libsysprop-platform", variant).Module().(*cc.Module)
+ expectedApexAvailableOnLibrary := []string{"//apex_available:platform"}
+ if !reflect.DeepEqual(library.ApexProperties.Apex_available, expectedApexAvailableOnLibrary) {
+ t.Errorf("apex available property on libsysprop-platform must be %#v, but was %#v.",
+ expectedApexAvailableOnLibrary, library.ApexProperties.Apex_available)
+ }
// core variant of vendor-owned sysprop_library is for product
ctx.ModuleForTests("libsysprop-vendor", variant)
diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go
index 95d049a..0bcdccb 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -99,6 +99,7 @@
hostOut("sdk_addon"),
hostOut("testcases"),
hostOut("vts"),
+ hostOut("vts10"),
hostOut("vts-core"),
productOut("*.img"),
productOut("*.zip"),
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())