Merge "java_sdk_library: Remove unused SetNoDist method"
diff --git a/android/Android.bp b/android/Android.bp
index 26605a7..66d361e 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -15,6 +15,7 @@
"apex.go",
"api_levels.go",
"arch.go",
+ "arch_list.go",
"bazel_handler.go",
"config.go",
"csuite_config.go",
diff --git a/android/arch.go b/android/arch.go
index afb9c7f..eb651e6 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -27,28 +27,6 @@
"github.com/google/blueprint/proptools"
)
-const COMMON_VARIANT = "common"
-
-var (
- archTypeList []ArchType
-
- Arm = newArch("arm", "lib32")
- Arm64 = newArch("arm64", "lib64")
- X86 = newArch("x86", "lib32")
- X86_64 = newArch("x86_64", "lib64")
-
- Common = ArchType{
- Name: COMMON_VARIANT,
- }
-)
-
-var archTypeMap = map[string]ArchType{
- "arm": Arm,
- "arm64": Arm64,
- "x86": X86,
- "x86_64": X86_64,
-}
-
/*
Example blueprints file containing all variant property groups, with comment listing what type
of variants get properties in that group:
@@ -111,405 +89,26 @@
}
*/
-var archVariants = map[ArchType][]string{
- Arm: {
- "armv7-a",
- "armv7-a-neon",
- "armv8-a",
- "armv8-2a",
- "cortex-a7",
- "cortex-a8",
- "cortex-a9",
- "cortex-a15",
- "cortex-a53",
- "cortex-a53-a57",
- "cortex-a55",
- "cortex-a72",
- "cortex-a73",
- "cortex-a75",
- "cortex-a76",
- "krait",
- "kryo",
- "kryo385",
- "exynos-m1",
- "exynos-m2",
- },
- Arm64: {
- "armv8_a",
- "armv8_2a",
- "armv8-2a-dotprod",
- "cortex-a53",
- "cortex-a55",
- "cortex-a72",
- "cortex-a73",
- "cortex-a75",
- "cortex-a76",
- "kryo",
- "kryo385",
- "exynos-m1",
- "exynos-m2",
- },
- X86: {
- "amberlake",
- "atom",
- "broadwell",
- "haswell",
- "icelake",
- "ivybridge",
- "kabylake",
- "sandybridge",
- "silvermont",
- "skylake",
- "stoneyridge",
- "tigerlake",
- "whiskeylake",
- "x86_64",
- },
- X86_64: {
- "amberlake",
- "broadwell",
- "haswell",
- "icelake",
- "ivybridge",
- "kabylake",
- "sandybridge",
- "silvermont",
- "skylake",
- "stoneyridge",
- "tigerlake",
- "whiskeylake",
- },
-}
-
-var archFeatures = map[ArchType][]string{
- Arm: {
- "neon",
- },
- Arm64: {
- "dotprod",
- },
- X86: {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "avx2",
- "avx512",
- "popcnt",
- "movbe",
- },
- X86_64: {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "avx2",
- "avx512",
- "popcnt",
- },
-}
-
-var archFeatureMap = map[ArchType]map[string][]string{
- Arm: {
- "armv7-a-neon": {
- "neon",
- },
- "armv8-a": {
- "neon",
- },
- "armv8-2a": {
- "neon",
- },
- },
- Arm64: {
- "armv8-2a-dotprod": {
- "dotprod",
- },
- },
- X86: {
- "amberlake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "atom": {
- "ssse3",
- "movbe",
- },
- "broadwell": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "haswell": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "popcnt",
- "movbe",
- },
- "icelake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "ivybridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "popcnt",
- },
- "kabylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "sandybridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "popcnt",
- },
- "silvermont": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "popcnt",
- "movbe",
- },
- "skylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "stoneyridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "avx2",
- "popcnt",
- "movbe",
- },
- "tigerlake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "whiskeylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "x86_64": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "popcnt",
- },
- },
- X86_64: {
- "amberlake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "broadwell": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "haswell": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "popcnt",
- },
- "icelake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "ivybridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "popcnt",
- },
- "kabylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "aes_ni",
- "popcnt",
- },
- "sandybridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "popcnt",
- },
- "silvermont": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "popcnt",
- },
- "skylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "stoneyridge": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "aes_ni",
- "avx",
- "avx2",
- "popcnt",
- },
- "tigerlake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- "whiskeylake": {
- "ssse3",
- "sse4",
- "sse4_1",
- "sse4_2",
- "avx",
- "avx2",
- "avx512",
- "aes_ni",
- "popcnt",
- },
- },
-}
-
-var defaultArchFeatureMap = map[OsType]map[ArchType][]string{}
-
-func RegisterDefaultArchVariantFeatures(os OsType, arch ArchType, features ...string) {
- checkCalledFromInit()
-
- for _, feature := range features {
- if !InList(feature, archFeatures[arch]) {
- panic(fmt.Errorf("Invalid feature %q for arch %q variant \"\"", feature, arch))
- }
- }
-
- if defaultArchFeatureMap[os] == nil {
- defaultArchFeatureMap[os] = make(map[ArchType][]string)
- }
- defaultArchFeatureMap[os][arch] = features
-}
-
// An Arch indicates a single CPU architecture.
type Arch struct {
- ArchType ArchType
- ArchVariant string
- CpuVariant string
- Abi []string
+ // The type of the architecture (arm, arm64, x86, or x86_64).
+ ArchType ArchType
+
+ // The variant of the architecture, for example "armv7-a" or "armv7-a-neon" for arm.
+ ArchVariant string
+
+ // The variant of the CPU, for example "cortex-a53" for arm64.
+ CpuVariant string
+
+ // The list of Android app ABIs supported by the CPU architecture, for example "arm64-v8a".
+ Abi []string
+
+ // The list of arch-specific features supported by the CPU architecture, for example "neon".
ArchFeatures []string
}
+// String returns the Arch as a string. The value is used as the name of the variant created
+// by archMutator.
func (a Arch) String() string {
s := a.ArchType.String()
if a.ArchVariant != "" {
@@ -521,12 +120,42 @@
return s
}
+// ArchType is used to define the 4 supported architecture types (arm, arm64, x86, x86_64), as
+// well as the "common" architecture used for modules that support multiple architectures, for
+// example Java modules.
type ArchType struct {
- Name string
- Field string
+ // Name is the name of the architecture type, "arm", "arm64", "x86", or "x86_64".
+ Name string
+
+ // Field is the name of the field used in properties that refer to the architecture, e.g. "Arm64".
+ Field string
+
+ // Multilib is either "lib32" or "lib64" for 32-bit or 64-bit architectures.
Multilib string
}
+// String returns the name of the ArchType.
+func (a ArchType) String() string {
+ return a.Name
+}
+
+const COMMON_VARIANT = "common"
+
+var (
+ archTypeList []ArchType
+
+ Arm = newArch("arm", "lib32")
+ Arm64 = newArch("arm64", "lib64")
+ X86 = newArch("x86", "lib32")
+ X86_64 = newArch("x86_64", "lib64")
+
+ Common = ArchType{
+ Name: COMMON_VARIANT,
+ }
+)
+
+var archTypeMap = map[string]ArchType{}
+
func newArch(name, multilib string) ArchType {
archType := ArchType{
Name: name,
@@ -534,25 +163,25 @@
Multilib: multilib,
}
archTypeList = append(archTypeList, archType)
+ archTypeMap[name] = archType
return archType
}
+// ArchTypeList returns the 4 supported ArchTypes for arm, arm64, x86 and x86_64.
func ArchTypeList() []ArchType {
return append([]ArchType(nil), archTypeList...)
}
-func (a ArchType) String() string {
- return a.Name
-}
-
-var _ encoding.TextMarshaler = ArchType{}
-
+// MarshalText allows an ArchType to be serialized through any encoder that supports
+// encoding.TextMarshaler.
func (a ArchType) MarshalText() ([]byte, error) {
return []byte(strconv.Quote(a.String())), nil
}
-var _ encoding.TextUnmarshaler = &ArchType{}
+var _ encoding.TextMarshaler = ArchType{}
+// UnmarshalText allows an ArchType to be deserialized through any decoder that supports
+// encoding.TextUnmarshaler.
func (a *ArchType) UnmarshalText(text []byte) error {
if u, ok := archTypeMap[string(text)]; ok {
*a = u
@@ -562,67 +191,22 @@
return fmt.Errorf("unknown ArchType %q", text)
}
-var BuildOs = func() OsType {
- switch runtime.GOOS {
- case "linux":
- return Linux
- case "darwin":
- return Darwin
- default:
- panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
- }
-}()
+var _ encoding.TextUnmarshaler = &ArchType{}
-var BuildArch = func() ArchType {
- switch runtime.GOARCH {
- case "amd64":
- return X86_64
- default:
- panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH))
- }
-}()
-
-var (
- OsTypeList []OsType
- commonTargetMap = make(map[string]Target)
-
- NoOsType OsType
- Linux = NewOsType("linux_glibc", Host, false)
- Darwin = NewOsType("darwin", Host, false)
- LinuxBionic = NewOsType("linux_bionic", Host, false)
- Windows = NewOsType("windows", Host, true)
- Android = NewOsType("android", Device, false)
- Fuchsia = NewOsType("fuchsia", Device, false)
-
- // A pseudo OSType for a common os variant, which is OSType agnostic and which
- // has dependencies on all the OS variants.
- CommonOS = NewOsType("common_os", Generic, false)
-
- osArchTypeMap = map[OsType][]ArchType{
- Linux: []ArchType{X86, X86_64},
- LinuxBionic: []ArchType{Arm64, X86_64},
- Darwin: []ArchType{X86_64},
- Windows: []ArchType{X86, X86_64},
- Android: []ArchType{Arm, Arm64, X86, X86_64},
- Fuchsia: []ArchType{Arm64, X86_64},
- }
-)
-
-type OsType struct {
- Name, Field string
- Class OsClass
-
- DefaultDisabled bool
-}
-
+// OsClass is an enum that describes whether a variant of a module runs on the host, on the device,
+// or is generic.
type OsClass int
const (
+ // Generic is used for variants of modules that are not OS-specific.
Generic OsClass = iota
+ // Device is used for variants of modules that run on the device.
Device
+ // Host is used for variants of modules that run on the host.
Host
)
+// String returns the OsClass as a string.
func (class OsClass) String() string {
switch class {
case Generic:
@@ -636,22 +220,48 @@
}
}
+// OsType describes an OS variant of a module.
+type OsType struct {
+ // Name is the name of the OS. It is also used as the name of the property in Android.bp
+ // files.
+ Name string
+
+ // Field is the name of the OS converted to an exported field name, i.e. with the first
+ // character capitalized.
+ Field string
+
+ // Class is the OsClass of the OS.
+ Class OsClass
+
+ // DefaultDisabled is set when the module variants for the OS should not be created unless
+ // the module explicitly requests them. This is used to limit Windows cross compilation to
+ // only modules that need it.
+ DefaultDisabled bool
+}
+
+// String returns the name of the OsType.
func (os OsType) String() string {
return os.Name
}
+// Bionic returns true if the OS uses the Bionic libc runtime, i.e. if the OS is Android or
+// is Linux with Bionic.
func (os OsType) Bionic() bool {
return os == Android || os == LinuxBionic
}
+// Linux returns true if the OS uses the Linux kernel, i.e. if the OS is Android or is Linux
+// with or without the Bionic libc runtime.
func (os OsType) Linux() bool {
return os == Android || os == Linux || os == LinuxBionic
}
-func NewOsType(name string, class OsClass, defDisabled bool) OsType {
+// newOsType constructs an OsType and adds it to the global lists.
+func newOsType(name string, class OsClass, defDisabled bool, archTypes ...ArchType) OsType {
+ checkCalledFromInit()
os := OsType{
Name: name,
- Field: strings.Title(name),
+ Field: proptools.FieldNameForProperty(name),
Class: class,
DefaultDisabled: defDisabled,
@@ -663,10 +273,12 @@
} else {
commonTargetMap[name] = Target{Os: os, Arch: Arch{ArchType: Common}}
}
+ osArchTypeMap[os] = archTypes
return os
}
+// osByName returns the OsType that has the given name, or NoOsType if none match.
func osByName(name string) OsType {
for _, os := range OsTypeList {
if os.Name == name {
@@ -677,18 +289,74 @@
return NoOsType
}
-type NativeBridgeSupport bool
+// BuildOs returns the OsType for the OS that the build is running on.
+var BuildOs = func() OsType {
+ switch runtime.GOOS {
+ case "linux":
+ return Linux
+ case "darwin":
+ return Darwin
+ default:
+ panic(fmt.Sprintf("unsupported OS: %s", runtime.GOOS))
+ }
+}()
-const (
- NativeBridgeDisabled NativeBridgeSupport = false
- NativeBridgeEnabled NativeBridgeSupport = true
+// BuildArch returns the ArchType for the CPU that the build is running on.
+var BuildArch = func() ArchType {
+ switch runtime.GOARCH {
+ case "amd64":
+ return X86_64
+ default:
+ panic(fmt.Sprintf("unsupported Arch: %s", runtime.GOARCH))
+ }
+}()
+
+var (
+ // OsTypeList contains a list of all the supported OsTypes, including ones not supported
+ // by the current build host or the target device.
+ OsTypeList []OsType
+ // commonTargetMap maps names of OsTypes to the corresponding common Target, i.e. the
+ // Target with the same OsType and the common ArchType.
+ commonTargetMap = make(map[string]Target)
+ // osArchTypeMap maps OsTypes to the list of supported ArchTypes for that OS.
+ osArchTypeMap = map[OsType][]ArchType{}
+
+ // NoOsType is a placeholder for when no OS is needed.
+ NoOsType OsType
+ // Linux is the OS for the Linux kernel plus the glibc runtime.
+ Linux = newOsType("linux_glibc", Host, false, X86, X86_64)
+ // Darwin is the OS for MacOS/Darwin host machines.
+ Darwin = newOsType("darwin", Host, false, X86_64)
+ // LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
+ // rest of Android.
+ LinuxBionic = newOsType("linux_bionic", Host, false, Arm64, X86_64)
+ // Windows the OS for Windows host machines.
+ Windows = newOsType("windows", Host, true, X86, X86_64)
+ // Android is the OS for target devices that run all of Android, including the Linux kernel
+ // and the Bionic libc runtime.
+ Android = newOsType("android", Device, false, Arm, Arm64, X86, X86_64)
+ // Fuchsia is the OS for target devices that run Fuchsia.
+ Fuchsia = newOsType("fuchsia", Device, false, Arm64, X86_64)
+
+ // CommonOS is a pseudo OSType for a common OS variant, which is OsType agnostic and which
+ // has dependencies on all the OS variants.
+ CommonOS = newOsType("common_os", Generic, false)
)
+// Target specifies the OS and architecture that a module is being compiled for.
type Target struct {
- Os OsType
- Arch Arch
- NativeBridge NativeBridgeSupport
+ // Os the OS that the module is being compiled for (e.g. "linux_glibc", "android").
+ Os OsType
+ // Arch is the architecture that the module is being compiled for.
+ Arch Arch
+ // NativeBridge is NativeBridgeEnabled if the architecture is supported using NativeBridge
+ // (i.e. arm on x86) for this device.
+ NativeBridge NativeBridgeSupport
+ // NativeBridgeHostArchName is the name of the real architecture that is used to implement
+ // the NativeBridge architecture. For example, for arm on x86 this would be "x86".
NativeBridgeHostArchName string
+ // NativeBridgeRelativePath is the name of the subdirectory that will contain NativeBridge
+ // libraries and binaries.
NativeBridgeRelativePath string
// HostCross is true when the target cannot run natively on the current build host.
@@ -697,14 +365,25 @@
HostCross bool
}
+// NativeBridgeSupport is an enum that specifies if a Target supports NativeBridge.
+type NativeBridgeSupport bool
+
+const (
+ NativeBridgeDisabled NativeBridgeSupport = false
+ NativeBridgeEnabled NativeBridgeSupport = true
+)
+
+// String returns the OS and arch variations used for the Target.
func (target Target) String() string {
return target.OsVariation() + "_" + target.ArchVariation()
}
+// OsVariation returns the name of the variation used by the osMutator for the Target.
func (target Target) OsVariation() string {
return target.Os.String()
}
+// ArchVariation returns the name of the variation used by the archMutator for the Target.
func (target Target) ArchVariation() string {
var variation string
if target.NativeBridge {
@@ -715,6 +394,8 @@
return variation
}
+// Variations returns a list of blueprint.Variations for the osMutator and archMutator for the
+// Target.
func (target Target) Variations() []blueprint.Variation {
return []blueprint.Variation{
{Mutator: "os", Variation: target.OsVariation()},
@@ -722,10 +403,16 @@
}
}
+// osMutator splits an arch-specific module into a variant for each OS that is enabled for the
+// module. It uses the HostOrDevice value passed to InitAndroidArchModule and the
+// device_supported and host_supported properties to determine which OsTypes are enabled for this
+// module, then searches through the Targets to determine which have enabled Targets for this
+// module.
func osMutator(bpctx blueprint.BottomUpMutatorContext) {
var module Module
var ok bool
if module, ok = bpctx.Module().(Module); !ok {
+ // The module is not a Soong module, it is a Blueprint module.
if bootstrap.IsBootstrapModule(bpctx.Module()) {
// Bootstrap Go modules are always the build OS or linux bionic.
config := bpctx.Config().(Config)
@@ -749,12 +436,14 @@
base := module.base()
+ // Nothing to do for modules that are not architecture specific (e.g. a genrule).
if !base.ArchSpecific() {
return
}
+ // Collect a list of OSTypes supported by this module based on the HostOrDevice value
+ // passed to InitAndroidArchModule and the device_supported and host_supported properties.
var moduleOSList []OsType
-
for _, os := range OsTypeList {
for _, t := range mctx.Config().Targets[os] {
if base.supportsTarget(t) {
@@ -764,20 +453,21 @@
}
}
+ // If there are no supported OSes then disable the module.
if len(moduleOSList) == 0 {
base.Disable()
return
}
+ // Convert the list of supported OsTypes to the variation names.
osNames := make([]string, len(moduleOSList))
-
for i, os := range moduleOSList {
osNames[i] = os.String()
}
createCommonOSVariant := base.commonProperties.CreateCommonOSVariant
if createCommonOSVariant {
- // A CommonOS variant was requested so add it to the list of OS's variants to
+ // A CommonOS variant was requested so add it to the list of OS variants to
// create. It needs to be added to the end because it needs to depend on the
// the other variants in the list returned by CreateVariations(...) and inter
// variant dependencies can only be created from a later variant in that list to
@@ -787,6 +477,8 @@
moduleOSList = append(moduleOSList, CommonOS)
}
+ // Create the variations, annotate each one with which OS it was created for, and
+ // squash the appropriate OS-specific properties into the top level properties.
modules := mctx.CreateVariations(osNames...)
for i, m := range modules {
m.base().commonProperties.CompileOS = moduleOSList[i]
@@ -841,7 +533,7 @@
}
// archMutator splits a module into a variant for each Target requested by the module. Target selection
-// for a module is in three levels, OsClass, mulitlib, and then Target.
+// for a module is in three levels, OsClass, multilib, and then Target.
// OsClass selection is determined by:
// - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
// whether the module type can compile for host, device or both.
@@ -858,7 +550,11 @@
// but may be arm for a 32-bit only build.
// "32": compile for only a single 32-bit Target supported by the OsClass.
// "64": compile for only a single 64-bit Target supported by the OsClass.
-// "common": compile a for a single Target that will work on all Targets suported by the OsClass (for example Java).
+// "common": compile a for a single Target that will work on all Targets supported by the OsClass (for example Java).
+// "common_first": compile a for a Target that will work on all Targets supported by the OsClass
+// (same as "common"), plus a second Target for the preferred Target supported by the OsClass
+// (same as "first"). This is used for java_binary that produces a common .jar and a wrapper
+// executable script.
//
// Once the list of Targets is determined, the module is split into a variant for each Target.
//
@@ -899,8 +595,8 @@
osTargets := mctx.Config().Targets[os]
image := base.commonProperties.ImageVariation
- // Filter NativeBridge targets unless they are explicitly supported
- // Skip creating native bridge variants for vendor modules
+ // Filter NativeBridge targets unless they are explicitly supported.
+ // Skip creating native bridge variants for non-core modules.
if os == Android &&
!(Bool(base.commonProperties.Native_bridge_supported) && image == CoreVariation) {
@@ -919,17 +615,24 @@
osTargets = []Target{osTargets[0]}
}
+ // Some modules want compile_multilib: "first" to mean 32-bit, not 64-bit.
+ // This is used for Windows support and for HOST_PREFER_32_BIT=true support for Art modules.
prefer32 := false
if base.prefer32 != nil {
prefer32 = base.prefer32(mctx, base, os)
}
+ // Determine the multilib selection for this module.
multilib, extraMultilib := decodeMultilib(base, os.Class)
+
+ // Convert the multilib selection into a list of Targets.
targets, err := decodeMultilibTargets(multilib, osTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
+ // If the module is using extraMultilib, decode the extraMultilib selection into
+ // a separate list of Targets.
var multiTargets []Target
if extraMultilib != "" {
multiTargets, err = decodeMultilibTargets(extraMultilib, osTargets, prefer32)
@@ -938,23 +641,27 @@
}
}
+ // Recovery is always the primary architecture, filter out any other architectures.
if image == RecoveryVariation {
primaryArch := mctx.Config().DevicePrimaryArchType()
targets = filterToArch(targets, primaryArch)
multiTargets = filterToArch(multiTargets, primaryArch)
}
+ // If there are no supported targets disable the module.
if len(targets) == 0 {
base.Disable()
return
}
+ // Convert the targets into a list of arch variation names.
targetNames := make([]string, len(targets))
-
for i, target := range targets {
targetNames[i] = target.ArchVariation()
}
+ // Create the variations, annotate each one with which Target it was created for, and
+ // squash the appropriate arch-specific properties into the top level properties.
modules := mctx.CreateVariations(targetNames...)
for i, m := range modules {
addTargetProperties(m, targets[i], multiTargets, i == 0)
@@ -968,22 +675,34 @@
}
}
+// addTargetProperties annotates a variant with the Target is is being compiled for, the list
+// of additional Targets it is supporting (if any), and whether it is the primary Target for
+// the module.
func addTargetProperties(m Module, target Target, multiTargets []Target, primaryTarget bool) {
m.base().commonProperties.CompileTarget = target
m.base().commonProperties.CompileMultiTargets = multiTargets
m.base().commonProperties.CompilePrimary = primaryTarget
}
+// decodeMultilib returns the appropriate compile_multilib property for the module, or the default
+// multilib from the factory's call to InitAndroidArchModule if none was set. For modules that
+// called InitAndroidMultiTargetsArchModule it always returns "common" for multilib, and returns
+// the actual multilib in extraMultilib.
func decodeMultilib(base *ModuleBase, class OsClass) (multilib, extraMultilib string) {
+ // First check the "android.compile_multilib" or "host.compile_multilib" properties.
switch class {
case Device:
multilib = String(base.commonProperties.Target.Android.Compile_multilib)
case Host:
multilib = String(base.commonProperties.Target.Host.Compile_multilib)
}
+
+ // If those aren't set, try the "compile_multilib" property.
if multilib == "" {
multilib = String(base.commonProperties.Compile_multilib)
}
+
+ // If that wasn't set, use the default multilib set by the factory.
if multilib == "" {
multilib = base.commonProperties.Default_multilib
}
@@ -1000,6 +719,8 @@
}
}
+// filterToArch takes a list of Targets and an ArchType, and returns a modified list that contains
+// only Targets that have the specified ArchType.
func filterToArch(targets []Target, arch ArchType) []Target {
for i := 0; i < len(targets); i++ {
if targets[i].Arch.ArchType != arch {
@@ -1010,17 +731,27 @@
return targets
}
-type archPropTypeDesc struct {
- arch, multilib, target reflect.Type
-}
-
+// archPropRoot is a struct type used as the top level of the arch-specific properties. It
+// contains the "arch", "multilib", and "target" property structs. It is used to split up the
+// property structs to limit how much is allocated when a single arch-specific property group is
+// used. The types are interface{} because they will hold instances of runtime-created types.
type archPropRoot struct {
Arch, Multilib, Target interface{}
}
+// archPropTypeDesc holds the runtime-created types for the property structs to instantiate to
+// create an archPropRoot property struct.
+type archPropTypeDesc struct {
+ arch, multilib, target reflect.Type
+}
+
// createArchPropTypeDesc takes a reflect.Type that is either a struct or a pointer to a struct, and
// returns lists of reflect.Types that contains the arch-variant properties inside structs for each
// arch, multilib and target property.
+//
+// This is a relatively expensive operation, so the results are cached in the global
+// archPropTypeMap. It is constructed entirely based on compile-time data, so there is no need
+// to isolate the results between multiple tests running in parallel.
func createArchPropTypeDesc(props reflect.Type) []archPropTypeDesc {
// Each property struct shard will be nested many times under the runtime generated arch struct,
// which can hit the limit of 64kB for the name of runtime generated structs. They are nested
@@ -1029,7 +760,12 @@
// could cause problems if a single deeply nested property no longer fits in the name.
const maxArchTypeNameSize = 500
+ // Convert the type to a new set of types that contains only the arch-specific properties
+ // (those that are tagged with `android:"arch_specific"`), and sharded into multiple types
+ // to keep the runtime-generated names under the limit.
propShards, _ := proptools.FilterPropertyStructSharded(props, maxArchTypeNameSize, filterArchStruct)
+
+ // If the type has no arch-specific properties there is nothing to do.
if len(propShards) == 0 {
return nil
}
@@ -1037,6 +773,8 @@
var ret []archPropTypeDesc
for _, props := range propShards {
+ // variantFields takes a list of variant property field names and returns a list the
+ // StructFields with the names and the type of the current shard.
variantFields := func(names []string) []reflect.StructField {
ret := make([]reflect.StructField, len(names))
@@ -1048,9 +786,11 @@
return ret
}
+ // Create a type that contains the properties in this shard repeated for each
+ // architecture, architecture variant, and architecture feature.
archFields := make([]reflect.StructField, len(archTypeList))
for i, arch := range archTypeList {
- variants := []string{}
+ var variants []string
for _, archVariant := range archVariants[arch] {
archVariant := variantReplacer.Replace(archVariant)
@@ -1061,8 +801,13 @@
variants = append(variants, proptools.FieldNameForProperty(feature))
}
+ // Create the StructFields for each architecture variant architecture feature
+ // (e.g. "arch.arm.cortex-a53" or "arch.arm.neon").
fields := variantFields(variants)
+ // Create the StructField for the architecture itself (e.g. "arch.arm"). The special
+ // "BlueprintEmbed" name is used by Blueprint to put the properties in the
+ // parent struct.
fields = append([]reflect.StructField{{
Name: "BlueprintEmbed",
Type: props,
@@ -1074,10 +819,15 @@
Type: reflect.StructOf(fields),
}
}
+
+ // Create the type of the "arch" property struct for this shard.
archType := reflect.StructOf(archFields)
+ // Create the type for the "multilib" property struct for this shard, containing the
+ // "multilib.lib32" and "multilib.lib64" property structs.
multilibType := reflect.StructOf(variantFields([]string{"Lib32", "Lib64"}))
+ // Start with a list of the special targets
targets := []string{
"Host",
"Android64",
@@ -1090,11 +840,14 @@
"Native_bridge",
}
for _, os := range OsTypeList {
+ // Add all the OSes.
targets = append(targets, os.Field)
+ // Add the OS/Arch combinations, e.g. "android_arm64".
for _, archType := range osArchTypeMap[os] {
targets = append(targets, os.Field+"_"+archType.Name)
+ // Also add the special "linux_<arch>" and "bionic_<arch>" property structs.
if os.Linux() {
target := "Linux_" + archType.Name
if !InList(target, targets) {
@@ -1110,8 +863,10 @@
}
}
+ // Create the type for the "target" property struct for this shard.
targetType := reflect.StructOf(variantFields(targets))
+ // Return a descriptor of the 3 runtime-created types.
ret = append(ret, archPropTypeDesc{
arch: reflect.PtrTo(archType),
multilib: reflect.PtrTo(multilibType),
@@ -1121,6 +876,11 @@
return ret
}
+// variantReplacer converts architecture variant or architecture feature names into names that
+// are valid for an Android.bp file.
+var variantReplacer = strings.NewReplacer("-", "_", ".", "_")
+
+// filterArchStruct returns true if the given field is an architecture specific property.
func filterArchStruct(field reflect.StructField, prefix string) (bool, reflect.StructField) {
if proptools.HasTag(field, "android", "arch_variant") {
// The arch_variant field isn't necessary past this point
@@ -1147,12 +907,17 @@
return false, field
}
+// archPropTypeMap contains a cache of the results of createArchPropTypeDesc for each type. It is
+// shared across all Contexts, but is constructed based only on compile-time information so there
+// is no risk of contaminating one Context with data from another.
var archPropTypeMap OncePer
-func InitArchModule(m Module) {
+// initArchModule adds the architecture-specific property structs to a Module.
+func initArchModule(m Module) {
base := m.base()
+ // Store the original list of top level property structs
base.generalProperties = m.GetProperties()
for _, properties := range base.generalProperties {
@@ -1169,10 +934,13 @@
propertiesValue.Interface()))
}
+ // Get or create the arch-specific property struct types for this property struct type.
archPropTypes := archPropTypeMap.Once(NewCustomOnceKey(t), func() interface{} {
return createArchPropTypeDesc(t)
}).([]archPropTypeDesc)
+ // Instantiate one of each arch-specific property struct type and add it to the
+ // properties for the Module.
var archProperties []interface{}
for _, t := range archPropTypes {
archProperties = append(archProperties, &archPropRoot{
@@ -1185,14 +953,18 @@
m.AddProperties(archProperties...)
}
+ // Update the list of properties that can be set by a defaults module or a call to
+ // AppendMatchingProperties or PrependMatchingProperties.
base.customizableProperties = m.GetProperties()
}
-var variantReplacer = strings.NewReplacer("-", "_", ".", "_")
-
+// appendProperties squashes properties from the given field of the given src property struct
+// into the dst property struct. Returns the reflect.Value of the field in the src property
+// struct to be used for further appendProperties calls on fields of that property struct.
func (m *ModuleBase) appendProperties(ctx BottomUpMutatorContext,
dst interface{}, src reflect.Value, field, srcPrefix string) reflect.Value {
+ // Step into non-nil pointers to structs in the src value.
if src.Kind() == reflect.Ptr {
if src.IsNil() {
return src
@@ -1200,18 +972,25 @@
src = src.Elem()
}
+ // Find the requested field in the src struct.
src = src.FieldByName(field)
if !src.IsValid() {
ctx.ModuleErrorf("field %q does not exist", srcPrefix)
return src
}
+ // Save the value of the field in the src struct to return.
ret := src
+ // If the value of the field is a struct (as opposed to a pointer to a struct) then step
+ // into the BlueprintEmbed field.
if src.Kind() == reflect.Struct {
src = src.FieldByName("BlueprintEmbed")
}
+ // order checks the `android:"variant_prepend"` tag to handle properties where the
+ // arch-specific value needs to come before the generic value, for example for lists of
+ // include directories.
order := func(property string,
dstField, srcField reflect.StructField,
dstValue, srcValue interface{}) (proptools.Order, error) {
@@ -1222,6 +1001,7 @@
}
}
+ // Squash the located property struct into the destination property struct.
err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, order)
if err != nil {
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
@@ -1234,7 +1014,8 @@
return ret
}
-// Rewrite the module's properties structs to contain os-specific values.
+// Squash the appropriate OS-specific property structs into the matching top level property structs
+// based on the CompileOS value that was annotated on the variant.
func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) {
os := m.commonProperties.CompileOS
@@ -1328,7 +1109,8 @@
}
}
-// Rewrite the module's properties structs to contain arch-specific values.
+// Squash the appropriate arch-specific property structs into the matching top level property
+// structs based on the CompileTarget value that was annotated on the variant.
func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) {
arch := m.Arch()
os := m.Os()
@@ -1480,22 +1262,7 @@
}
}
-func forEachInterface(v reflect.Value, f func(reflect.Value)) {
- switch v.Kind() {
- case reflect.Interface:
- f(v)
- case reflect.Struct:
- for i := 0; i < v.NumField(); i++ {
- forEachInterface(v.Field(i), f)
- }
- case reflect.Ptr:
- forEachInterface(v.Elem(), f)
- default:
- panic(fmt.Errorf("Unsupported kind %s", v.Kind()))
- }
-}
-
-// Convert the arch product variables into a list of targets for each os class structs
+// Convert the arch product variables into a list of targets for each OsType.
func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) {
variables := config.productVariables
@@ -1567,19 +1334,26 @@
return nil, fmt.Errorf("No host primary architecture set")
}
+ // The primary host target, which must always exist.
addTarget(BuildOs, *variables.HostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ // An optional secondary host target.
if variables.HostSecondaryArch != nil && *variables.HostSecondaryArch != "" {
addTarget(BuildOs, *variables.HostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
}
+ // An optional host target that uses the Bionic glibc runtime.
if Bool(config.Host_bionic) {
addTarget(LinuxBionic, "x86_64", nil, nil, nil, NativeBridgeDisabled, nil, nil)
}
+
+ // An optional cross-compiled host target that uses the Bionic glibc runtime on an arm64
+ // architecture.
if Bool(config.Host_bionic_arm64) {
addTarget(LinuxBionic, "arm64", nil, nil, nil, NativeBridgeDisabled, nil, nil)
}
+ // Optional cross-compiled host targets, generally Windows.
if String(variables.CrossHost) != "" {
crossHostOs := osByName(*variables.CrossHost)
if crossHostOs == NoOsType {
@@ -1590,28 +1364,34 @@
return nil, fmt.Errorf("No cross-host primary architecture set")
}
+ // The primary cross-compiled host target.
addTarget(crossHostOs, *variables.CrossHostArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
+ // An optional secondary cross-compiled host target.
if variables.CrossHostSecondaryArch != nil && *variables.CrossHostSecondaryArch != "" {
addTarget(crossHostOs, *variables.CrossHostSecondaryArch, nil, nil, nil, NativeBridgeDisabled, nil, nil)
}
}
+ // Optional device targets
if variables.DeviceArch != nil && *variables.DeviceArch != "" {
var target = Android
if Bool(variables.Fuchsia) {
target = Fuchsia
}
+ // The primary device target.
addTarget(target, *variables.DeviceArch, variables.DeviceArchVariant,
variables.DeviceCpuVariant, variables.DeviceAbi, NativeBridgeDisabled, nil, nil)
+ // An optional secondary device target.
if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" {
addTarget(Android, *variables.DeviceSecondaryArch,
variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
variables.DeviceSecondaryAbi, NativeBridgeDisabled, nil, nil)
}
+ // An optional NativeBridge device target.
if variables.NativeBridgeArch != nil && *variables.NativeBridgeArch != "" {
addTarget(Android, *variables.NativeBridgeArch,
variables.NativeBridgeArchVariant, variables.NativeBridgeCpuVariant,
@@ -1619,6 +1399,7 @@
variables.NativeBridgeRelativePath)
}
+ // An optional secondary NativeBridge device target.
if variables.DeviceSecondaryArch != nil && *variables.DeviceSecondaryArch != "" &&
variables.NativeBridgeSecondaryArch != nil && *variables.NativeBridgeSecondaryArch != "" {
addTarget(Android, *variables.NativeBridgeSecondaryArch,
@@ -1653,6 +1434,7 @@
return false
}
+// archConfig describes a built-in configuration.
type archConfig struct {
arch string
archVariant string
@@ -1660,6 +1442,7 @@
abi []string
}
+// getMegaDeviceConfig returns a list of archConfigs for every architecture simultaneously.
func getMegaDeviceConfig() []archConfig {
return []archConfig{
{"arm", "armv7-a", "generic", []string{"armeabi-v7a"}},
@@ -1706,6 +1489,7 @@
}
}
+// getNdkAbisConfig returns a list of archConfigs for the ABIs supported by the NDK.
func getNdkAbisConfig() []archConfig {
return []archConfig{
{"arm", "armv7-a", "", []string{"armeabi-v7a"}},
@@ -1715,6 +1499,7 @@
}
}
+// getAmlAbisConfig returns a list of archConfigs for the ABIs supported by mainline modules.
func getAmlAbisConfig() []archConfig {
return []archConfig{
{"arm", "armv7-a-neon", "", []string{"armeabi-v7a"}},
@@ -1724,6 +1509,7 @@
}
}
+// decodeArchSettings converts a list of archConfigs into a list of Targets for the given OsType.
func decodeArchSettings(os OsType, archConfigs []archConfig) ([]Target, error) {
var ret []Target
@@ -1743,15 +1529,9 @@
return ret, nil
}
-// Convert a set of strings from product variables into a single Arch struct
+// decodeArch converts a set of strings from product variables into an Arch struct.
func decodeArch(os OsType, arch string, archVariant, cpuVariant *string, abi []string) (Arch, error) {
- stringPtr := func(p *string) string {
- if p != nil {
- return *p
- }
- return ""
- }
-
+ // Verify the arch is valid
archType, ok := archTypeMap[arch]
if !ok {
return Arch{}, fmt.Errorf("unknown arch %q", arch)
@@ -1759,19 +1539,22 @@
a := Arch{
ArchType: archType,
- ArchVariant: stringPtr(archVariant),
- CpuVariant: stringPtr(cpuVariant),
+ ArchVariant: String(archVariant),
+ CpuVariant: String(cpuVariant),
Abi: abi,
}
+ // Convert generic arch variants into the empty string.
if a.ArchVariant == a.ArchType.Name || a.ArchVariant == "generic" {
a.ArchVariant = ""
}
+ // Convert generic CPU variants into the empty string.
if a.CpuVariant == a.ArchType.Name || a.CpuVariant == "generic" {
a.CpuVariant = ""
}
+ // Filter empty ABIs out of the list.
for i := 0; i < len(a.Abi); i++ {
if a.Abi[i] == "" {
a.Abi = append(a.Abi[:i], a.Abi[i+1:]...)
@@ -1780,10 +1563,12 @@
}
if a.ArchVariant == "" {
+ // Set ArchFeatures from the default arch features.
if featureMap, ok := defaultArchFeatureMap[os]; ok {
a.ArchFeatures = featureMap[archType]
}
} else {
+ // Set ArchFeatures from the arch type.
if featureMap, ok := archFeatureMap[archType]; ok {
a.ArchFeatures = featureMap[a.ArchVariant]
}
@@ -1792,6 +1577,8 @@
return a, nil
}
+// filterMultilibTargets takes a list of Targets and a multilib value and returns a new list of
+// Targets containing only those that have the given multilib value.
func filterMultilibTargets(targets []Target, multilib string) []Target {
var ret []Target
for _, t := range targets {
@@ -1802,8 +1589,8 @@
return ret
}
-// Return the set of Os specific common architecture targets for each Os in a list of
-// targets.
+// getCommonTargets returns the set of Os specific common architecture targets for each Os in a list
+// of targets.
func getCommonTargets(targets []Target) []Target {
var ret []Target
set := make(map[string]bool)
@@ -1818,6 +1605,9 @@
return ret
}
+// firstTarget takes a list of Targets and a list of multilib values and returns a list of Targets
+// that contains zero or one Target for each OsType, selecting the one that matches the earliest
+// filter.
func firstTarget(targets []Target, filters ...string) []Target {
// find the first target from each OS
var ret []Target
@@ -1837,9 +1627,10 @@
return ret
}
-// Use the module multilib setting to select one or more targets from a target list
+// decodeMultilibTargets uses the module's multilib setting to select one or more targets from a
+// list of Targets.
func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([]Target, error) {
- buildTargets := []Target{}
+ var buildTargets []Target
switch multilib {
case "common":
diff --git a/android/arch_list.go b/android/arch_list.go
new file mode 100644
index 0000000..0c33b9d
--- /dev/null
+++ b/android/arch_list.go
@@ -0,0 +1,410 @@
+// Copyright 2020 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import "fmt"
+
+var archVariants = map[ArchType][]string{
+ Arm: {
+ "armv7-a",
+ "armv7-a-neon",
+ "armv8-a",
+ "armv8-2a",
+ "cortex-a7",
+ "cortex-a8",
+ "cortex-a9",
+ "cortex-a15",
+ "cortex-a53",
+ "cortex-a53-a57",
+ "cortex-a55",
+ "cortex-a72",
+ "cortex-a73",
+ "cortex-a75",
+ "cortex-a76",
+ "krait",
+ "kryo",
+ "kryo385",
+ "exynos-m1",
+ "exynos-m2",
+ },
+ Arm64: {
+ "armv8_a",
+ "armv8_2a",
+ "armv8-2a-dotprod",
+ "cortex-a53",
+ "cortex-a55",
+ "cortex-a72",
+ "cortex-a73",
+ "cortex-a75",
+ "cortex-a76",
+ "kryo",
+ "kryo385",
+ "exynos-m1",
+ "exynos-m2",
+ },
+ X86: {
+ "amberlake",
+ "atom",
+ "broadwell",
+ "haswell",
+ "icelake",
+ "ivybridge",
+ "kabylake",
+ "sandybridge",
+ "silvermont",
+ "skylake",
+ "stoneyridge",
+ "tigerlake",
+ "whiskeylake",
+ "x86_64",
+ },
+ X86_64: {
+ "amberlake",
+ "broadwell",
+ "haswell",
+ "icelake",
+ "ivybridge",
+ "kabylake",
+ "sandybridge",
+ "silvermont",
+ "skylake",
+ "stoneyridge",
+ "tigerlake",
+ "whiskeylake",
+ },
+}
+
+var archFeatures = map[ArchType][]string{
+ Arm: {
+ "neon",
+ },
+ Arm64: {
+ "dotprod",
+ },
+ X86: {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "avx2",
+ "avx512",
+ "popcnt",
+ "movbe",
+ },
+ X86_64: {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "avx2",
+ "avx512",
+ "popcnt",
+ },
+}
+
+var archFeatureMap = map[ArchType]map[string][]string{
+ Arm: {
+ "armv7-a-neon": {
+ "neon",
+ },
+ "armv8-a": {
+ "neon",
+ },
+ "armv8-2a": {
+ "neon",
+ },
+ },
+ Arm64: {
+ "armv8-2a-dotprod": {
+ "dotprod",
+ },
+ },
+ X86: {
+ "amberlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "atom": {
+ "ssse3",
+ "movbe",
+ },
+ "broadwell": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "haswell": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "popcnt",
+ "movbe",
+ },
+ "icelake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "ivybridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "popcnt",
+ },
+ "kabylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "sandybridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "popcnt",
+ },
+ "silvermont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ "movbe",
+ },
+ "skylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "stoneyridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "avx2",
+ "popcnt",
+ "movbe",
+ },
+ "tigerlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "whiskeylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "x86_64": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "popcnt",
+ },
+ },
+ X86_64: {
+ "amberlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "broadwell": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "haswell": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "popcnt",
+ },
+ "icelake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "ivybridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "popcnt",
+ },
+ "kabylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "aes_ni",
+ "popcnt",
+ },
+ "sandybridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "popcnt",
+ },
+ "silvermont": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "popcnt",
+ },
+ "skylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "stoneyridge": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "aes_ni",
+ "avx",
+ "avx2",
+ "popcnt",
+ },
+ "tigerlake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ "whiskeylake": {
+ "ssse3",
+ "sse4",
+ "sse4_1",
+ "sse4_2",
+ "avx",
+ "avx2",
+ "avx512",
+ "aes_ni",
+ "popcnt",
+ },
+ },
+}
+
+var defaultArchFeatureMap = map[OsType]map[ArchType][]string{}
+
+// RegisterDefaultArchVariantFeatures is called by files that define Toolchains to specify the
+// arch features that are available for the default arch variant. It must be called from an
+// init() function.
+func RegisterDefaultArchVariantFeatures(os OsType, arch ArchType, features ...string) {
+ checkCalledFromInit()
+
+ for _, feature := range features {
+ if !InList(feature, archFeatures[arch]) {
+ panic(fmt.Errorf("Invalid feature %q for arch %q variant \"\"", feature, arch))
+ }
+ }
+
+ if defaultArchFeatureMap[os] == nil {
+ defaultArchFeatureMap[os] = make(map[ArchType][]string)
+ }
+ defaultArchFeatureMap[os][arch] = features
+}
diff --git a/android/defaults.go b/android/defaults.go
index eb013d7..44753ce 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -183,7 +183,7 @@
initAndroidModuleBase(module)
initProductVariableModule(module)
- InitArchModule(module)
+ initArchModule(module)
InitDefaultableModule(module)
// Add properties that will not have defaults applied to them.
diff --git a/android/module.go b/android/module.go
index eeb4fae..6b659d2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -717,7 +717,9 @@
DebugMutators []string `blueprint:"mutated"`
DebugVariations []string `blueprint:"mutated"`
- // set by ImageMutator
+ // ImageVariation is set by ImageMutator to specify which image this variation is for,
+ // for example "" for core or "recovery" for recovery. It will often be set to one of the
+ // constants in image.go, but can also be set to a custom value by individual module types.
ImageVariation string `blueprint:"mutated"`
}
@@ -825,6 +827,8 @@
m.base().module = m
}
+// InitAndroidModule initializes the Module as an Android module that is not architecture-specific.
+// It adds the common properties, for example "name" and "enabled".
func InitAndroidModule(m Module) {
initAndroidModuleBase(m)
base := m.base()
@@ -844,6 +848,12 @@
setPrimaryVisibilityProperty(m, "visibility", &base.commonProperties.Visibility)
}
+// InitAndroidArchModule initializes the Module as an Android module that is architecture-specific.
+// It adds the common properties, for example "name" and "enabled", as well as runtime generated
+// property structs for architecture-specific versions of generic properties tagged with
+// `android:"arch_variant"`.
+//
+// InitAndroidModule should not be called if InitAndroidArchModule was called.
func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
InitAndroidModule(m)
@@ -857,16 +867,33 @@
m.AddProperties(&base.hostAndDeviceProperties)
}
- InitArchModule(m)
+ initArchModule(m)
}
+// InitAndroidMultiTargetsArchModule initializes the Module as an Android module that is
+// architecture-specific, but will only have a single variant per OS that handles all the
+// architectures simultaneously. The list of Targets that it must handle will be available from
+// ModuleContext.MultiTargets. It adds the common properties, for example "name" and "enabled", as
+// well as runtime generated property structs for architecture-specific versions of generic
+// properties tagged with `android:"arch_variant"`.
+//
+// InitAndroidModule or InitAndroidArchModule should not be called if
+// InitAndroidMultiTargetsArchModule was called.
func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
InitAndroidArchModule(m, hod, defaultMultilib)
m.base().commonProperties.UseTargetVariants = false
}
-// As InitAndroidMultiTargetsArchModule except it creates an additional CommonOS variant that
-// has dependencies on all the OsType specific variants.
+// InitCommonOSAndroidMultiTargetsArchModule initializes the Module as an Android module that is
+// architecture-specific, but will only have a single variant per OS that handles all the
+// architectures simultaneously, and will also have an additional CommonOS variant that has
+// dependencies on all the OS-specific variants. The list of Targets that it must handle will be
+// available from ModuleContext.MultiTargets. It adds the common properties, for example "name" and
+// "enabled", as well as runtime generated property structs for architecture-specific versions of
+// generic properties tagged with `android:"arch_variant"`.
+//
+// InitAndroidModule, InitAndroidArchModule or InitAndroidMultiTargetsArchModule should not be
+// called if InitCommonOSAndroidMultiTargetsArchModule was called.
func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
InitAndroidArchModule(m, hod, defaultMultilib)
m.base().commonProperties.UseTargetVariants = false
diff --git a/androidmk/androidmk/androidmk.go b/androidmk/androidmk/androidmk.go
index 03cf74d..f4e5fa0 100644
--- a/androidmk/androidmk/androidmk.go
+++ b/androidmk/androidmk/androidmk.go
@@ -137,7 +137,14 @@
switch x := node.(type) {
case *mkparser.Comment:
- file.insertComment("//" + x.Comment)
+ // Split the comment on escaped newlines and then
+ // add each chunk separately.
+ chunks := strings.Split(x.Comment, "\\\n")
+ file.insertComment("//" + chunks[0])
+ for i := 1; i < len(chunks); i++ {
+ file.bpPos.Line++
+ file.insertComment("//" + chunks[i])
+ }
case *mkparser.Assignment:
handleAssignment(file, x, assignmentCond)
case *mkparser.Directive:
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 16cb138..f32ff2a 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1260,10 +1260,10 @@
desc: "comment with ESC",
in: `
# Comment line 1 \
-# Comment line 2
+ Comment line 2
`,
expected: `
-// Comment line 1 \
+// Comment line 1
// Comment line 2
`,
},
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index e61241b..c14910a 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -497,12 +497,6 @@
switch p.tok {
case '\\':
p.parseEscape()
- if p.tok == '\n' {
- // Special case: '\' does not "escape" newline in comment (b/127521510)
- comment += "\\"
- p.accept(p.tok)
- break loop
- }
comment += "\\" + p.scanner.TokenText()
p.accept(p.tok)
case '\n':
diff --git a/apex/apex.go b/apex/apex.go
index 91770f4..ce323ca 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -33,19 +33,456 @@
"android/soong/sh"
)
+func init() {
+ android.RegisterModuleType("apex", BundleFactory)
+ android.RegisterModuleType("apex_test", testApexBundleFactory)
+ android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
+ android.RegisterModuleType("apex_defaults", defaultsFactory)
+ android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
+ android.RegisterModuleType("override_apex", overrideApexFactory)
+ android.RegisterModuleType("apex_set", apexSetFactory)
+
+ android.PreDepsMutators(RegisterPreDepsMutators)
+ android.PostDepsMutators(RegisterPostDepsMutators)
+}
+
+func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
+ ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
+}
+
+func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
+ ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
+ ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
+ ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
+ ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
+ ctx.BottomUp("apex", apexMutator).Parallel()
+ ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
+ ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
+ ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
+}
+
+type apexBundleProperties struct {
+ // Json manifest file describing meta info of this APEX bundle. Default:
+ // "apex_manifest.json"
+ Manifest *string `android:"path"`
+
+ // AndroidManifest.xml file used for the zip container of this APEX bundle.
+ // If unspecified, a default one is automatically generated.
+ AndroidManifest *string `android:"path"`
+
+ // Canonical name of the APEX bundle. Used to determine the path to the activated APEX on
+ // device (/apex/<apex_name>).
+ // If unspecified, defaults to the value of name.
+ Apex_name *string
+
+ // Determines the file contexts file for setting security context to each file in this APEX bundle.
+ // For platform APEXes, this should points to a file under /system/sepolicy
+ // Default: /system/sepolicy/apex/<module_name>_file_contexts.
+ File_contexts *string `android:"path"`
+
+ ApexNativeDependencies
+
+ // List of java libraries that are embedded inside this APEX bundle
+ Java_libs []string
+
+ // List of prebuilt files that are embedded inside this APEX bundle
+ Prebuilts []string
+
+ // List of BPF programs inside APEX
+ Bpfs []string
+
+ // Name of the apex_key module that provides the private key to sign APEX
+ Key *string
+
+ // The type of APEX to build. Controls what the APEX payload is. Either
+ // 'image', 'zip' or 'both'. Default: 'image'.
+ Payload_type *string
+
+ // The name of a certificate in the default certificate directory, blank to use the default product certificate,
+ // or an android_app_certificate module name in the form ":module".
+ Certificate *string
+
+ // Whether this APEX is installable to one of the partitions. Default: true.
+ Installable *bool
+
+ // For native libraries and binaries, use the vendor variant instead of the core (platform) variant.
+ // Default is false.
+ Use_vendor *bool
+
+ // For telling the apex to ignore special handling for system libraries such as bionic. Default is false.
+ Ignore_system_library_special_case *bool
+
+ Multilib apexMultilibProperties
+
+ // List of sanitizer names that this APEX is enabled for
+ SanitizerNames []string `blueprint:"mutated"`
+
+ PreventInstall bool `blueprint:"mutated"`
+
+ HideFromMake bool `blueprint:"mutated"`
+
+ // package format of this apex variant; could be non-flattened, flattened, or zip.
+ // imageApex, zipApex or flattened
+ ApexType apexPackaging `blueprint:"mutated"`
+
+ // List of SDKs that are used to build this APEX. A reference to an SDK should be either
+ // `name#version` or `name` which is an alias for `name#current`. If left empty, `platform#current`
+ // is implied. This value affects all modules included in this APEX. In other words, they are
+ // also built with the SDKs specified here.
+ Uses_sdks []string
+
+ // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
+ // Should be only used in tests#.
+ Test_only_no_hashtree *bool
+
+ // Whenever apex_payload.img of the APEX should not be dm-verity signed.
+ // Should be only used in tests#.
+ Test_only_unsigned_payload *bool
+
+ IsCoverageVariant bool `blueprint:"mutated"`
+
+ // Whether this APEX is considered updatable or not. When set to true, this will enforce additional
+ // rules for making sure that the APEX is truly updatable.
+ // - To be updatable, min_sdk_version should be set as well
+ // This will also disable the size optimizations like symlinking to the system libs.
+ // Default is false.
+ Updatable *bool
+
+ // The minimum SDK version that this apex must be compatibile with.
+ Min_sdk_version *string
+
+ // If set true, VNDK libs are considered as stable libs and are not included in this apex.
+ // Should be only used in non-system apexes (e.g. vendor: true).
+ // Default is false.
+ Use_vndk_as_stable *bool
+
+ // The type of filesystem to use for an image apex. Either 'ext4' or 'f2fs'.
+ // Default 'ext4'.
+ Payload_fs_type *string
+}
+
+type ApexNativeDependencies struct {
+ // List of native libraries
+ Native_shared_libs []string
+
+ // List of JNI libraries
+ Jni_libs []string
+
+ // List of native executables
+ Binaries []string
+
+ // List of native tests
+ Tests []string
+}
+
+type apexMultilibProperties struct {
+ // Native dependencies whose compile_multilib is "first"
+ First ApexNativeDependencies
+
+ // Native dependencies whose compile_multilib is "both"
+ Both ApexNativeDependencies
+
+ // Native dependencies whose compile_multilib is "prefer32"
+ Prefer32 ApexNativeDependencies
+
+ // Native dependencies whose compile_multilib is "32"
+ Lib32 ApexNativeDependencies
+
+ // Native dependencies whose compile_multilib is "64"
+ Lib64 ApexNativeDependencies
+}
+
+type apexTargetBundleProperties struct {
+ Target struct {
+ // Multilib properties only for android.
+ Android struct {
+ Multilib apexMultilibProperties
+ }
+
+ // Multilib properties only for host.
+ Host struct {
+ Multilib apexMultilibProperties
+ }
+
+ // Multilib properties only for host linux_bionic.
+ Linux_bionic struct {
+ Multilib apexMultilibProperties
+ }
+
+ // Multilib properties only for host linux_glibc.
+ Linux_glibc struct {
+ Multilib apexMultilibProperties
+ }
+ }
+}
+
+type overridableProperties struct {
+ // List of APKs to package inside APEX
+ Apps []string
+
+ // List of runtime resource overlays (RROs) inside APEX
+ Rros []string
+
+ // Names of modules to be overridden. Listed modules can only be other binaries
+ // (in Make or Soong).
+ // This does not completely prevent installation of the overridden binaries, but if both
+ // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
+ // from PRODUCT_PACKAGES.
+ Overrides []string
+
+ // Logging Parent value
+ Logging_parent string
+
+ // Apex Container Package Name.
+ // Override value for attribute package:name in AndroidManifest.xml
+ Package_name string
+
+ // A txt file containing list of files that are allowed to be included in this APEX.
+ Allowed_files *string `android:"path"`
+}
+
+type apexBundle struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ android.OverridableModuleBase
+ android.SdkBase
+
+ properties apexBundleProperties
+ targetProperties apexTargetBundleProperties
+ overridableProperties overridableProperties
+
+ // specific to apex_vndk modules
+ vndkProperties apexVndkProperties
+
+ bundleModuleFile android.WritablePath
+ outputFile android.WritablePath
+ installDir android.InstallPath
+
+ prebuiltFileToDelete string
+
+ public_key_file android.Path
+ private_key_file android.Path
+
+ container_certificate_file android.Path
+ container_private_key_file android.Path
+
+ fileContexts android.WritablePath
+
+ // list of files to be included in this apex
+ filesInfo []apexFile
+
+ // list of module names that should be installed along with this APEX
+ requiredDeps []string
+
+ // list of module names that this APEX is including (to be shown via *-deps-info target)
+ android.ApexBundleDepsInfo
+
+ testApex bool
+ vndkApex bool
+ artApex bool
+ primaryApexType bool
+
+ manifestJsonOut android.WritablePath
+ manifestPbOut android.WritablePath
+
+ // list of commands to create symlinks for backward compatibility.
+ // these commands will be attached as LOCAL_POST_INSTALL_CMD to
+ // apex package itself(for unflattened build) or apex_manifest(for flattened build)
+ // so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
+ compatSymlinks []string
+
+ // Suffix of module name in Android.mk
+ // ".flattened", ".apex", ".zipapex", or ""
+ suffix string
+
+ installedFilesFile android.WritablePath
+
+ // Whether to create symlink to the system file instead of having a file
+ // inside the apex or not
+ linkToSystemLib bool
+
+ // Struct holding the merged notice file paths in different formats
+ mergedNotices android.NoticeOutputs
+
+ // Optional list of lint report zip files for apexes that contain java or app modules
+ lintReports android.Paths
+
+ payloadFsType fsType
+
+ distFiles android.TaggedDistFiles
+}
+
+type apexFileClass int
+
const (
- imageApexSuffix = ".apex"
- zipApexSuffix = ".zipapex"
- flattenedSuffix = ".flattened"
-
- imageApexType = "image"
- zipApexType = "zip"
- flattenedApexType = "flattened"
-
- ext4FsType = "ext4"
- f2fsFsType = "f2fs"
+ etc apexFileClass = iota
+ nativeSharedLib
+ nativeExecutable
+ shBinary
+ pyBinary
+ goBinary
+ javaSharedLib
+ nativeTest
+ app
+ appSet
)
+func (class apexFileClass) NameInMake() string {
+ switch class {
+ case etc:
+ return "ETC"
+ case nativeSharedLib:
+ return "SHARED_LIBRARIES"
+ case nativeExecutable, shBinary, pyBinary, goBinary:
+ return "EXECUTABLES"
+ case javaSharedLib:
+ return "JAVA_LIBRARIES"
+ case nativeTest:
+ return "NATIVE_TESTS"
+ case app, appSet:
+ // b/142537672 Why isn't this APP? We want to have full control over
+ // the paths and file names of the apk file under the flattend APEX.
+ // If this is set to APP, then the paths and file names are modified
+ // by the Make build system. For example, it is installed to
+ // /system/apex/<apexname>/app/<Appname>/<apexname>.<Appname>/ instead of
+ // /system/apex/<apexname>/app/<Appname> because the build system automatically
+ // appends module name (which is <apexname>.<Appname> to the path.
+ return "ETC"
+ default:
+ panic(fmt.Errorf("unknown class %d", class))
+ }
+}
+
+// apexFile represents a file in an APEX bundle
+type apexFile struct {
+ builtFile android.Path
+ stem string
+ // Module name of `module` in AndroidMk. Note the generated AndroidMk module for
+ // apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>]
+ androidMkModuleName string
+ installDir string
+ class apexFileClass
+ module android.Module
+ // list of symlinks that will be created in installDir that point to this apexFile
+ symlinks []string
+ dataPaths []android.DataPath
+ transitiveDep bool
+ moduleDir string
+
+ requiredModuleNames []string
+ targetRequiredModuleNames []string
+ hostRequiredModuleNames []string
+
+ jacocoReportClassesFile android.Path // only for javalibs and apps
+ lintDepSets java.LintDepSets // only for javalibs and apps
+ certificate java.Certificate // only for apps
+ overriddenPackageName string // only for apps
+
+ isJniLib bool
+
+ noticeFiles android.Paths
+}
+
+func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
+ ret := apexFile{
+ builtFile: builtFile,
+ androidMkModuleName: androidMkModuleName,
+ installDir: installDir,
+ class: class,
+ module: module,
+ }
+ if module != nil {
+ ret.moduleDir = ctx.OtherModuleDir(module)
+ ret.requiredModuleNames = module.RequiredModuleNames()
+ ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
+ ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
+ ret.noticeFiles = module.NoticeFiles()
+ }
+ return ret
+}
+
+func (af *apexFile) Ok() bool {
+ return af.builtFile != nil && af.builtFile.String() != ""
+}
+
+func (af *apexFile) apexRelativePath(path string) string {
+ return filepath.Join(af.installDir, path)
+}
+
+// Path() returns path of this apex file relative to the APEX root
+func (af *apexFile) Path() string {
+ return af.apexRelativePath(af.Stem())
+}
+
+func (af *apexFile) Stem() string {
+ if af.stem != "" {
+ return af.stem
+ }
+ return af.builtFile.Base()
+}
+
+// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root
+func (af *apexFile) SymlinkPaths() []string {
+ var ret []string
+ for _, symlink := range af.symlinks {
+ ret = append(ret, af.apexRelativePath(symlink))
+ }
+ return ret
+}
+
+func (af *apexFile) AvailableToPlatform() bool {
+ if af.module == nil {
+ return false
+ }
+ if am, ok := af.module.(android.ApexModule); ok {
+ return am.AvailableFor(android.AvailableToPlatform)
+ }
+ return false
+}
+
+func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
+ nativeModules ApexNativeDependencies,
+ target android.Target, imageVariation string) {
+ // Use *FarVariation* to be able to depend on modules having
+ // conflicting variations with this module. This is required since
+ // arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64'
+ // for native shared libs.
+
+ binVariations := target.Variations()
+ libVariations := append(target.Variations(),
+ blueprint.Variation{Mutator: "link", Variation: "shared"})
+
+ if ctx.Device() {
+ binVariations = append(binVariations,
+ blueprint.Variation{Mutator: "image", Variation: imageVariation})
+ libVariations = append(libVariations,
+ blueprint.Variation{Mutator: "image", Variation: imageVariation},
+ blueprint.Variation{Mutator: "version", Variation: ""}) // "" is the non-stub variant
+ }
+
+ ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
+
+ ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
+
+ ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
+
+ ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
+}
+
+func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
+ if ctx.Os().Class == android.Device {
+ proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
+ } else {
+ proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
+ if ctx.Os().Bionic() {
+ proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
+ } else {
+ proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
+ }
+ }
+}
+
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
@@ -67,704 +504,162 @@
rroTag = dependencyTag{name: "rro", payload: true}
bpfTag = dependencyTag{name: "bpf", payload: true}
testForTag = dependencyTag{name: "test for"}
-
- apexAvailBaseline = makeApexAvailableBaseline()
-
- inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
)
-// Transform the map of apex -> modules to module -> apexes.
-func invertApexBaseline(m map[string][]string) map[string][]string {
- r := make(map[string][]string)
- for apex, modules := range m {
- for _, module := range modules {
- r[module] = append(r[module], apex)
+func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) {
+ ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
+ }
+
+ targets := ctx.MultiTargets()
+ config := ctx.DeviceConfig()
+ imageVariation := a.getImageVariation(ctx)
+
+ a.combineProperties(ctx)
+
+ has32BitTarget := false
+ for _, target := range targets {
+ if target.Arch.ArchType.Multilib == "lib32" {
+ has32BitTarget = true
}
}
- return r
-}
+ for i, target := range targets {
+ if target.HostCross {
+ // Don't include artifats for the host cross targets because there is no way
+ // for us to run those artifacts natively on host
+ continue
+ }
-// Retrieve the baseline of apexes to which the supplied module belongs.
-func BaselineApexAvailable(moduleName string) []string {
- return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
-}
+ // When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies
+ // multilib.both
+ addDependenciesForNativeModules(ctx,
+ ApexNativeDependencies{
+ Native_shared_libs: a.properties.Native_shared_libs,
+ Tests: a.properties.Tests,
+ Jni_libs: a.properties.Jni_libs,
+ Binaries: nil,
+ },
+ target, imageVariation)
-// This is a map from apex to modules, which overrides the
-// apex_available setting for that particular module to make
-// it available for the apex regardless of its setting.
-// TODO(b/147364041): remove this
-func makeApexAvailableBaseline() map[string][]string {
- // The "Module separator"s below are employed to minimize merge conflicts.
- m := make(map[string][]string)
- //
- // Module separator
- //
- m["com.android.appsearch"] = []string{
- "icing-java-proto-lite",
- "libprotobuf-java-lite",
- }
- //
- // Module separator
- //
- m["com.android.bluetooth.updatable"] = []string{
- "android.hardware.audio.common@5.0",
- "android.hardware.bluetooth.a2dp@1.0",
- "android.hardware.bluetooth.audio@2.0",
- "android.hardware.bluetooth@1.0",
- "android.hardware.bluetooth@1.1",
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hardware.graphics.bufferqueue@2.0",
- "android.hardware.graphics.common@1.0",
- "android.hardware.graphics.common@1.1",
- "android.hardware.graphics.common@1.2",
- "android.hardware.media@1.0",
- "android.hidl.safe_union@1.0",
- "android.hidl.token@1.0",
- "android.hidl.token@1.0-utils",
- "avrcp-target-service",
- "avrcp_headers",
- "bluetooth-protos-lite",
- "bluetooth.mapsapi",
- "com.android.vcard",
- "dnsresolver_aidl_interface-V2-java",
- "ipmemorystore-aidl-interfaces-V5-java",
- "ipmemorystore-aidl-interfaces-java",
- "internal_include_headers",
- "lib-bt-packets",
- "lib-bt-packets-avrcp",
- "lib-bt-packets-base",
- "libFraunhoferAAC",
- "libaudio-a2dp-hw-utils",
- "libaudio-hearing-aid-hw-utils",
- "libbinder_headers",
- "libbluetooth",
- "libbluetooth-types",
- "libbluetooth-types-header",
- "libbluetooth_gd",
- "libbluetooth_headers",
- "libbluetooth_jni",
- "libbt-audio-hal-interface",
- "libbt-bta",
- "libbt-common",
- "libbt-hci",
- "libbt-platform-protos-lite",
- "libbt-protos-lite",
- "libbt-sbc-decoder",
- "libbt-sbc-encoder",
- "libbt-stack",
- "libbt-utils",
- "libbtcore",
- "libbtdevice",
- "libbte",
- "libbtif",
- "libchrome",
- "libevent",
- "libfmq",
- "libg722codec",
- "libgui_headers",
- "libmedia_headers",
- "libmodpb64",
- "libosi",
- "libstagefright_foundation_headers",
- "libstagefright_headers",
- "libstatslog",
- "libstatssocket",
- "libtinyxml2",
- "libudrv-uipc",
- "libz",
- "media_plugin_headers",
- "net-utils-services-common",
- "netd_aidl_interface-unstable-java",
- "netd_event_listener_interface-java",
- "netlink-client",
- "networkstack-client",
- "sap-api-java-static",
- "services.net",
- }
- //
- // Module separator
- //
- m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
- //
- // Module separator
- //
- m["com.android.extservices"] = []string{
- "error_prone_annotations",
- "ExtServices-core",
- "ExtServices",
- "libtextclassifier-java",
- "libz_current",
- "textclassifier-statsd",
- "TextClassifierNotificationLibNoManifest",
- "TextClassifierServiceLibNoManifest",
- }
- //
- // Module separator
- //
- m["com.android.neuralnetworks"] = []string{
- "android.hardware.neuralnetworks@1.0",
- "android.hardware.neuralnetworks@1.1",
- "android.hardware.neuralnetworks@1.2",
- "android.hardware.neuralnetworks@1.3",
- "android.hidl.allocator@1.0",
- "android.hidl.memory.token@1.0",
- "android.hidl.memory@1.0",
- "android.hidl.safe_union@1.0",
- "libarect",
- "libbuildversion",
- "libmath",
- "libprocpartition",
- "libsync",
- }
- //
- // Module separator
- //
- m["com.android.media"] = []string{
- "android.frameworks.bufferhub@1.0",
- "android.hardware.cas.native@1.0",
- "android.hardware.cas@1.0",
- "android.hardware.configstore-utils",
- "android.hardware.configstore@1.0",
- "android.hardware.configstore@1.1",
- "android.hardware.graphics.allocator@2.0",
- "android.hardware.graphics.allocator@3.0",
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hardware.graphics.bufferqueue@2.0",
- "android.hardware.graphics.common@1.0",
- "android.hardware.graphics.common@1.1",
- "android.hardware.graphics.common@1.2",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@2.1",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.media.omx@1.0",
- "android.hardware.media@1.0",
- "android.hidl.allocator@1.0",
- "android.hidl.memory.token@1.0",
- "android.hidl.memory@1.0",
- "android.hidl.token@1.0",
- "android.hidl.token@1.0-utils",
- "bionic_libc_platform_headers",
- "exoplayer2-extractor",
- "exoplayer2-extractor-annotation-stubs",
- "gl_headers",
- "jsr305",
- "libEGL",
- "libEGL_blobCache",
- "libEGL_getProcAddress",
- "libFLAC",
- "libFLAC-config",
- "libFLAC-headers",
- "libGLESv2",
- "libaacextractor",
- "libamrextractor",
- "libarect",
- "libaudio_system_headers",
- "libaudioclient",
- "libaudioclient_headers",
- "libaudiofoundation",
- "libaudiofoundation_headers",
- "libaudiomanager",
- "libaudiopolicy",
- "libaudioutils",
- "libaudioutils_fixedfft",
- "libbinder_headers",
- "libbluetooth-types-header",
- "libbufferhub",
- "libbufferhub_headers",
- "libbufferhubqueue",
- "libc_malloc_debug_backtrace",
- "libcamera_client",
- "libcamera_metadata",
- "libdvr_headers",
- "libexpat",
- "libfifo",
- "libflacextractor",
- "libgrallocusage",
- "libgraphicsenv",
- "libgui",
- "libgui_headers",
- "libhardware_headers",
- "libinput",
- "liblzma",
- "libmath",
- "libmedia",
- "libmedia_codeclist",
- "libmedia_headers",
- "libmedia_helper",
- "libmedia_helper_headers",
- "libmedia_midiiowrapper",
- "libmedia_omx",
- "libmediautils",
- "libmidiextractor",
- "libmkvextractor",
- "libmp3extractor",
- "libmp4extractor",
- "libmpeg2extractor",
- "libnativebase_headers",
- "libnativewindow_headers",
- "libnblog",
- "liboggextractor",
- "libpackagelistparser",
- "libpdx",
- "libpdx_default_transport",
- "libpdx_headers",
- "libpdx_uds",
- "libprocinfo",
- "libspeexresampler",
- "libspeexresampler",
- "libstagefright_esds",
- "libstagefright_flacdec",
- "libstagefright_flacdec",
- "libstagefright_foundation",
- "libstagefright_foundation_headers",
- "libstagefright_foundation_without_imemory",
- "libstagefright_headers",
- "libstagefright_id3",
- "libstagefright_metadatautils",
- "libstagefright_mpeg2extractor",
- "libstagefright_mpeg2support",
- "libsync",
- "libui",
- "libui_headers",
- "libunwindstack",
- "libvibrator",
- "libvorbisidec",
- "libwavextractor",
- "libwebm",
- "media_ndk_headers",
- "media_plugin_headers",
- "updatable-media",
- }
- //
- // Module separator
- //
- m["com.android.media.swcodec"] = []string{
- "android.frameworks.bufferhub@1.0",
- "android.hardware.common-ndk_platform",
- "android.hardware.configstore-utils",
- "android.hardware.configstore@1.0",
- "android.hardware.configstore@1.1",
- "android.hardware.graphics.allocator@2.0",
- "android.hardware.graphics.allocator@3.0",
- "android.hardware.graphics.allocator@4.0",
- "android.hardware.graphics.bufferqueue@1.0",
- "android.hardware.graphics.bufferqueue@2.0",
- "android.hardware.graphics.common-ndk_platform",
- "android.hardware.graphics.common@1.0",
- "android.hardware.graphics.common@1.1",
- "android.hardware.graphics.common@1.2",
- "android.hardware.graphics.mapper@2.0",
- "android.hardware.graphics.mapper@2.1",
- "android.hardware.graphics.mapper@3.0",
- "android.hardware.graphics.mapper@4.0",
- "android.hardware.media.bufferpool@2.0",
- "android.hardware.media.c2@1.0",
- "android.hardware.media.c2@1.1",
- "android.hardware.media.omx@1.0",
- "android.hardware.media@1.0",
- "android.hardware.media@1.0",
- "android.hidl.memory.token@1.0",
- "android.hidl.memory@1.0",
- "android.hidl.safe_union@1.0",
- "android.hidl.token@1.0",
- "android.hidl.token@1.0-utils",
- "libEGL",
- "libFLAC",
- "libFLAC-config",
- "libFLAC-headers",
- "libFraunhoferAAC",
- "libLibGuiProperties",
- "libarect",
- "libaudio_system_headers",
- "libaudioutils",
- "libaudioutils",
- "libaudioutils_fixedfft",
- "libavcdec",
- "libavcenc",
- "libavservices_minijail",
- "libavservices_minijail",
- "libbinder_headers",
- "libbinderthreadstateutils",
- "libbluetooth-types-header",
- "libbufferhub_headers",
- "libcodec2",
- "libcodec2_headers",
- "libcodec2_hidl@1.0",
- "libcodec2_hidl@1.1",
- "libcodec2_internal",
- "libcodec2_soft_aacdec",
- "libcodec2_soft_aacenc",
- "libcodec2_soft_amrnbdec",
- "libcodec2_soft_amrnbenc",
- "libcodec2_soft_amrwbdec",
- "libcodec2_soft_amrwbenc",
- "libcodec2_soft_av1dec_gav1",
- "libcodec2_soft_avcdec",
- "libcodec2_soft_avcenc",
- "libcodec2_soft_common",
- "libcodec2_soft_flacdec",
- "libcodec2_soft_flacenc",
- "libcodec2_soft_g711alawdec",
- "libcodec2_soft_g711mlawdec",
- "libcodec2_soft_gsmdec",
- "libcodec2_soft_h263dec",
- "libcodec2_soft_h263enc",
- "libcodec2_soft_hevcdec",
- "libcodec2_soft_hevcenc",
- "libcodec2_soft_mp3dec",
- "libcodec2_soft_mpeg2dec",
- "libcodec2_soft_mpeg4dec",
- "libcodec2_soft_mpeg4enc",
- "libcodec2_soft_opusdec",
- "libcodec2_soft_opusenc",
- "libcodec2_soft_rawdec",
- "libcodec2_soft_vorbisdec",
- "libcodec2_soft_vp8dec",
- "libcodec2_soft_vp8enc",
- "libcodec2_soft_vp9dec",
- "libcodec2_soft_vp9enc",
- "libcodec2_vndk",
- "libdvr_headers",
- "libfmq",
- "libfmq",
- "libgav1",
- "libgralloctypes",
- "libgrallocusage",
- "libgraphicsenv",
- "libgsm",
- "libgui_bufferqueue_static",
- "libgui_headers",
- "libhardware",
- "libhardware_headers",
- "libhevcdec",
- "libhevcenc",
- "libion",
- "libjpeg",
- "liblzma",
- "libmath",
- "libmedia_codecserviceregistrant",
- "libmedia_headers",
- "libmpeg2dec",
- "libnativebase_headers",
- "libnativewindow_headers",
- "libpdx_headers",
- "libscudo_wrapper",
- "libsfplugin_ccodec_utils",
- "libspeexresampler",
- "libstagefright_amrnb_common",
- "libstagefright_amrnbdec",
- "libstagefright_amrnbenc",
- "libstagefright_amrwbdec",
- "libstagefright_amrwbenc",
- "libstagefright_bufferpool@2.0.1",
- "libstagefright_bufferqueue_helper",
- "libstagefright_enc_common",
- "libstagefright_flacdec",
- "libstagefright_foundation",
- "libstagefright_foundation_headers",
- "libstagefright_headers",
- "libstagefright_m4vh263dec",
- "libstagefright_m4vh263enc",
- "libstagefright_mp3dec",
- "libsync",
- "libui",
- "libui_headers",
- "libunwindstack",
- "libvorbisidec",
- "libvpx",
- "libyuv",
- "libyuv_static",
- "media_ndk_headers",
- "media_plugin_headers",
- "mediaswcodec",
- }
- //
- // Module separator
- //
- m["com.android.mediaprovider"] = []string{
- "MediaProvider",
- "MediaProviderGoogle",
- "fmtlib_ndk",
- "libbase_ndk",
- "libfuse",
- "libfuse_jni",
- }
- //
- // Module separator
- //
- m["com.android.permission"] = []string{
- "car-ui-lib",
- "iconloader",
- "kotlin-annotations",
- "kotlin-stdlib",
- "kotlin-stdlib-jdk7",
- "kotlin-stdlib-jdk8",
- "kotlinx-coroutines-android",
- "kotlinx-coroutines-android-nodeps",
- "kotlinx-coroutines-core",
- "kotlinx-coroutines-core-nodeps",
- "permissioncontroller-statsd",
- "GooglePermissionController",
- "PermissionController",
- "SettingsLibActionBarShadow",
- "SettingsLibAppPreference",
- "SettingsLibBarChartPreference",
- "SettingsLibLayoutPreference",
- "SettingsLibProgressBar",
- "SettingsLibSearchWidget",
- "SettingsLibSettingsTheme",
- "SettingsLibRestrictedLockUtils",
- "SettingsLibHelpUtils",
- }
- //
- // Module separator
- //
- m["com.android.runtime"] = []string{
- "bionic_libc_platform_headers",
- "libarm-optimized-routines-math",
- "libc_aeabi",
- "libc_bionic",
- "libc_bionic_ndk",
- "libc_bootstrap",
- "libc_common",
- "libc_common_shared",
- "libc_common_static",
- "libc_dns",
- "libc_dynamic_dispatch",
- "libc_fortify",
- "libc_freebsd",
- "libc_freebsd_large_stack",
- "libc_gdtoa",
- "libc_init_dynamic",
- "libc_init_static",
- "libc_jemalloc_wrapper",
- "libc_netbsd",
- "libc_nomalloc",
- "libc_nopthread",
- "libc_openbsd",
- "libc_openbsd_large_stack",
- "libc_openbsd_ndk",
- "libc_pthread",
- "libc_static_dispatch",
- "libc_syscalls",
- "libc_tzcode",
- "libc_unwind_static",
- "libdebuggerd",
- "libdebuggerd_common_headers",
- "libdebuggerd_handler_core",
- "libdebuggerd_handler_fallback",
- "libdl_static",
- "libjemalloc5",
- "liblinker_main",
- "liblinker_malloc",
- "liblz4",
- "liblzma",
- "libprocinfo",
- "libpropertyinfoparser",
- "libscudo",
- "libstdc++",
- "libsystemproperties",
- "libtombstoned_client_static",
- "libunwindstack",
- "libz",
- "libziparchive",
- }
- //
- // Module separator
- //
- m["com.android.tethering"] = []string{
- "android.hardware.tetheroffload.config-V1.0-java",
- "android.hardware.tetheroffload.control-V1.0-java",
- "android.hidl.base-V1.0-java",
- "libcgrouprc",
- "libcgrouprc_format",
- "libtetherutilsjni",
- "libvndksupport",
- "net-utils-framework-common",
- "netd_aidl_interface-V3-java",
- "netlink-client",
- "networkstack-aidl-interfaces-java",
- "tethering-aidl-interfaces-java",
- "TetheringApiCurrentLib",
- }
- //
- // Module separator
- //
- m["com.android.wifi"] = []string{
- "PlatformProperties",
- "android.hardware.wifi-V1.0-java",
- "android.hardware.wifi-V1.0-java-constants",
- "android.hardware.wifi-V1.1-java",
- "android.hardware.wifi-V1.2-java",
- "android.hardware.wifi-V1.3-java",
- "android.hardware.wifi-V1.4-java",
- "android.hardware.wifi.hostapd-V1.0-java",
- "android.hardware.wifi.hostapd-V1.1-java",
- "android.hardware.wifi.hostapd-V1.2-java",
- "android.hardware.wifi.supplicant-V1.0-java",
- "android.hardware.wifi.supplicant-V1.1-java",
- "android.hardware.wifi.supplicant-V1.2-java",
- "android.hardware.wifi.supplicant-V1.3-java",
- "android.hidl.base-V1.0-java",
- "android.hidl.manager-V1.0-java",
- "android.hidl.manager-V1.1-java",
- "android.hidl.manager-V1.2-java",
- "bouncycastle-unbundled",
- "dnsresolver_aidl_interface-V2-java",
- "error_prone_annotations",
- "framework-wifi-pre-jarjar",
- "framework-wifi-util-lib",
- "ipmemorystore-aidl-interfaces-V3-java",
- "ipmemorystore-aidl-interfaces-java",
- "ksoap2",
- "libnanohttpd",
- "libwifi-jni",
- "net-utils-services-common",
- "netd_aidl_interface-V2-java",
- "netd_aidl_interface-unstable-java",
- "netd_event_listener_interface-java",
- "netlink-client",
- "networkstack-client",
- "services.net",
- "wifi-lite-protos",
- "wifi-nano-protos",
- "wifi-service-pre-jarjar",
- "wifi-service-resources",
- }
- //
- // Module separator
- //
- m["com.android.sdkext"] = []string{
- "fmtlib_ndk",
- "libbase_ndk",
- "libprotobuf-cpp-lite-ndk",
- }
- //
- // Module separator
- //
- m["com.android.os.statsd"] = []string{
- "libstatssocket",
- }
- //
- // Module separator
- //
- m[android.AvailableToAnyApex] = []string{
- // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
- "androidx",
- "androidx-constraintlayout_constraintlayout",
- "androidx-constraintlayout_constraintlayout-nodeps",
- "androidx-constraintlayout_constraintlayout-solver",
- "androidx-constraintlayout_constraintlayout-solver-nodeps",
- "com.google.android.material_material",
- "com.google.android.material_material-nodeps",
+ // Add native modules targetting both ABIs
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.Both,
+ target,
+ imageVariation)
- "libatomic",
- "libclang_rt",
- "libgcc_stripped",
- "libprofile-clang-extras",
- "libprofile-clang-extras_ndk",
- "libprofile-extras",
- "libprofile-extras_ndk",
- "libunwind_llvm",
- }
- return m
-}
+ isPrimaryAbi := i == 0
+ if isPrimaryAbi {
+ // When multilib.* is omitted for binaries, it implies
+ // multilib.first
+ addDependenciesForNativeModules(ctx,
+ ApexNativeDependencies{
+ Native_shared_libs: nil,
+ Tests: nil,
+ Jni_libs: nil,
+ Binaries: a.properties.Binaries,
+ },
+ target, imageVariation)
-// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
-// Adding code to the bootclasspath in new packages will cause issues on module update.
-func qModulesPackages() map[string][]string {
- return map[string][]string{
- "com.android.conscrypt": []string{
- "android.net.ssl",
- "com.android.org.conscrypt",
- },
- "com.android.media": []string{
- "android.media",
- },
+ // Add native modules targetting the first ABI
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.First,
+ target,
+ imageVariation)
+ }
+
+ switch target.Arch.ArchType.Multilib {
+ case "lib32":
+ // Add native modules targetting 32-bit ABI
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.Lib32,
+ target,
+ imageVariation)
+
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.Prefer32,
+ target,
+ imageVariation)
+ case "lib64":
+ // Add native modules targetting 64-bit ABI
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.Lib64,
+ target,
+ imageVariation)
+
+ if !has32BitTarget {
+ addDependenciesForNativeModules(ctx,
+ a.properties.Multilib.Prefer32,
+ target,
+ imageVariation)
+ }
+ }
+ }
+
+ // For prebuilt_etc, use the first variant (64 on 64/32bit device,
+ // 32 on 32bit device) regardless of the TARGET_PREFER_* setting.
+ // b/144532908
+ archForPrebuiltEtc := config.Arches()[0]
+ for _, arch := range config.Arches() {
+ // Prefer 64-bit arch if there is any
+ if arch.ArchType.Multilib == "lib64" {
+ archForPrebuiltEtc = arch
+ break
+ }
+ }
+ ctx.AddFarVariationDependencies([]blueprint.Variation{
+ {Mutator: "os", Variation: ctx.Os().String()},
+ {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
+ }, prebuiltTag, a.properties.Prebuilts...)
+
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ javaLibTag, a.properties.Java_libs...)
+
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ bpfTag, a.properties.Bpfs...)
+
+ // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
+ if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ javaLibTag, "jacocoagent")
+ }
+
+ if String(a.properties.Key) == "" {
+ ctx.ModuleErrorf("key is missing")
+ return
+ }
+ ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
+
+ cert := android.SrcIsModule(a.getCertString(ctx))
+ if cert != "" {
+ ctx.AddDependency(ctx.Module(), certificateTag, cert)
+ }
+
+ // TODO(jiyong): ensure that all apexes are with non-empty uses_sdks
+ if len(a.properties.Uses_sdks) > 0 {
+ sdkRefs := []android.SdkRef{}
+ for _, str := range a.properties.Uses_sdks {
+ parsed := android.ParseSdkRef(ctx, str, "uses_sdks")
+ sdkRefs = append(sdkRefs, parsed)
+ }
+ a.BuildWithSdks(sdkRefs)
}
}
-// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
-// Adding code to the bootclasspath in new packages will cause issues on module update.
-func rModulesPackages() map[string][]string {
- return map[string][]string{
- "com.android.mediaprovider": []string{
- "android.provider",
- },
- "com.android.permission": []string{
- "android.permission",
- "android.app.role",
- "com.android.permission",
- "com.android.role",
- },
- "com.android.sdkext": []string{
- "android.os.ext",
- },
- "com.android.os.statsd": []string{
- "android.app",
- "android.os",
- "android.util",
- "com.android.internal.statsd",
- "com.android.server.stats",
- },
- "com.android.wifi": []string{
- "com.android.server.wifi",
- "com.android.wifi.x",
- "android.hardware.wifi",
- "android.net.wifi",
- },
- "com.android.tethering": []string{
- "android.net",
- },
+func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
+ if a.overridableProperties.Allowed_files != nil {
+ android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
}
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ androidAppTag, a.overridableProperties.Apps...)
+ ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
+ rroTag, a.overridableProperties.Rros...)
}
-func init() {
- android.RegisterModuleType("apex", BundleFactory)
- android.RegisterModuleType("apex_test", testApexBundleFactory)
- android.RegisterModuleType("apex_vndk", vndkApexBundleFactory)
- android.RegisterModuleType("apex_defaults", defaultsFactory)
- android.RegisterModuleType("prebuilt_apex", PrebuiltFactory)
- android.RegisterModuleType("override_apex", overrideApexFactory)
- android.RegisterModuleType("apex_set", apexSetFactory)
-
- android.PreDepsMutators(RegisterPreDepsMutators)
- android.PostDepsMutators(RegisterPostDepsMutators)
-
- android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
- android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
+type ApexBundleInfo struct {
+ Contents *android.ApexContents
}
-func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
- rules := make([]android.Rule, 0, len(modules_packages))
- for module_name, module_packages := range modules_packages {
- permitted_packages_rule := android.NeverAllow().
- BootclasspathJar().
- With("apex_available", module_name).
- WithMatcher("permitted_packages", android.NotInList(module_packages)).
- Because("jars that are part of the " + module_name +
- " module may only allow these packages: " + strings.Join(module_packages, ",") +
- ". Please jarjar or move code around.")
- rules = append(rules, permitted_packages_rule)
- }
- return rules
-}
-
-func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_vndk", apexVndkMutator).Parallel()
- ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel()
-}
-
-func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) {
- ctx.TopDown("apex_deps", apexDepsMutator).Parallel()
- ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel()
- ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel()
- ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel()
- ctx.BottomUp("apex", apexMutator).Parallel()
- ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel()
- ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel()
- ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel()
-}
+var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_deps")
// Mark the direct and transitive dependencies of apex bundles so that they
// can be built for the apex bundles.
@@ -967,6 +862,50 @@
}
}
+type apexPackaging int
+
+const (
+ imageApex apexPackaging = iota
+ zipApex
+ flattenedApex
+)
+
+const (
+ imageApexSuffix = ".apex"
+ zipApexSuffix = ".zipapex"
+ flattenedSuffix = ".flattened"
+
+ imageApexType = "image"
+ zipApexType = "zip"
+ flattenedApexType = "flattened"
+
+ ext4FsType = "ext4"
+ f2fsFsType = "f2fs"
+)
+
+// The suffix for the output "file", not the module
+func (a apexPackaging) suffix() string {
+ switch a {
+ case imageApex:
+ return imageApexSuffix
+ case zipApex:
+ return zipApexSuffix
+ default:
+ panic(fmt.Errorf("unknown APEX type %d", a))
+ }
+}
+
+func (a apexPackaging) name() string {
+ switch a {
+ case imageApex:
+ return imageApexType
+ case zipApex:
+ return zipApexType
+ default:
+ panic(fmt.Errorf("unknown APEX type %d", a))
+ }
+}
+
func apexFlattenedMutator(mctx android.BottomUpMutatorContext) {
if !mctx.Module().Enabled() {
return
@@ -1033,351 +972,6 @@
})
}
-type ApexNativeDependencies struct {
- // List of native libraries
- Native_shared_libs []string
-
- // List of JNI libraries
- Jni_libs []string
-
- // List of native executables
- Binaries []string
-
- // List of native tests
- Tests []string
-}
-
-type apexMultilibProperties struct {
- // Native dependencies whose compile_multilib is "first"
- First ApexNativeDependencies
-
- // Native dependencies whose compile_multilib is "both"
- Both ApexNativeDependencies
-
- // Native dependencies whose compile_multilib is "prefer32"
- Prefer32 ApexNativeDependencies
-
- // Native dependencies whose compile_multilib is "32"
- Lib32 ApexNativeDependencies
-
- // Native dependencies whose compile_multilib is "64"
- Lib64 ApexNativeDependencies
-}
-
-type apexBundleProperties struct {
- // Json manifest file describing meta info of this APEX bundle. Default:
- // "apex_manifest.json"
- Manifest *string `android:"path"`
-
- // AndroidManifest.xml file used for the zip container of this APEX bundle.
- // If unspecified, a default one is automatically generated.
- AndroidManifest *string `android:"path"`
-
- // Canonical name of the APEX bundle. Used to determine the path to the activated APEX on
- // device (/apex/<apex_name>).
- // If unspecified, defaults to the value of name.
- Apex_name *string
-
- // Determines the file contexts file for setting security context to each file in this APEX bundle.
- // For platform APEXes, this should points to a file under /system/sepolicy
- // Default: /system/sepolicy/apex/<module_name>_file_contexts.
- File_contexts *string `android:"path"`
-
- ApexNativeDependencies
-
- // List of java libraries that are embedded inside this APEX bundle
- Java_libs []string
-
- // List of prebuilt files that are embedded inside this APEX bundle
- Prebuilts []string
-
- // List of BPF programs inside APEX
- Bpfs []string
-
- // Name of the apex_key module that provides the private key to sign APEX
- Key *string
-
- // The type of APEX to build. Controls what the APEX payload is. Either
- // 'image', 'zip' or 'both'. Default: 'image'.
- Payload_type *string
-
- // The name of a certificate in the default certificate directory, blank to use the default product certificate,
- // or an android_app_certificate module name in the form ":module".
- Certificate *string
-
- // Whether this APEX is installable to one of the partitions. Default: true.
- Installable *bool
-
- // For native libraries and binaries, use the vendor variant instead of the core (platform) variant.
- // Default is false.
- Use_vendor *bool
-
- // For telling the apex to ignore special handling for system libraries such as bionic. Default is false.
- Ignore_system_library_special_case *bool
-
- Multilib apexMultilibProperties
-
- // List of sanitizer names that this APEX is enabled for
- SanitizerNames []string `blueprint:"mutated"`
-
- PreventInstall bool `blueprint:"mutated"`
-
- HideFromMake bool `blueprint:"mutated"`
-
- // package format of this apex variant; could be non-flattened, flattened, or zip.
- // imageApex, zipApex or flattened
- ApexType apexPackaging `blueprint:"mutated"`
-
- // List of SDKs that are used to build this APEX. A reference to an SDK should be either
- // `name#version` or `name` which is an alias for `name#current`. If left empty, `platform#current`
- // is implied. This value affects all modules included in this APEX. In other words, they are
- // also built with the SDKs specified here.
- Uses_sdks []string
-
- // Whenever apex_payload.img of the APEX should include dm-verity hashtree.
- // Should be only used in tests#.
- Test_only_no_hashtree *bool
-
- // Whenever apex_payload.img of the APEX should not be dm-verity signed.
- // Should be only used in tests#.
- Test_only_unsigned_payload *bool
-
- IsCoverageVariant bool `blueprint:"mutated"`
-
- // Whether this APEX is considered updatable or not. When set to true, this will enforce additional
- // rules for making sure that the APEX is truly updatable.
- // - To be updatable, min_sdk_version should be set as well
- // This will also disable the size optimizations like symlinking to the system libs.
- // Default is false.
- Updatable *bool
-
- // The minimum SDK version that this apex must be compatibile with.
- Min_sdk_version *string
-
- // If set true, VNDK libs are considered as stable libs and are not included in this apex.
- // Should be only used in non-system apexes (e.g. vendor: true).
- // Default is false.
- Use_vndk_as_stable *bool
-
- // The type of filesystem to use for an image apex. Either 'ext4' or 'f2fs'.
- // Default 'ext4'.
- Payload_fs_type *string
-}
-
-type ApexBundleInfo struct {
- Contents *android.ApexContents
-}
-
-var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_deps")
-
-type apexTargetBundleProperties struct {
- Target struct {
- // Multilib properties only for android.
- Android struct {
- Multilib apexMultilibProperties
- }
-
- // Multilib properties only for host.
- Host struct {
- Multilib apexMultilibProperties
- }
-
- // Multilib properties only for host linux_bionic.
- Linux_bionic struct {
- Multilib apexMultilibProperties
- }
-
- // Multilib properties only for host linux_glibc.
- Linux_glibc struct {
- Multilib apexMultilibProperties
- }
- }
-}
-
-type overridableProperties struct {
- // List of APKs to package inside APEX
- Apps []string
-
- // List of runtime resource overlays (RROs) inside APEX
- Rros []string
-
- // Names of modules to be overridden. Listed modules can only be other binaries
- // (in Make or Soong).
- // This does not completely prevent installation of the overridden binaries, but if both
- // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
- // from PRODUCT_PACKAGES.
- Overrides []string
-
- // Logging Parent value
- Logging_parent string
-
- // Apex Container Package Name.
- // Override value for attribute package:name in AndroidManifest.xml
- Package_name string
-
- // A txt file containing list of files that are allowed to be included in this APEX.
- Allowed_files *string `android:"path"`
-}
-
-type apexPackaging int
-
-const (
- imageApex apexPackaging = iota
- zipApex
- flattenedApex
-)
-
-// The suffix for the output "file", not the module
-func (a apexPackaging) suffix() string {
- switch a {
- case imageApex:
- return imageApexSuffix
- case zipApex:
- return zipApexSuffix
- default:
- panic(fmt.Errorf("unknown APEX type %d", a))
- }
-}
-
-func (a apexPackaging) name() string {
- switch a {
- case imageApex:
- return imageApexType
- case zipApex:
- return zipApexType
- default:
- panic(fmt.Errorf("unknown APEX type %d", a))
- }
-}
-
-type apexFileClass int
-
-const (
- etc apexFileClass = iota
- nativeSharedLib
- nativeExecutable
- shBinary
- pyBinary
- goBinary
- javaSharedLib
- nativeTest
- app
- appSet
-)
-
-func (class apexFileClass) NameInMake() string {
- switch class {
- case etc:
- return "ETC"
- case nativeSharedLib:
- return "SHARED_LIBRARIES"
- case nativeExecutable, shBinary, pyBinary, goBinary:
- return "EXECUTABLES"
- case javaSharedLib:
- return "JAVA_LIBRARIES"
- case nativeTest:
- return "NATIVE_TESTS"
- case app, appSet:
- // b/142537672 Why isn't this APP? We want to have full control over
- // the paths and file names of the apk file under the flattend APEX.
- // If this is set to APP, then the paths and file names are modified
- // by the Make build system. For example, it is installed to
- // /system/apex/<apexname>/app/<Appname>/<apexname>.<Appname>/ instead of
- // /system/apex/<apexname>/app/<Appname> because the build system automatically
- // appends module name (which is <apexname>.<Appname> to the path.
- return "ETC"
- default:
- panic(fmt.Errorf("unknown class %d", class))
- }
-}
-
-// apexFile represents a file in an APEX bundle
-type apexFile struct {
- builtFile android.Path
- stem string
- // Module name of `module` in AndroidMk. Note the generated AndroidMk module for
- // apexFile is named something like <AndroidMk module name>.<apex name>[<apex suffix>]
- androidMkModuleName string
- installDir string
- class apexFileClass
- module android.Module
- // list of symlinks that will be created in installDir that point to this apexFile
- symlinks []string
- dataPaths []android.DataPath
- transitiveDep bool
- moduleDir string
-
- requiredModuleNames []string
- targetRequiredModuleNames []string
- hostRequiredModuleNames []string
-
- jacocoReportClassesFile android.Path // only for javalibs and apps
- lintDepSets java.LintDepSets // only for javalibs and apps
- certificate java.Certificate // only for apps
- overriddenPackageName string // only for apps
-
- isJniLib bool
-
- noticeFiles android.Paths
-}
-
-func newApexFile(ctx android.BaseModuleContext, builtFile android.Path, androidMkModuleName string, installDir string, class apexFileClass, module android.Module) apexFile {
- ret := apexFile{
- builtFile: builtFile,
- androidMkModuleName: androidMkModuleName,
- installDir: installDir,
- class: class,
- module: module,
- }
- if module != nil {
- ret.moduleDir = ctx.OtherModuleDir(module)
- ret.requiredModuleNames = module.RequiredModuleNames()
- ret.targetRequiredModuleNames = module.TargetRequiredModuleNames()
- ret.hostRequiredModuleNames = module.HostRequiredModuleNames()
- ret.noticeFiles = module.NoticeFiles()
- }
- return ret
-}
-
-func (af *apexFile) Ok() bool {
- return af.builtFile != nil && af.builtFile.String() != ""
-}
-
-func (af *apexFile) apexRelativePath(path string) string {
- return filepath.Join(af.installDir, path)
-}
-
-// Path() returns path of this apex file relative to the APEX root
-func (af *apexFile) Path() string {
- return af.apexRelativePath(af.Stem())
-}
-
-func (af *apexFile) Stem() string {
- if af.stem != "" {
- return af.stem
- }
- return af.builtFile.Base()
-}
-
-// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root
-func (af *apexFile) SymlinkPaths() []string {
- var ret []string
- for _, symlink := range af.symlinks {
- ret = append(ret, af.apexRelativePath(symlink))
- }
- return ret
-}
-
-func (af *apexFile) AvailableToPlatform() bool {
- if af.module == nil {
- return false
- }
- if am, ok := af.module.(android.ApexModule); ok {
- return am.AvailableFor(android.AvailableToPlatform)
- }
- return false
-}
-
type fsType int
const (
@@ -1396,268 +990,6 @@
}
}
-type apexBundle struct {
- android.ModuleBase
- android.DefaultableModuleBase
- android.OverridableModuleBase
- android.SdkBase
-
- properties apexBundleProperties
- targetProperties apexTargetBundleProperties
- overridableProperties overridableProperties
-
- // specific to apex_vndk modules
- vndkProperties apexVndkProperties
-
- bundleModuleFile android.WritablePath
- outputFile android.WritablePath
- installDir android.InstallPath
-
- prebuiltFileToDelete string
-
- public_key_file android.Path
- private_key_file android.Path
-
- container_certificate_file android.Path
- container_private_key_file android.Path
-
- fileContexts android.WritablePath
-
- // list of files to be included in this apex
- filesInfo []apexFile
-
- // list of module names that should be installed along with this APEX
- requiredDeps []string
-
- // list of module names that this APEX is including (to be shown via *-deps-info target)
- android.ApexBundleDepsInfo
-
- testApex bool
- vndkApex bool
- artApex bool
- primaryApexType bool
-
- manifestJsonOut android.WritablePath
- manifestPbOut android.WritablePath
-
- // list of commands to create symlinks for backward compatibility.
- // these commands will be attached as LOCAL_POST_INSTALL_CMD to
- // apex package itself(for unflattened build) or apex_manifest(for flattened build)
- // so that compat symlinks are always installed regardless of TARGET_FLATTEN_APEX setting.
- compatSymlinks []string
-
- // Suffix of module name in Android.mk
- // ".flattened", ".apex", ".zipapex", or ""
- suffix string
-
- installedFilesFile android.WritablePath
-
- // Whether to create symlink to the system file instead of having a file
- // inside the apex or not
- linkToSystemLib bool
-
- // Struct holding the merged notice file paths in different formats
- mergedNotices android.NoticeOutputs
-
- // Optional list of lint report zip files for apexes that contain java or app modules
- lintReports android.Paths
-
- payloadFsType fsType
-
- distFiles android.TaggedDistFiles
-}
-
-func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
- nativeModules ApexNativeDependencies,
- target android.Target, imageVariation string) {
- // Use *FarVariation* to be able to depend on modules having
- // conflicting variations with this module. This is required since
- // arch variant of an APEX bundle is 'common' but it is 'arm' or 'arm64'
- // for native shared libs.
-
- binVariations := target.Variations()
- libVariations := append(target.Variations(),
- blueprint.Variation{Mutator: "link", Variation: "shared"})
-
- if ctx.Device() {
- binVariations = append(binVariations,
- blueprint.Variation{Mutator: "image", Variation: imageVariation})
- libVariations = append(libVariations,
- blueprint.Variation{Mutator: "image", Variation: imageVariation},
- blueprint.Variation{Mutator: "version", Variation: ""}) // "" is the non-stub variant
- }
-
- ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
-
- ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
-
- ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
-
- ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
-}
-
-func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
- if ctx.Os().Class == android.Device {
- proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Android.Multilib, nil)
- } else {
- proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Host.Multilib, nil)
- if ctx.Os().Bionic() {
- proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_bionic.Multilib, nil)
- } else {
- proptools.AppendProperties(&a.properties.Multilib, &a.targetProperties.Target.Linux_glibc.Multilib, nil)
- }
- }
-}
-
-func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
- if proptools.Bool(a.properties.Use_vendor) && !android.InList(a.Name(), useVendorAllowList(ctx.Config())) {
- ctx.PropertyErrorf("use_vendor", "not allowed to set use_vendor: true")
- }
-
- targets := ctx.MultiTargets()
- config := ctx.DeviceConfig()
- imageVariation := a.getImageVariation(ctx)
-
- a.combineProperties(ctx)
-
- has32BitTarget := false
- for _, target := range targets {
- if target.Arch.ArchType.Multilib == "lib32" {
- has32BitTarget = true
- }
- }
- for i, target := range targets {
- if target.HostCross {
- // Don't include artifats for the host cross targets because there is no way
- // for us to run those artifacts natively on host
- continue
- }
-
- // When multilib.* is omitted for native_shared_libs/jni_libs/tests, it implies
- // multilib.both
- addDependenciesForNativeModules(ctx,
- ApexNativeDependencies{
- Native_shared_libs: a.properties.Native_shared_libs,
- Tests: a.properties.Tests,
- Jni_libs: a.properties.Jni_libs,
- Binaries: nil,
- },
- target, imageVariation)
-
- // Add native modules targetting both ABIs
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Both,
- target,
- imageVariation)
-
- isPrimaryAbi := i == 0
- if isPrimaryAbi {
- // When multilib.* is omitted for binaries, it implies
- // multilib.first
- addDependenciesForNativeModules(ctx,
- ApexNativeDependencies{
- Native_shared_libs: nil,
- Tests: nil,
- Jni_libs: nil,
- Binaries: a.properties.Binaries,
- },
- target, imageVariation)
-
- // Add native modules targetting the first ABI
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.First,
- target,
- imageVariation)
- }
-
- switch target.Arch.ArchType.Multilib {
- case "lib32":
- // Add native modules targetting 32-bit ABI
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Lib32,
- target,
- imageVariation)
-
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Prefer32,
- target,
- imageVariation)
- case "lib64":
- // Add native modules targetting 64-bit ABI
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Lib64,
- target,
- imageVariation)
-
- if !has32BitTarget {
- addDependenciesForNativeModules(ctx,
- a.properties.Multilib.Prefer32,
- target,
- imageVariation)
- }
- }
- }
-
- // For prebuilt_etc, use the first variant (64 on 64/32bit device,
- // 32 on 32bit device) regardless of the TARGET_PREFER_* setting.
- // b/144532908
- archForPrebuiltEtc := config.Arches()[0]
- for _, arch := range config.Arches() {
- // Prefer 64-bit arch if there is any
- if arch.ArchType.Multilib == "lib64" {
- archForPrebuiltEtc = arch
- break
- }
- }
- ctx.AddFarVariationDependencies([]blueprint.Variation{
- {Mutator: "os", Variation: ctx.Os().String()},
- {Mutator: "arch", Variation: archForPrebuiltEtc.String()},
- }, prebuiltTag, a.properties.Prebuilts...)
-
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
- javaLibTag, a.properties.Java_libs...)
-
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
- bpfTag, a.properties.Bpfs...)
-
- // With EMMA_INSTRUMENT_FRAMEWORK=true the ART boot image includes jacoco library.
- if a.artApex && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
- javaLibTag, "jacocoagent")
- }
-
- if String(a.properties.Key) == "" {
- ctx.ModuleErrorf("key is missing")
- return
- }
- ctx.AddDependency(ctx.Module(), keyTag, String(a.properties.Key))
-
- cert := android.SrcIsModule(a.getCertString(ctx))
- if cert != "" {
- ctx.AddDependency(ctx.Module(), certificateTag, cert)
- }
-
- // TODO(jiyong): ensure that all apexes are with non-empty uses_sdks
- if len(a.properties.Uses_sdks) > 0 {
- sdkRefs := []android.SdkRef{}
- for _, str := range a.properties.Uses_sdks {
- parsed := android.ParseSdkRef(ctx, str, "uses_sdks")
- sdkRefs = append(sdkRefs, parsed)
- }
- a.BuildWithSdks(sdkRefs)
- }
-}
-
-func (a *apexBundle) OverridablePropertiesDepsMutator(ctx android.BottomUpMutatorContext) {
- if a.overridableProperties.Allowed_files != nil {
- android.ExtractSourceDeps(ctx, a.overridableProperties.Allowed_files)
- }
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
- androidAppTag, a.overridableProperties.Apps...)
- ctx.AddFarVariationDependencies(ctx.Config().AndroidCommonTarget.Variations(),
- rroTag, a.overridableProperties.Rros...)
-}
-
func (a *apexBundle) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
// direct deps of an APEX bundle are all part of the APEX bundle
return true
@@ -2615,3 +1947,674 @@
android.InitOverrideModule(m)
return m
}
+
+var (
+ apexAvailBaseline = makeApexAvailableBaseline()
+ inverseApexAvailBaseline = invertApexBaseline(apexAvailBaseline)
+)
+
+// Transform the map of apex -> modules to module -> apexes.
+func invertApexBaseline(m map[string][]string) map[string][]string {
+ r := make(map[string][]string)
+ for apex, modules := range m {
+ for _, module := range modules {
+ r[module] = append(r[module], apex)
+ }
+ }
+ return r
+}
+
+// Retrieve the baseline of apexes to which the supplied module belongs.
+func BaselineApexAvailable(moduleName string) []string {
+ return inverseApexAvailBaseline[normalizeModuleName(moduleName)]
+}
+
+// This is a map from apex to modules, which overrides the
+// apex_available setting for that particular module to make
+// it available for the apex regardless of its setting.
+// TODO(b/147364041): remove this
+func makeApexAvailableBaseline() map[string][]string {
+ // The "Module separator"s below are employed to minimize merge conflicts.
+ m := make(map[string][]string)
+ //
+ // Module separator
+ //
+ m["com.android.appsearch"] = []string{
+ "icing-java-proto-lite",
+ "libprotobuf-java-lite",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.bluetooth.updatable"] = []string{
+ "android.hardware.audio.common@5.0",
+ "android.hardware.bluetooth.a2dp@1.0",
+ "android.hardware.bluetooth.audio@2.0",
+ "android.hardware.bluetooth@1.0",
+ "android.hardware.bluetooth@1.1",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.media@1.0",
+ "android.hidl.safe_union@1.0",
+ "android.hidl.token@1.0",
+ "android.hidl.token@1.0-utils",
+ "avrcp-target-service",
+ "avrcp_headers",
+ "bluetooth-protos-lite",
+ "bluetooth.mapsapi",
+ "com.android.vcard",
+ "dnsresolver_aidl_interface-V2-java",
+ "ipmemorystore-aidl-interfaces-V5-java",
+ "ipmemorystore-aidl-interfaces-java",
+ "internal_include_headers",
+ "lib-bt-packets",
+ "lib-bt-packets-avrcp",
+ "lib-bt-packets-base",
+ "libFraunhoferAAC",
+ "libaudio-a2dp-hw-utils",
+ "libaudio-hearing-aid-hw-utils",
+ "libbinder_headers",
+ "libbluetooth",
+ "libbluetooth-types",
+ "libbluetooth-types-header",
+ "libbluetooth_gd",
+ "libbluetooth_headers",
+ "libbluetooth_jni",
+ "libbt-audio-hal-interface",
+ "libbt-bta",
+ "libbt-common",
+ "libbt-hci",
+ "libbt-platform-protos-lite",
+ "libbt-protos-lite",
+ "libbt-sbc-decoder",
+ "libbt-sbc-encoder",
+ "libbt-stack",
+ "libbt-utils",
+ "libbtcore",
+ "libbtdevice",
+ "libbte",
+ "libbtif",
+ "libchrome",
+ "libevent",
+ "libfmq",
+ "libg722codec",
+ "libgui_headers",
+ "libmedia_headers",
+ "libmodpb64",
+ "libosi",
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ "libstatslog",
+ "libstatssocket",
+ "libtinyxml2",
+ "libudrv-uipc",
+ "libz",
+ "media_plugin_headers",
+ "net-utils-services-common",
+ "netd_aidl_interface-unstable-java",
+ "netd_event_listener_interface-java",
+ "netlink-client",
+ "networkstack-client",
+ "sap-api-java-static",
+ "services.net",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.cellbroadcast"] = []string{"CellBroadcastApp", "CellBroadcastServiceModule"}
+ //
+ // Module separator
+ //
+ m["com.android.extservices"] = []string{
+ "error_prone_annotations",
+ "ExtServices-core",
+ "ExtServices",
+ "libtextclassifier-java",
+ "libz_current",
+ "textclassifier-statsd",
+ "TextClassifierNotificationLibNoManifest",
+ "TextClassifierServiceLibNoManifest",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.neuralnetworks"] = []string{
+ "android.hardware.neuralnetworks@1.0",
+ "android.hardware.neuralnetworks@1.1",
+ "android.hardware.neuralnetworks@1.2",
+ "android.hardware.neuralnetworks@1.3",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory.token@1.0",
+ "android.hidl.memory@1.0",
+ "android.hidl.safe_union@1.0",
+ "libarect",
+ "libbuildversion",
+ "libmath",
+ "libprocpartition",
+ "libsync",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.media"] = []string{
+ "android.frameworks.bufferhub@1.0",
+ "android.hardware.cas.native@1.0",
+ "android.hardware.cas@1.0",
+ "android.hardware.configstore-utils",
+ "android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.media.omx@1.0",
+ "android.hardware.media@1.0",
+ "android.hidl.allocator@1.0",
+ "android.hidl.memory.token@1.0",
+ "android.hidl.memory@1.0",
+ "android.hidl.token@1.0",
+ "android.hidl.token@1.0-utils",
+ "bionic_libc_platform_headers",
+ "exoplayer2-extractor",
+ "exoplayer2-extractor-annotation-stubs",
+ "gl_headers",
+ "jsr305",
+ "libEGL",
+ "libEGL_blobCache",
+ "libEGL_getProcAddress",
+ "libFLAC",
+ "libFLAC-config",
+ "libFLAC-headers",
+ "libGLESv2",
+ "libaacextractor",
+ "libamrextractor",
+ "libarect",
+ "libaudio_system_headers",
+ "libaudioclient",
+ "libaudioclient_headers",
+ "libaudiofoundation",
+ "libaudiofoundation_headers",
+ "libaudiomanager",
+ "libaudiopolicy",
+ "libaudioutils",
+ "libaudioutils_fixedfft",
+ "libbinder_headers",
+ "libbluetooth-types-header",
+ "libbufferhub",
+ "libbufferhub_headers",
+ "libbufferhubqueue",
+ "libc_malloc_debug_backtrace",
+ "libcamera_client",
+ "libcamera_metadata",
+ "libdvr_headers",
+ "libexpat",
+ "libfifo",
+ "libflacextractor",
+ "libgrallocusage",
+ "libgraphicsenv",
+ "libgui",
+ "libgui_headers",
+ "libhardware_headers",
+ "libinput",
+ "liblzma",
+ "libmath",
+ "libmedia",
+ "libmedia_codeclist",
+ "libmedia_headers",
+ "libmedia_helper",
+ "libmedia_helper_headers",
+ "libmedia_midiiowrapper",
+ "libmedia_omx",
+ "libmediautils",
+ "libmidiextractor",
+ "libmkvextractor",
+ "libmp3extractor",
+ "libmp4extractor",
+ "libmpeg2extractor",
+ "libnativebase_headers",
+ "libnativewindow_headers",
+ "libnblog",
+ "liboggextractor",
+ "libpackagelistparser",
+ "libpdx",
+ "libpdx_default_transport",
+ "libpdx_headers",
+ "libpdx_uds",
+ "libprocinfo",
+ "libspeexresampler",
+ "libspeexresampler",
+ "libstagefright_esds",
+ "libstagefright_flacdec",
+ "libstagefright_flacdec",
+ "libstagefright_foundation",
+ "libstagefright_foundation_headers",
+ "libstagefright_foundation_without_imemory",
+ "libstagefright_headers",
+ "libstagefright_id3",
+ "libstagefright_metadatautils",
+ "libstagefright_mpeg2extractor",
+ "libstagefright_mpeg2support",
+ "libsync",
+ "libui",
+ "libui_headers",
+ "libunwindstack",
+ "libvibrator",
+ "libvorbisidec",
+ "libwavextractor",
+ "libwebm",
+ "media_ndk_headers",
+ "media_plugin_headers",
+ "updatable-media",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.media.swcodec"] = []string{
+ "android.frameworks.bufferhub@1.0",
+ "android.hardware.common-ndk_platform",
+ "android.hardware.configstore-utils",
+ "android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.1",
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.allocator@3.0",
+ "android.hardware.graphics.allocator@4.0",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.graphics.common-ndk_platform",
+ "android.hardware.graphics.common@1.0",
+ "android.hardware.graphics.common@1.1",
+ "android.hardware.graphics.common@1.2",
+ "android.hardware.graphics.mapper@2.0",
+ "android.hardware.graphics.mapper@2.1",
+ "android.hardware.graphics.mapper@3.0",
+ "android.hardware.graphics.mapper@4.0",
+ "android.hardware.media.bufferpool@2.0",
+ "android.hardware.media.c2@1.0",
+ "android.hardware.media.c2@1.1",
+ "android.hardware.media.omx@1.0",
+ "android.hardware.media@1.0",
+ "android.hardware.media@1.0",
+ "android.hidl.memory.token@1.0",
+ "android.hidl.memory@1.0",
+ "android.hidl.safe_union@1.0",
+ "android.hidl.token@1.0",
+ "android.hidl.token@1.0-utils",
+ "libEGL",
+ "libFLAC",
+ "libFLAC-config",
+ "libFLAC-headers",
+ "libFraunhoferAAC",
+ "libLibGuiProperties",
+ "libarect",
+ "libaudio_system_headers",
+ "libaudioutils",
+ "libaudioutils",
+ "libaudioutils_fixedfft",
+ "libavcdec",
+ "libavcenc",
+ "libavservices_minijail",
+ "libavservices_minijail",
+ "libbinder_headers",
+ "libbinderthreadstateutils",
+ "libbluetooth-types-header",
+ "libbufferhub_headers",
+ "libcodec2",
+ "libcodec2_headers",
+ "libcodec2_hidl@1.0",
+ "libcodec2_hidl@1.1",
+ "libcodec2_internal",
+ "libcodec2_soft_aacdec",
+ "libcodec2_soft_aacenc",
+ "libcodec2_soft_amrnbdec",
+ "libcodec2_soft_amrnbenc",
+ "libcodec2_soft_amrwbdec",
+ "libcodec2_soft_amrwbenc",
+ "libcodec2_soft_av1dec_gav1",
+ "libcodec2_soft_avcdec",
+ "libcodec2_soft_avcenc",
+ "libcodec2_soft_common",
+ "libcodec2_soft_flacdec",
+ "libcodec2_soft_flacenc",
+ "libcodec2_soft_g711alawdec",
+ "libcodec2_soft_g711mlawdec",
+ "libcodec2_soft_gsmdec",
+ "libcodec2_soft_h263dec",
+ "libcodec2_soft_h263enc",
+ "libcodec2_soft_hevcdec",
+ "libcodec2_soft_hevcenc",
+ "libcodec2_soft_mp3dec",
+ "libcodec2_soft_mpeg2dec",
+ "libcodec2_soft_mpeg4dec",
+ "libcodec2_soft_mpeg4enc",
+ "libcodec2_soft_opusdec",
+ "libcodec2_soft_opusenc",
+ "libcodec2_soft_rawdec",
+ "libcodec2_soft_vorbisdec",
+ "libcodec2_soft_vp8dec",
+ "libcodec2_soft_vp8enc",
+ "libcodec2_soft_vp9dec",
+ "libcodec2_soft_vp9enc",
+ "libcodec2_vndk",
+ "libdvr_headers",
+ "libfmq",
+ "libfmq",
+ "libgav1",
+ "libgralloctypes",
+ "libgrallocusage",
+ "libgraphicsenv",
+ "libgsm",
+ "libgui_bufferqueue_static",
+ "libgui_headers",
+ "libhardware",
+ "libhardware_headers",
+ "libhevcdec",
+ "libhevcenc",
+ "libion",
+ "libjpeg",
+ "liblzma",
+ "libmath",
+ "libmedia_codecserviceregistrant",
+ "libmedia_headers",
+ "libmpeg2dec",
+ "libnativebase_headers",
+ "libnativewindow_headers",
+ "libpdx_headers",
+ "libscudo_wrapper",
+ "libsfplugin_ccodec_utils",
+ "libspeexresampler",
+ "libstagefright_amrnb_common",
+ "libstagefright_amrnbdec",
+ "libstagefright_amrnbenc",
+ "libstagefright_amrwbdec",
+ "libstagefright_amrwbenc",
+ "libstagefright_bufferpool@2.0.1",
+ "libstagefright_bufferqueue_helper",
+ "libstagefright_enc_common",
+ "libstagefright_flacdec",
+ "libstagefright_foundation",
+ "libstagefright_foundation_headers",
+ "libstagefright_headers",
+ "libstagefright_m4vh263dec",
+ "libstagefright_m4vh263enc",
+ "libstagefright_mp3dec",
+ "libsync",
+ "libui",
+ "libui_headers",
+ "libunwindstack",
+ "libvorbisidec",
+ "libvpx",
+ "libyuv",
+ "libyuv_static",
+ "media_ndk_headers",
+ "media_plugin_headers",
+ "mediaswcodec",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.mediaprovider"] = []string{
+ "MediaProvider",
+ "MediaProviderGoogle",
+ "fmtlib_ndk",
+ "libbase_ndk",
+ "libfuse",
+ "libfuse_jni",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.permission"] = []string{
+ "car-ui-lib",
+ "iconloader",
+ "kotlin-annotations",
+ "kotlin-stdlib",
+ "kotlin-stdlib-jdk7",
+ "kotlin-stdlib-jdk8",
+ "kotlinx-coroutines-android",
+ "kotlinx-coroutines-android-nodeps",
+ "kotlinx-coroutines-core",
+ "kotlinx-coroutines-core-nodeps",
+ "permissioncontroller-statsd",
+ "GooglePermissionController",
+ "PermissionController",
+ "SettingsLibActionBarShadow",
+ "SettingsLibAppPreference",
+ "SettingsLibBarChartPreference",
+ "SettingsLibLayoutPreference",
+ "SettingsLibProgressBar",
+ "SettingsLibSearchWidget",
+ "SettingsLibSettingsTheme",
+ "SettingsLibRestrictedLockUtils",
+ "SettingsLibHelpUtils",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.runtime"] = []string{
+ "bionic_libc_platform_headers",
+ "libarm-optimized-routines-math",
+ "libc_aeabi",
+ "libc_bionic",
+ "libc_bionic_ndk",
+ "libc_bootstrap",
+ "libc_common",
+ "libc_common_shared",
+ "libc_common_static",
+ "libc_dns",
+ "libc_dynamic_dispatch",
+ "libc_fortify",
+ "libc_freebsd",
+ "libc_freebsd_large_stack",
+ "libc_gdtoa",
+ "libc_init_dynamic",
+ "libc_init_static",
+ "libc_jemalloc_wrapper",
+ "libc_netbsd",
+ "libc_nomalloc",
+ "libc_nopthread",
+ "libc_openbsd",
+ "libc_openbsd_large_stack",
+ "libc_openbsd_ndk",
+ "libc_pthread",
+ "libc_static_dispatch",
+ "libc_syscalls",
+ "libc_tzcode",
+ "libc_unwind_static",
+ "libdebuggerd",
+ "libdebuggerd_common_headers",
+ "libdebuggerd_handler_core",
+ "libdebuggerd_handler_fallback",
+ "libdl_static",
+ "libjemalloc5",
+ "liblinker_main",
+ "liblinker_malloc",
+ "liblz4",
+ "liblzma",
+ "libprocinfo",
+ "libpropertyinfoparser",
+ "libscudo",
+ "libstdc++",
+ "libsystemproperties",
+ "libtombstoned_client_static",
+ "libunwindstack",
+ "libz",
+ "libziparchive",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.tethering"] = []string{
+ "android.hardware.tetheroffload.config-V1.0-java",
+ "android.hardware.tetheroffload.control-V1.0-java",
+ "android.hidl.base-V1.0-java",
+ "libcgrouprc",
+ "libcgrouprc_format",
+ "libtetherutilsjni",
+ "libvndksupport",
+ "net-utils-framework-common",
+ "netd_aidl_interface-V3-java",
+ "netlink-client",
+ "networkstack-aidl-interfaces-java",
+ "tethering-aidl-interfaces-java",
+ "TetheringApiCurrentLib",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.wifi"] = []string{
+ "PlatformProperties",
+ "android.hardware.wifi-V1.0-java",
+ "android.hardware.wifi-V1.0-java-constants",
+ "android.hardware.wifi-V1.1-java",
+ "android.hardware.wifi-V1.2-java",
+ "android.hardware.wifi-V1.3-java",
+ "android.hardware.wifi-V1.4-java",
+ "android.hardware.wifi.hostapd-V1.0-java",
+ "android.hardware.wifi.hostapd-V1.1-java",
+ "android.hardware.wifi.hostapd-V1.2-java",
+ "android.hardware.wifi.supplicant-V1.0-java",
+ "android.hardware.wifi.supplicant-V1.1-java",
+ "android.hardware.wifi.supplicant-V1.2-java",
+ "android.hardware.wifi.supplicant-V1.3-java",
+ "android.hidl.base-V1.0-java",
+ "android.hidl.manager-V1.0-java",
+ "android.hidl.manager-V1.1-java",
+ "android.hidl.manager-V1.2-java",
+ "bouncycastle-unbundled",
+ "dnsresolver_aidl_interface-V2-java",
+ "error_prone_annotations",
+ "framework-wifi-pre-jarjar",
+ "framework-wifi-util-lib",
+ "ipmemorystore-aidl-interfaces-V3-java",
+ "ipmemorystore-aidl-interfaces-java",
+ "ksoap2",
+ "libnanohttpd",
+ "libwifi-jni",
+ "net-utils-services-common",
+ "netd_aidl_interface-V2-java",
+ "netd_aidl_interface-unstable-java",
+ "netd_event_listener_interface-java",
+ "netlink-client",
+ "networkstack-client",
+ "services.net",
+ "wifi-lite-protos",
+ "wifi-nano-protos",
+ "wifi-service-pre-jarjar",
+ "wifi-service-resources",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.sdkext"] = []string{
+ "fmtlib_ndk",
+ "libbase_ndk",
+ "libprotobuf-cpp-lite-ndk",
+ }
+ //
+ // Module separator
+ //
+ m["com.android.os.statsd"] = []string{
+ "libstatssocket",
+ }
+ //
+ // Module separator
+ //
+ m[android.AvailableToAnyApex] = []string{
+ // TODO(b/156996905) Set apex_available/min_sdk_version for androidx/extras support libraries
+ "androidx",
+ "androidx-constraintlayout_constraintlayout",
+ "androidx-constraintlayout_constraintlayout-nodeps",
+ "androidx-constraintlayout_constraintlayout-solver",
+ "androidx-constraintlayout_constraintlayout-solver-nodeps",
+ "com.google.android.material_material",
+ "com.google.android.material_material-nodeps",
+
+ "libatomic",
+ "libclang_rt",
+ "libgcc_stripped",
+ "libprofile-clang-extras",
+ "libprofile-clang-extras_ndk",
+ "libprofile-extras",
+ "libprofile-extras_ndk",
+ "libunwind_llvm",
+ }
+ return m
+}
+
+func init() {
+ android.AddNeverAllowRules(createApexPermittedPackagesRules(qModulesPackages())...)
+ android.AddNeverAllowRules(createApexPermittedPackagesRules(rModulesPackages())...)
+}
+
+func createApexPermittedPackagesRules(modules_packages map[string][]string) []android.Rule {
+ rules := make([]android.Rule, 0, len(modules_packages))
+ for module_name, module_packages := range modules_packages {
+ permitted_packages_rule := android.NeverAllow().
+ BootclasspathJar().
+ With("apex_available", module_name).
+ WithMatcher("permitted_packages", android.NotInList(module_packages)).
+ Because("jars that are part of the " + module_name +
+ " module may only allow these packages: " + strings.Join(module_packages, ",") +
+ ". Please jarjar or move code around.")
+ rules = append(rules, permitted_packages_rule)
+ }
+ return rules
+}
+
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func qModulesPackages() map[string][]string {
+ return map[string][]string{
+ "com.android.conscrypt": []string{
+ "android.net.ssl",
+ "com.android.org.conscrypt",
+ },
+ "com.android.media": []string{
+ "android.media",
+ },
+ }
+}
+
+// DO NOT EDIT! These are the package prefixes that are exempted from being AOT'ed by ART.
+// Adding code to the bootclasspath in new packages will cause issues on module update.
+func rModulesPackages() map[string][]string {
+ return map[string][]string{
+ "com.android.mediaprovider": []string{
+ "android.provider",
+ },
+ "com.android.permission": []string{
+ "android.permission",
+ "android.app.role",
+ "com.android.permission",
+ "com.android.role",
+ },
+ "com.android.sdkext": []string{
+ "android.os.ext",
+ },
+ "com.android.os.statsd": []string{
+ "android.app",
+ "android.os",
+ "android.util",
+ "com.android.internal.statsd",
+ "com.android.server.stats",
+ },
+ "com.android.wifi": []string{
+ "com.android.server.wifi",
+ "com.android.wifi.x",
+ "android.hardware.wifi",
+ "android.net.wifi",
+ },
+ "com.android.tethering": []string{
+ "android.net",
+ },
+ }
+}
diff --git a/java/app_test.go b/java/app_test.go
index 6429ab8..6efb0dc 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -291,7 +291,7 @@
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
android_app {
name: "foo",
srcs: ["a.java"],
@@ -335,7 +335,7 @@
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
android_app {
name: "foo",
srcs: ["a.java"],
diff --git a/java/droiddoc.go b/java/droiddoc.go
index c7a27c2..cf7f4fb 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1748,8 +1748,6 @@
properties PrebuiltStubsSourcesProperties
- // The source directories containing stubs source files.
- srcDirs android.Paths
stubsSrcJar android.ModuleOutPath
}
@@ -1769,21 +1767,29 @@
func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.stubsSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"stubs.srcjar")
- p.srcDirs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+ if len(p.properties.Srcs) != 1 {
+ ctx.PropertyErrorf("srcs", "must only specify one directory path, contains %d paths", len(p.properties.Srcs))
+ return
+ }
+
+ localSrcDir := p.properties.Srcs[0]
+ // Although PathForModuleSrc can return nil if either the path doesn't exist or
+ // the path components are invalid it won't in this case because no components
+ // are specified and the module directory must exist in order to get this far.
+ srcDir := android.PathForModuleSrc(ctx).(android.SourcePath).Join(ctx, localSrcDir)
+
+ // Glob the contents of the directory just in case the directory does not exist.
+ srcGlob := localSrcDir + "/**/*"
+ srcPaths := android.PathsForModuleSrc(ctx, []string{srcGlob})
rule := android.NewRuleBuilder()
- command := rule.Command().
+ rule.Command().
BuiltTool(ctx, "soong_zip").
Flag("-write_if_changed").
Flag("-jar").
- FlagWithOutput("-o ", p.stubsSrcJar)
-
- for _, d := range p.srcDirs {
- dir := d.String()
- command.
- FlagWithArg("-C ", dir).
- FlagWithInput("-D ", d)
- }
+ FlagWithOutput("-o ", p.stubsSrcJar).
+ FlagWithArg("-C ", srcDir.String()).
+ FlagWithRspFileInputList("-r ", srcPaths)
rule.Restat()
diff --git a/java/java.go b/java/java.go
index a23c649..7cf04fa 100644
--- a/java/java.go
+++ b/java/java.go
@@ -248,6 +248,9 @@
Errorprone struct {
// List of javac flags that should only be used when running errorprone.
Javacflags []string
+
+ // List of java_plugin modules that provide extra errorprone checks.
+ Extra_check_modules []string
}
Proto struct {
@@ -569,6 +572,7 @@
libTag = dependencyTag{name: "javalib"}
java9LibTag = dependencyTag{name: "java9lib"}
pluginTag = dependencyTag{name: "plugin"}
+ errorpronePluginTag = dependencyTag{name: "errorprone-plugin"}
exportedPluginTag = dependencyTag{name: "exported-plugin"}
bootClasspathTag = dependencyTag{name: "bootclasspath"}
systemModulesTag = dependencyTag{name: "system modules"}
@@ -765,6 +769,7 @@
}
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...)
+ ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...)
ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...)
android.ProtoDeps(ctx, &j.protoProperties)
@@ -852,21 +857,22 @@
}
type deps struct {
- classpath classpath
- java9Classpath classpath
- bootClasspath classpath
- processorPath classpath
- processorClasses []string
- staticJars android.Paths
- staticHeaderJars android.Paths
- staticResourceJars android.Paths
- aidlIncludeDirs android.Paths
- srcs android.Paths
- srcJars android.Paths
- systemModules *systemModules
- aidlPreprocess android.OptionalPath
- kotlinStdlib android.Paths
- kotlinAnnotations android.Paths
+ classpath classpath
+ java9Classpath classpath
+ bootClasspath classpath
+ processorPath classpath
+ errorProneProcessorPath classpath
+ processorClasses []string
+ staticJars android.Paths
+ staticHeaderJars android.Paths
+ staticResourceJars android.Paths
+ aidlIncludeDirs android.Paths
+ srcs android.Paths
+ srcJars android.Paths
+ systemModules *systemModules
+ aidlPreprocess android.OptionalPath
+ kotlinStdlib android.Paths
+ kotlinAnnotations android.Paths
disableTurbine bool
}
@@ -952,7 +958,9 @@
return
}
otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to))
- commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
+ commonMessage := " In order to fix this, consider adjusting sdk_version: OR platform_apis: " +
+ "property of the source or target module so that target module is built with the same " +
+ "or smaller API set when compared to the source."
switch myLinkType {
case javaCore:
@@ -1066,6 +1074,12 @@
} else {
ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
}
+ case errorpronePluginTag:
+ if plugin, ok := dep.(*Plugin); ok {
+ deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, plugin.ImplementationAndResourcesJars()...)
+ } else {
+ ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName)
+ }
case exportedPluginTag:
if plugin, ok := dep.(*Plugin); ok {
if plugin.pluginProperties.Generates_api != nil && *plugin.pluginProperties.Generates_api {
@@ -1189,7 +1203,7 @@
flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j))
if ctx.Config().RunErrorProne() {
- if config.ErrorProneClasspath == nil {
+ if config.ErrorProneClasspath == nil && ctx.Config().TestProductVariables == nil {
ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?")
}
@@ -1209,6 +1223,7 @@
flags.classpath = append(flags.classpath, deps.classpath...)
flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...)
flags.processorPath = append(flags.processorPath, deps.processorPath...)
+ flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...)
flags.processors = append(flags.processors, deps.processorClasses...)
flags.processors = android.FirstUniqueStrings(flags.processors)
@@ -2325,7 +2340,7 @@
func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template,
- j.testProperties.Test_suites, j.testProperties.Auto_gen_config)
+ j.testProperties.Test_suites, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test)
j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data)
@@ -2344,7 +2359,7 @@
func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil,
- j.prebuiltTestProperties.Test_suites, nil)
+ j.prebuiltTestProperties.Test_suites, nil, nil)
j.Import.GenerateAndroidBuildActions(ctx)
}
diff --git a/java/java_test.go b/java/java_test.go
index 845a03a..cf56e66 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -15,6 +15,7 @@
package java
import (
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -202,7 +203,7 @@
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
java_library {
name: "foo",
srcs: ["a.java"],
@@ -246,7 +247,7 @@
}
`)
- testJavaError(t, "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source.", `
+ testJavaError(t, "consider adjusting sdk_version: OR platform_apis:", `
java_library {
name: "foo",
srcs: ["a.java"],
@@ -622,6 +623,35 @@
}
}
+func TestPrebuiltStubsSources(t *testing.T) {
+ test := func(t *testing.T, sourcesPath string, expectedInputs []string) {
+ ctx, _ := testJavaWithFS(t, fmt.Sprintf(`
+prebuilt_stubs_sources {
+ name: "stubs-source",
+ srcs: ["%s"],
+}`, sourcesPath), map[string][]byte{
+ "stubs/sources/pkg/A.java": nil,
+ "stubs/sources/pkg/B.java": nil,
+ })
+
+ zipSrc := ctx.ModuleForTests("stubs-source", "android_common").Rule("zip_src")
+ if expected, actual := expectedInputs, zipSrc.Inputs.Strings(); !reflect.DeepEqual(expected, actual) {
+ t.Errorf("mismatch of inputs to soong_zip: expected %q, actual %q", expected, actual)
+ }
+ }
+
+ t.Run("empty/missing directory", func(t *testing.T) {
+ test(t, "empty-directory", []string{})
+ })
+
+ t.Run("non-empty set of sources", func(t *testing.T) {
+ test(t, "stubs/sources", []string{
+ "stubs/sources/pkg/A.java",
+ "stubs/sources/pkg/B.java",
+ })
+ })
+}
+
func TestJavaSdkLibraryImport(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
diff --git a/java/kotlin_test.go b/java/kotlin_test.go
index 60ca1c4..77ef294 100644
--- a/java/kotlin_test.go
+++ b/java/kotlin_test.go
@@ -84,11 +84,14 @@
}
func TestKapt(t *testing.T) {
- ctx, _ := testJava(t, `
+ bp := `
java_library {
name: "foo",
srcs: ["a.java", "b.kt"],
plugins: ["bar", "baz"],
+ errorprone: {
+ extra_check_modules: ["my_check"],
+ },
}
java_plugin {
@@ -102,64 +105,119 @@
processor_class: "com.baz",
srcs: ["b.java"],
}
- `)
- buildOS := android.BuildOs.String()
+ java_plugin {
+ name: "my_check",
+ srcs: ["b.java"],
+ }
+ `
+ t.Run("", func(t *testing.T) {
+ ctx, _ := testJava(t, bp)
- kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
- kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
- javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
+ buildOS := android.BuildOs.String()
- bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
- baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
+ kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
+ kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
+ javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
- // Test that the kotlin and java sources are passed to kapt and kotlinc
- if len(kapt.Inputs) != 2 || kapt.Inputs[0].String() != "a.java" || kapt.Inputs[1].String() != "b.kt" {
- t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kapt.Inputs)
- }
- if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
- t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
- }
+ bar := ctx.ModuleForTests("bar", buildOS+"_common").Rule("javac").Output.String()
+ baz := ctx.ModuleForTests("baz", buildOS+"_common").Rule("javac").Output.String()
- // Test that only the java sources are passed to javac
- if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
- t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
- }
+ // Test that the kotlin and java sources are passed to kapt and kotlinc
+ if len(kapt.Inputs) != 2 || kapt.Inputs[0].String() != "a.java" || kapt.Inputs[1].String() != "b.kt" {
+ t.Errorf(`foo kapt inputs %v != ["a.java", "b.kt"]`, kapt.Inputs)
+ }
+ if len(kotlinc.Inputs) != 2 || kotlinc.Inputs[0].String() != "a.java" || kotlinc.Inputs[1].String() != "b.kt" {
+ t.Errorf(`foo kotlinc inputs %v != ["a.java", "b.kt"]`, kotlinc.Inputs)
+ }
- // Test that the kapt srcjar is a dependency of kotlinc and javac rules
- if !inList(kapt.Output.String(), kotlinc.Implicits.Strings()) {
- t.Errorf("expected %q in kotlinc implicits %v", kapt.Output.String(), kotlinc.Implicits.Strings())
- }
- if !inList(kapt.Output.String(), javac.Implicits.Strings()) {
- t.Errorf("expected %q in javac implicits %v", kapt.Output.String(), javac.Implicits.Strings())
- }
+ // Test that only the java sources are passed to javac
+ if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
+ t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
+ }
- // Test that the kapt srcjar is extracted by the kotlinc and javac rules
- if kotlinc.Args["srcJars"] != kapt.Output.String() {
- t.Errorf("expected %q in kotlinc srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
- }
- if javac.Args["srcJars"] != kapt.Output.String() {
- t.Errorf("expected %q in javac srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
- }
+ // Test that the kapt srcjar is a dependency of kotlinc and javac rules
+ if !inList(kapt.Output.String(), kotlinc.Implicits.Strings()) {
+ t.Errorf("expected %q in kotlinc implicits %v", kapt.Output.String(), kotlinc.Implicits.Strings())
+ }
+ if !inList(kapt.Output.String(), javac.Implicits.Strings()) {
+ t.Errorf("expected %q in javac implicits %v", kapt.Output.String(), javac.Implicits.Strings())
+ }
- // Test that the processors are passed to kapt
- expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
- " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
- if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
- t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
- }
- expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
- if kapt.Args["kaptProcessor"] != expectedProcessor {
- t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
- }
+ // Test that the kapt srcjar is extracted by the kotlinc and javac rules
+ if kotlinc.Args["srcJars"] != kapt.Output.String() {
+ t.Errorf("expected %q in kotlinc srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
+ }
+ if javac.Args["srcJars"] != kapt.Output.String() {
+ t.Errorf("expected %q in javac srcjars %v", kapt.Output.String(), kotlinc.Args["srcJars"])
+ }
- // Test that the processors are not passed to javac
- if javac.Args["processorPath"] != "" {
- t.Errorf("expected processorPath '', got %q", javac.Args["processorPath"])
- }
- if javac.Args["processor"] != "-proc:none" {
- t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
- }
+ // Test that the processors are passed to kapt
+ expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
+ " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
+ if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
+ t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
+ }
+ expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
+ if kapt.Args["kaptProcessor"] != expectedProcessor {
+ t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
+ }
+
+ // Test that the processors are not passed to javac
+ if javac.Args["processorpath"] != "" {
+ t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
+ }
+ if javac.Args["processor"] != "-proc:none" {
+ t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
+ }
+ })
+
+ t.Run("errorprone", func(t *testing.T) {
+ env := map[string]string{
+ "RUN_ERROR_PRONE": "true",
+ }
+ config := testConfig(env, bp, nil)
+ ctx, _ := testJavaWithConfig(t, config)
+
+ buildOS := android.BuildOs.String()
+
+ kapt := ctx.ModuleForTests("foo", "android_common").Rule("kapt")
+ //kotlinc := ctx.ModuleForTests("foo", "android_common").Rule("kotlinc")
+ javac := ctx.ModuleForTests("foo", "android_common").Description("javac")
+ errorprone := ctx.ModuleForTests("foo", "android_common").Description("errorprone")
+
+ bar := ctx.ModuleForTests("bar", buildOS+"_common").Description("javac").Output.String()
+ baz := ctx.ModuleForTests("baz", buildOS+"_common").Description("javac").Output.String()
+ myCheck := ctx.ModuleForTests("my_check", buildOS+"_common").Description("javac").Output.String()
+
+ // Test that the errorprone plugins are not passed to kapt
+ expectedProcessorPath := "-P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + bar +
+ " -P plugin:org.jetbrains.kotlin.kapt3:apclasspath=" + baz
+ if kapt.Args["kaptProcessorPath"] != expectedProcessorPath {
+ t.Errorf("expected kaptProcessorPath %q, got %q", expectedProcessorPath, kapt.Args["kaptProcessorPath"])
+ }
+ expectedProcessor := "-P plugin:org.jetbrains.kotlin.kapt3:processors=com.bar -P plugin:org.jetbrains.kotlin.kapt3:processors=com.baz"
+ if kapt.Args["kaptProcessor"] != expectedProcessor {
+ t.Errorf("expected kaptProcessor %q, got %q", expectedProcessor, kapt.Args["kaptProcessor"])
+ }
+
+ // Test that the errorprone plugins are not passed to javac
+ if javac.Args["processorpath"] != "" {
+ t.Errorf("expected processorPath '', got %q", javac.Args["processorpath"])
+ }
+ if javac.Args["processor"] != "-proc:none" {
+ t.Errorf("expected processor '-proc:none', got %q", javac.Args["processor"])
+ }
+
+ // Test that the errorprone plugins are passed to errorprone
+ expectedProcessorPath = "-processorpath " + myCheck
+ if errorprone.Args["processorpath"] != expectedProcessorPath {
+ t.Errorf("expected processorpath %q, got %q", expectedProcessorPath, errorprone.Args["processorpath"])
+ }
+ if errorprone.Args["processor"] != "-proc:none" {
+ t.Errorf("expected processor '-proc:none', got %q", errorprone.Args["processor"])
+ }
+ })
}
func TestKaptEncodeFlags(t *testing.T) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index a259822..9bb6ae8 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -2296,11 +2296,10 @@
scopeSet.AddProperty("jars", jars)
// Merge the stubs source jar into the snapshot zip so that when it is unpacked
- // the source files are also unpacked. Use a glob so that if the directory is missing
- // (because there are no stubs sources for this scope) it will not fail.
+ // the source files are also unpacked.
snapshotRelativeDir := filepath.Join(scopeDir, ctx.Name()+"_stub_sources")
ctx.SnapshotBuilder().UnzipToSnapshot(properties.StubsSrcJar, snapshotRelativeDir)
- scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir + "/**/*.java"})
+ scopeSet.AddProperty("stub_srcs", []string{snapshotRelativeDir})
if properties.CurrentApiFile != nil {
currentApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+".txt")
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index ec8ebb3..b44f66e 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -976,21 +976,21 @@
shared_library: false,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
test: {
jars: ["sdk_library/test/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/test/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/test/myjavalib_stub_sources"],
current_api: "sdk_library/test/myjavalib.txt",
removed_api: "sdk_library/test/myjavalib-removed.txt",
sdk_version: "test_current",
@@ -1005,21 +1005,21 @@
shared_library: false,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
test: {
jars: ["sdk_library/test/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/test/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/test/myjavalib_stub_sources"],
current_api: "sdk_library/test/myjavalib.txt",
removed_api: "sdk_library/test/myjavalib-removed.txt",
sdk_version: "test_current",
@@ -1077,7 +1077,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "none",
@@ -1092,7 +1092,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "none",
@@ -1146,7 +1146,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "module_current",
@@ -1161,7 +1161,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "module_current",
@@ -1218,14 +1218,14 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
@@ -1240,14 +1240,14 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
@@ -1311,21 +1311,21 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
module_lib: {
jars: ["sdk_library/module-lib/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/module-lib/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/module-lib/myjavalib_stub_sources"],
current_api: "sdk_library/module-lib/myjavalib.txt",
removed_api: "sdk_library/module-lib/myjavalib-removed.txt",
sdk_version: "module_current",
@@ -1340,21 +1340,21 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system: {
jars: ["sdk_library/system/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system/myjavalib_stub_sources"],
current_api: "sdk_library/system/myjavalib.txt",
removed_api: "sdk_library/system/myjavalib-removed.txt",
sdk_version: "system_current",
},
module_lib: {
jars: ["sdk_library/module-lib/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/module-lib/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/module-lib/myjavalib_stub_sources"],
current_api: "sdk_library/module-lib/myjavalib.txt",
removed_api: "sdk_library/module-lib/myjavalib-removed.txt",
sdk_version: "module_current",
@@ -1419,14 +1419,14 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system_server: {
jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
current_api: "sdk_library/system-server/myjavalib.txt",
removed_api: "sdk_library/system-server/myjavalib-removed.txt",
sdk_version: "system_server_current",
@@ -1441,14 +1441,14 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
},
system_server: {
jars: ["sdk_library/system-server/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/system-server/myjavalib_stub_sources"],
current_api: "sdk_library/system-server/myjavalib.txt",
removed_api: "sdk_library/system-server/myjavalib-removed.txt",
sdk_version: "system_server_current",
@@ -1508,7 +1508,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
@@ -1524,7 +1524,7 @@
shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
@@ -1584,7 +1584,7 @@
doctag_files: ["doctags/docs/known_doctags"],
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
@@ -1600,7 +1600,7 @@
doctag_files: ["doctags/docs/known_doctags"],
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
- stub_srcs: ["sdk_library/public/myjavalib_stub_sources/**/*.java"],
+ stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
current_api: "sdk_library/public/myjavalib.txt",
removed_api: "sdk_library/public/myjavalib-removed.txt",
sdk_version: "current",
diff --git a/tradefed/autogen.go b/tradefed/autogen.go
index b35f831..27d71e8 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -188,7 +188,7 @@
}
func AutoGenJavaTestConfig(ctx android.ModuleContext, testConfigProp *string, testConfigTemplateProp *string,
- testSuites []string, autoGenConfig *bool) android.Path {
+ testSuites []string, autoGenConfig *bool, unitTest *bool) android.Path {
path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
if autogenPath != nil {
templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
@@ -198,7 +198,11 @@
if ctx.Device() {
autogenTemplate(ctx, autogenPath, "${JavaTestConfigTemplate}", nil, "")
} else {
- autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", nil, "")
+ if Bool(unitTest) {
+ autogenTemplate(ctx, autogenPath, "${JavaHostUnitTestConfigTemplate}", nil, "")
+ } else {
+ autogenTemplate(ctx, autogenPath, "${JavaHostTestConfigTemplate}", nil, "")
+ }
}
}
return autogenPath
diff --git a/tradefed/config.go b/tradefed/config.go
index f7e8349..f3566a8 100644
--- a/tradefed/config.go
+++ b/tradefed/config.go
@@ -27,6 +27,7 @@
pctx.SourcePathVariable("InstrumentationTestConfigTemplate", "build/make/core/instrumentation_test_config_template.xml")
pctx.SourcePathVariable("JavaTestConfigTemplate", "build/make/core/java_test_config_template.xml")
pctx.SourcePathVariable("JavaHostTestConfigTemplate", "build/make/core/java_host_test_config_template.xml")
+ pctx.SourcePathVariable("JavaHostUnitTestConfigTemplate", "build/make/core/java_host_unit_test_config_template.xml")
pctx.SourcePathVariable("NativeBenchmarkTestConfigTemplate", "build/make/core/native_benchmark_test_config_template.xml")
pctx.SourcePathVariable("NativeHostTestConfigTemplate", "build/make/core/native_host_test_config_template.xml")
pctx.SourcePathVariable("NativeTestConfigTemplate", "build/make/core/native_test_config_template.xml")
diff --git a/ui/build/kati.go b/ui/build/kati.go
index f6c0f52..06ec646 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -33,12 +33,18 @@
const katiCleanspecSuffix = "-cleanspec"
const katiPackageSuffix = "-package"
-// genKatiSuffix creates a suffix for kati-generated files so that we can cache
-// them based on their inputs. So this should encode all common changes to Kati
-// inputs. Currently that includes the TARGET_PRODUCT, kati-processed command
-// line arguments, and the directories specified by mm/mmm.
+// genKatiSuffix creates a filename suffix for kati-generated files so that we
+// can cache them based on their inputs. Such files include the generated Ninja
+// files and env.sh environment variable setup files.
+//
+// The filename suffix should encode all common changes to Kati inputs.
+// Currently that includes the TARGET_PRODUCT and kati-processed command line
+// arguments.
func genKatiSuffix(ctx Context, config Config) {
+ // Construct the base suffix.
katiSuffix := "-" + config.TargetProduct()
+
+ // Append kati arguments to the suffix.
if args := config.KatiArgs(); len(args) > 0 {
katiSuffix += "-" + spaceSlashReplacer.Replace(strings.Join(args, "_"))
}
@@ -60,51 +66,101 @@
}
}
+// Base function to construct and run the Kati command line with additional
+// arguments, and a custom function closure to mutate the environment Kati runs
+// in.
func runKati(ctx Context, config Config, extraSuffix string, args []string, envFunc func(*Environment)) {
executable := config.PrebuiltBuildTool("ckati")
+ // cKati arguments.
args = append([]string{
+ // Instead of executing commands directly, generate a Ninja file.
"--ninja",
+ // Generate Ninja files in the output directory.
"--ninja_dir=" + config.OutDir(),
+ // Filename suffix of the generated Ninja file.
"--ninja_suffix=" + config.KatiSuffix() + extraSuffix,
+ // Remove common parts at the beginning of a Ninja file, like build_dir,
+ // local_pool and _kati_always_build_. Allows Kati to be run multiple
+ // times, with generated Ninja files combined in a single invocation
+ // using 'include'.
"--no_ninja_prelude",
+ // Support declaring phony outputs in AOSP Ninja.
"--use_ninja_phony_output",
+ // Support declaring symlink outputs in AOSP Ninja.
"--use_ninja_symlink_outputs",
+ // Regenerate the Ninja file if environment inputs have changed. e.g.
+ // CLI flags, .mk file timestamps, env vars, $(wildcard ..) and some
+ // $(shell ..) results.
"--regen",
+ // Skip '-include' directives starting with the specified path. Used to
+ // ignore generated .mk files.
"--ignore_optional_include=" + filepath.Join(config.OutDir(), "%.P"),
+ // Detect the use of $(shell echo ...).
"--detect_android_echo",
+ // Colorful ANSI-based warning and error messages.
"--color_warnings",
+ // Generate all targets, not just the top level requested ones.
"--gen_all_targets",
+ // Use the built-in emulator of GNU find for better file finding
+ // performance. Used with $(shell find ...).
"--use_find_emulator",
+ // Fail when the find emulator encounters problems.
"--werror_find_emulator",
+ // Do not provide any built-in rules.
"--no_builtin_rules",
+ // Fail when suffix rules are used.
"--werror_suffix_rules",
- "--warn_real_to_phony",
- "--warn_phony_looks_real",
+ // Fail when a real target depends on a phony target.
"--werror_real_to_phony",
- "--werror_phony_looks_real",
- "--werror_writable",
+ // Makes real_to_phony checks assume that any top-level or leaf
+ // dependencies that does *not* have a '/' in it is a phony target.
"--top_level_phony",
+ // Fail when a phony target contains slashes.
+ "--werror_phony_looks_real",
+ // Fail when writing to a read-only directory.
+ "--werror_writable",
+ // Print Kati's internal statistics, such as the number of variables,
+ // implicit/explicit/suffix rules, and so on.
"--kati_stats",
}, args...)
+ // Generate a minimal Ninja file.
+ //
+ // Used for build_test and multiproduct_kati, which runs Kati several
+ // hundred times for different configurations to test file generation logic.
+ // These can result in generating Ninja files reaching ~1GB or more,
+ // resulting in ~hundreds of GBs of writes.
+ //
+ // Since we don't care about executing the Ninja files in these test cases,
+ // generating the Ninja file content wastes time, so skip writing any
+ // information out with --empty_ninja_file.
+ //
+ // From https://github.com/google/kati/commit/87b8da7af2c8bea28b1d8ab17679453d859f96e5
if config.Environment().IsEnvTrue("EMPTY_NINJA_FILE") {
args = append(args, "--empty_ninja_file")
}
+ // Apply 'local_pool' to to all rules that don't specify a pool.
if config.UseRemoteBuild() {
args = append(args, "--default_pool=local_pool")
}
cmd := Command(ctx, config, "ckati", executable, args...)
+
+ // Set up the nsjail sandbox.
cmd.Sandbox = katiSandbox
+
+ // Set up stdout and stderr.
pipe, err := cmd.StdoutPipe()
if err != nil {
ctx.Fatalln("Error getting output pipe for ckati:", err)
}
cmd.Stderr = cmd.Stdout
+ // Apply the caller's function closure to mutate the environment variables.
envFunc(cmd.Environment)
+ // Pass on various build environment metadata to Kati.
if _, ok := cmd.Environment.Get("BUILD_USERNAME"); !ok {
username := "unknown"
if u, err := user.Current(); err == nil {
@@ -125,6 +181,8 @@
}
cmd.StartOrFatal()
+ // Set up the ToolStatus command line reader for Kati for a consistent UI
+ // for the user.
status.KatiReader(ctx.Status.StartTool(), pipe)
cmd.WaitOrFatal()
}
@@ -134,35 +192,57 @@
defer ctx.EndTrace()
args := []string{
+ // Mark the output directory as writable.
"--writable", config.OutDir() + "/",
+ // Fail when encountering implicit rules. e.g.
+ // %.foo: %.bar
+ // cp $< $@
"--werror_implicit_rules",
+ // Entry point for the Kati Ninja file generation.
"-f", "build/make/core/main.mk",
}
if !config.BuildBrokenDupRules() {
+ // Fail when redefining / duplicating a target.
args = append(args, "--werror_overriding_commands")
}
args = append(args, config.KatiArgs()...)
args = append(args,
+ // Location of the Make vars .mk file generated by Soong.
"SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
+ // Location of the Android.mk file generated by Soong. This
+ // file contains Soong modules represented as Kati modules,
+ // allowing Kati modules to depend on Soong modules.
"SOONG_ANDROID_MK="+config.SoongAndroidMk(),
+ // Directory containing outputs for the target device.
"TARGET_DEVICE_DIR="+config.TargetDeviceDir(),
+ // Directory containing .mk files for packaging purposes, such as
+ // the dist.mk file, containing dist-for-goals data.
"KATI_PACKAGE_MK_DIR="+config.KatiPackageMkDir())
runKati(ctx, config, katiBuildSuffix, args, func(env *Environment) {})
+ // compress and dist the main build ninja file.
distGzipFile(ctx, config, config.KatiBuildNinjaFile())
+ // Cleanup steps.
cleanCopyHeaders(ctx, config)
cleanOldInstalledFiles(ctx, config)
}
+// Clean out obsolete header files on the disk that were *not copied* during the
+// build with BUILD_COPY_HEADERS and LOCAL_COPY_HEADERS.
+//
+// These should be increasingly uncommon, as it's a deprecated feature and there
+// isn't an equivalent feature in Soong.
func cleanCopyHeaders(ctx Context, config Config) {
ctx.BeginTrace("clean", "clean copy headers")
defer ctx.EndTrace()
+ // Read and parse the list of copied headers from a file in the product
+ // output directory.
data, err := ioutil.ReadFile(filepath.Join(config.ProductOut(), ".copied_headers_list"))
if err != nil {
if os.IsNotExist(err) {
@@ -178,6 +258,8 @@
headerDir := headers[0]
headers = headers[1:]
+ // Walk the tree and remove any headers that are not in the list of copied
+ // headers in the current build.
filepath.Walk(headerDir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
@@ -196,6 +278,8 @@
})
}
+// Clean out any previously installed files from the disk that are not installed
+// in the current build.
func cleanOldInstalledFiles(ctx Context, config Config) {
ctx.BeginTrace("clean", "clean old installed files")
defer ctx.EndTrace()
@@ -213,18 +297,27 @@
cleanOldFiles(ctx, config.HostOut(), ".installable_test_files")
}
+// Generate the Ninja file containing the packaging command lines for the dist
+// dir.
func runKatiPackage(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunKati, "kati package")
defer ctx.EndTrace()
args := []string{
+ // Mark the dist dir as writable.
"--writable", config.DistDir() + "/",
+ // Fail when encountering implicit rules. e.g.
"--werror_implicit_rules",
+ // Fail when redefining / duplicating a target.
"--werror_overriding_commands",
+ // Entry point.
"-f", "build/make/packaging/main.mk",
+ // Directory containing .mk files for packaging purposes, such as
+ // the dist.mk file, containing dist-for-goals data.
"KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
}
+ // Run Kati against a restricted set of environment variables.
runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
env.Allow([]string{
// Some generic basics
@@ -251,16 +344,21 @@
}
})
+ // Compress and dist the packaging Ninja file.
distGzipFile(ctx, config, config.KatiPackageNinjaFile())
}
+// Run Kati on the cleanspec files to clean the build.
func runKatiCleanSpec(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunKati, "kati cleanspec")
defer ctx.EndTrace()
runKati(ctx, config, katiCleanspecSuffix, []string{
+ // Fail when encountering implicit rules. e.g.
"--werror_implicit_rules",
+ // Fail when redefining / duplicating a target.
"--werror_overriding_commands",
+ // Entry point.
"-f", "build/make/core/cleanbuild.mk",
"SOONG_MAKEVARS_MK=" + config.SoongMakeVarsMk(),
"TARGET_DEVICE_DIR=" + config.TargetDeviceDir(),
diff --git a/ui/build/path.go b/ui/build/path.go
index 6f5cf78..86e61c0 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -29,6 +29,9 @@
"android/soong/ui/metrics"
)
+// parsePathDir returns the list of filenames of readable files in a directory.
+// This does not recurse into subdirectories, and does not contain subdirectory
+// names in the list.
func parsePathDir(dir string) []string {
f, err := os.Open(dir)
if err != nil {
@@ -54,10 +57,12 @@
return ret
}
-// A "lite" version of SetupPath used for dumpvars, or other places that need
-// minimal overhead (but at the expense of logging). If tmpDir is empty, the
-// default TMPDIR is used from config.
+// SetupLitePath is the "lite" version of SetupPath used for dumpvars, or other
+// places that does not need the full logging capabilities of path_interposer,
+// wants the minimal performance overhead, and still get the benefits of $PATH
+// hermeticity.
func SetupLitePath(ctx Context, config Config, tmpDir string) {
+ // Don't replace the path twice.
if config.pathReplaced {
return
}
@@ -67,6 +72,7 @@
origPath, _ := config.Environment().Get("PATH")
+ // If tmpDir is empty, the default TMPDIR is used from config.
if tmpDir == "" {
tmpDir, _ = config.Environment().Get("TMPDIR")
}
@@ -74,8 +80,10 @@
ensureEmptyDirectoriesExist(ctx, myPath)
os.Setenv("PATH", origPath)
+ // Iterate over the ACL configuration of host tools for this build.
for name, pathConfig := range paths.Configuration {
if !pathConfig.Symlink {
+ // Excludes 'Forbidden' and 'LinuxOnlyPrebuilt' PathConfigs.
continue
}
@@ -88,6 +96,7 @@
continue
}
+ // Symlink allowed host tools into a directory for hermeticity.
err = os.Symlink(origExec, filepath.Join(myPath, name))
if err != nil {
ctx.Fatalln("Failed to create symlink:", err)
@@ -96,14 +105,26 @@
myPath, _ = filepath.Abs(myPath)
+ // Set up the checked-in prebuilts path directory for the current host OS.
prebuiltsPath, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86")
myPath = prebuiltsPath + string(os.PathListSeparator) + myPath
+ // Set $PATH to be the directories containing the host tool symlinks, and
+ // the prebuilts directory for the current host OS.
config.Environment().Set("PATH", myPath)
config.pathReplaced = true
}
+// SetupPath uses the path_interposer to intercept calls to $PATH binaries, and
+// communicates with the interposer to validate allowed $PATH binaries at
+// runtime, using logs as a medium.
+//
+// This results in hermetic directories in $PATH containing only allowed host
+// tools for the build, and replaces $PATH to contain *only* these directories,
+// and enables an incremental restriction of tools allowed in the $PATH without
+// breaking existing use cases.
func SetupPath(ctx Context, config Config) {
+ // Don't replace $PATH twice.
if config.pathReplaced {
return
}
@@ -112,9 +133,11 @@
defer ctx.EndTrace()
origPath, _ := config.Environment().Get("PATH")
+ // The directory containing symlinks from binaries in $PATH to the interposer.
myPath := filepath.Join(config.OutDir(), ".path")
interposer := myPath + "_interposer"
+ // Bootstrap the path_interposer Go binary with microfactory.
var cfg microfactory.Config
cfg.Map("android/soong", "build/soong")
cfg.TrimPath, _ = filepath.Abs(".")
@@ -122,15 +145,20 @@
ctx.Fatalln("Failed to build path interposer:", err)
}
+ // Save the original $PATH in a file.
if err := ioutil.WriteFile(interposer+"_origpath", []byte(origPath), 0777); err != nil {
ctx.Fatalln("Failed to write original path:", err)
}
+ // Communication with the path interposer works over log entries. Set up the
+ // listener channel for the log entries here.
entries, err := paths.LogListener(ctx.Context, interposer+"_log")
if err != nil {
ctx.Fatalln("Failed to listen for path logs:", err)
}
+ // Loop over all log entry listener channels to validate usage of only
+ // allowed PATH tools at runtime.
go func() {
for log := range entries {
curPid := os.Getpid()
@@ -140,6 +168,8 @@
break
}
}
+ // Compute the error message along with the process tree, including
+ // parents, for this log line.
procPrints := []string{
"See https://android.googlesource.com/platform/build/+/master/Changes.md#PATH_Tools for more information.",
}
@@ -150,6 +180,7 @@
}
}
+ // Validate usage against disallowed or missing PATH tools.
config := paths.GetConfig(log.Basename)
if config.Error {
ctx.Printf("Disallowed PATH tool %q used: %#v", log.Basename, log.Args)
@@ -165,8 +196,10 @@
}
}()
+ // Create the .path directory.
ensureEmptyDirectoriesExist(ctx, myPath)
+ // Compute the full list of binaries available in the original $PATH.
var execs []string
for _, pathEntry := range filepath.SplitList(origPath) {
if pathEntry == "" {
@@ -185,8 +218,14 @@
ctx.Fatalln("TEMPORARY_DISABLE_PATH_RESTRICTIONS was a temporary migration method, and is now obsolete.")
}
+ // Create symlinks from the path_interposer binary to all binaries for each
+ // directory in the original $PATH. This ensures that during the build,
+ // every call to a binary that's expected to be in the $PATH will be
+ // intercepted by the path_interposer binary, and validated with the
+ // LogEntry listener above at build time.
for _, name := range execs {
if !paths.GetConfig(name).Symlink {
+ // Ignore host tools that shouldn't be symlinked.
continue
}
@@ -200,11 +239,13 @@
myPath, _ = filepath.Abs(myPath)
- // We put some prebuilts in $PATH, since it's infeasible to add dependencies for all of
- // them.
+ // We put some prebuilts in $PATH, since it's infeasible to add dependencies
+ // for all of them.
prebuiltsPath, _ := filepath.Abs("prebuilts/build-tools/path/" + runtime.GOOS + "-x86")
myPath = prebuiltsPath + string(os.PathListSeparator) + myPath
+ // Replace the $PATH variable with the path_interposer symlinks, and
+ // checked-in prebuilts.
config.Environment().Set("PATH", myPath)
config.pathReplaced = true
}