Merge "rust: Support protobuf wrappers well known types"
diff --git a/android/androidmk.go b/android/androidmk.go
index 4f6e24c..72b6584 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -518,7 +518,7 @@
a.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
// If the install rule was generated by Soong tell Make about it.
- if amod.InstallBypassMake() && len(base.katiInstalls) > 0 {
+ if len(base.katiInstalls) > 0 {
// Assume the primary install file is last since it probably needs to depend on any other
// installed files. If that is not the case we can add a method to specify the primary
// installed file.
diff --git a/android/arch.go b/android/arch.go
index 3cc5e82..e08fd5c 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -168,7 +168,7 @@
return archType
}
-// ArchTypeList returns the a slice copy of the 4 supported ArchTypes for arm,
+// ArchTypeList returns a slice copy of the 4 supported ArchTypes for arm,
// arm64, x86 and x86_64.
func ArchTypeList() []ArchType {
return append([]ArchType(nil), archTypeList...)
@@ -408,7 +408,7 @@
// addPathDepsForProps does not descend into sub structs, so we need to descend into the
// arch-specific properties ourselves
- properties := []interface{}{}
+ var properties []interface{}
for _, archProperties := range m.archProperties {
for _, archProps := range archProperties {
archPropValues := reflect.ValueOf(archProps).Elem()
@@ -995,8 +995,11 @@
// Store the original list of top level property structs
base.generalProperties = m.GetProperties()
+ if len(base.archProperties) != 0 {
+ panic(fmt.Errorf("module %s already has archProperties", m.Name()))
+ }
- for _, properties := range base.generalProperties {
+ getStructType := func(properties interface{}) reflect.Type {
propertiesValue := reflect.ValueOf(properties)
t := propertiesValue.Type()
if propertiesValue.Kind() != reflect.Ptr {
@@ -1006,10 +1009,14 @@
propertiesValue = propertiesValue.Elem()
if propertiesValue.Kind() != reflect.Struct {
- panic(fmt.Errorf("properties must be a pointer to a struct, got %T",
+ panic(fmt.Errorf("properties must be a pointer to a struct, got a pointer to %T",
propertiesValue.Interface()))
}
+ return t
+ }
+ for _, properties := range base.generalProperties {
+ t := getStructType(properties)
// Get or create the arch-specific property struct types for this property struct type.
archPropTypes := archPropTypeMap.Once(NewCustomOnceKey(t), func() interface{} {
return createArchPropTypeDesc(t)
diff --git a/android/bazel.go b/android/bazel.go
index 8c63204..970ad0d 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -245,6 +245,7 @@
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
+ "build/soong/scripts": Bp2BuildDefaultTrueRecursively,
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
"development/apps/DevelopmentSettings": Bp2BuildDefaultTrue,
"development/apps/Fallback": Bp2BuildDefaultTrue,
@@ -296,6 +297,7 @@
"external/libcxx": Bp2BuildDefaultTrueRecursively,
"external/libcxxabi": Bp2BuildDefaultTrueRecursively,
"external/libevent": Bp2BuildDefaultTrueRecursively,
+ "external/libpng": Bp2BuildDefaultTrueRecursively,
"external/lz4/lib": Bp2BuildDefaultTrue,
"external/lzma/C": Bp2BuildDefaultTrueRecursively,
"external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
@@ -303,9 +305,9 @@
"external/pcre": Bp2BuildDefaultTrueRecursively,
"external/protobuf": Bp2BuildDefaultTrueRecursively,
"external/python/six": Bp2BuildDefaultTrueRecursively,
- "external/selinux/libsepol": Bp2BuildDefaultTrueRecursively,
"external/scudo": Bp2BuildDefaultTrueRecursively,
"external/selinux/libselinux": Bp2BuildDefaultTrueRecursively,
+ "external/selinux/libsepol": Bp2BuildDefaultTrueRecursively,
"external/zlib": Bp2BuildDefaultTrueRecursively,
"external/zstd": Bp2BuildDefaultTrueRecursively,
"frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
@@ -322,6 +324,7 @@
"packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
"packages/apps/Protips": Bp2BuildDefaultTrue,
"packages/modules/adb": Bp2BuildDefaultTrue,
+ "packages/modules/adb/apex": Bp2BuildDefaultTrue,
"packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
@@ -333,7 +336,7 @@
"packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue,
"prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
"system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures
- "system/core/debuggerd": Bp2BuildDefaultTrue,
+ "system/core/debuggerd": Bp2BuildDefaultTrueRecursively,
"system/core/diagnose_usb": Bp2BuildDefaultTrueRecursively,
"system/core/libasyncio": Bp2BuildDefaultTrue,
"system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively,
@@ -361,24 +364,28 @@
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
bp2buildModuleDoNotConvertList = []string{
- "libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
- "art_libdexfile_dex_instruction_list_header", // breaks libart_mterp.armng, header not found
-
"libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers
"libcmd", // depends on unconverted modules: libbinder
+ "libdexfile_support_static", // Depends on unconverted module: libdexfile_external_headers
+ "libunwindstack_local", "libunwindstack_utils", "libc_malloc_debug", "libfdtrack", // Depends on unconverted module: libunwindstack
+
+ "libdexfile_support", // TODO(b/210546943): Enabled based on product variables.
+ "libdexfile_external_headers", // TODO(b/210546943): Enabled based on product variables.
+
+ "libunwindstack", // Depends on unconverted module libdexfile_support.
+ "libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
+
"chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol
"libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules
- "get_clang_version_test", // depends on unconverted module: get_clang_version
+ "gen-kotlin-build-file.py", // module has same name as source
- "libbinder", // TODO(b/188503688): Disabled for some archs,
"libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup.
- "libnativehelper_lazy_mts_jni", // depends on unconverted modules: libgmock_ndk
- "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk
- "libnativetesthelper_jni", // depends on unconverted modules: libgtest_ndk_c++
+ "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk
+ "libnativetesthelper_jni", "libgmock_main_ndk", "libgmock_ndk", // depends on unconverted module: libgtest_ndk_c++
"statslog-framework-java-gen", "statslog.cpp", "statslog.h", "statslog.rs", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
@@ -386,31 +393,24 @@
"libstatslog", // depends on unconverted modules: statslog.cpp, statslog.h, ...
- "libgmock_main_ndk", "libgmock_ndk", // depends on unconverted module: libgtest_ndk_c++
-
"cmd", // depends on unconverted module packagemanager_aidl-cpp, of unsupported type aidl_interface
"servicedispatcher", // depends on unconverted module android.debug_aidl, of unsupported type aidl_interface
"libutilscallstack", // depends on unconverted module libbacktrace
"libbacktrace", // depends on unconverted module libunwindstack
"libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core
"libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
- "unwind_for_offline", // depends on unconverted module libunwindstack_utils
- "libdebuggerd", // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite
- "libdexfile_static", // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library.
+ "unwind_for_offline", // depends on unconverted module libunwindstack_utils
+ "libdebuggerd", // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite
+ "libdexfile_static", // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library.
+
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
+ "static_crasher", // depends on unconverted modules: libdebuggerd_handler
- "pbtombstone", // depends on libprotobuf-cpp-lite, libtombstone_proto
- "crash_dump", // depends on unconverted module libprotobuf-cpp-lite
-
- "libunwindstack_local", "libunwindstack_utils", // depends on unconverted module libunwindstack
- "libunwindstack", // depends on libdexfile_support, of unsupported module type art_cc_library_static
- "libc_malloc_debug", // depends on unconverted module libunwindstack
+ "pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
"libbase_ndk", // http://b/186826477, fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
- "lib_linker_config_proto_lite", // contains .proto sources
-
"libprotobuf-python", // contains .proto sources
"libprotobuf-internal-protos", // b/210751803, we don't handle path property for filegroups
"libprotobuf-internal-python-srcs", // b/210751803, we don't handle path property for filegroups
@@ -418,10 +418,7 @@
"libprotobuf-java-util-full", // b/210751803, we don't handle path property for filegroups
"conscrypt", // b/210751803, we don't handle path property for filegroups
- "libseccomp_policy", // b/201094425: depends on func_to_syscall_nrs, which depends on py_binary, which is unsupported in mixed builds.
- "libfdtrack", // depends on unconverted module libunwindstack
-
- "gwp_asan_crash_handler", // cc_library, ld.lld: error: undefined symbol: memset
+ "conv_linker_config", // depends on linker_config_proto, a python lib with proto sources
"brotli-fuzzer-corpus", // b/202015218: outputs are in location incompatible with bazel genrule handling.
@@ -430,14 +427,8 @@
"platform_tools_properties",
"build_tools_source_properties",
- // Tests. Handle later.
- "libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found
- "libjemalloc5_integrationtest",
- "libjemalloc5_stresstestlib",
- "libjemalloc5_unittest",
-
// APEX support
- "com.android.runtime", // http://b/194746715, apex, depends on 'libc_malloc_debug'
+ "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
"libgtest_ndk_c++", // b/201816222: Requires sdk_version support.
"libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
@@ -451,8 +442,7 @@
"linkerconfig", // http://b/202876379 has arch-variant static_executable
"mdnsd", // http://b/202876379 has arch-variant static_executable
- "acvp_modulewrapper", // disabled for android x86/x86_64
- "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
+ "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
"libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette,
"libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
@@ -460,13 +450,13 @@
// Per-module denylist of cc_library modules to only generate the static
// variant if their shared variant isn't ready or buildable by Bazel.
- bp2buildCcLibraryStaticOnlyList = []string{
- "libjemalloc5", // http://b/188503688, cc_library, `target: { android: { enabled: false } }` for android targets.
- }
+ bp2buildCcLibraryStaticOnlyList = []string{}
// Per-module denylist to opt modules out of mixed builds. Such modules will
// still be generated via bp2build.
mixedBuildsDisabledList = []string{
+ "art_libdexfile_dex_instruction_list_header", // breaks libart_mterp.armng, header not found
+
"libbrotli", // http://b/198585397, ld.lld: error: bionic/libc/arch-arm64/generic/bionic/memmove.S:95:(.text+0x10): relocation R_AARCH64_CONDBR19 out of range: -1404176 is not in [-1048576, 1048575]; references __memcpy
"minijail_constants_json", // http://b/200899432, bazel-built cc_genrule does not work in mixed build when it is a dependency of another soong module.
@@ -528,6 +518,9 @@
// Windows toolchains are not currently supported.
return false
}
+ if !ctx.Module().Enabled() {
+ return false
+ }
if !ctx.Config().BazelContext.BazelEnabled() {
return false
}
diff --git a/android/config.go b/android/config.go
index 5d90fd2..0187a8a 100644
--- a/android/config.go
+++ b/android/config.go
@@ -569,9 +569,6 @@
func (c *config) HostToolPath(ctx PathContext, tool string) Path {
path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false, tool)
- if ctx.Config().KatiEnabled() {
- path = path.ToMakePath()
- }
return path
}
@@ -581,17 +578,11 @@
ext = ".dylib"
}
path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "lib64", false, lib+ext)
- if ctx.Config().KatiEnabled() {
- path = path.ToMakePath()
- }
return path
}
func (c *config) HostJavaToolPath(ctx PathContext, tool string) Path {
path := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "framework", false, tool)
- if ctx.Config().KatiEnabled() {
- path = path.ToMakePath()
- }
return path
}
@@ -667,6 +658,10 @@
return value == "0" || value == "n" || value == "no" || value == "off" || value == "false"
}
+func (c *config) TargetsJava11() bool {
+ return c.IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11")
+}
+
// EnvDeps returns the environment variables this build depends on. The first
// call to this function blocks future reads from the environment.
func (c *config) EnvDeps() map[string]string {
@@ -1250,6 +1245,10 @@
return coverage
}
+func (c *deviceConfig) AfdoAdditionalProfileDirs() []string {
+ return c.config.productVariables.AfdoAdditionalProfileDirs
+}
+
func (c *deviceConfig) PgoAdditionalProfileDirs() []string {
return c.config.productVariables.PgoAdditionalProfileDirs
}
@@ -1485,6 +1484,22 @@
return c.config.productVariables.BoardReqdMaskPolicy
}
+func (c *deviceConfig) BoardSystemExtPublicPrebuiltDirs() []string {
+ return c.config.productVariables.BoardSystemExtPublicPrebuiltDirs
+}
+
+func (c *deviceConfig) BoardSystemExtPrivatePrebuiltDirs() []string {
+ return c.config.productVariables.BoardSystemExtPrivatePrebuiltDirs
+}
+
+func (c *deviceConfig) BoardProductPublicPrebuiltDirs() []string {
+ return c.config.productVariables.BoardProductPublicPrebuiltDirs
+}
+
+func (c *deviceConfig) BoardProductPrivatePrebuiltDirs() []string {
+ return c.config.productVariables.BoardProductPrivatePrebuiltDirs
+}
+
func (c *deviceConfig) DirectedVendorSnapshot() bool {
return c.config.productVariables.DirectedVendorSnapshot
}
@@ -1698,7 +1713,7 @@
}
// Append a list of (apex, jar) pairs to the list.
-func (l *ConfiguredJarList) AppendList(other ConfiguredJarList) ConfiguredJarList {
+func (l *ConfiguredJarList) AppendList(other *ConfiguredJarList) ConfiguredJarList {
apexes := make([]string, 0, l.Len()+other.Len())
jars := make([]string, 0, l.Len()+other.Len())
diff --git a/android/defaults.go b/android/defaults.go
index 7b3d38c..5677638 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -92,6 +92,7 @@
if module.base().module == nil {
panic("InitAndroidModule must be called before InitDefaultableModule")
}
+
module.setProperties(module.GetProperties(), module.base().variableProperties)
module.AddProperties(module.defaults())
@@ -118,6 +119,11 @@
type DefaultsModuleBase struct {
DefaultableModuleBase
+
+ // Included to support setting bazel_module.label for multiple Soong modules to the same Bazel
+ // target. This is primarily useful for modules that were architecture specific and instead are
+ // handled in Bazel as a select().
+ BazelModuleBase
}
// The common pattern for defaults modules is to register separate instances of
@@ -160,6 +166,7 @@
type DefaultsModule interface {
Module
Defaults
+ Bazelable
}
func (d *DefaultsModuleBase) properties() []interface{} {
@@ -170,8 +177,7 @@
return d.defaultableVariableProperties
}
-func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
+func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {}
// ConvertWithBp2build to fulfill Bazelable interface; however, at this time defaults module are
// *NOT* converted with bp2build
@@ -186,6 +192,8 @@
&ApexProperties{},
&distProperties{})
+ // Bazel module must be initialized _before_ Defaults to be included in cc_defaults module.
+ InitBazelModule(module)
initAndroidModuleBase(module)
initProductVariableModule(module)
initArchModule(module)
@@ -212,7 +220,6 @@
// The applicable licenses property for defaults is 'licenses'.
setPrimaryLicensesProperty(module, "licenses", &commonProperties.Licenses)
- base.module = module
}
var _ Defaults = (*DefaultsModuleBase)(nil)
diff --git a/android/module.go b/android/module.go
index 189781a..2750131 100644
--- a/android/module.go
+++ b/android/module.go
@@ -429,7 +429,6 @@
InstallInRecovery() bool
InstallInRoot() bool
InstallInVendor() bool
- InstallBypassMake() bool
InstallForceOS() (*OsType, *ArchType)
RequiredModuleNames() []string
@@ -496,7 +495,6 @@
InstallInRecovery() bool
InstallInRoot() bool
InstallInVendor() bool
- InstallBypassMake() bool
InstallForceOS() (*OsType, *ArchType)
HideFromMake()
IsHideFromMake() bool
@@ -871,6 +869,13 @@
Data bazel.LabelListAttribute
}
+// constraintAttributes represents Bazel attributes pertaining to build constraints,
+// which make restrict building a Bazel target for some set of platforms.
+type constraintAttributes struct {
+ // Constraint values this target can be built for.
+ Target_compatible_with bazel.LabelListAttribute
+}
+
type distProperties struct {
// configuration to distribute output files from this module to the distribution
// directory (default: $OUT/dist, configurable with $DIST_DIR)
@@ -1091,7 +1096,8 @@
m.base().commonProperties.CreateCommonOSVariant = true
}
-func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext) {
+func (attrs *CommonAttributes) fillCommonBp2BuildModuleAttrs(ctx *topDownMutatorContext,
+ enabledPropertyOverrides bazel.BoolAttribute) constraintAttributes {
// Assert passed-in attributes include Name
name := attrs.Name
if len(name) == 0 {
@@ -1109,14 +1115,45 @@
required := depsToLabelList(props.Required)
archVariantProps := mod.GetArchVariantProperties(ctx, &commonProperties{})
+
+ var enabledProperty bazel.BoolAttribute
+ if props.Enabled != nil {
+ enabledProperty.Value = props.Enabled
+ }
+
for axis, configToProps := range archVariantProps {
for config, _props := range configToProps {
if archProps, ok := _props.(*commonProperties); ok {
required.SetSelectValue(axis, config, depsToLabelList(archProps.Required).Value)
+ if archProps.Enabled != nil {
+ enabledProperty.SetSelectValue(axis, config, archProps.Enabled)
+ }
}
}
}
+
+ if enabledPropertyOverrides.Value != nil {
+ enabledProperty.Value = enabledPropertyOverrides.Value
+ }
+ for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
+ configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
+ for cfg, val := range configToBools {
+ enabledProperty.SetSelectValue(axis, cfg, &val)
+ }
+ }
+
data.Append(required)
+
+ var err error
+ constraints := constraintAttributes{}
+ constraints.Target_compatible_with, err = enabledProperty.ToLabelListAttribute(
+ bazel.LabelList{[]bazel.Label{bazel.Label{Label: "@platforms//:incompatible"}}, nil},
+ bazel.LabelList{[]bazel.Label{}, nil})
+
+ if err != nil {
+ ctx.ModuleErrorf("Error processing enabled attribute: %s", err)
+ }
+ return constraints
}
// A ModuleBase object contains the properties that are common to all Android
@@ -1235,10 +1272,11 @@
// A struct containing all relevant information about a Bazel target converted via bp2build.
type bp2buildInfo struct {
- Dir string
- BazelProps bazel.BazelTargetModuleProperties
- CommonAttrs CommonAttributes
- Attrs interface{}
+ Dir string
+ BazelProps bazel.BazelTargetModuleProperties
+ CommonAttrs CommonAttributes
+ ConstraintAttrs constraintAttributes
+ Attrs interface{}
}
// TargetName returns the Bazel target name of a bp2build converted target.
@@ -1264,7 +1302,7 @@
// BazelAttributes returns the Bazel attributes of a bp2build converted target.
func (b bp2buildInfo) BazelAttributes() []interface{} {
- return []interface{}{&b.CommonAttrs, b.Attrs}
+ return []interface{}{&b.CommonAttrs, &b.ConstraintAttrs, b.Attrs}
}
func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
@@ -1704,10 +1742,6 @@
return false
}
-func (m *ModuleBase) InstallBypassMake() bool {
- return true
-}
-
func (m *ModuleBase) InstallForceOS() (*OsType, *ArchType) {
return nil, nil
}
@@ -2096,18 +2130,18 @@
return GlobFiles(e, globPattern, excludes)
}
-func (b *earlyModuleContext) IsSymlink(path Path) bool {
- fileInfo, err := b.config.fs.Lstat(path.String())
+func (e *earlyModuleContext) IsSymlink(path Path) bool {
+ fileInfo, err := e.config.fs.Lstat(path.String())
if err != nil {
- b.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
+ e.ModuleErrorf("os.Lstat(%q) failed: %s", path.String(), err)
}
return fileInfo.Mode()&os.ModeSymlink == os.ModeSymlink
}
-func (b *earlyModuleContext) Readlink(path Path) string {
- dest, err := b.config.fs.Readlink(path.String())
+func (e *earlyModuleContext) Readlink(path Path) string {
+ dest, err := e.config.fs.Readlink(path.String())
if err != nil {
- b.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
+ e.ModuleErrorf("os.Readlink(%q) failed: %s", path.String(), err)
}
return dest
}
@@ -2829,10 +2863,6 @@
return m.module.InstallInRoot()
}
-func (m *moduleContext) InstallBypassMake() bool {
- return m.module.InstallBypassMake()
-}
-
func (m *moduleContext) InstallForceOS() (*OsType, *ArchType) {
return m.module.InstallForceOS()
}
@@ -2857,12 +2887,6 @@
return true
}
- if m.Device() {
- if m.Config().KatiEnabled() && !m.InstallBypassMake() {
- return true
- }
- }
-
return false
}
@@ -2921,7 +2945,7 @@
orderOnlyDeps = deps
}
- if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ if m.Config().KatiEnabled() {
// When creating the install rule in Soong but embedding in Make, write the rule to a
// makefile instead of directly to the ninja file so that main.mk can add the
// dependencies from the `required` property that are hard to resolve in Soong.
@@ -2980,7 +3004,7 @@
}
if !m.skipInstall() {
- if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ if m.Config().KatiEnabled() {
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
// makefile instead of directly to the ninja file so that main.mk can add the
// dependencies from the `required` property that are hard to resolve in Soong.
@@ -3026,7 +3050,7 @@
m.module.base().hooks.runInstallHooks(m, nil, fullInstallPath, true)
if !m.skipInstall() {
- if m.Config().KatiEnabled() && m.InstallBypassMake() {
+ if m.Config().KatiEnabled() {
// When creating the symlink rule in Soong but embedding in Make, write the rule to a
// makefile instead of directly to the ninja file so that main.mk can add the
// dependencies from the `required` property that are hard to resolve in Soong.
diff --git a/android/module_test.go b/android/module_test.go
index 8607a8d..d9e2c87 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -204,10 +204,6 @@
}
}
-func (m *depsModule) InstallBypassMake() bool {
- return true
-}
-
func (m *depsModule) GenerateAndroidBuildActions(ctx ModuleContext) {
outputFile := PathForModuleOut(ctx, ctx.ModuleName())
ctx.Build(pctx, BuildParams{
@@ -450,7 +446,7 @@
assertOrderOnlys(symlinkRule("foo"))
}
-func TestInstallBypassMake(t *testing.T) {
+func TestInstallKatiEnabled(t *testing.T) {
if runtime.GOOS != "linux" {
t.Skip("requires linux")
}
diff --git a/android/mutator.go b/android/mutator.go
index dbd8c04..fa6f2be8 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -254,6 +254,14 @@
// BazelTargetModuleProperties containing additional metadata for the
// bp2build codegenerator.
CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
+
+ // CreateBazelTargetModuleWithRestrictions creates a BazelTargetModule by calling the
+ // factory method, just like in CreateModule, but also requires
+ // BazelTargetModuleProperties containing additional metadata for the
+ // bp2build codegenerator. The generated target is restricted to only be buildable for certain
+ // platforms, as dictated by a given bool attribute: the target will not be buildable in
+ // any platform for which this bool attribute is false.
+ CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
}
type topDownMutatorContext struct {
@@ -502,13 +510,30 @@
bazelProps bazel.BazelTargetModuleProperties,
commonAttrs CommonAttributes,
attrs interface{}) {
- commonAttrs.fillCommonBp2BuildModuleAttrs(t)
+ t.createBazelTargetModule(bazelProps, commonAttrs, attrs, bazel.BoolAttribute{})
+}
+
+func (t *topDownMutatorContext) CreateBazelTargetModuleWithRestrictions(
+ bazelProps bazel.BazelTargetModuleProperties,
+ commonAttrs CommonAttributes,
+ attrs interface{},
+ enabledProperty bazel.BoolAttribute) {
+ t.createBazelTargetModule(bazelProps, commonAttrs, attrs, enabledProperty)
+}
+
+func (t *topDownMutatorContext) createBazelTargetModule(
+ bazelProps bazel.BazelTargetModuleProperties,
+ commonAttrs CommonAttributes,
+ attrs interface{},
+ enabledProperty bazel.BoolAttribute) {
+ constraintAttributes := commonAttrs.fillCommonBp2BuildModuleAttrs(t, enabledProperty)
mod := t.Module()
info := bp2buildInfo{
- Dir: t.OtherModuleDir(mod),
- BazelProps: bazelProps,
- CommonAttrs: commonAttrs,
- Attrs: attrs,
+ Dir: t.OtherModuleDir(mod),
+ BazelProps: bazelProps,
+ CommonAttrs: commonAttrs,
+ ConstraintAttrs: constraintAttributes,
+ Attrs: attrs,
}
mod.base().addBp2buildInfo(info)
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 0348619..4bb3e57 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -15,6 +15,7 @@
package android
import (
+ "fmt"
"path/filepath"
"reflect"
"regexp"
@@ -372,6 +373,20 @@
matcher ValueMatcher
}
+func (r *ruleProperty) String() string {
+ return fmt.Sprintf("%q matches: %s", strings.Join(r.fields, "."), r.matcher)
+}
+
+type ruleProperties []ruleProperty
+
+func (r ruleProperties) String() string {
+ var s []string
+ for _, r := range r {
+ s = append(s, r.String())
+ }
+ return strings.Join(s, " ")
+}
+
// A NeverAllow rule.
type Rule interface {
In(path ...string) Rule
@@ -413,8 +428,8 @@
moduleTypes []string
unlessModuleTypes []string
- props []ruleProperty
- unlessProps []ruleProperty
+ props ruleProperties
+ unlessProps ruleProperties
onlyBootclasspathJar bool
}
@@ -424,16 +439,19 @@
return &rule{directDeps: make(map[string]bool)}
}
+// In adds path(s) where this rule applies.
func (r *rule) In(path ...string) Rule {
r.paths = append(r.paths, cleanPaths(path)...)
return r
}
+// NotIn adds path(s) to that this rule does not apply to.
func (r *rule) NotIn(path ...string) Rule {
r.unlessPaths = append(r.unlessPaths, cleanPaths(path)...)
return r
}
+// InDirectDeps adds dep(s) that are not allowed with this rule.
func (r *rule) InDirectDeps(deps ...string) Rule {
for _, d := range deps {
r.directDeps[d] = true
@@ -441,25 +459,30 @@
return r
}
+// WithOsClass adds osClass(es) that this rule applies to.
func (r *rule) WithOsClass(osClasses ...OsClass) Rule {
r.osClasses = append(r.osClasses, osClasses...)
return r
}
+// ModuleType adds type(s) that this rule applies to.
func (r *rule) ModuleType(types ...string) Rule {
r.moduleTypes = append(r.moduleTypes, types...)
return r
}
+// NotModuleType adds type(s) that this rule does not apply to..
func (r *rule) NotModuleType(types ...string) Rule {
r.unlessModuleTypes = append(r.unlessModuleTypes, types...)
return r
}
+// With specifies property/value combinations that are restricted for this rule.
func (r *rule) With(properties, value string) Rule {
return r.WithMatcher(properties, selectMatcher(value))
}
+// WithMatcher specifies property/matcher combinations that are restricted for this rule.
func (r *rule) WithMatcher(properties string, matcher ValueMatcher) Rule {
r.props = append(r.props, ruleProperty{
fields: fieldNamesForProperties(properties),
@@ -468,10 +491,12 @@
return r
}
+// Without specifies property/value combinations that this rule does not apply to.
func (r *rule) Without(properties, value string) Rule {
return r.WithoutMatcher(properties, selectMatcher(value))
}
+// Without specifies property/matcher combinations that this rule does not apply to.
func (r *rule) WithoutMatcher(properties string, matcher ValueMatcher) Rule {
r.unlessProps = append(r.unlessProps, ruleProperty{
fields: fieldNamesForProperties(properties),
@@ -487,49 +512,54 @@
return &equalMatcher{expected: expected}
}
+// Because specifies a reason for this rule.
func (r *rule) Because(reason string) Rule {
r.reason = reason
return r
}
+// BootclasspathJar whether this rule only applies to Jars in the Bootclasspath
func (r *rule) BootclasspathJar() Rule {
r.onlyBootclasspathJar = true
return r
}
func (r *rule) String() string {
- s := "neverallow"
- for _, v := range r.paths {
- s += " dir:" + v + "*"
+ s := []string{"neverallow requirements. Not allowed:"}
+ if len(r.paths) > 0 {
+ s = append(s, fmt.Sprintf("in dirs: %q", r.paths))
}
- for _, v := range r.unlessPaths {
- s += " -dir:" + v + "*"
+ if len(r.moduleTypes) > 0 {
+ s = append(s, fmt.Sprintf("module types: %q", r.moduleTypes))
}
- for _, v := range r.moduleTypes {
- s += " type:" + v
+ if len(r.props) > 0 {
+ s = append(s, fmt.Sprintf("properties matching: %s", r.props))
}
- for _, v := range r.unlessModuleTypes {
- s += " -type:" + v
+ if len(r.directDeps) > 0 {
+ s = append(s, fmt.Sprintf("dep(s): %q", SortedStringKeys(r.directDeps)))
}
- for _, v := range r.props {
- s += " " + strings.Join(v.fields, ".") + v.matcher.String()
- }
- for _, v := range r.unlessProps {
- s += " -" + strings.Join(v.fields, ".") + v.matcher.String()
- }
- for k := range r.directDeps {
- s += " deps:" + k
- }
- for _, v := range r.osClasses {
- s += " os:" + v.String()
+ if len(r.osClasses) > 0 {
+ s = append(s, fmt.Sprintf("os class(es): %q", r.osClasses))
}
if r.onlyBootclasspathJar {
- s += " inBcp"
+ s = append(s, "in bootclasspath jar")
+ }
+ if len(r.unlessPaths) > 0 {
+ s = append(s, fmt.Sprintf("EXCEPT in dirs: %q", r.unlessPaths))
+ }
+ if len(r.unlessModuleTypes) > 0 {
+ s = append(s, fmt.Sprintf("EXCEPT module types: %q", r.unlessModuleTypes))
+ }
+ if len(r.unlessProps) > 0 {
+ s = append(s, fmt.Sprintf("EXCEPT properties matching: %q", r.unlessProps))
}
if len(r.reason) != 0 {
- s += " which is restricted because " + r.reason
+ s = append(s, " which is restricted because "+r.reason)
}
- return s
+ if len(s) == 1 {
+ s[0] = "neverallow requirements (empty)"
+ }
+ return strings.Join(s, "\n\t")
}
func (r *rule) appliesToPath(dir string) bool {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 18a8705..58a90b3 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -15,6 +15,7 @@
package android
import (
+ "regexp"
"testing"
"github.com/google/blueprint"
@@ -55,7 +56,37 @@
}`),
},
expectedErrors: []string{
- `module "libother": violates neverallow deps:not_allowed_in_direct_deps`,
+ regexp.QuoteMeta("module \"libother\": violates neverallow requirements. Not allowed:\n\tdep(s): [\"not_allowed_in_direct_deps\"]"),
+ },
+ },
+ {
+ name: "multiple constraints",
+ rules: []Rule{
+ NeverAllow().
+ InDirectDeps("not_allowed_in_direct_deps").
+ In("other").
+ ModuleType("cc_library").
+ NotIn("top").
+ NotModuleType("cc_binary"),
+ },
+ fs: map[string][]byte{
+ "top/Android.bp": []byte(`
+ cc_library {
+ name: "not_allowed_in_direct_deps",
+ }`),
+ "other/Android.bp": []byte(`
+ cc_library {
+ name: "libother",
+ static_libs: ["not_allowed_in_direct_deps"],
+ }`),
+ },
+ expectedErrors: []string{
+ regexp.QuoteMeta(`module "libother": violates neverallow requirements. Not allowed:
+ in dirs: ["other/"]
+ module types: ["cc_library"]
+ dep(s): ["not_allowed_in_direct_deps"]
+ EXCEPT in dirs: ["top/"]
+ EXCEPT module types: ["cc_binary"]`),
},
},
diff --git a/android/package_test.go b/android/package_test.go
index 7ea10a4..65c4240 100644
--- a/android/package_test.go
+++ b/android/package_test.go
@@ -11,7 +11,7 @@
}{
// Package default_visibility handling is tested in visibility_test.go
{
- name: "package must not accept visibility and name properties",
+ name: "package must not accept visibility, name or licenses properties",
fs: map[string][]byte{
"top/Android.bp": []byte(`
package {
@@ -48,8 +48,7 @@
default_visibility: ["//visibility:private"],
default_applicable_licenses: ["license"],
}
-
- package {
+ package {
}`),
},
expectedErrors: []string{
diff --git a/android/paths.go b/android/paths.go
index e68106c..70e427b 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -112,7 +112,6 @@
InstallInDebugRamdisk() bool
InstallInRecovery() bool
InstallInRoot() bool
- InstallBypassMake() bool
InstallForceOS() (*OsType, *ArchType)
}
@@ -465,9 +464,6 @@
// PathForGoBinary returns the path to the installed location of a bootstrap_go_binary module.
func PathForGoBinary(ctx PathContext, goBinary bootstrap.GoBinaryTool) Path {
goBinaryInstallDir := pathForInstall(ctx, ctx.Config().BuildOS, ctx.Config().BuildArch, "bin", false)
- if ctx.Config().KatiEnabled() {
- goBinaryInstallDir = goBinaryInstallDir.ToMakePath()
- }
rel := Rel(ctx, goBinaryInstallDir.String(), goBinary.InstallPath())
return goBinaryInstallDir.Join(ctx, rel)
}
@@ -1646,8 +1642,8 @@
return p
}
-// ToMakePath returns a new InstallPath that points to Make's install directory instead of Soong's,
-// i.e. out/ instead of out/soong/.
+// Deprecated: ToMakePath is a noop, PathForModuleInstall always returns Make paths when building
+// embedded in Make.
func (p InstallPath) ToMakePath() InstallPath {
p.makePath = true
return p
@@ -1688,9 +1684,6 @@
func makePathForInstall(ctx ModuleInstallPathContext, os OsType, arch ArchType, partition string, debug bool, pathComponents ...string) InstallPath {
ret := pathForInstall(ctx, os, arch, partition, debug, pathComponents...)
- if ctx.InstallBypassMake() && ctx.Config().KatiEnabled() {
- ret = ret.ToMakePath()
- }
return ret
}
@@ -1732,7 +1725,10 @@
soongOutDir: ctx.Config().soongOutDir,
partitionDir: partionPath,
partition: partition,
- makePath: false,
+ }
+
+ if ctx.Config().KatiEnabled() {
+ base.makePath = true
}
return base.Join(ctx, pathComponents...)
@@ -2008,10 +2004,6 @@
return m.inRoot
}
-func (m testModuleInstallPathContext) InstallBypassMake() bool {
- return false
-}
-
func (m testModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return m.forceOS, m.forceArch
}
diff --git a/android/paths_test.go b/android/paths_test.go
index 3cad852..2f87977 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -1486,7 +1486,8 @@
AssertPathRelativeToTopEquals(t, "install path for soong", "out/soong/target/product/test_device/system/install/path", p)
})
t.Run("install for make", func(t *testing.T) {
- p := PathForModuleInstall(ctx, "install/path").ToMakePath()
+ p := PathForModuleInstall(ctx, "install/path")
+ p.makePath = true
AssertPathRelativeToTopEquals(t, "install path for make", "out/target/product/test_device/system/install/path", p)
})
t.Run("output", func(t *testing.T) {
@@ -1500,14 +1501,12 @@
t.Run("mixture", func(t *testing.T) {
paths := Paths{
PathForModuleInstall(ctx, "install/path"),
- PathForModuleInstall(ctx, "install/path").ToMakePath(),
PathForOutput(ctx, "output/path"),
PathForSource(ctx, "source/path"),
}
expected := []string{
"out/soong/target/product/test_device/system/install/path",
- "out/target/product/test_device/system/install/path",
"out/soong/output/path",
"source/path",
}
diff --git a/android/rule_builder.go b/android/rule_builder.go
index f8de5fb..1c6b1c0 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -839,14 +839,6 @@
// The tool is in the Soong output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
return filepath.Join(sboxToolsSubDir, "out", relOutSoong)
}
- if ctx.Config().KatiEnabled() {
- toolDir = toolDir.ToMakePath()
- relOut, isRelOut, _ := maybeRelErr(toolDir.String(), path.String())
- if isRelOut {
- // The tool is in the Make output directory, it will be copied to __SBOX_OUT_DIR__/tools/out
- return filepath.Join(sboxToolsSubDir, "out", relOut)
- }
- }
// The tool is in the source directory, it will be copied to __SBOX_OUT_DIR__/tools/src
return filepath.Join(sboxToolsSubDir, "src", path.String())
}
diff --git a/android/test_suites.go b/android/test_suites.go
index 22f6cf2..55e1da7 100644
--- a/android/test_suites.go
+++ b/android/test_suites.go
@@ -60,7 +60,7 @@
for _, module := range SortedStringKeys(files) {
installedPaths = append(installedPaths, files[module]...)
}
- testCasesDir := pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases", false).ToMakePath()
+ testCasesDir := pathForInstall(ctx, ctx.Config().BuildOS, X86, "testcases", false)
outputFile := PathForOutput(ctx, "packaging", "robolectric-tests.zip")
rule := NewRuleBuilder(pctx, ctx)
diff --git a/android/util.go b/android/util.go
index a0394f6..0ee253e 100644
--- a/android/util.go
+++ b/android/util.go
@@ -65,22 +65,6 @@
return buf.String()
}
-// SortedIntKeys returns the keys of the given integer-keyed map in the ascending order
-// TODO(asmundak): once Go has generics, combine this with SortedStringKeys below.
-func SortedIntKeys(m interface{}) []int {
- v := reflect.ValueOf(m)
- if v.Kind() != reflect.Map {
- panic(fmt.Sprintf("%#v is not a map", m))
- }
- keys := v.MapKeys()
- s := make([]int, 0, len(keys))
- for _, key := range keys {
- s = append(s, int(key.Int()))
- }
- sort.Ints(s)
- return s
-}
-
// SorterStringKeys returns the keys of the given string-keyed map in the ascending order
func SortedStringKeys(m interface{}) []string {
v := reflect.ValueOf(m)
@@ -96,21 +80,6 @@
return s
}
-// SortedStringMapValues returns the values of the string-values map in the ascending order
-func SortedStringMapValues(m interface{}) []string {
- v := reflect.ValueOf(m)
- if v.Kind() != reflect.Map {
- panic(fmt.Sprintf("%#v is not a map", m))
- }
- keys := v.MapKeys()
- s := make([]string, 0, len(keys))
- for _, key := range keys {
- s = append(s, v.MapIndex(key).String())
- }
- sort.Strings(s)
- return s
-}
-
// IndexList returns the index of the first occurrence of the given string in the list or -1
func IndexList(s string, list []string) int {
for i, l := range list {
diff --git a/android/variable.go b/android/variable.go
index a7068108..a6156b1 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -124,6 +124,8 @@
Shared_libs []string
Cmdline []string
+ Srcs []string
+ Exclude_srcs []string
}
// eng is true for -eng builds, and can be used to turn on additionaly heavyweight debugging
@@ -327,7 +329,8 @@
NamespacesToExport []string `json:",omitempty"`
- PgoAdditionalProfileDirs []string `json:",omitempty"`
+ AfdoAdditionalProfileDirs []string `json:",omitempty"`
+ PgoAdditionalProfileDirs []string `json:",omitempty"`
VndkUseCoreVariant *bool `json:",omitempty"`
VndkSnapshotBuildArtifacts *bool `json:",omitempty"`
@@ -344,13 +347,17 @@
RecoverySnapshotDirsIncluded []string `json:",omitempty"`
HostFakeSnapshotEnabled bool `json:",omitempty"`
- BoardVendorSepolicyDirs []string `json:",omitempty"`
- BoardOdmSepolicyDirs []string `json:",omitempty"`
- BoardReqdMaskPolicy []string `json:",omitempty"`
- BoardPlatVendorPolicy []string `json:",omitempty"`
- SystemExtPublicSepolicyDirs []string `json:",omitempty"`
- SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
- BoardSepolicyM4Defs []string `json:",omitempty"`
+ BoardVendorSepolicyDirs []string `json:",omitempty"`
+ BoardOdmSepolicyDirs []string `json:",omitempty"`
+ BoardReqdMaskPolicy []string `json:",omitempty"`
+ BoardPlatVendorPolicy []string `json:",omitempty"`
+ BoardSystemExtPublicPrebuiltDirs []string `json:",omitempty"`
+ BoardSystemExtPrivatePrebuiltDirs []string `json:",omitempty"`
+ BoardProductPublicPrebuiltDirs []string `json:",omitempty"`
+ BoardProductPrivatePrebuiltDirs []string `json:",omitempty"`
+ SystemExtPublicSepolicyDirs []string `json:",omitempty"`
+ SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
+ BoardSepolicyM4Defs []string `json:",omitempty"`
BoardSepolicyVers *string `json:",omitempty"`
PlatformSepolicyVersion *string `json:",omitempty"`
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 1045ca6..ae52688 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -229,6 +229,8 @@
"LOCAL_IS_UNIT_TEST": "unit_test",
"LOCAL_ENFORCE_USES_LIBRARIES": "enforce_uses_libs",
+
+ "LOCAL_CHECK_ELF_FILES": "check_elf_files",
})
}
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index a2d6992..ea53705 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1566,6 +1566,25 @@
}
`,
},
+ {
+ desc: "LOCAL_CHECK_ELF_FILES",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_SRC_FILES := test.c
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_CHECK_ELF_FILES := false
+include $(BUILD_PREBUILT)
+ `,
+ expected: `
+cc_prebuilt_library_shared {
+ name: "foo",
+ srcs: ["test.c"],
+
+ check_elf_files: false,
+}
+`,
+ },
}
func TestEndToEnd(t *testing.T) {
diff --git a/apex/androidmk.go b/apex/androidmk.go
index f001fa2..8cca137 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -149,7 +149,7 @@
var modulePath string
if apexType == flattenedApex {
// /system/apex/<name>/{lib|framework|...}
- modulePath = filepath.Join(a.installDir.ToMakePath().String(), apexBundleName, fi.installDir)
+ modulePath = filepath.Join(a.installDir.String(), apexBundleName, fi.installDir)
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
if a.primaryApexType && !symbolFilesNotNeeded {
fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
@@ -362,7 +362,7 @@
data.Entries.WriteLicenseVariables(w)
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
- fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.ToMakePath().String())
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", a.installDir.String())
stemSuffix := apexType.suffix()
if a.isCompressed {
stemSuffix = imageCapexSuffix
diff --git a/apex/apex.go b/apex/apex.go
index b7faa5b..635ff30 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -458,10 +458,6 @@
modulePaths []string
}
-func (*apexBundle) InstallBypassMake() bool {
- return true
-}
-
// apexFileClass represents a type of file that can be included in APEX.
type apexFileClass int
@@ -2647,7 +2643,7 @@
//
// Module separator
//
- m["com.android.bluetooth.updatable"] = []string{
+ m["com.android.bluetooth"] = []string{
"android.hardware.audio.common@5.0",
"android.hardware.bluetooth.a2dp@1.0",
"android.hardware.bluetooth.audio@2.0",
diff --git a/apex/apex_test.go b/apex/apex_test.go
index a749ea1..727a1f2 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -2657,7 +2657,10 @@
}
func TestVendorApex(t *testing.T) {
- ctx := testApex(t, `
+ result := android.GroupFixturePreparers(
+ prepareForApexTest,
+ android.FixtureModifyConfig(android.SetKatiEnabledForTests),
+ ).RunTestWithBp(t, `
apex {
name: "myapex",
key: "myapex.key",
@@ -2681,24 +2684,24 @@
}
`)
- ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
+ ensureExactContents(t, result.TestContext, "myapex", "android_common_myapex_image", []string{
"bin/mybin",
"lib64/libfoo.so",
// TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX
"lib64/libc++.so",
})
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, ctx, apexBundle)
+ apexBundle := result.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, result.TestContext, apexBundle)
name := apexBundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
- androidMk := android.StringRelativeToTop(ctx.Config(), builder.String())
+ androidMk := android.StringRelativeToTop(result.Config, builder.String())
installPath := "out/target/product/test_device/vendor/apex"
ensureContains(t, androidMk, "LOCAL_MODULE_PATH := "+installPath)
- apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
+ apexManifestRule := result.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
ensureListNotContains(t, requireNativeLibs, ":vndk")
}
@@ -7454,7 +7457,7 @@
},
{
name: "Bootclasspath apex jar not satisfying allowed module packages on Q.",
- expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
+ expectedError: `(?s)module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
bp: `
java_library {
name: "bcp_lib1",
@@ -7491,7 +7494,7 @@
},
{
name: "Bootclasspath apex jar not satisfying allowed module packages on R.",
- expectedError: `module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
+ expectedError: `(?s)module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar with min_sdk < T. Please jarjar or move code around.`,
bp: `
java_library {
name: "bcp_lib1",
@@ -8500,7 +8503,7 @@
java_import {
name: "foo",
jars: ["foo.jar"],
- installable: true,
+ apex_available: ["myapex"],
}
`,
dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go
index 7ecf9b2..ce828e1 100644
--- a/apex/bootclasspath_fragment_test.go
+++ b/apex/bootclasspath_fragment_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "path"
"sort"
"strings"
"testing"
@@ -442,6 +443,24 @@
checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo")
})
+ t.Run("boot image disable generate profile", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ commonPreparer,
+
+ // Configure some libraries in the art bootclasspath_fragment that match the source
+ // bootclasspath_fragment's contents property.
+ java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"),
+ addSource("foo", "bar"),
+ dexpreopt.FixtureDisableGenerateProfile(true),
+ ).RunTest(t)
+
+ files := getFiles(t, result.TestContext, "com.android.art", "android_common_com.android.art_image")
+ for _, file := range files {
+ matched, _ := path.Match("etc/boot-image.prof", file.path)
+ android.AssertBoolEquals(t, "\"etc/boot-image.prof\" should not be in the APEX", matched, false)
+ }
+ })
+
t.Run("boot image files with preferred prebuilt", func(t *testing.T) {
result := android.GroupFixturePreparers(
commonPreparer,
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 254c90e..02d8075 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -222,7 +222,7 @@
Host_required: p.hostRequired,
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", p.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
entries.SetString("LOCAL_MODULE_STEM", p.installFilename)
entries.SetPath("LOCAL_SOONG_INSTALLED_MODULE", p.installedFile)
entries.SetString("LOCAL_SOONG_INSTALL_PAIRS", p.outputApex.String()+":"+p.installedFile.String())
@@ -256,7 +256,7 @@
Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", p.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDir.String())
entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", filepath.Join(p.installDir.String(), fi.stem()))
entries.SetString("LOCAL_SOONG_INSTALL_PAIRS",
fi.builtFile.String()+":"+filepath.Join(p.installDir.String(), fi.stem()))
@@ -472,10 +472,6 @@
inputApex android.Path
}
-func (p *Prebuilt) InstallBypassMake() bool {
- return true
-}
-
type ApexFileProperties struct {
// the path to the prebuilt .apex file to import.
//
diff --git a/bazel/configurability.go b/bazel/configurability.go
index 1993f76..7355ac7 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -109,6 +109,21 @@
osArchWindowsX86_64: "//build/bazel/platforms/os_arch:windows_x86_64",
ConditionsDefaultConfigKey: ConditionsDefaultSelectKey, // The default condition of an os select map.
}
+
+ // Map where keys are OsType names, and values are slices containing the archs
+ // that that OS supports.
+ // These definitions copied from arch.go.
+ // TODO(cparsons): Source from arch.go; this task is nontrivial, as it currently results
+ // in a cyclic dependency.
+ osToArchMap = map[string][]string{
+ osAndroid: {archArm, archArm64, archX86, archX86_64},
+ osLinux: {archX86, archX86_64},
+ osLinuxMusl: {archX86, archX86_64},
+ osDarwin: {archArm64, archX86_64},
+ osLinuxBionic: {archArm64, archX86_64},
+ // TODO(cparsons): According to arch.go, this should contain archArm, archArm64, as well.
+ osWindows: {archX86, archX86_64},
+ }
)
// basic configuration types
@@ -122,6 +137,10 @@
productVariables
)
+func osArchString(os string, arch string) string {
+ return fmt.Sprintf("%s_%s", os, arch)
+}
+
func (ct configurationType) String() string {
return map[configurationType]string{
noConfig: "no_config",
diff --git a/bazel/properties.go b/bazel/properties.go
index 76be058..d8b3a3a 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -244,9 +244,69 @@
ConfigurableValues configurableLabels
}
+func (la *LabelAttribute) axisTypes() map[configurationType]bool {
+ types := map[configurationType]bool{}
+ for k := range la.ConfigurableValues {
+ if len(la.ConfigurableValues[k]) > 0 {
+ types[k.configurationType] = true
+ }
+ }
+ return types
+}
+
+// Collapse reduces the configurable axes of the label attribute to a single axis.
+// This is necessary for final writing to bp2build, as a configurable label
+// attribute can only be comprised by a single select.
+func (la *LabelAttribute) Collapse() error {
+ axisTypes := la.axisTypes()
+ _, containsOs := axisTypes[os]
+ _, containsArch := axisTypes[arch]
+ _, containsOsArch := axisTypes[osArch]
+ _, containsProductVariables := axisTypes[productVariables]
+ if containsProductVariables {
+ if containsOs || containsArch || containsOsArch {
+ return fmt.Errorf("label attribute could not be collapsed as it has two or more unrelated axes")
+ }
+ }
+ if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
+ // If a bool attribute has both os and arch configuration axes, the only
+ // way to successfully union their values is to increase the granularity
+ // of the configuration criteria to os_arch.
+ for osType, supportedArchs := range osToArchMap {
+ for _, supportedArch := range supportedArchs {
+ osArch := osArchString(osType, supportedArch)
+ if archOsVal := la.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
+ // Do nothing, as the arch_os is explicitly defined already.
+ } else {
+ archVal := la.SelectValue(ArchConfigurationAxis, supportedArch)
+ osVal := la.SelectValue(OsConfigurationAxis, osType)
+ if osVal != nil && archVal != nil {
+ // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
+ // runs after os mutator.
+ la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
+ } else if osVal != nil && archVal == nil {
+ la.SetSelectValue(OsArchConfigurationAxis, osArch, *osVal)
+ } else if osVal == nil && archVal != nil {
+ la.SetSelectValue(OsArchConfigurationAxis, osArch, *archVal)
+ }
+ }
+ }
+ }
+ // All os_arch values are now set. Clear os and arch axes.
+ delete(la.ConfigurableValues, ArchConfigurationAxis)
+ delete(la.ConfigurableValues, OsConfigurationAxis)
+ }
+ return nil
+}
+
// HasConfigurableValues returns whether there are configurable values set for this label.
func (la LabelAttribute) HasConfigurableValues() bool {
- return len(la.ConfigurableValues) > 0
+ for _, selectValues := range la.ConfigurableValues {
+ if len(selectValues) > 0 {
+ return true
+ }
+ }
+ return false
}
// SetValue sets the base, non-configured value for the Label
@@ -271,13 +331,13 @@
}
// SelectValue gets a value for a bazel select for the given axis and config.
-func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Label {
+func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) *Label {
axis.validateConfig(config)
switch axis.configurationType {
case noConfig:
- return *la.Value
+ return la.Value
case arch, os, osArch, productVariables:
- return *la.ConfigurableValues[axis][config]
+ return la.ConfigurableValues[axis][config]
default:
panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
}
@@ -324,7 +384,12 @@
// HasConfigurableValues returns whether there are configurable values for this attribute.
func (ba BoolAttribute) HasConfigurableValues() bool {
- return len(ba.ConfigurableValues) > 0
+ for _, cfgToBools := range ba.ConfigurableValues {
+ if len(cfgToBools) > 0 {
+ return true
+ }
+ }
+ return false
}
// SetSelectValue sets value for the given axis/config.
@@ -343,6 +408,106 @@
}
}
+// ToLabelListAttribute creates and returns a LabelListAttribute from this
+// bool attribute, where each bool in this attribute corresponds to a
+// label list value in the resultant attribute.
+func (ba *BoolAttribute) ToLabelListAttribute(falseVal LabelList, trueVal LabelList) (LabelListAttribute, error) {
+ getLabelList := func(boolPtr *bool) LabelList {
+ if boolPtr == nil {
+ return LabelList{nil, nil}
+ } else if *boolPtr {
+ return trueVal
+ } else {
+ return falseVal
+ }
+ }
+
+ mainVal := getLabelList(ba.Value)
+ if !ba.HasConfigurableValues() {
+ return MakeLabelListAttribute(mainVal), nil
+ }
+
+ result := LabelListAttribute{}
+ if err := ba.Collapse(); err != nil {
+ return result, err
+ }
+
+ for axis, configToBools := range ba.ConfigurableValues {
+ if len(configToBools) < 1 {
+ continue
+ }
+ for config, boolPtr := range configToBools {
+ val := getLabelList(&boolPtr)
+ if !val.Equals(mainVal) {
+ result.SetSelectValue(axis, config, val)
+ }
+ }
+ result.SetSelectValue(axis, ConditionsDefaultConfigKey, mainVal)
+ }
+
+ return result, nil
+}
+
+// Collapse reduces the configurable axes of the boolean attribute to a single axis.
+// This is necessary for final writing to bp2build, as a configurable boolean
+// attribute can only be comprised by a single select.
+func (ba *BoolAttribute) Collapse() error {
+ axisTypes := ba.axisTypes()
+ _, containsOs := axisTypes[os]
+ _, containsArch := axisTypes[arch]
+ _, containsOsArch := axisTypes[osArch]
+ _, containsProductVariables := axisTypes[productVariables]
+ if containsProductVariables {
+ if containsOs || containsArch || containsOsArch {
+ return fmt.Errorf("boolean attribute could not be collapsed as it has two or more unrelated axes")
+ }
+ }
+ if (containsOs && containsArch) || (containsOsArch && (containsOs || containsArch)) {
+ // If a bool attribute has both os and arch configuration axes, the only
+ // way to successfully union their values is to increase the granularity
+ // of the configuration criteria to os_arch.
+ for osType, supportedArchs := range osToArchMap {
+ for _, supportedArch := range supportedArchs {
+ osArch := osArchString(osType, supportedArch)
+ if archOsVal := ba.SelectValue(OsArchConfigurationAxis, osArch); archOsVal != nil {
+ // Do nothing, as the arch_os is explicitly defined already.
+ } else {
+ archVal := ba.SelectValue(ArchConfigurationAxis, supportedArch)
+ osVal := ba.SelectValue(OsConfigurationAxis, osType)
+ if osVal != nil && archVal != nil {
+ // In this case, arch takes precedence. (This fits legacy Soong behavior, as arch mutator
+ // runs after os mutator.
+ ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+ } else if osVal != nil && archVal == nil {
+ ba.SetSelectValue(OsArchConfigurationAxis, osArch, osVal)
+ } else if osVal == nil && archVal != nil {
+ ba.SetSelectValue(OsArchConfigurationAxis, osArch, archVal)
+ }
+ }
+ }
+ }
+ // All os_arch values are now set. Clear os and arch axes.
+ delete(ba.ConfigurableValues, ArchConfigurationAxis)
+ delete(ba.ConfigurableValues, OsConfigurationAxis)
+ // Verify post-condition; this should never fail, provided no additional
+ // axes are introduced.
+ if len(ba.ConfigurableValues) > 1 {
+ panic(fmt.Errorf("error in collapsing attribute: %s", ba))
+ }
+ }
+ return nil
+}
+
+func (ba *BoolAttribute) axisTypes() map[configurationType]bool {
+ types := map[configurationType]bool{}
+ for k := range ba.ConfigurableValues {
+ if len(ba.ConfigurableValues[k]) > 0 {
+ types[k.configurationType] = true
+ }
+ }
+ return types
+}
+
// SelectValue gets the value for the given axis/config.
func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
axis.validateConfig(config)
@@ -550,7 +715,12 @@
// HasConfigurableValues returns true if the attribute contains axis-specific label list values.
func (lla LabelListAttribute) HasConfigurableValues() bool {
- return len(lla.ConfigurableValues) > 0
+ for _, selectValues := range lla.ConfigurableValues {
+ if len(selectValues) > 0 {
+ return true
+ }
+ }
+ return false
}
// IsEmpty returns true if the attribute has no values under any configuration.
@@ -800,7 +970,12 @@
// HasConfigurableValues returns true if the attribute contains axis-specific string_list values.
func (sla StringListAttribute) HasConfigurableValues() bool {
- return len(sla.ConfigurableValues) > 0
+ for _, selectValues := range sla.ConfigurableValues {
+ if len(selectValues) > 0 {
+ return true
+ }
+ }
+ return false
}
// Append appends all values, including os and arch specific ones, from another
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index b4eb28f..59a2389 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1369,6 +1369,94 @@
})
}
+func TestCCLibraryNoLibCrtArchAndTargetVariant(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ x86: {
+ no_libcrt: true,
+ },
+ },
+ target: {
+ darwin: {
+ no_libcrt: true,
+ }
+ },
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ "use_libcrt": `select({
+ "//build/bazel/platforms/os_arch:android_arm": False,
+ "//build/bazel/platforms/os_arch:android_x86": False,
+ "//build/bazel/platforms/os_arch:darwin_arm64": False,
+ "//build/bazel/platforms/os_arch:darwin_x86_64": False,
+ "//build/bazel/platforms/os_arch:linux_glibc_x86": False,
+ "//build/bazel/platforms/os_arch:linux_musl_x86": False,
+ "//build/bazel/platforms/os_arch:windows_x86": False,
+ "//conditions:default": None,
+ })`,
+ }),
+ })
+}
+
+func TestCCLibraryNoLibCrtArchAndTargetVariantConflict(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ filesystem: map[string]string{
+ "impl.cpp": "",
+ },
+ blueprint: soongCcLibraryPreamble + `
+cc_library {
+ name: "foo-lib",
+ srcs: ["impl.cpp"],
+ arch: {
+ arm: {
+ no_libcrt: true,
+ },
+ // This is expected to override the value for darwin_x86_64.
+ x86_64: {
+ no_libcrt: true,
+ },
+ },
+ target: {
+ darwin: {
+ no_libcrt: false,
+ }
+ },
+ include_build_directory: false,
+}
+`,
+ expectedBazelTargets: makeCcLibraryTargets("foo-lib", attrNameToString{
+ "srcs": `["impl.cpp"]`,
+ "use_libcrt": `select({
+ "//build/bazel/platforms/os_arch:android_arm": False,
+ "//build/bazel/platforms/os_arch:android_x86_64": False,
+ "//build/bazel/platforms/os_arch:darwin_arm64": True,
+ "//build/bazel/platforms/os_arch:darwin_x86_64": False,
+ "//build/bazel/platforms/os_arch:linux_bionic_x86_64": False,
+ "//build/bazel/platforms/os_arch:linux_glibc_x86_64": False,
+ "//build/bazel/platforms/os_arch:linux_musl_x86_64": False,
+ "//build/bazel/platforms/os_arch:windows_x86_64": False,
+ "//conditions:default": None,
+ })`,
+ }),
+ })
+}
+
func TestCcLibraryStrip(t *testing.T) {
expectedTargets := []string{}
expectedTargets = append(expectedTargets, makeCcLibraryTargets("all", attrNameToString{
@@ -2041,3 +2129,264 @@
},
})
}
+
+func TestCcLibraryProtoFilegroups(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ blueprint: soongCcProtoPreamble +
+ simpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") +
+ simpleModuleDoNotConvertBp2build("filegroup", "b_protos") +
+ simpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") +
+ simpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + `
+cc_library {
+ name: "a",
+ srcs: [":a_fg_proto"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}
+
+cc_library {
+ name: "b",
+ srcs: [":b_protos"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}
+
+cc_library {
+ name: "c",
+ srcs: [":c-proto-srcs"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}
+
+cc_library {
+ name: "d",
+ srcs: [":proto-srcs-d"],
+ proto: {
+ canonical_path_from_root: false,
+ export_proto_headers: true,
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("proto_library", "a_proto", attrNameToString{
+ "srcs": `[":a_fg_proto"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "a_cc_proto_lite", attrNameToString{
+ "deps": `[":a_proto"]`,
+ }), makeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":a_cc_proto_lite"]`,
+ "srcs": `[":a_fg_proto_cpp_srcs"]`,
+ "srcs_as": `[":a_fg_proto_as_srcs"]`,
+ "srcs_c": `[":a_fg_proto_c_srcs"]`,
+ }), makeBazelTarget("cc_library_shared", "a", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":a_cc_proto_lite"]`,
+ "srcs": `[":a_fg_proto_cpp_srcs"]`,
+ "srcs_as": `[":a_fg_proto_as_srcs"]`,
+ "srcs_c": `[":a_fg_proto_c_srcs"]`,
+ }), makeBazelTarget("proto_library", "b_proto", attrNameToString{
+ "srcs": `[":b_protos"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "b_cc_proto_lite", attrNameToString{
+ "deps": `[":b_proto"]`,
+ }), makeBazelTarget("cc_library_static", "b_bp2build_cc_library_static", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":b_cc_proto_lite"]`,
+ "srcs": `[":b_protos_cpp_srcs"]`,
+ "srcs_as": `[":b_protos_as_srcs"]`,
+ "srcs_c": `[":b_protos_c_srcs"]`,
+ }), makeBazelTarget("cc_library_shared", "b", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":b_cc_proto_lite"]`,
+ "srcs": `[":b_protos_cpp_srcs"]`,
+ "srcs_as": `[":b_protos_as_srcs"]`,
+ "srcs_c": `[":b_protos_c_srcs"]`,
+ }), makeBazelTarget("proto_library", "c_proto", attrNameToString{
+ "srcs": `[":c-proto-srcs"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "c_cc_proto_lite", attrNameToString{
+ "deps": `[":c_proto"]`,
+ }), makeBazelTarget("cc_library_static", "c_bp2build_cc_library_static", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":c_cc_proto_lite"]`,
+ "srcs": `[":c-proto-srcs_cpp_srcs"]`,
+ "srcs_as": `[":c-proto-srcs_as_srcs"]`,
+ "srcs_c": `[":c-proto-srcs_c_srcs"]`,
+ }), makeBazelTarget("cc_library_shared", "c", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":c_cc_proto_lite"]`,
+ "srcs": `[":c-proto-srcs_cpp_srcs"]`,
+ "srcs_as": `[":c-proto-srcs_as_srcs"]`,
+ "srcs_c": `[":c-proto-srcs_c_srcs"]`,
+ }), makeBazelTarget("proto_library", "d_proto", attrNameToString{
+ "srcs": `[":proto-srcs-d"]`,
+ }), makeBazelTarget("cc_lite_proto_library", "d_cc_proto_lite", attrNameToString{
+ "deps": `[":d_proto"]`,
+ }), makeBazelTarget("cc_library_static", "d_bp2build_cc_library_static", attrNameToString{
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":d_cc_proto_lite"]`,
+ "srcs": `[":proto-srcs-d_cpp_srcs"]`,
+ "srcs_as": `[":proto-srcs-d_as_srcs"]`,
+ "srcs_c": `[":proto-srcs-d_c_srcs"]`,
+ }), makeBazelTarget("cc_library_shared", "d", attrNameToString{
+ "dynamic_deps": `[":libprotobuf-cpp-lite"]`,
+ "whole_archive_deps": `[":d_cc_proto_lite"]`,
+ "srcs": `[":proto-srcs-d_cpp_srcs"]`,
+ "srcs_as": `[":proto-srcs-d_as_srcs"]`,
+ "srcs_c": `[":proto-srcs-d_c_srcs"]`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryDisabledArchAndTarget(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ windows: {
+ enabled: false,
+ },
+ linux_glibc_x86: {
+ enabled: false,
+ },
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: makeCcLibraryTargets("foo", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os_arch:darwin_arm64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/os_arch:darwin_x86_64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/os_arch:linux_glibc_x86": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/os_arch:windows_x86": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/os_arch:windows_x86_64": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ })
+}
+
+func TestCcLibraryDisabledArchAndTargetWithDefault(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ enabled: false,
+ target: {
+ darwin: {
+ enabled: true,
+ },
+ windows: {
+ enabled: false,
+ },
+ linux_glibc_x86: {
+ enabled: false,
+ },
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: makeCcLibraryTargets("foo", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os_arch:darwin_arm64": [],
+ "//build/bazel/platforms/os_arch:darwin_x86_64": [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ })`,
+ }),
+ })
+}
+
+func TestCcLibrarySharedDisabled(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ enabled: false,
+ shared: {
+ enabled: true,
+ },
+ target: {
+ android: {
+ shared: {
+ enabled: false,
+ },
+ }
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `["@platforms//:incompatible"]`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ },
+ })
+}
+
+func TestCcLibraryStaticDisabledForSomeArch(t *testing.T) {
+ runCcLibraryTestCase(t, bp2buildTestCase{
+ moduleTypeUnderTest: "cc_library",
+ moduleTypeUnderTestFactory: cc.LibraryFactory,
+ blueprint: soongCcProtoPreamble + `cc_library {
+ name: "foo",
+ srcs: ["foo.cpp"],
+ shared: {
+ enabled: false
+ },
+ target: {
+ darwin: {
+ enabled: true,
+ },
+ windows: {
+ enabled: false,
+ },
+ linux_glibc_x86: {
+ shared: {
+ enabled: true,
+ },
+ },
+ },
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{makeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:windows": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }), makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "srcs": `["foo.cpp"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os_arch:darwin_arm64": [],
+ "//build/bazel/platforms/os_arch:darwin_x86_64": [],
+ "//build/bazel/platforms/os_arch:linux_glibc_x86": [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ })`,
+ }),
+ }})
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index e2e55dd..e65a1fa 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -1433,3 +1433,21 @@
},
})
}
+
+func TestCcLibraryStaticStdInFlags(t *testing.T) {
+ runCcLibraryStaticTestCase(t, bp2buildTestCase{
+ blueprint: soongCcProtoPreamble + `cc_library_static {
+ name: "foo",
+ cflags: ["-std=candcpp"],
+ conlyflags: ["-std=conly"],
+ cppflags: ["-std=cpp"],
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("cc_library_static", "foo", attrNameToString{
+ "conlyflags": `["-std=conly"]`,
+ "cppflags": `["-std=cpp"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/configurability.go b/bp2build/configurability.go
index c953259..dfbb265 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -1,10 +1,11 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/bazel"
"fmt"
"reflect"
+
+ "android/soong/android"
+ "android/soong/bazel"
)
// Configurability support for bp2build.
@@ -89,13 +90,15 @@
}
archSelects := map[string]reflect.Value{}
defaultVal := configToLabels[bazel.ConditionsDefaultConfigKey]
+ // Skip empty list values unless ether EmitEmptyList is true, or these values differ from the default.
+ emitEmptyList := list.EmitEmptyList || len(defaultVal.Includes) > 0
for config, labels := range configToLabels {
// Omit any entries in the map which match the default value, for brevity.
if config != bazel.ConditionsDefaultConfigKey && labels.Equals(defaultVal) {
continue
}
selectKey := axis.SelectKey(config)
- if use, value := labelListSelectValue(selectKey, labels, list.EmitEmptyList); use {
+ if use, value := labelListSelectValue(selectKey, labels, emitEmptyList); use {
archSelects[selectKey] = value
}
}
@@ -144,9 +147,15 @@
shouldPrintDefault = true
}
case bazel.LabelAttribute:
+ if err := list.Collapse(); err != nil {
+ return "", err
+ }
value, configurableAttrs = getLabelValue(list)
defaultSelectValue = &bazelNone
case bazel.BoolAttribute:
+ if err := list.Collapse(); err != nil {
+ return "", err
+ }
value, configurableAttrs = getBoolValue(list)
defaultSelectValue = &bazelNone
default:
@@ -204,11 +213,12 @@
continue
}
value := selectMap[selectKey]
- if isZero(value) && !emitZeroValues {
- // Ignore zero values to not generate empty lists.
+ if isZero(value) && !emitZeroValues && isZero(selectMap[bazel.ConditionsDefaultSelectKey]) {
+ // Ignore zero values to not generate empty lists. However, always note zero values if
+ // the default value is non-zero.
continue
}
- s, err := prettyPrintSelectEntry(value, selectKey, indent, emitZeroValues)
+ s, err := prettyPrintSelectEntry(value, selectKey, indent, true)
if err != nil {
return "", err
}
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index 5065893..3a5d5bb 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -86,3 +86,45 @@
"sub_dir": `"tz"`,
})}})
}
+
+func TestPrebuiltEtcArchAndTargetVariant(t *testing.T) {
+ runPrebuiltEtcTestCase(t, bp2buildTestCase{
+ description: "prebuilt_etc - arch variant",
+ filesystem: map[string]string{},
+ blueprint: `
+prebuilt_etc {
+ name: "apex_tz_version",
+ src: "version/tz_version",
+ filename: "tz_version",
+ sub_dir: "tz",
+ installable: false,
+ arch: {
+ arm: {
+ src: "arm",
+ },
+ arm64: {
+ src: "darwin_or_arm64",
+ },
+ },
+ target: {
+ darwin: {
+ src: "darwin_or_arm64",
+ }
+ },
+}
+`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("prebuilt_etc", "apex_tz_version", attrNameToString{
+ "filename": `"tz_version"`,
+ "installable": `False`,
+ "src": `select({
+ "//build/bazel/platforms/os_arch:android_arm": "arm",
+ "//build/bazel/platforms/os_arch:android_arm64": "darwin_or_arm64",
+ "//build/bazel/platforms/os_arch:darwin_arm64": "darwin_or_arm64",
+ "//build/bazel/platforms/os_arch:darwin_x86_64": "darwin_or_arm64",
+ "//build/bazel/platforms/os_arch:linux_bionic_arm64": "darwin_or_arm64",
+ "//conditions:default": "version/tz_version",
+ })`,
+ "sub_dir": `"tz"`,
+ })}})
+}
diff --git a/bp2build/sh_conversion_test.go b/bp2build/sh_conversion_test.go
index f6d2a20..ac89087 100644
--- a/bp2build/sh_conversion_test.go
+++ b/bp2build/sh_conversion_test.go
@@ -73,3 +73,20 @@
})},
})
}
+
+func TestShBinaryDefaults(t *testing.T) {
+ runShBinaryTestCase(t, bp2buildTestCase{
+ description: "sh_binary test",
+ moduleTypeUnderTest: "sh_binary",
+ moduleTypeUnderTestFactory: sh.ShBinaryFactory,
+ blueprint: `sh_binary {
+ name: "foo",
+ src: "foo.sh",
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("sh_binary", "foo", attrNameToString{
+ "srcs": `["foo.sh"]`,
+ })},
+ })
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 15cf486..8ae1a38 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -133,8 +133,8 @@
android.FailIfErrored(t, errs)
}
if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got `%d``",
- tc.description, expectedCount, actualCount)
+ t.Errorf("%s: Expected %d bazel target (%s), got `%d`` (%s)",
+ tc.description, expectedCount, tc.expectedBazelTargets, actualCount, bazelTargets)
} else {
for i, target := range bazelTargets {
if w, g := tc.expectedBazelTargets[i], target.content; w != g {
diff --git a/bpf/bpf.go b/bpf/bpf.go
index fa1a84d..9f0c86c 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -83,9 +83,9 @@
// The architecture doesn't matter here, but asm/types.h is included by linux/types.h.
"-isystem bionic/libc/kernel/uapi/asm-arm64",
"-isystem bionic/libc/kernel/android/uapi",
+ "-I frameworks/libs/net/common/native/bpf_headers/include/bpf",
// TODO(b/149785767): only give access to specific file with AID_* constants
"-I system/core/libcutils/include",
- "-I system/bpf/progs/include",
"-I " + ctx.ModuleDir(),
}
diff --git a/cc/Android.bp b/cc/Android.bp
index 07aa7cb..0bf0045 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -19,10 +19,11 @@
"soong-tradefed",
],
srcs: [
+ "afdo.go",
"androidmk.go",
"api_level.go",
- "builder.go",
"bp2build.go",
+ "builder.go",
"cc.go",
"ccdeps.go",
"check.go",
diff --git a/cc/afdo.go b/cc/afdo.go
new file mode 100644
index 0000000..022f283
--- /dev/null
+++ b/cc/afdo.go
@@ -0,0 +1,194 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+)
+
+var (
+ globalAfdoProfileProjects = []string{
+ "vendor/google_data/pgo_profile/sampling/",
+ "toolchain/pgo-profiles/sampling/",
+ }
+)
+
+var afdoProfileProjectsConfigKey = android.NewOnceKey("AfdoProfileProjects")
+
+const afdoCFlagsFormat = "-fprofile-sample-accurate -fprofile-sample-use=%s"
+
+func getAfdoProfileProjects(config android.DeviceConfig) []string {
+ return config.OnceStringSlice(afdoProfileProjectsConfigKey, func() []string {
+ return append(globalAfdoProfileProjects, config.AfdoAdditionalProfileDirs()...)
+ })
+}
+
+func recordMissingAfdoProfileFile(ctx BaseModuleContext, missing string) {
+ getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
+}
+
+type AfdoProperties struct {
+ Afdo bool
+
+ AfdoTarget *string `blueprint:"mutated"`
+ AfdoDeps []string `blueprint:"mutated"`
+}
+
+type afdo struct {
+ Properties AfdoProperties
+}
+
+func (afdo *afdo) props() []interface{} {
+ return []interface{}{&afdo.Properties}
+}
+
+func (afdo *afdo) AfdoEnabled() bool {
+ return afdo != nil && afdo.Properties.Afdo && afdo.Properties.AfdoTarget != nil
+}
+
+// Get list of profile file names, ordered by level of specialisation. For example:
+// 1. libfoo_arm64.afdo
+// 2. libfoo.afdo
+// Add more specialisation as needed.
+func getProfileFiles(ctx BaseModuleContext, moduleName string) []string {
+ var files []string
+ files = append(files, moduleName+"_"+ctx.Arch().ArchType.String()+".afdo")
+ files = append(files, moduleName+".afdo")
+ return files
+}
+
+func (props *AfdoProperties) getAfdoProfileFile(ctx BaseModuleContext, module string) android.OptionalPath {
+ // Test if the profile_file is present in any of the Afdo profile projects
+ for _, profileFile := range getProfileFiles(ctx, module) {
+ for _, profileProject := range getAfdoProfileProjects(ctx.DeviceConfig()) {
+ path := android.ExistentPathForSource(ctx, profileProject, profileFile)
+ if path.Valid() {
+ return path
+ }
+ }
+ }
+
+ // Record that this module's profile file is absent
+ missing := ctx.ModuleDir() + ":" + module
+ recordMissingAfdoProfileFile(ctx, missing)
+
+ return android.OptionalPathForPath(nil)
+}
+
+func (afdo *afdo) begin(ctx BaseModuleContext) {
+ if afdo.Properties.Afdo && !ctx.static() && !ctx.Host() {
+ module := ctx.ModuleName()
+ if afdo.Properties.getAfdoProfileFile(ctx, module).Valid() {
+ afdo.Properties.AfdoTarget = proptools.StringPtr(module)
+ }
+ }
+}
+
+func (afdo *afdo) flags(ctx ModuleContext, flags Flags) Flags {
+ if profile := afdo.Properties.AfdoTarget; profile != nil {
+ if profileFile := afdo.Properties.getAfdoProfileFile(ctx, *profile); profileFile.Valid() {
+ profileFilePath := profileFile.Path()
+
+ profileUseFlag := fmt.Sprintf(afdoCFlagsFormat, profileFile)
+ flags.Local.CFlags = append(flags.Local.CFlags, profileUseFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, profileUseFlag)
+ flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-mllvm,-no-warn-sample-unused=true")
+
+ // Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
+ // if profileFile gets updated
+ flags.CFlagsDeps = append(flags.CFlagsDeps, profileFilePath)
+ flags.LdFlagsDeps = append(flags.LdFlagsDeps, profileFilePath)
+ }
+ }
+
+ return flags
+}
+
+// Propagate afdo requirements down from binaries
+func afdoDepsMutator(mctx android.TopDownMutatorContext) {
+ if m, ok := mctx.Module().(*Module); ok && m.afdo.AfdoEnabled() {
+ afdoTarget := *m.afdo.Properties.AfdoTarget
+ mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ tag := mctx.OtherModuleDependencyTag(dep)
+ libTag, isLibTag := tag.(libraryDependencyTag)
+
+ // Do not recurse down non-static dependencies
+ if isLibTag {
+ if !libTag.static() {
+ return false
+ }
+ } else {
+ if tag != objDepTag && tag != reuseObjTag {
+ return false
+ }
+ }
+
+ if dep, ok := dep.(*Module); ok {
+ dep.afdo.Properties.AfdoDeps = append(dep.afdo.Properties.AfdoDeps, afdoTarget)
+ }
+
+ return true
+ })
+ }
+}
+
+// Create afdo variants for modules that need them
+func afdoMutator(mctx android.BottomUpMutatorContext) {
+ if m, ok := mctx.Module().(*Module); ok && m.afdo != nil {
+ if m.afdo.AfdoEnabled() && !m.static() {
+ afdoTarget := *m.afdo.Properties.AfdoTarget
+ mctx.SetDependencyVariation(encodeTarget(afdoTarget))
+ }
+
+ variationNames := []string{""}
+ afdoDeps := android.FirstUniqueStrings(m.afdo.Properties.AfdoDeps)
+ for _, dep := range afdoDeps {
+ variationNames = append(variationNames, encodeTarget(dep))
+ }
+ if len(variationNames) > 1 {
+ modules := mctx.CreateVariations(variationNames...)
+ for i, name := range variationNames {
+ if name == "" {
+ continue
+ }
+ variation := modules[i].(*Module)
+ variation.Properties.PreventInstall = true
+ variation.Properties.HideFromMake = true
+ variation.afdo.Properties.AfdoTarget = proptools.StringPtr(decodeTarget(name))
+ }
+ }
+ }
+}
+
+// Encode target name to variation name.
+func encodeTarget(target string) string {
+ if target == "" {
+ return ""
+ }
+ return "afdo-" + target
+}
+
+// Decode target name from variation name.
+func decodeTarget(variation string) string {
+ if variation == "" {
+ return ""
+ }
+ return strings.TrimPrefix(variation, "afdo-")
+}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 636bab8..800b58f 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -453,7 +453,7 @@
}
entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- path, file := filepath.Split(installer.path.ToMakePath().String())
+ path, file := filepath.Split(installer.path.String())
stem, suffix, _ := android.SplitFileExt(file)
entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
entries.SetString("LOCAL_MODULE_PATH", path)
@@ -532,7 +532,7 @@
c.libraryDecorator.androidMkWriteExportedFlags(entries)
if c.shared() || c.static() {
- path, file := filepath.Split(c.path.ToMakePath().String())
+ path, file := filepath.Split(c.path.String())
stem, suffix, ext := android.SplitFileExt(file)
entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
diff --git a/cc/binary.go b/cc/binary.go
index 50175d9..b59e762 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -558,13 +558,6 @@
}
func binaryBp2build(ctx android.TopDownMutatorContext, m *Module, typ string) {
- var compatibleWith bazel.StringListAttribute
- if typ == "cc_binary_host" {
- //incompatible with android OS
- compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"})
- compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{})
- }
-
baseAttrs := bp2BuildParseBaseProps(ctx, m)
binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
@@ -610,16 +603,22 @@
None: baseAttrs.stripNone,
},
- Target_compatible_with: compatibleWith,
- Features: baseAttrs.features,
+ Features: baseAttrs.features,
}
- ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+ var enabledProperty bazel.BoolAttribute
+ if typ == "cc_binary_host" {
+ falseVal := false
+ enabledProperty.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, &falseVal)
+ }
+
+ ctx.CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties{
Rule_class: "cc_binary",
Bzl_load_location: "//build/bazel/rules:cc_binary.bzl",
},
android.CommonAttributes{Name: m.Name()},
- attrs)
+ attrs,
+ enabledProperty)
}
// binaryAttributes contains Bazel attributes corresponding to a cc binary
@@ -655,6 +654,4 @@
Strip stripAttributes
Features bazel.StringListAttribute
-
- Target_compatible_with bazel.StringListAttribute
}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 6c1646c..e4762a0 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -16,6 +16,7 @@
import (
"fmt"
"path/filepath"
+ "regexp"
"strings"
"android/soong/android"
@@ -33,6 +34,12 @@
protoSrcPartition = "proto"
)
+var (
+ // ignoring case, checks for proto or protos as an independent word in the name, whether at the
+ // beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
+ filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
+)
+
// staticOrSharedAttributes are the Bazel-ified versions of StaticOrSharedProperties --
// properties which apply to either the shared or static version of a cc_library module.
type staticOrSharedAttributes struct {
@@ -50,6 +57,8 @@
Implementation_whole_archive_deps bazel.LabelListAttribute
System_dynamic_deps bazel.LabelListAttribute
+
+ Enabled bazel.BoolAttribute
}
func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
@@ -77,18 +86,18 @@
if !exists || !isFilegroup(m) {
return labelStr, false
}
- likelyProtos := strings.HasSuffix(labelStr, "proto") || strings.HasSuffix(labelStr, "protos")
+ likelyProtos := filegroupLikelyProtoPattern.MatchString(label.OriginalModuleName)
return labelStr, likelyProtos
}
// TODO(b/190006308): Handle language detection of sources in a Bazel rule.
partitioned := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
- cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
- asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
+ protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup},
+ cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")},
+ asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")},
// C++ is the "catch-all" group, and comprises generated sources because we don't
// know the language of these sources until the genrule is executed.
- cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
- protoSrcPartition: bazel.LabelPartition{Extensions: []string{".proto"}, LabelMapper: isProtoFilegroup},
+ cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
})
return partitioned
@@ -155,7 +164,7 @@
attrs := staticOrSharedAttributes{}
setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
- attrs.Copts.SetSelectValue(axis, config, props.Cflags)
+ attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag))
attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
@@ -168,6 +177,7 @@
attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation)
attrs.Whole_archive_deps.SetSelectValue(axis, config, bazelLabelForWholeDeps(ctx, props.Whole_static_libs))
+ attrs.Enabled.SetSelectValue(axis, config, props.Enabled)
}
// system_dynamic_deps distinguishes between nil/empty list behavior:
// nil -> use default values
@@ -272,9 +282,18 @@
protoSrcs bazel.LabelListAttribute
}
-func parseCommandLineFlags(soongFlags []string) []string {
+type filterOutFn func(string) bool
+
+func filterOutStdFlag(flag string) bool {
+ return strings.HasPrefix(flag, "-std=")
+}
+
+func parseCommandLineFlags(soongFlags []string, filterOut filterOutFn) []string {
var result []string
for _, flag := range soongFlags {
+ if filterOut != nil && filterOut(flag) {
+ continue
+ }
// Soong's cflags can contain spaces, like `-include header.h`. For
// Bazel's copts, split them up to be compatible with the
// no_copts_tokenization feature.
@@ -301,10 +320,14 @@
ca.absoluteIncludes.SetSelectValue(axis, config, props.Include_dirs)
ca.localIncludes.SetSelectValue(axis, config, localIncludeDirs)
- ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags))
- ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags))
- ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags))
- ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags))
+ // In Soong, cflags occur on the command line before -std=<val> flag, resulting in the value being
+ // overridden. In Bazel we always allow overriding, via flags; however, this can cause
+ // incompatibilities, so we remove "-std=" flags from Cflag properties while leaving it in other
+ // cases.
+ ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag))
+ ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, nil))
+ ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, nil))
+ ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, nil))
ca.rtti.SetSelectValue(axis, config, props.Rtti)
}
diff --git a/cc/builder.go b/cc/builder.go
index 8af2255..fa7f7a3 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -529,6 +529,14 @@
cppflags += " ${config.NoOverrideGlobalCflags}"
toolingCppflags += " ${config.NoOverrideGlobalCflags}"
+ modulePath := android.PathForModuleSrc(ctx).String()
+ if android.IsThirdPartyPath(modulePath) {
+ cflags += " ${config.NoOverrideExternalGlobalCflags}"
+ toolingCflags += " ${config.NoOverrideExternalGlobalCflags}"
+ cppflags += " ${config.NoOverrideExternalGlobalCflags}"
+ toolingCppflags += " ${config.NoOverrideExternalGlobalCflags}"
+ }
+
// Multiple source files have build rules usually share the same cFlags or tidyFlags.
// Define only one version in this module and share it in multiple build rules.
// To simplify the code, the shared variables are all named as $flags<nnn>.
diff --git a/cc/cc.go b/cc/cc.go
index 5c4edb9..a4b7c9c 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -64,6 +64,9 @@
ctx.BottomUp("coverage", coverageMutator).Parallel()
+ ctx.TopDown("afdo_deps", afdoDepsMutator)
+ ctx.BottomUp("afdo", afdoMutator).Parallel()
+
ctx.TopDown("lto_deps", ltoDepsMutator)
ctx.BottomUp("lto", ltoMutator).Parallel()
@@ -810,6 +813,7 @@
sabi *sabi
vndkdep *vndkdep
lto *lto
+ afdo *afdo
pgo *pgo
library libraryInterface
@@ -1143,6 +1147,9 @@
if c.lto != nil {
c.AddProperties(c.lto.props()...)
}
+ if c.afdo != nil {
+ c.AddProperties(c.afdo.props()...)
+ }
if c.pgo != nil {
c.AddProperties(c.pgo.props()...)
}
@@ -1385,8 +1392,6 @@
return c.installer != nil && c.installer.installInRoot()
}
-func (c *Module) InstallBypassMake() bool { return true }
-
type baseModuleContext struct {
android.BaseModuleContext
moduleContextImpl
@@ -1622,6 +1627,7 @@
module.sabi = &sabi{}
module.vndkdep = &vndkdep{}
module.lto = <o{}
+ module.afdo = &afdo{}
module.pgo = &pgo{}
return module
}
@@ -1817,6 +1823,9 @@
if c.lto != nil {
flags = c.lto.flags(ctx, flags)
}
+ if c.afdo != nil {
+ flags = c.afdo.flags(ctx, flags)
+ }
if c.pgo != nil {
flags = c.pgo.flags(ctx, flags)
}
@@ -1944,6 +1953,9 @@
if c.lto != nil {
c.lto.begin(ctx)
}
+ if c.afdo != nil {
+ c.afdo.begin(ctx)
+ }
if c.pgo != nil {
c.pgo.begin(ctx)
}
@@ -3463,8 +3475,15 @@
objectBp2Build(ctx, c)
}
} else if c.CcLibrary() {
- static := c.BuildStaticVariant()
- shared := c.BuildSharedVariant()
+ static := false
+ shared := false
+ if library, ok := c.linker.(*libraryDecorator); ok {
+ static = library.MutatedProperties.BuildStatic
+ shared = library.MutatedProperties.BuildShared
+ } else if library, ok := c.linker.(*prebuiltLibraryLinker); ok {
+ static = library.MutatedProperties.BuildStatic
+ shared = library.MutatedProperties.BuildShared
+ }
if static && shared {
if !prebuilt {
@@ -3496,10 +3515,6 @@
type Defaults struct {
android.ModuleBase
android.DefaultsModuleBase
- // Included to support setting bazel_module.label for multiple Soong modules to the same Bazel
- // target. This is primarily useful for modules that were architecture specific and instead are
- // handled in Bazel as a select().
- android.BazelModuleBase
android.ApexModuleBase
}
@@ -3540,6 +3555,7 @@
&SAbiProperties{},
&VndkProperties{},
<OProperties{},
+ &AfdoProperties{},
&PgoProperties{},
&android.ProtoProperties{},
// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
@@ -3547,8 +3563,6 @@
&prebuiltLinkerProperties{},
)
- // Bazel module must be initialized _before_ Defaults to be included in cc_defaults module.
- android.InitBazelModule(module)
android.InitDefaultsModule(module)
return module
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 9ffe48d..31d91b6 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3980,9 +3980,9 @@
conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
- cflags := []string{"-Wall", "-Werror"}
- cstd := []string{"-std=gnu99"}
- cppstd := []string{"-std=gnu++17", "-fno-rtti"}
+ cflags := []string{"-Wall", "-Werror", "-std=candcpp"}
+ cstd := []string{"-std=gnu99", "-std=conly"}
+ cppstd := []string{"-std=gnu++17", "-std=cpp", "-fno-rtti"}
lastIncludes := []string{
"out/soong/ndk/sysroot/usr/include",
@@ -4005,12 +4005,12 @@
{
name: "c",
src: "foo.c",
- expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+ expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
},
{
name: "cc",
src: "foo.cc",
- expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}"}),
+ expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
},
{
name: "assemble",
@@ -4025,6 +4025,9 @@
cc_library {
name: "libfoo",
srcs: ["%s"],
+ cflags: ["-std=candcpp"],
+ conlyflags: ["-std=conly"],
+ cppflags: ["-std=cpp"],
local_include_dirs: ["local_include_dirs"],
export_include_dirs: ["export_include_dirs"],
export_system_include_dirs: ["export_system_include_dirs"],
diff --git a/cc/config/global.go b/cc/config/global.go
index a340e46..7f2c23e 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -224,8 +224,6 @@
"-Wno-pessimizing-move", // http://b/154270751
// New warnings to be fixed after clang-r399163
"-Wno-non-c-typedef-for-linkage", // http://b/161304145
- // New warnings to be fixed after clang-r407598
- "-Wno-string-concatenation", // http://b/175068488
// New warnings to be fixed after clang-r428724
"-Wno-align-mismatch", // http://b/193679946
// New warnings to be fixed after clang-r433403
@@ -233,6 +231,12 @@
"-Wno-error=unused-but-set-parameter", // http://b/197240255
}
+ noOverrideExternalGlobalCflags = []string{
+ // http://b/197240255
+ "-Wno-unused-but-set-variable",
+ "-Wno-unused-but-set-parameter",
+ }
+
// Extra cflags for external third-party projects to disable warnings that
// are infeasible to fix in all the external projects and their upstream repos.
extraExternalCflags = []string{
@@ -259,6 +263,9 @@
// http://b/199369603
"-Wno-null-pointer-subtraction",
+
+ // http://b/175068488
+ "-Wno-string-concatenation",
}
IllegalFlags = []string{
@@ -346,6 +353,7 @@
exportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
exportStringListStaticVariable("NoOverrideGlobalCflags", noOverrideGlobalCflags)
+ exportStringListStaticVariable("NoOverrideExternalGlobalCflags", noOverrideExternalGlobalCflags)
exportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
exportStringListStaticVariable("ExternalCflags", extraExternalCflags)
diff --git a/cc/library.go b/cc/library.go
index 216c124..5720944 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -392,8 +392,12 @@
Bzl_load_location: "//build/bazel/rules:cc_library_shared.bzl",
}
- ctx.CreateBazelTargetModule(staticProps, android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"}, staticTargetAttrs)
- ctx.CreateBazelTargetModule(sharedProps, android.CommonAttributes{Name: m.Name()}, sharedTargetAttrs)
+ ctx.CreateBazelTargetModuleWithRestrictions(staticProps,
+ android.CommonAttributes{Name: m.Name() + "_bp2build_cc_library_static"},
+ staticTargetAttrs, staticAttrs.Enabled)
+ ctx.CreateBazelTargetModuleWithRestrictions(sharedProps,
+ android.CommonAttributes{Name: m.Name()},
+ sharedTargetAttrs, sharedAttrs.Enabled)
}
// cc_library creates both static and/or shared libraries for a device and/or
diff --git a/cc/makevars.go b/cc/makevars.go
index 8d7a163..b7aaaad 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -95,6 +95,7 @@
ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ExternalCflags}")
ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideGlobalCflags}")
ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "")
+ ctx.Strict("GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE", "${config.NoOverrideExternalGlobalCflags}")
ctx.Strict("BOARD_VNDK_VERSION", ctx.DeviceConfig().VndkVersion())
ctx.Strict("RECOVERY_SNAPSHOT_VERSION", ctx.DeviceConfig().RecoverySnapshotVersion())
diff --git a/cc/object.go b/cc/object.go
index bd43e36..24f6ed4 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -155,7 +155,8 @@
for config, props := range configToProps {
if objectLinkerProps, ok := props.(*ObjectLinkerProperties); ok {
if objectLinkerProps.Linker_script != nil {
- linkerScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script))
+ label := android.BazelLabelForModuleSrcSingle(ctx, *objectLinkerProps.Linker_script)
+ linkerScript.SetSelectValue(axis, config, label)
}
deps.SetSelectValue(axis, config, android.BazelLabelForModuleDeps(ctx, objectLinkerProps.Objs))
systemSharedLibs := objectLinkerProps.System_shared_libs
diff --git a/cc/sanitize.go b/cc/sanitize.go
index d7b1ade..6c68822 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -539,11 +539,6 @@
if Bool(s.Hwaddress) {
s.Address = nil
s.Thread = nil
- // Disable ubsan diagnosic as a workaround for a compiler bug.
- // TODO(b/191808836): re-enable.
- s.Diag.Undefined = nil
- s.Diag.Integer_overflow = nil
- s.Diag.Misc_undefined = nil
}
// TODO(b/131771163): CFI transiently depends on LTO, and thus Fuzzer is
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index 6d6b41d..1f99a96 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -100,6 +100,48 @@
RelaxUsesLibraryCheck bool
}
+var allPlatformSystemServerJarsKey = android.NewOnceKey("allPlatformSystemServerJars")
+
+// Returns all jars on the platform that system_server loads, including those on classpath and those
+// loaded dynamically.
+func (g *GlobalConfig) AllPlatformSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
+ return ctx.Config().Once(allPlatformSystemServerJarsKey, func() interface{} {
+ res := g.SystemServerJars.AppendList(&g.StandaloneSystemServerJars)
+ return &res
+ }).(*android.ConfiguredJarList)
+}
+
+var allApexSystemServerJarsKey = android.NewOnceKey("allApexSystemServerJars")
+
+// Returns all jars delivered via apex that system_server loads, including those on classpath and
+// those loaded dynamically.
+func (g *GlobalConfig) AllApexSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
+ return ctx.Config().Once(allApexSystemServerJarsKey, func() interface{} {
+ res := g.ApexSystemServerJars.AppendList(&g.ApexStandaloneSystemServerJars)
+ return &res
+ }).(*android.ConfiguredJarList)
+}
+
+var allSystemServerClasspathJarsKey = android.NewOnceKey("allSystemServerClasspathJars")
+
+// Returns all system_server classpath jars.
+func (g *GlobalConfig) AllSystemServerClasspathJars(ctx android.PathContext) *android.ConfiguredJarList {
+ return ctx.Config().Once(allSystemServerClasspathJarsKey, func() interface{} {
+ res := g.SystemServerJars.AppendList(&g.ApexSystemServerJars)
+ return &res
+ }).(*android.ConfiguredJarList)
+}
+
+var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
+
+// Returns all jars that system_server loads.
+func (g *GlobalConfig) AllSystemServerJars(ctx android.PathContext) *android.ConfiguredJarList {
+ return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
+ res := g.AllPlatformSystemServerJars(ctx).AppendList(g.AllApexSystemServerJars(ctx))
+ return &res
+ }).(*android.ConfiguredJarList)
+}
+
// GlobalSoongConfig contains the global config that is generated from Soong,
// stored in dexpreopt_soong.config.
type GlobalSoongConfig struct {
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 3145315..de139c4 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -115,7 +115,7 @@
// /data. If we don't do this they will need to be extracted which is not favorable for RAM usage
// or performance. If PreoptExtractedApk is true, we ignore the only preopt boot image options.
if global.OnlyPreoptBootImageAndSystemServer && !global.BootJars.ContainsJar(module.Name) &&
- !AllSystemServerJars(ctx, global).ContainsJar(module.Name) && !module.PreoptExtractedApk {
+ !global.AllSystemServerJars(ctx).ContainsJar(module.Name) && !module.PreoptExtractedApk {
return true
}
@@ -197,8 +197,8 @@
}
// Returns the dex location of a system server java library.
-func GetSystemServerDexLocation(global *GlobalConfig, lib string) string {
- if apex := global.ApexSystemServerJars.ApexOfJar(lib); apex != "" {
+func GetSystemServerDexLocation(ctx android.PathContext, global *GlobalConfig, lib string) string {
+ if apex := global.AllApexSystemServerJars(ctx).ApexOfJar(lib); apex != "" {
return fmt.Sprintf("/apex/%s/javalib/%s.jar", apex, lib)
}
return fmt.Sprintf("/system/framework/%s.jar", lib)
@@ -240,7 +240,8 @@
invocationPath := odexPath.ReplaceExtension(ctx, "invocation")
- systemServerJars := AllSystemServerJars(ctx, global)
+ systemServerJars := global.AllSystemServerJars(ctx)
+ systemServerClasspathJars := global.AllSystemServerClasspathJars(ctx)
rule.Command().FlagWithArg("mkdir -p ", filepath.Dir(odexPath.String()))
rule.Command().FlagWithOutput("rm -f ", odexPath)
@@ -251,10 +252,15 @@
var clcHost android.Paths
var clcTarget []string
- for i := 0; i < jarIndex; i++ {
- lib := systemServerJars.Jar(i)
+ endIndex := systemServerClasspathJars.IndexOfJar(module.Name)
+ if endIndex < 0 {
+ // The jar is a standalone one. Use the full classpath as the class loader context.
+ endIndex = systemServerClasspathJars.Len()
+ }
+ for i := 0; i < endIndex; i++ {
+ lib := systemServerClasspathJars.Jar(i)
clcHost = append(clcHost, SystemServerDexJarHostPath(ctx, lib))
- clcTarget = append(clcTarget, GetSystemServerDexLocation(global, lib))
+ clcTarget = append(clcTarget, GetSystemServerDexLocation(ctx, global, lib))
}
if DexpreoptRunningInSoong {
@@ -270,12 +276,22 @@
// cannot see the rule in the generated dexpreopt.sh script).
}
- checkSystemServerOrder(ctx, jarIndex)
+ clcHostString := "PCL[" + strings.Join(clcHost.Strings(), ":") + "]"
+ clcTargetString := "PCL[" + strings.Join(clcTarget, ":") + "]"
+
+ if systemServerClasspathJars.ContainsJar(module.Name) {
+ checkSystemServerOrder(ctx, jarIndex)
+ } else {
+ // Standalone jars are loaded by separate class loaders with SYSTEMSERVERCLASSPATH as the
+ // parent.
+ clcHostString = "PCL[];" + clcHostString
+ clcTargetString = "PCL[];" + clcTargetString
+ }
rule.Command().
- Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(clcHost.Strings(), ":") + "]").
+ Text(`class_loader_context_arg=--class-loader-context="` + clcHostString + `"`).
Implicits(clcHost).
- Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clcTarget, ":") + "]")
+ Text(`stored_class_loader_context_arg=--stored-class-loader-context="` + clcTargetString + `"`)
} else {
// There are three categories of Java modules handled here:
@@ -533,17 +549,6 @@
}
}
-var allSystemServerJarsKey = android.NewOnceKey("allSystemServerJars")
-
-// TODO: eliminate the superficial global config parameter by moving global config definition
-// from java subpackage to dexpreopt.
-func AllSystemServerJars(ctx android.PathContext, global *GlobalConfig) *android.ConfiguredJarList {
- return ctx.Config().Once(allSystemServerJarsKey, func() interface{} {
- allSystemServerJars := global.SystemServerJars.AppendList(global.ApexSystemServerJars)
- return &allSystemServerJars
- }).(*android.ConfiguredJarList)
-}
-
// A predefined location for the system server dex jars. This is needed in order to generate
// class loader context for dex2oat, as the path to the jar in the Soong module may be unknown
// at that time (Soong processes the jars in dependency order, which may be different from the
@@ -567,7 +572,7 @@
mctx, isModule := ctx.(android.ModuleContext)
if isModule {
config := GetGlobalConfig(ctx)
- jars := AllSystemServerJars(ctx, config)
+ jars := config.AllSystemServerClasspathJars(ctx)
mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
depIndex := jars.IndexOfJar(dep.Name())
if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 798d776..07e4fad 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -50,6 +50,15 @@
android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
}
+func testPlatformSystemServerModuleConfig(ctx android.PathContext, name string) *ModuleConfig {
+ return createTestModuleConfig(
+ name,
+ fmt.Sprintf("/system/framework/%s.jar", name),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/dexpreopt/%s.jar", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/aligned/%s.jar", name, name)),
+ android.PathForOutput(ctx, fmt.Sprintf("%s/enforce_uses_libraries.status", name)))
+}
+
func createTestModuleConfig(name, dexLocation string, buildPath, dexPath, enforceUsesLibrariesStatusFile android.OutputPath) *ModuleConfig {
return &ModuleConfig{
Name: name,
@@ -181,6 +190,52 @@
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
}
+func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
+ config := android.TestConfig("out", nil, "", nil)
+ ctx := android.BuilderContextForTesting(config)
+ globalSoong := globalSoongConfigForTests()
+ global := GlobalConfigForTests(ctx)
+ module := testPlatformSystemServerModuleConfig(ctx, "service-A")
+
+ global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
+ []string{"platform:service-A"})
+
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wantInstalls := android.RuleBuilderInstalls{
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/service-A.odex"},
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/service-A.vdex"},
+ }
+
+ android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
+}
+
+func TestDexPreoptApexStandaloneSystemServerJars(t *testing.T) {
+ config := android.TestConfig("out", nil, "", nil)
+ ctx := android.BuilderContextForTesting(config)
+ globalSoong := globalSoongConfigForTests()
+ global := GlobalConfigForTests(ctx)
+ module := testApexModuleConfig(ctx, "service-A", "com.android.apex1")
+
+ global.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(
+ []string{"com.android.apex1:service-A"})
+
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wantInstalls := android.RuleBuilderInstalls{
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.odex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.odex"},
+ {android.PathForOutput(ctx, "service-A/dexpreopt/oat/arm/javalib.vdex"), "/system/framework/oat/arm/apex@com.android.apex1@javalib@service-A.jar@classes.vdex"},
+ }
+
+ android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
+}
+
func TestDexPreoptProfile(t *testing.T) {
config := android.TestConfig("out", nil, "", nil)
ctx := android.BuilderContextForTesting(config)
diff --git a/dexpreopt/testing.go b/dexpreopt/testing.go
index 5131cd3..47ae494 100644
--- a/dexpreopt/testing.go
+++ b/dexpreopt/testing.go
@@ -167,3 +167,10 @@
dexpreoptConfig.BootImageProfiles = android.PathsForSource(ctx, profiles)
})
}
+
+// FixtureDisableGenerateProfile sets the DisableGenerateProfile property in the global config.
+func FixtureDisableGenerateProfile(disable bool) android.FixturePreparer {
+ return FixtureModifyGlobalConfig(func(_ android.PathContext, dexpreoptConfig *GlobalConfig) {
+ dexpreoptConfig.DisableGenerateProfile = disable
+ })
+}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 80ab41b..83de65f 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -376,7 +376,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
if len(p.properties.Symlinks) > 0 {
entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
@@ -681,7 +681,8 @@
continue
}
if props.Src != nil {
- srcLabelAttribute.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *props.Src))
+ label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
+ srcLabelAttribute.SetSelectValue(axis, config, label)
}
}
}
diff --git a/etc/snapshot_etc.go b/etc/snapshot_etc.go
index 9a25d5a..b54a8a6 100644
--- a/etc/snapshot_etc.go
+++ b/etc/snapshot_etc.go
@@ -128,7 +128,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base())
},
},
diff --git a/filesystem/bootimg.go b/filesystem/bootimg.go
index 73d807d..fc973a4 100644
--- a/filesystem/bootimg.go
+++ b/filesystem/bootimg.go
@@ -267,7 +267,7 @@
OutputFile: android.OptionalPathForPath(b.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", b.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", b.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", b.installFileName())
},
},
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index b2caa51..0796258 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -394,7 +394,7 @@
OutputFile: android.OptionalPathForPath(f.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", f.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", f.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", f.installFileName())
},
},
diff --git a/filesystem/logical_partition.go b/filesystem/logical_partition.go
index 739e609..e2f7d7b 100644
--- a/filesystem/logical_partition.go
+++ b/filesystem/logical_partition.go
@@ -215,7 +215,7 @@
OutputFile: android.OptionalPathForPath(l.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", l.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", l.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", l.installFileName())
},
},
diff --git a/filesystem/vbmeta.go b/filesystem/vbmeta.go
index 3f16c0d..63e0aba 100644
--- a/filesystem/vbmeta.go
+++ b/filesystem/vbmeta.go
@@ -247,7 +247,7 @@
OutputFile: android.OptionalPathForPath(v.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", v.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", v.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
},
},
diff --git a/java/androidmk.go b/java/androidmk.go
index 272a4fd..19fe7e2 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -182,7 +182,14 @@
}
func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries {
- if prebuilt.hideApexVariantFromMake || !prebuilt.ContainingSdk().Unversioned() {
+ if prebuilt.hideApexVariantFromMake {
+ // For a library imported from a prebuilt APEX, we don't need a Make module for itself, as we
+ // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it
+ // is preopted.
+ dexpreoptEntries := prebuilt.dexpreopter.AndroidMkEntriesForApex()
+ return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true})
+ }
+ if !prebuilt.ContainingSdk().Unversioned() {
return []android.AndroidMkEntries{android.AndroidMkEntries{
Disabled: true,
}}
@@ -685,7 +692,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_CERTIFICATE", r.certificate.AndroidMkString())
- entries.SetPath("LOCAL_MODULE_PATH", r.installDir.ToMakePath())
+ entries.SetPath("LOCAL_MODULE_PATH", r.installDir)
entries.AddStrings("LOCAL_OVERRIDES_PACKAGES", r.properties.Overrides...)
},
},
diff --git a/java/app.go b/java/app.go
index b753c0c..1c69aeb 100755
--- a/java/app.go
+++ b/java/app.go
@@ -485,7 +485,7 @@
a.jniLibs = jniLibs
if a.shouldEmbedJnis(ctx) {
jniJarFile = android.PathForModuleOut(ctx, "jnilibs.zip")
- a.installPathForJNISymbols = a.installPath(ctx).ToMakePath()
+ a.installPathForJNISymbols = a.installPath(ctx)
TransformJniLibsToJar(ctx, jniJarFile, jniLibs, a.useEmbeddedNativeLibs(ctx))
for _, jni := range jniLibs {
if jni.coverageFile.Valid() {
diff --git a/java/app_import.go b/java/app_import.go
index 4d1969e..3e5f972 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -108,8 +108,6 @@
return true
}
-func (a *AndroidAppImport) InstallBypassMake() bool { return true }
-
// Updates properties with variant-specific values.
func (a *AndroidAppImport) processVariants(ctx android.LoadHookContext) {
config := ctx.Config()
diff --git a/java/base.go b/java/base.go
index c45ef64..7cd71a2 100644
--- a/java/base.go
+++ b/java/base.go
@@ -122,6 +122,14 @@
Javacflags []string
}
+ Openjdk11 struct {
+ // List of source files that should only be used when passing -source 1.9 or higher
+ Srcs []string `android:"path"`
+
+ // List of javac flags that should only be used when passing -source 1.9 or higher
+ Javacflags []string
+ }
+
// When compiling language level 9+ .java code in packages that are part of
// a system module, patch_module names the module that your sources and
// dependencies should be patched into. The Android runtime currently
@@ -959,6 +967,10 @@
if flags.javaVersion.usesJavaModules() {
j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...)
}
+ if ctx.Config().TargetsJava11() {
+ j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk11.Srcs...)
+ }
+
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
if hasSrcExt(srcFiles.Strings(), ".proto") {
flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags)
diff --git a/java/classpath_fragment.go b/java/classpath_fragment.go
index e77971b..ca27528 100644
--- a/java/classpath_fragment.go
+++ b/java/classpath_fragment.go
@@ -204,7 +204,7 @@
OutputFile: android.OptionalPathForPath(c.outputFilepath),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", c.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base())
},
},
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index f3a53ee..e9bc518 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -115,6 +115,11 @@
return !apexInfo.IsForPlatform()
}
+func forPrebuiltApex(ctx android.BaseModuleContext) bool {
+ apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo)
+ return apexInfo.ForPrebuiltApex
+}
+
func moduleName(ctx android.BaseModuleContext) string {
// Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not
// expected by dexpreopter.
@@ -134,7 +139,9 @@
return true
}
- if !ctx.Module().(DexpreopterInterface).IsInstallable() {
+ // If the module is from a prebuilt APEX, it shouldn't be installable, but it can still be
+ // dexpreopted.
+ if !ctx.Module().(DexpreopterInterface).IsInstallable() && !forPrebuiltApex(ctx) {
return true
}
@@ -152,15 +159,16 @@
return true
}
+ isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
if isApexVariant(ctx) {
// Don't preopt APEX variant module unless the module is an APEX system server jar and we are
// building the entire system image.
- if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) || ctx.Config().UnbundledBuild() {
+ if !isApexSystemServerJar || ctx.Config().UnbundledBuild() {
return true
}
} else {
// Don't preopt the platform variant of an APEX system server jar to avoid conflicts.
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ if isApexSystemServerJar {
return true
}
}
@@ -191,8 +199,8 @@
func (d *dexpreopter) getInstallPath(
ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath {
global := dexpreopt.GetGlobalConfig(ctx)
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
- dexLocation := dexpreopt.GetSystemServerDexLocation(global, moduleName(ctx))
+ if global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) {
+ dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, moduleName(ctx))
return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/"))
}
if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) &&
@@ -229,8 +237,7 @@
return
}
- isSystemServerJar := global.SystemServerJars.ContainsJar(moduleName(ctx)) ||
- global.ApexSystemServerJars.ContainsJar(moduleName(ctx))
+ isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx))
bootImage := defaultBootImageConfig(ctx)
if global.UseArtImage {
@@ -336,6 +343,8 @@
dexpreoptRule.Build("dexpreopt", "dexpreopt")
+ isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx))
+
for _, install := range dexpreoptRule.Installs() {
// Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT.
installDir := strings.TrimPrefix(filepath.Dir(install.To), "/")
@@ -343,7 +352,7 @@
arch := filepath.Base(installDir)
installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir)
- if global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ if isApexSystemServerJar {
// APEX variants of java libraries are hidden from Make, so their dexpreopt
// outputs need special handling. Currently, for APEX variants of java
// libraries, only those in the system server classpath are handled here.
@@ -362,7 +371,7 @@
}
}
- if !global.ApexSystemServerJars.ContainsJar(moduleName(ctx)) {
+ if !isApexSystemServerJar {
d.builtInstalled = dexpreoptRule.Installs().String()
}
}
@@ -381,7 +390,7 @@
OutputFile: android.OptionalPathForPath(install.outputPathOnHost),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice)
entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false")
},
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 75083e8..c599c4d 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -506,8 +506,18 @@
dst := dstBootJarsByModule[name]
if src == nil {
+ // A dex boot jar should be provided by the source java module. It needs to be installable or
+ // have compile_dex=true - cf. assignments to java.Module.dexJarFile.
+ //
+ // However, the source java module may be either replaced or overridden (using prefer:true) by
+ // a prebuilt java module with the same name. In that case the dex boot jar needs to be
+ // provided by the corresponding prebuilt APEX module. That APEX is the one that refers
+ // through a exported_(boot|systemserver)classpath_fragments property to a
+ // prebuilt_(boot|systemserver)classpath_fragment module, which in turn lists the prebuilt
+ // java module in the contents property. If that chain is broken then this dependency will
+ // fail.
if !ctx.Config().AllowMissingDependencies() {
- ctx.ModuleErrorf("module %s does not provide a dex boot jar", name)
+ ctx.ModuleErrorf("module %s does not provide a dex boot jar (see comment next to this message in Soong for details)", name)
} else {
ctx.AddMissingDependencies([]string{name})
}
diff --git a/java/dexpreopt_check.go b/java/dexpreopt_check.go
index 565901d..83c088c 100644
--- a/java/dexpreopt_check.go
+++ b/java/dexpreopt_check.go
@@ -59,7 +59,7 @@
func getInstallPath(ctx android.ModuleContext, location string) android.InstallPath {
return android.PathForModuleInPartitionInstall(
- ctx, "", strings.TrimPrefix(location, "/")).ToMakePath()
+ ctx, "", strings.TrimPrefix(location, "/"))
}
func (m *dexpreoptSystemserverCheck) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -72,9 +72,9 @@
return
}
- systemServerJars := dexpreopt.AllSystemServerJars(ctx, global)
+ systemServerJars := global.AllSystemServerJars(ctx)
for _, jar := range systemServerJars.CopyOfJars() {
- dexLocation := dexpreopt.GetSystemServerDexLocation(global, jar)
+ dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, jar)
odexLocation := dexpreopt.ToOdexPath(dexLocation, targets[0].Arch.ArchType)
odexPath := getInstallPath(ctx, odexLocation)
vdexPath := getInstallPath(ctx, pathtools.ReplaceExtension(odexLocation, "vdex"))
diff --git a/java/java.go b/java/java.go
index f77c694..9b4a005 100644
--- a/java/java.go
+++ b/java/java.go
@@ -267,8 +267,6 @@
return j.kytheFiles
}
-func (j *Module) InstallBypassMake() bool { return true }
-
type dependencyTag struct {
blueprint.BaseDependencyTag
name string
@@ -451,7 +449,7 @@
return normalizeJavaVersion(ctx, javaVersion)
} else if ctx.Device() {
return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx))
- } else if ctx.Config().IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") {
+ } else if ctx.Config().TargetsJava11() {
// Temporary experimental flag to be able to try and build with
// java version 11 options. The flag, if used, just sets Java
// 11 as the default version, leaving any components that
diff --git a/java/lint.go b/java/lint.go
index fe3218e..7845c33 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -377,6 +377,7 @@
html := android.PathForModuleOut(ctx, "lint", "lint-report.html")
text := android.PathForModuleOut(ctx, "lint", "lint-report.txt")
xml := android.PathForModuleOut(ctx, "lint", "lint-report.xml")
+ baseline := android.PathForModuleOut(ctx, "lint", "lint-baseline.xml")
depSetsBuilder := NewLintDepSetBuilder().Direct(html, text, xml)
@@ -447,6 +448,8 @@
cmd.FlagWithInput("--baseline ", lintBaseline.Path())
}
+ cmd.FlagWithOutput("--write-reference-baseline ", baseline)
+
cmd.Text("|| (").Text("if [ -e").Input(text).Text("]; then cat").Input(text).Text("; fi; exit 7)")
rule.Command().Text("rm -rf").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 0d8ebac..f442ddf 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -115,7 +115,7 @@
Include: "$(BUILD_PREBUILT)",
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.configFile.Base())
},
},
diff --git a/java/robolectric.go b/java/robolectric.go
index 16af546..f719521 100644
--- a/java/robolectric.go
+++ b/java/robolectric.go
@@ -352,7 +352,6 @@
return module
}
-func (r *robolectricTest) InstallBypassMake() bool { return true }
func (r *robolectricTest) InstallInTestcases() bool { return true }
func (r *robolectricTest) InstallForceOS() (*android.OsType, *android.ArchType) {
return &r.forceOSType, &r.forceArchType
@@ -430,7 +429,6 @@
}
}
-func (r *robolectricRuntimes) InstallBypassMake() bool { return true }
func (r *robolectricRuntimes) InstallInTestcases() bool { return true }
func (r *robolectricRuntimes) InstallForceOS() (*android.OsType, *android.ArchType) {
return &r.forceOSType, &r.forceArchType
diff --git a/java/rro_test.go b/java/rro_test.go
index 27abbe4..be0d7ba 100644
--- a/java/rro_test.go
+++ b/java/rro_test.go
@@ -62,6 +62,7 @@
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
PrepareForTestWithOverlayBuildComponents,
+ android.FixtureModifyConfig(android.SetKatiEnabledForTests),
fs.AddToFixture(),
).RunTestWithBp(t, bp)
@@ -127,7 +128,10 @@
}
func TestRuntimeResourceOverlay_JavaDefaults(t *testing.T) {
- ctx, config := testJava(t, `
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyConfig(android.SetKatiEnabledForTests),
+ ).RunTestWithBp(t, `
java_defaults {
name: "rro_defaults",
theme: "default_theme",
@@ -148,7 +152,7 @@
//
// RRO module with defaults
//
- m := ctx.ModuleForTests("foo_with_defaults", "android_common")
+ m := result.ModuleForTests("foo_with_defaults", "android_common")
// Check AAPT2 link flags.
aapt2Flags := strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -159,14 +163,14 @@
}
// Check device location.
- path := android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ path := android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
expectedPath := []string{shared.JoinPath("out/target/product/test_device/product/overlay/default_theme")}
- android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
+ android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
//
// RRO module without defaults
//
- m = ctx.ModuleForTests("foo_barebones", "android_common")
+ m = result.ModuleForTests("foo_barebones", "android_common")
// Check AAPT2 link flags.
aapt2Flags = strings.Split(m.Output("package-res.apk").Args["flags"], " ")
@@ -176,9 +180,9 @@
}
// Check device location.
- path = android.AndroidMkEntriesForTest(t, ctx, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
+ path = android.AndroidMkEntriesForTest(t, result.TestContext, m.Module())[0].EntryMap["LOCAL_MODULE_PATH"]
expectedPath = []string{shared.JoinPath("out/target/product/test_device/product/overlay")}
- android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", config, expectedPath, path)
+ android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_MODULE_PATH", result.Config, expectedPath, path)
}
func TestOverrideRuntimeResourceOverlay(t *testing.T) {
diff --git a/java/sdk.go b/java/sdk.go
index de7070e..756a24d 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -55,7 +55,7 @@
return JAVA_VERSION_7
} else if sdk.FinalOrFutureInt() <= 29 {
return JAVA_VERSION_8
- } else if ctx.Config().IsEnvTrue("EXPERIMENTAL_TARGET_JAVA_VERSION_11") {
+ } else if ctx.Config().TargetsJava11() {
// Temporary experimental flag to be able to try and build with
// java version 11 options. The flag, if used, just sets Java
// 11 as the default version, leaving any components that
diff --git a/java/sdk_library.go b/java/sdk_library.go
index de0d796..0bc8895 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1392,6 +1392,10 @@
Srcs []string
Javacflags []string
}
+ Openjdk11 struct {
+ Srcs []string
+ Javacflags []string
+ }
Dist struct {
Targets []string
Dest *string
@@ -1418,6 +1422,8 @@
}
props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
+ props.Openjdk11.Srcs = module.properties.Openjdk11.Srcs
+ props.Openjdk11.Javacflags = module.properties.Openjdk11.Javacflags
// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
@@ -2641,7 +2647,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_TAGS", "optional")
- entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", module.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", module.outputFilePath.Base())
},
},
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 2ec33a4..fa61ea6 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -60,7 +60,7 @@
classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, p.classpathType)
standaloneConfiguredJars := p.standaloneConfiguredJars(ctx)
standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
- configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
+ configuredJars = configuredJars.AppendList(&standaloneConfiguredJars)
classpathJars = append(classpathJars, standaloneClasspathJars...)
p.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
}
@@ -122,7 +122,7 @@
classpathJars := configuredJarListToClasspathJars(ctx, configuredJars, s.classpathType)
standaloneConfiguredJars := s.standaloneConfiguredJars(ctx)
standaloneClasspathJars := configuredJarListToClasspathJars(ctx, standaloneConfiguredJars, STANDALONE_SYSTEMSERVER_JARS)
- configuredJars = configuredJars.AppendList(standaloneConfiguredJars)
+ configuredJars = configuredJars.AppendList(&standaloneConfiguredJars)
classpathJars = append(classpathJars, standaloneClasspathJars...)
s.classpathFragmentBase().generateClasspathProtoBuildActions(ctx, configuredJars, classpathJars)
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 8d0ad7c..dbc112e 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -155,7 +155,7 @@
OutputFile: android.OptionalPathForPath(l.outputFilePath),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", l.installDirPath.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", l.installDirPath.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", l.outputFilePath.Base())
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !installable)
entries.SetString("LINKER_CONFIG_PATH_"+l.Name(), l.OutputFile().String())
diff --git a/mk2rbc/expr.go b/mk2rbc/expr.go
index 81b31c7..7cd4899 100644
--- a/mk2rbc/expr.go
+++ b/mk2rbc/expr.go
@@ -16,21 +16,22 @@
import (
"fmt"
- "strconv"
"strings"
)
-// Represents an expression in the Starlark code. An expression has
-// a type, and it can be evaluated.
+// Represents an expression in the Starlark code. An expression has a type.
type starlarkExpr interface {
starlarkNode
typ() starlarkType
- // Try to substitute variable values. Return substitution result
- // and whether it is the same as the original expression.
- eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool)
// Emit the code to copy the expression, otherwise we will end up
// with source and target pointing to the same list.
emitListVarCopy(gctx *generationContext)
+ // Return the expression, calling the transformer func for
+ // every expression in the tree. If the transformer func returns non-nil,
+ // its result is used in place of the expression it was called with in the
+ // resulting expression. The resulting starlarkExpr will contain as many
+ // of the same objects from the original expression as possible.
+ transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr
}
func maybeString(expr starlarkExpr) (string, bool) {
@@ -44,12 +45,6 @@
literal string
}
-func (s *stringLiteralExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
- res = s
- same = true
- return
-}
-
func (s *stringLiteralExpr) emit(gctx *generationContext) {
gctx.writef("%q", s.literal)
}
@@ -62,17 +57,19 @@
s.emit(gctx)
}
+func (s *stringLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(s); replacement != nil {
+ return replacement
+ } else {
+ return s
+ }
+}
+
// Integer literal
type intLiteralExpr struct {
literal int
}
-func (s *intLiteralExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
- res = s
- same = true
- return
-}
-
func (s *intLiteralExpr) emit(gctx *generationContext) {
gctx.writef("%d", s.literal)
}
@@ -85,15 +82,19 @@
s.emit(gctx)
}
+func (s *intLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(s); replacement != nil {
+ return replacement
+ } else {
+ return s
+ }
+}
+
// Boolean literal
type boolLiteralExpr struct {
literal bool
}
-func (b *boolLiteralExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
- return b, true
-}
-
func (b *boolLiteralExpr) emit(gctx *generationContext) {
if b.literal {
gctx.write("True")
@@ -110,6 +111,14 @@
b.emit(gctx)
}
+func (b *boolLiteralExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(b); replacement != nil {
+ return replacement
+ } else {
+ return b
+ }
+}
+
// interpolateExpr represents Starlark's interpolation operator <string> % list
// we break <string> into a list of chunks, i.e., "first%second%third" % (X, Y)
// will have chunks = ["first", "second", "third"] and args = [X, Y]
@@ -118,6 +127,35 @@
args []starlarkExpr
}
+func NewInterpolateExpr(parts []starlarkExpr) starlarkExpr {
+ result := &interpolateExpr{}
+ needString := true
+ for _, part := range parts {
+ if needString {
+ if strLit, ok := part.(*stringLiteralExpr); ok {
+ result.chunks = append(result.chunks, strLit.literal)
+ } else {
+ result.chunks = append(result.chunks, "")
+ }
+ needString = false
+ } else {
+ if strLit, ok := part.(*stringLiteralExpr); ok {
+ result.chunks[len(result.chunks)-1] += strLit.literal
+ } else {
+ result.args = append(result.args, part)
+ needString = true
+ }
+ }
+ }
+ if len(result.chunks) == len(result.args) {
+ result.chunks = append(result.chunks, "")
+ }
+ if len(result.args) == 0 {
+ return &stringLiteralExpr{literal: strings.Join(result.chunks, "")}
+ }
+ return result
+}
+
func (xi *interpolateExpr) emit(gctx *generationContext) {
if len(xi.chunks) != len(xi.args)+1 {
panic(fmt.Errorf("malformed interpolateExpr: #chunks(%d) != #args(%d)+1",
@@ -151,37 +189,6 @@
}
}
-func (xi *interpolateExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- same = true
- newChunks := []string{xi.chunks[0]}
- var newArgs []starlarkExpr
- for i, arg := range xi.args {
- newArg, sameArg := arg.eval(valueMap)
- same = same && sameArg
- switch x := newArg.(type) {
- case *stringLiteralExpr:
- newChunks[len(newChunks)-1] += x.literal + xi.chunks[i+1]
- same = false
- continue
- case *intLiteralExpr:
- newChunks[len(newChunks)-1] += strconv.Itoa(x.literal) + xi.chunks[i+1]
- same = false
- continue
- default:
- newChunks = append(newChunks, xi.chunks[i+1])
- newArgs = append(newArgs, newArg)
- }
- }
- if same {
- res = xi
- } else if len(newChunks) == 1 {
- res = &stringLiteralExpr{newChunks[0]}
- } else {
- res = &interpolateExpr{chunks: newChunks, args: newArgs}
- }
- return
-}
-
func (_ *interpolateExpr) typ() starlarkType {
return starlarkTypeString
}
@@ -190,19 +197,29 @@
xi.emit(gctx)
}
+func (xi *interpolateExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ argsCopy := make([]starlarkExpr, len(xi.args))
+ for i, arg := range xi.args {
+ argsCopy[i] = arg.transform(transformer)
+ }
+ xi.args = argsCopy
+ if replacement := transformer(xi); replacement != nil {
+ return replacement
+ } else {
+ return xi
+ }
+}
+
type variableRefExpr struct {
ref variable
isDefined bool
}
-func (v *variableRefExpr) eval(map[string]starlarkExpr) (res starlarkExpr, same bool) {
- predefined, ok := v.ref.(*predefinedVariable)
- if same = !ok; same {
- res = v
- } else {
- res = predefined.value
+func NewVariableRefExpr(ref variable, isDefined bool) starlarkExpr {
+ if predefined, ok := ref.(*predefinedVariable); ok {
+ return predefined.value
}
- return
+ return &variableRefExpr{ref, isDefined}
}
func (v *variableRefExpr) emit(gctx *generationContext) {
@@ -220,17 +237,16 @@
}
}
-type toStringExpr struct {
- expr starlarkExpr
+func (v *variableRefExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(v); replacement != nil {
+ return replacement
+ } else {
+ return v
+ }
}
-func (s *toStringExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- if x, same := s.expr.eval(valueMap); same {
- res = s
- } else {
- res = &toStringExpr{expr: x}
- }
- return
+type toStringExpr struct {
+ expr starlarkExpr
}
func (s *toStringExpr) emit(ctx *generationContext) {
@@ -265,17 +281,17 @@
s.emit(gctx)
}
-type notExpr struct {
- expr starlarkExpr
+func (s *toStringExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ s.expr = s.expr.transform(transformer)
+ if replacement := transformer(s); replacement != nil {
+ return replacement
+ } else {
+ return s
+ }
}
-func (n *notExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- if x, same := n.expr.eval(valueMap); same {
- res = n
- } else {
- res = ¬Expr{expr: x}
- }
- return
+type notExpr struct {
+ expr starlarkExpr
}
func (n *notExpr) emit(ctx *generationContext) {
@@ -291,22 +307,20 @@
n.emit(gctx)
}
+func (n *notExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ n.expr = n.expr.transform(transformer)
+ if replacement := transformer(n); replacement != nil {
+ return replacement
+ } else {
+ return n
+ }
+}
+
type eqExpr struct {
left, right starlarkExpr
isEq bool // if false, it's !=
}
-func (eq *eqExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- xLeft, sameLeft := eq.left.eval(valueMap)
- xRight, sameRight := eq.right.eval(valueMap)
- if same = sameLeft && sameRight; same {
- res = eq
- } else {
- res = &eqExpr{left: xLeft, right: xRight, isEq: eq.isEq}
- }
- return
-}
-
func (eq *eqExpr) emit(gctx *generationContext) {
var stringOperand string
var otherOperand starlarkExpr
@@ -360,18 +374,21 @@
eq.emit(gctx)
}
+func (eq *eqExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ eq.left = eq.left.transform(transformer)
+ eq.right = eq.right.transform(transformer)
+ if replacement := transformer(eq); replacement != nil {
+ return replacement
+ } else {
+ return eq
+ }
+}
+
// variableDefinedExpr corresponds to Make's ifdef VAR
type variableDefinedExpr struct {
v variable
}
-func (v *variableDefinedExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
- res = v
- same = true
- return
-
-}
-
func (v *variableDefinedExpr) emit(gctx *generationContext) {
if v.v != nil {
v.v.emitDefined(gctx)
@@ -388,24 +405,13 @@
v.emit(gctx)
}
-type listExpr struct {
- items []starlarkExpr
+func (v *variableDefinedExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ // TODO: VariableDefinedExpr isn't really an expression?
+ return v
}
-func (l *listExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- newItems := make([]starlarkExpr, len(l.items))
- same = true
- for i, item := range l.items {
- var sameItem bool
- newItems[i], sameItem = item.eval(valueMap)
- same = same && sameItem
- }
- if same {
- res = l
- } else {
- res = &listExpr{newItems}
- }
- return
+type listExpr struct {
+ items []starlarkExpr
}
func (l *listExpr) emit(gctx *generationContext) {
@@ -442,6 +448,19 @@
l.emit(gctx)
}
+func (l *listExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ itemsCopy := make([]starlarkExpr, len(l.items))
+ for i, item := range l.items {
+ itemsCopy[i] = item.transform(transformer)
+ }
+ l.items = itemsCopy
+ if replacement := transformer(l); replacement != nil {
+ return replacement
+ } else {
+ return l
+ }
+}
+
func newStringListExpr(items []string) *listExpr {
v := listExpr{}
for _, item := range items {
@@ -481,22 +500,6 @@
gctx.indentLevel -= 2
}
-func (c *concatExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- same = true
- xConcat := &concatExpr{items: make([]starlarkExpr, len(c.items))}
- for i, item := range c.items {
- var sameItem bool
- xConcat.items[i], sameItem = item.eval(valueMap)
- same = same && sameItem
- }
- if same {
- res = c
- } else {
- res = xConcat
- }
- return
-}
-
func (_ *concatExpr) typ() starlarkType {
return starlarkTypeList
}
@@ -505,6 +508,19 @@
c.emit(gctx)
}
+func (c *concatExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ itemsCopy := make([]starlarkExpr, len(c.items))
+ for i, item := range c.items {
+ itemsCopy[i] = item.transform(transformer)
+ }
+ c.items = itemsCopy
+ if replacement := transformer(c); replacement != nil {
+ return replacement
+ } else {
+ return c
+ }
+}
+
// inExpr generates <expr> [not] in <list>
type inExpr struct {
expr starlarkExpr
@@ -512,19 +528,6 @@
isNot bool
}
-func (i *inExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- x := &inExpr{isNot: i.isNot}
- var sameExpr, sameList bool
- x.expr, sameExpr = i.expr.eval(valueMap)
- x.list, sameList = i.list.eval(valueMap)
- if same = sameExpr && sameList; same {
- res = i
- } else {
- res = x
- }
- return
-}
-
func (i *inExpr) emit(gctx *generationContext) {
i.expr.emit(gctx)
if i.isNot {
@@ -543,35 +546,44 @@
i.emit(gctx)
}
+func (i *inExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ i.expr = i.expr.transform(transformer)
+ i.list = i.list.transform(transformer)
+ if replacement := transformer(i); replacement != nil {
+ return replacement
+ } else {
+ return i
+ }
+}
+
type indexExpr struct {
array starlarkExpr
index starlarkExpr
}
-func (ix indexExpr) emit(gctx *generationContext) {
+func (ix *indexExpr) emit(gctx *generationContext) {
ix.array.emit(gctx)
gctx.write("[")
ix.index.emit(gctx)
gctx.write("]")
}
-func (ix indexExpr) typ() starlarkType {
+func (ix *indexExpr) typ() starlarkType {
return starlarkTypeString
}
-func (ix indexExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- newArray, isSameArray := ix.array.eval(valueMap)
- newIndex, isSameIndex := ix.index.eval(valueMap)
- if same = isSameArray && isSameIndex; same {
- res = ix
- } else {
- res = &indexExpr{newArray, newIndex}
- }
- return
+func (ix *indexExpr) emitListVarCopy(gctx *generationContext) {
+ ix.emit(gctx)
}
-func (ix indexExpr) emitListVarCopy(gctx *generationContext) {
- ix.emit(gctx)
+func (ix *indexExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ ix.array = ix.array.transform(transformer)
+ ix.index = ix.index.transform(transformer)
+ if replacement := transformer(ix); replacement != nil {
+ return replacement
+ } else {
+ return ix
+ }
}
type callExpr struct {
@@ -581,27 +593,6 @@
returnType starlarkType
}
-func (cx *callExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- newCallExpr := &callExpr{name: cx.name, args: make([]starlarkExpr, len(cx.args)),
- returnType: cx.returnType}
- if cx.object != nil {
- newCallExpr.object, same = cx.object.eval(valueMap)
- } else {
- same = true
- }
- for i, args := range cx.args {
- var s bool
- newCallExpr.args[i], s = args.eval(valueMap)
- same = same && s
- }
- if same {
- res = cx
- } else {
- res = newCallExpr
- }
- return
-}
-
func (cx *callExpr) emit(gctx *generationContext) {
sep := ""
if cx.object != nil {
@@ -642,28 +633,27 @@
cx.emit(gctx)
}
+func (cx *callExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if cx.object != nil {
+ cx.object = cx.object.transform(transformer)
+ }
+ argsCopy := make([]starlarkExpr, len(cx.args))
+ for i, arg := range cx.args {
+ argsCopy[i] = arg.transform(transformer)
+ }
+ if replacement := transformer(cx); replacement != nil {
+ return replacement
+ } else {
+ return cx
+ }
+}
+
type ifExpr struct {
condition starlarkExpr
ifTrue starlarkExpr
ifFalse starlarkExpr
}
-func (i *ifExpr) eval(valueMap map[string]starlarkExpr) (res starlarkExpr, same bool) {
- cond, condSame := i.condition.eval(valueMap)
- t, tSame := i.ifTrue.eval(valueMap)
- f, fSame := i.ifFalse.eval(valueMap)
- same = condSame && tSame && fSame
- if same {
- return i, same
- } else {
- return &ifExpr{
- condition: cond,
- ifTrue: t,
- ifFalse: f,
- }, same
- }
-}
-
func (i *ifExpr) emit(gctx *generationContext) {
gctx.write("(")
i.ifTrue.emit(gctx)
@@ -691,17 +681,78 @@
i.emit(gctx)
}
+func (i *ifExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ i.condition = i.condition.transform(transformer)
+ i.ifTrue = i.ifTrue.transform(transformer)
+ i.ifFalse = i.ifFalse.transform(transformer)
+ if replacement := transformer(i); replacement != nil {
+ return replacement
+ } else {
+ return i
+ }
+}
+
+type identifierExpr struct {
+ name string
+}
+
+func (i *identifierExpr) emit(gctx *generationContext) {
+ gctx.write(i.name)
+}
+
+func (i *identifierExpr) typ() starlarkType {
+ return starlarkTypeUnknown
+}
+
+func (i *identifierExpr) emitListVarCopy(gctx *generationContext) {
+ i.emit(gctx)
+}
+
+func (i *identifierExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(i); replacement != nil {
+ return replacement
+ } else {
+ return i
+ }
+}
+
+type foreachExpr struct {
+ varName string
+ list starlarkExpr
+ action starlarkExpr
+}
+
+func (f *foreachExpr) emit(gctx *generationContext) {
+ gctx.write("[")
+ f.action.emit(gctx)
+ gctx.write(" for " + f.varName + " in ")
+ f.list.emit(gctx)
+ gctx.write("]")
+}
+
+func (f *foreachExpr) typ() starlarkType {
+ return starlarkTypeList
+}
+
+func (f *foreachExpr) emitListVarCopy(gctx *generationContext) {
+ f.emit(gctx)
+}
+
+func (f *foreachExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ f.list = f.list.transform(transformer)
+ f.action = f.action.transform(transformer)
+ if replacement := transformer(f); replacement != nil {
+ return replacement
+ } else {
+ return f
+ }
+}
+
type badExpr struct {
errorLocation ErrorLocation
message string
}
-func (b *badExpr) eval(_ map[string]starlarkExpr) (res starlarkExpr, same bool) {
- res = b
- same = true
- return
-}
-
func (b *badExpr) emit(gctx *generationContext) {
gctx.emitConversionError(b.errorLocation, b.message)
}
@@ -714,6 +765,14 @@
panic("implement me")
}
+func (b *badExpr) transform(transformer func(expr starlarkExpr) starlarkExpr) starlarkExpr {
+ if replacement := transformer(b); replacement != nil {
+ return replacement
+ } else {
+ return b
+ }
+}
+
func maybeConvertToStringList(expr starlarkExpr) starlarkExpr {
if xString, ok := expr.(*stringLiteralExpr); ok {
return newStringListExpr(strings.Fields(xString.literal))
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index d5ff181..2a80e56 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -105,12 +105,13 @@
"dist-for-goals": {baseName + ".mkdist_for_goals", starlarkTypeVoid, hiddenArgGlobal},
"enforce-product-packages-exist": {baseName + ".enforce_product_packages_exist", starlarkTypeVoid, hiddenArgNone},
"error": {baseName + ".mkerror", starlarkTypeVoid, hiddenArgNone},
- "findstring": {"!findstring", starlarkTypeInt, hiddenArgNone},
+ "findstring": {baseName + ".findstring", starlarkTypeString, hiddenArgNone},
"find-copy-subdir-files": {baseName + ".find_and_copy", starlarkTypeList, hiddenArgNone},
"find-word-in-list": {"!find-word-in-list", starlarkTypeUnknown, hiddenArgNone}, // internal macro
"filter": {baseName + ".filter", starlarkTypeList, hiddenArgNone},
"filter-out": {baseName + ".filter_out", starlarkTypeList, hiddenArgNone},
"firstword": {"!firstword", starlarkTypeString, hiddenArgNone},
+ "foreach": {"!foreach", starlarkTypeList, hiddenArgNone},
"get-vendor-board-platforms": {"!get-vendor-board-platforms", starlarkTypeList, hiddenArgNone}, // internal macro, used by is-board-platform, etc.
"if": {"!if", starlarkTypeUnknown, hiddenArgNone},
"info": {baseName + ".mkinfo", starlarkTypeVoid, hiddenArgNone},
@@ -147,14 +148,10 @@
"warning": {baseName + ".mkwarning", starlarkTypeVoid, hiddenArgNone},
"word": {baseName + "!word", starlarkTypeString, hiddenArgNone},
"wildcard": {baseName + ".expand_wildcard", starlarkTypeList, hiddenArgNone},
+ "words": {baseName + ".words", starlarkTypeList, hiddenArgNone},
}
-var builtinFuncRex = regexp.MustCompile(
- "^(addprefix|addsuffix|abspath|and|basename|call|dir|error|eval" +
- "|flavor|foreach|file|filter|filter-out|findstring|firstword|guile" +
- "|if|info|join|lastword|notdir|or|origin|patsubst|realpath" +
- "|shell|sort|strip|subst|suffix|value|warning|word|wordlist|words" +
- "|wildcard)")
+var identifierFullMatchRegex = regexp.MustCompile("^[a-zA-Z_][a-zA-Z0-9_]*$")
// Conversion request parameters
type Request struct {
@@ -414,7 +411,6 @@
ifNestLevel int
moduleNameCount map[string]int // count of imported modules with given basename
fatalError error
- builtinMakeVars map[string]starlarkExpr
outputSuffix string
errorLogger ErrorLogger
tracedVariables map[string]bool // variables to be traced in the generated script
@@ -467,7 +463,6 @@
currentNodeIndex: 0,
ifNestLevel: 0,
moduleNameCount: make(map[string]int),
- builtinMakeVars: map[string]starlarkExpr{},
variables: make(map[string]variable),
dependentModules: make(map[string]*moduleInfo),
soongNamespaces: make(map[string]map[string]bool),
@@ -603,9 +598,6 @@
}
}
- // TODO(asmundak): move evaluation to a separate pass
- asgn.value, _ = asgn.value.eval(ctx.builtinMakeVars)
-
asgn.previous = ctx.lastAssignment(name)
ctx.setLastAssignment(name, asgn)
switch a.Type {
@@ -632,7 +624,6 @@
ctx.wrapBadExpr(xBad)
return
}
- val, _ = val.eval(ctx.builtinMakeVars)
// Unfortunately, Soong namespaces can be set up by directly setting corresponding Make
// variables instead of via add_soong_config_namespace + add_soong_config_var_value.
@@ -788,7 +779,6 @@
func (ctx *parseContext) handleSubConfig(
v mkparser.Node, pathExpr starlarkExpr, loadAlways bool, processModule func(inheritedModule)) {
- pathExpr, _ = pathExpr.eval(ctx.builtinMakeVars)
// In a simple case, the name of a module to inherit/include is known statically.
if path, ok := maybeString(pathExpr); ok {
@@ -1125,7 +1115,7 @@
return xBad, true
}
return &eqExpr{
- left: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ left: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM"), false),
right: call.args[0],
isEq: isEq,
}, true
@@ -1134,7 +1124,7 @@
return xBad, true
}
return &inExpr{
- expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM"), false),
list: maybeConvertToStringList(call.args[0]),
isNot: !isEq,
}, true
@@ -1143,7 +1133,7 @@
return xBad, true
}
return &inExpr{
- expr: &variableRefExpr{ctx.addVariable("TARGET_PRODUCT"), true},
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_PRODUCT"), true),
list: maybeConvertToStringList(call.args[0]),
isNot: !isEq,
}, true
@@ -1156,8 +1146,8 @@
return ctx.newBadExpr(directive, "cannot handle non-constant argument to is-vendor-board-platform"), true
}
return &inExpr{
- expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
- list: &variableRefExpr{ctx.addVariable(s + "_BOARD_PLATFORMS"), true},
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM"), false),
+ list: NewVariableRefExpr(ctx.addVariable(s+"_BOARD_PLATFORMS"), true),
isNot: !isEq,
}, true
@@ -1186,8 +1176,8 @@
// if the expression is ifneq (,$(call is-vendor-board-platform,...)), negate==true,
// so we should set inExpr.isNot to false
return &inExpr{
- expr: &variableRefExpr{ctx.addVariable("TARGET_BOARD_PLATFORM"), false},
- list: &variableRefExpr{ctx.addVariable("QCOM_BOARD_PLATFORMS"), true},
+ expr: NewVariableRefExpr(ctx.addVariable("TARGET_BOARD_PLATFORM"), false),
+ list: NewVariableRefExpr(ctx.addVariable("QCOM_BOARD_PLATFORMS"), true),
isNot: isEq,
}, true
}
@@ -1288,8 +1278,21 @@
right: &intLiteralExpr{-1},
isEq: !negate,
}
+ } else if s, ok := maybeString(xValue); ok {
+ if s2, ok := maybeString(xCall.args[0]); ok && s == s2 {
+ return &eqExpr{
+ left: &callExpr{
+ object: xCall.args[1],
+ name: "find",
+ args: []starlarkExpr{xCall.args[0]},
+ returnType: starlarkTypeInt,
+ },
+ right: &intLiteralExpr{-1},
+ isEq: negate,
+ }
+ }
}
- return ctx.newBadExpr(directive, "findstring result can be compared only to empty: %s", xValue)
+ return ctx.newBadExpr(directive, "$(findstring) can only be compared to nothing or its first argument")
}
func (ctx *parseContext) parseCompareStripFuncResult(directive *mkparser.Directive,
@@ -1356,12 +1359,12 @@
args: []starlarkExpr{
&stringLiteralExpr{literal: substParts[0]},
&stringLiteralExpr{literal: substParts[1]},
- &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil},
+ NewVariableRefExpr(v, ctx.lastAssignment(v.name()) != nil),
},
}
}
if v := ctx.addVariable(refDump); v != nil {
- return &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil}
+ return NewVariableRefExpr(v, ctx.lastAssignment(v.name()) != nil)
}
return ctx.newBadExpr(node, "unknown variable %s", refDump)
}
@@ -1399,12 +1402,14 @@
switch expr.name {
case "if":
return ctx.parseIfFunc(node, args)
+ case "foreach":
+ return ctx.parseForeachFunc(node, args)
case "word":
return ctx.parseWordFunc(node, args)
case "firstword", "lastword":
return ctx.parseFirstOrLastwordFunc(node, expr.name, args)
case "my-dir":
- return &variableRefExpr{ctx.addVariable("LOCAL_PATH"), true}
+ return NewVariableRefExpr(ctx.addVariable("LOCAL_PATH"), true)
case "subst", "patsubst":
return ctx.parseSubstFunc(node, expr.name, args)
default:
@@ -1483,6 +1488,38 @@
}
}
+func (ctx *parseContext) parseForeachFunc(node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
+ words := args.Split(",")
+ if len(words) != 3 {
+ return ctx.newBadExpr(node, "foreach function should have 3 arguments, found "+strconv.Itoa(len(words)))
+ }
+ if !words[0].Const() || words[0].Empty() || !identifierFullMatchRegex.MatchString(words[0].Strings[0]) {
+ return ctx.newBadExpr(node, "first argument to foreach function must be a simple string identifier")
+ }
+ loopVarName := words[0].Strings[0]
+ list := ctx.parseMakeString(node, words[1])
+ action := ctx.parseMakeString(node, words[2]).transform(func(expr starlarkExpr) starlarkExpr {
+ if varRefExpr, ok := expr.(*variableRefExpr); ok && varRefExpr.ref.name() == loopVarName {
+ return &identifierExpr{loopVarName}
+ }
+ return nil
+ })
+
+ if list.typ() != starlarkTypeList {
+ list = &callExpr{
+ name: "words",
+ returnType: knownFunctions["words"].returnType,
+ args: []starlarkExpr{list},
+ }
+ }
+
+ return &foreachExpr{
+ varName: loopVarName,
+ list: list,
+ action: action,
+ }
+}
+
func (ctx *parseContext) parseWordFunc(node mkparser.Node, args *mkparser.MakeString) starlarkExpr {
words := args.Split(",")
if len(words) != 2 {
@@ -1504,7 +1541,7 @@
if array.typ() != starlarkTypeList {
array = &callExpr{object: array, name: "split", returnType: starlarkTypeList}
}
- return indexExpr{array, &intLiteralExpr{int(index - 1)}}
+ return &indexExpr{array, &intLiteralExpr{int(index - 1)}}
}
func (ctx *parseContext) parseFirstOrLastwordFunc(node mkparser.Node, name string, args *mkparser.MakeString) starlarkExpr {
@@ -1535,16 +1572,18 @@
// If we reached here, it's neither string literal nor a simple variable,
// we need a full-blown interpolation node that will generate
// "a%b%c" % (X, Y) for a$(X)b$(Y)c
- xInterp := &interpolateExpr{args: make([]starlarkExpr, len(mk.Variables))}
- for i, ref := range mk.Variables {
- arg := ctx.parseReference(node, ref.Name)
- if x, ok := arg.(*badExpr); ok {
- return x
+ parts := make([]starlarkExpr, len(mk.Variables)+len(mk.Strings))
+ for i := 0; i < len(parts); i++ {
+ if i%2 == 0 {
+ parts[i] = &stringLiteralExpr{literal: mk.Strings[i/2]}
+ } else {
+ parts[i] = ctx.parseReference(node, mk.Variables[i/2].Name)
+ if x, ok := parts[i].(*badExpr); ok {
+ return x
+ }
}
- xInterp.args[i] = arg
}
- xInterp.chunks = append(xInterp.chunks, mk.Strings...)
- return xInterp
+ return NewInterpolateExpr(parts)
}
// Handles the statements whose treatment is the same in all contexts: comment,
@@ -1590,6 +1629,13 @@
return
}
if p, ok := maybeTrim(annotation, "include_top"); ok {
+ // Don't allow duplicate include tops, because then we will generate
+ // invalid starlark code. (duplicate keys in the _entry dictionary)
+ for _, top := range ctx.includeTops {
+ if top == p {
+ return
+ }
+ }
ctx.includeTops = append(ctx.includeTops, p)
return
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 78444c9..1ba273b 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -633,15 +633,42 @@
desc: "findstring call",
mkname: "product.mk",
in: `
+result := $(findstring a,a b c)
+result := $(findstring b,x y z)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ _result = rblf.findstring("a", "a b c")
+ _result = rblf.findstring("b", "x y z")
+`,
+ },
+ {
+ desc: "findstring in if statement",
+ mkname: "product.mk",
+ in: `
+ifeq ($(findstring foo,$(PRODUCT_PACKAGES)),)
+endif
ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),)
endif
+ifeq ($(findstring foo,$(PRODUCT_PACKAGES)),foo)
+endif
+ifneq ($(findstring foo,$(PRODUCT_PACKAGES)),foo)
+endif
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
def init(g, handle):
cfg = rblf.cfg(handle)
+ if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") == -1:
+ pass
if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
pass
+ if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") != -1:
+ pass
+ if (cfg.get("PRODUCT_PACKAGES", [])).find("foo") == -1:
+ pass
`,
},
{
@@ -1022,7 +1049,7 @@
}.get("vendor/%s/cfg.mk" % g["MY_PATH"])
(_varmod, _varmod_init) = _entry if _entry else (None, None)
if not _varmod_init:
- rblf.mkerror("cannot")
+ rblf.mkerror("product.mk", "Cannot find %s" % ("vendor/%s/cfg.mk" % g["MY_PATH"]))
rblf.inherit(handle, _varmod, _varmod_init)
`,
},
@@ -1046,7 +1073,41 @@
}.get("%s/cfg.mk" % g["MY_PATH"])
(_varmod, _varmod_init) = _entry if _entry else (None, None)
if not _varmod_init:
- rblf.mkerror("cannot")
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
+ rblf.inherit(handle, _varmod, _varmod_init)
+`,
+ },
+ {
+ desc: "Dynamic inherit with duplicated hint",
+ mkname: "product.mk",
+ in: `
+MY_PATH:=foo
+#RBC# include_top vendor/foo1
+$(call inherit-product,$(MY_PATH)/cfg.mk)
+#RBC# include_top vendor/foo1
+$(call inherit-product,$(MY_PATH)/cfg.mk)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+load("//vendor/foo1:cfg.star|init", _cfg_init = "init")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["MY_PATH"] = "foo"
+ #RBC# include_top vendor/foo1
+ _entry = {
+ "vendor/foo1/cfg.mk": ("_cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
+ rblf.inherit(handle, _varmod, _varmod_init)
+ #RBC# include_top vendor/foo1
+ _entry = {
+ "vendor/foo1/cfg.mk": ("_cfg", _cfg_init),
+ }.get("%s/cfg.mk" % g["MY_PATH"])
+ (_varmod, _varmod_init) = _entry if _entry else (None, None)
+ if not _varmod_init:
+ rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"]))
rblf.inherit(handle, _varmod, _varmod_init)
`,
},
@@ -1131,6 +1192,55 @@
g["OBJECTS2"] = rblf.mkpatsubst("%.c", "%.o", g["SOURCES"])
`,
},
+ {
+ desc: "foreach expressions",
+ mkname: "product.mk",
+ in: `
+BOOT_KERNEL_MODULES := foo.ko bar.ko
+BOOT_KERNEL_MODULES_FILTER := $(foreach m,$(BOOT_KERNEL_MODULES),%/$(m))
+BOOT_KERNEL_MODULES_LIST := foo.ko
+BOOT_KERNEL_MODULES_LIST += bar.ko
+BOOT_KERNEL_MODULES_FILTER_2 := $(foreach m,$(BOOT_KERNEL_MODULES_LIST),%/$(m))
+
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["BOOT_KERNEL_MODULES"] = "foo.ko bar.ko"
+ g["BOOT_KERNEL_MODULES_FILTER"] = ["%%/%s" % m for m in rblf.words(g["BOOT_KERNEL_MODULES"])]
+ g["BOOT_KERNEL_MODULES_LIST"] = ["foo.ko"]
+ g["BOOT_KERNEL_MODULES_LIST"] += ["bar.ko"]
+ g["BOOT_KERNEL_MODULES_FILTER_2"] = ["%%/%s" % m for m in g["BOOT_KERNEL_MODULES_LIST"]]
+`,
+ },
+ {
+ desc: "List appended to string",
+ mkname: "product.mk",
+ in: `
+NATIVE_BRIDGE_PRODUCT_PACKAGES := \
+ libnative_bridge_vdso.native_bridge \
+ native_bridge_guest_app_process.native_bridge \
+ native_bridge_guest_linker.native_bridge
+
+NATIVE_BRIDGE_MODIFIED_GUEST_LIBS := \
+ libaaudio \
+ libamidi \
+ libandroid \
+ libandroid_runtime
+
+NATIVE_BRIDGE_PRODUCT_PACKAGES += \
+ $(addsuffix .native_bridge,$(NATIVE_BRIDGE_ORIG_GUEST_LIBS))
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] = "libnative_bridge_vdso.native_bridge native_bridge_guest_app_process.native_bridge native_bridge_guest_linker.native_bridge"
+ g["NATIVE_BRIDGE_MODIFIED_GUEST_LIBS"] = "libaaudio libamidi libandroid libandroid_runtime"
+ g["NATIVE_BRIDGE_PRODUCT_PACKAGES"] += " " + " ".join(rblf.addsuffix(".native_bridge", g.get("NATIVE_BRIDGE_ORIG_GUEST_LIBS", "")))
+`,
+ },
}
var known_variables = []struct {
diff --git a/mk2rbc/node.go b/mk2rbc/node.go
index d38299d..ebc57b2 100644
--- a/mk2rbc/node.go
+++ b/mk2rbc/node.go
@@ -110,7 +110,9 @@
gctx.writef("if not %s:", i.entryName())
gctx.indentLevel++
gctx.newLine()
- gctx.write(`rblf.mkerror("cannot")`)
+ gctx.write(`rblf.mkerror("`, gctx.starScript.mkFile, `", "Cannot find %s" % (`)
+ i.path.emit(gctx)
+ gctx.write("))")
gctx.indentLevel--
}
}
diff --git a/mk2rbc/variable.go b/mk2rbc/variable.go
index 6b67a7c..f7adca5 100644
--- a/mk2rbc/variable.go
+++ b/mk2rbc/variable.go
@@ -81,10 +81,12 @@
emitAppend := func() {
pcv.emitGet(gctx, true)
gctx.write(" += ")
+ value := asgn.value
if pcv.valueType() == starlarkTypeString {
gctx.writef(`" " + `)
+ value = &toStringExpr{expr: value}
}
- asgn.value.emit(gctx)
+ value.emit(gctx)
}
switch asgn.flavor {
@@ -136,10 +138,12 @@
emitAppend := func() {
scv.emitGet(gctx, true)
gctx.write(" += ")
+ value := asgn.value
if scv.valueType() == starlarkTypeString {
gctx.writef(`" " + `)
+ value = &toStringExpr{expr: value}
}
- asgn.value.emit(gctx)
+ value.emit(gctx)
}
switch asgn.flavor {
@@ -193,10 +197,12 @@
case asgnAppend:
lv.emitGet(gctx, false)
gctx.write(" += ")
+ value := asgn.value
if lv.valueType() == starlarkTypeString {
gctx.writef(`" " + `)
+ value = &toStringExpr{expr: value}
}
- asgn.value.emit(gctx)
+ value.emit(gctx)
case asgnMaybeAppend:
gctx.writef("%s(%q, ", cfnLocalAppend, lv)
asgn.value.emit(gctx)
diff --git a/python/androidmk.go b/python/androidmk.go
index ccc85ec..233d867 100644
--- a/python/androidmk.go
+++ b/python/androidmk.go
@@ -78,7 +78,7 @@
entries.Required = append(entries.Required, "libc++")
entries.ExtraEntries = append(entries.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- path, file := filepath.Split(installer.path.ToMakePath().String())
+ path, file := filepath.Split(installer.path.String())
stem := strings.TrimSuffix(file, filepath.Ext(file))
entries.SetString("LOCAL_MODULE_SUFFIX", filepath.Ext(file))
diff --git a/rust/androidmk.go b/rust/androidmk.go
index 1f18b4a..4e58632 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -193,7 +193,7 @@
ret.ExtraEntries = append(ret.ExtraEntries,
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetPath("LOCAL_SOONG_UNSTRIPPED_BINARY", compiler.unstrippedOutputFile)
- path, file := filepath.Split(compiler.path.ToMakePath().String())
+ path, file := filepath.Split(compiler.path.String())
stem, suffix, _ := android.SplitFileExt(file)
entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
entries.SetString("LOCAL_MODULE_PATH", path)
diff --git a/rust/library.go b/rust/library.go
index 07843fe..bb2e83f 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -681,6 +681,12 @@
}
variation := v.(*Module).ModuleBase.ImageVariation().Variation
+ if strings.HasPrefix(variation, cc.VendorVariationPrefix) {
+ // TODO(b/204303985)
+ // Disable vendor dylibs until they are supported
+ v.(*Module).Disable()
+ }
+
if strings.HasPrefix(variation, cc.VendorVariationPrefix) &&
m.HasVendorVariant() &&
!snapshot.IsVendorProprietaryModule(mctx) &&
diff --git a/rust/rust.go b/rust/rust.go
index 300c0f5..c2585f2 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1312,10 +1312,6 @@
return mod.InRecovery()
}
-func (mod *Module) InstallBypassMake() bool {
- return true
-}
-
func linkPathFromFilePath(filepath android.Path) string {
return strings.Split(filepath.String(), filepath.Base())[0]
}
diff --git a/scripts/OWNERS b/scripts/OWNERS
index 88787cd..3f4f9c0 100644
--- a/scripts/OWNERS
+++ b/scripts/OWNERS
@@ -1,5 +1,4 @@
per-file system-clang-format,system-clang-format-2 = enh@google.com,smoreland@google.com
-per-file build-mainline-modules.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
per-file build-aml-prebuilts.sh = ngeoffray@google.com,paulduffin@google.com,mast@google.com
per-file construct_context.py = ngeoffray@google.com,calin@google.com,skvadrik@google.com
per-file conv_linker_config.py = kiyoungkim@google.com, jiyong@google.com, jooyung@google.com
diff --git a/scripts/build-mainline-modules.sh b/scripts/build-mainline-modules.sh
deleted file mode 100755
index 1e3f6ce..0000000
--- a/scripts/build-mainline-modules.sh
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/bin/bash -e
-
-# Non exhaustive list of modules where we want prebuilts. More can be added as
-# needed.
-MAINLINE_MODULES=(
- com.android.art
- com.android.art.debug
- com.android.art.testing
- com.android.conscrypt
- com.android.i18n
- com.android.os.statsd
- com.android.runtime
- com.android.tzdata
-)
-
-# List of SDKs and module exports we know of.
-MODULES_SDK_AND_EXPORTS=(
- art-module-sdk
- art-module-test-exports
- conscrypt-module-host-exports
- conscrypt-module-sdk
- conscrypt-module-test-exports
- i18n-module-host-exports
- i18n-module-sdk
- i18n-module-test-exports
- platform-mainline-sdk
- platform-mainline-test-exports
- runtime-module-host-exports
- runtime-module-sdk
- statsd-module-sdk
- tzdata-module-test-exports
-)
-
-# List of libraries installed on the platform that are needed for ART chroot
-# testing.
-PLATFORM_LIBRARIES=(
- heapprofd_client_api
- libartpalette-system
- liblog
-)
-
-# We want to create apex modules for all supported architectures.
-PRODUCTS=(
- aosp_arm
- aosp_arm64
- aosp_x86
- aosp_x86_64
-)
-
-if [ ! -e "build/make/core/Makefile" ]; then
- echo "$0 must be run from the top of the tree"
- exit 1
-fi
-
-echo_and_run() {
- echo "$*"
- "$@"
-}
-
-lib_dir() {
- case $1 in
- (aosp_arm|aosp_x86) echo "lib";;
- (aosp_arm64|aosp_x86_64) echo "lib64";;
- esac
-}
-
-# Make sure this build builds from source, regardless of the default.
-export SOONG_CONFIG_art_module_source_build=true
-
-# This script does not intend to handle compressed APEX
-export OVERRIDE_PRODUCT_COMPRESSED_APEX=false
-
-OUT_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var OUT_DIR)
-DIST_DIR=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT= get_build_var DIST_DIR)
-
-for product in "${PRODUCTS[@]}"; do
- echo_and_run build/soong/soong_ui.bash --make-mode $@ \
- TARGET_PRODUCT=${product} \
- ${MAINLINE_MODULES[@]} \
- ${PLATFORM_LIBRARIES[@]}
-
- PRODUCT_OUT=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var PRODUCT_OUT)
- TARGET_ARCH=$(source build/envsetup.sh > /dev/null; TARGET_PRODUCT=${product} get_build_var TARGET_ARCH)
- rm -rf ${DIST_DIR}/${TARGET_ARCH}/
- mkdir -p ${DIST_DIR}/${TARGET_ARCH}/
- for module in "${MAINLINE_MODULES[@]}"; do
- echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/apex/${module}.apex ${DIST_DIR}/${TARGET_ARCH}/
- done
- for library in "${PLATFORM_LIBRARIES[@]}"; do
- libdir=$(lib_dir $product)
- echo_and_run cp ${PWD}/${PRODUCT_OUT}/system/${libdir}/${library}.so ${DIST_DIR}/${TARGET_ARCH}/
- done
-done
-
-# We use force building LLVM components flag (even though we actually don't
-# compile them) because we don't have bionic host prebuilts
-# for them.
-export FORCE_BUILD_LLVM_COMPONENTS=true
-
-# Create multi-archs SDKs in a different out directory. The multi-arch script
-# uses Soong in --soong-only mode which cannot use the same directory as normal
-# mode with make.
-export OUT_DIR=${OUT_DIR}/aml
-echo_and_run build/soong/scripts/build-aml-prebuilts.sh \
- TARGET_PRODUCT=mainline_sdk ${MODULES_SDK_AND_EXPORTS[@]}
-
-rm -rf ${DIST_DIR}/mainline-sdks
-echo_and_run cp -R ${OUT_DIR}/soong/mainline-sdks ${DIST_DIR}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 2d98e8b..b1d1bb2 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -166,10 +166,6 @@
var _ android.HostToolProvider = (*ShBinary)(nil)
-func (s *ShBinary) InstallBypassMake() bool {
- return true
-}
-
type ShTest struct {
ShBinary
@@ -435,7 +431,7 @@
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
s.customAndroidMkEntries(entries)
- entries.SetPath("LOCAL_MODULE_PATH", s.installDir.ToMakePath())
+ entries.SetPath("LOCAL_MODULE_PATH", s.installDir)
entries.AddCompatibilityTestSuites(s.testProperties.Test_suites...)
if s.testConfig != nil {
entries.SetPath("LOCAL_FULL_TEST_CONFIG", s.testConfig)
@@ -515,8 +511,8 @@
type bazelShBinaryAttributes struct {
Srcs bazel.LabelListAttribute
- Filename string
- Sub_dir string
+ Filename *string
+ Sub_dir *string
// Bazel also supports the attributes below, but (so far) these are not required for Bionic
// deps
// data
@@ -542,14 +538,14 @@
srcs := bazel.MakeLabelListAttribute(
android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
- var filename string
+ var filename *string
if m.properties.Filename != nil {
- filename = *m.properties.Filename
+ filename = m.properties.Filename
}
- var subDir string
+ var subDir *string
if m.properties.Sub_dir != nil {
- subDir = *m.properties.Sub_dir
+ subDir = m.properties.Sub_dir
}
attrs := &bazelShBinaryAttributes{
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 865d5f3..28b6fb9 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -42,7 +42,10 @@
}
func TestShTestSubDir(t *testing.T) {
- ctx, config := testShBinary(t, `
+ result := android.GroupFixturePreparers(
+ prepareForShTest,
+ android.FixtureModifyConfig(android.SetKatiEnabledForTests),
+ ).RunTestWithBp(t, `
sh_test {
name: "foo",
src: "test.sh",
@@ -50,17 +53,20 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+ mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
- entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+ entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
expectedPath := "out/target/product/test_device/data/nativetest64/foo_test"
actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
- android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", config, expectedPath, actualPath)
+ android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", result.Config, expectedPath, actualPath)
}
func TestShTest(t *testing.T) {
- ctx, config := testShBinary(t, `
+ result := android.GroupFixturePreparers(
+ prepareForShTest,
+ android.FixtureModifyConfig(android.SetKatiEnabledForTests),
+ ).RunTestWithBp(t, `
sh_test {
name: "foo",
src: "test.sh",
@@ -72,13 +78,13 @@
}
`)
- mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
+ mod := result.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest)
- entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+ entries := android.AndroidMkEntriesForTest(t, result.TestContext, mod)[0]
expectedPath := "out/target/product/test_device/data/nativetest64/foo"
actualPath := entries.EntryMap["LOCAL_MODULE_PATH"][0]
- android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", config, expectedPath, actualPath)
+ android.AssertStringPathRelativeToTopEquals(t, "LOCAL_MODULE_PATH[0]", result.Config, expectedPath, actualPath)
expectedData := []string{":testdata/data1", ":testdata/sub/data2"}
actualData := entries.EntryMap["LOCAL_TEST_DATA"]
diff --git a/snapshot/host_snapshot.go b/snapshot/host_snapshot.go
index 2a25a00..252cef8 100644
--- a/snapshot/host_snapshot.go
+++ b/snapshot/host_snapshot.go
@@ -180,7 +180,7 @@
DistFiles: android.MakeDefaultDistFiles(f.zipFile.Path()),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_PATH", f.installDir.ToMakePath().String())
+ entries.SetString("LOCAL_MODULE_PATH", f.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", f.installFileName())
},
},
diff --git a/ui/build/config.go b/ui/build/config.go
index 4c26d3e..b6d0d27 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -721,10 +721,6 @@
}
func (c *configImpl) SoongBuildInvocationNeeded() bool {
- if c.Dist() {
- return true
- }
-
if len(c.Arguments()) > 0 {
// Explicit targets requested that are not special targets like b2pbuild
// or the JSON module graph
@@ -736,6 +732,11 @@
return true
}
+ // bp2build + dist may be used to dist bp2build logs but does not require SoongBuildInvocation
+ if c.Dist() && !c.Bp2Build() {
+ return true
+ }
+
// build.ninja doesn't need to be generated
return false
}