Merge "Revert "Only allow setting presigned without preprocessed on targetSdk < 30"" into main
diff --git a/aconfig/java_aconfig_library.go b/aconfig/java_aconfig_library.go
index 53f8bd1..4db0ef7 100644
--- a/aconfig/java_aconfig_library.go
+++ b/aconfig/java_aconfig_library.go
@@ -52,6 +52,9 @@
} else {
ctx.AddDependency(ctx.Module(), declarationsTag, declarations)
}
+
+ // Add aconfig-annotations-lib as a dependency for the optimization / code stripping annotations
+ module.AddSharedLibrary("aconfig-annotations-lib")
}
func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuildActions(module *java.GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path {
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index d7fbb62..fb2e0d7 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -228,6 +228,7 @@
"frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue,
"frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
"frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively,
+ "frameworks/base/tools/aapt": Bp2BuildDefaultTrue,
"frameworks/base/tools/aapt2": Bp2BuildDefaultTrue,
"frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively,
@@ -310,6 +311,7 @@
"packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb": Bp2BuildDefaultTrue,
"packages/modules/adb/apex": Bp2BuildDefaultTrue,
+ "packages/modules/adb/fastdeploy": Bp2BuildDefaultTrue,
"packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively,
"packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively,
@@ -488,6 +490,55 @@
}
Bp2buildModuleAlwaysConvertList = []string{
+ // aconfig
+ "libonce_cell",
+ "libanyhow",
+ "libunicode_segmentation",
+ "libmemchr",
+ "libbitflags-1.3.2",
+ "libryu",
+ "libitoa",
+ "libos_str_bytes",
+ "libheck",
+ "libclap_lex",
+ "libsyn",
+ "libquote",
+ "libunicode_ident",
+ "libproc_macro2",
+ "libthiserror_impl",
+ "libserde_derive",
+ "libclap_derive",
+ "libthiserror",
+ "libserde",
+ "libclap",
+ "libbytes",
+ "libprotobuf_support",
+ "libtinytemplate",
+ "libserde_json",
+ "libprotobuf",
+
+ "protoc-gen-rust",
+ "libprotobuf_codegen",
+ "libprotobuf_parse",
+ "libregex",
+ "libtempfile",
+ "libwhich",
+ "libregex_syntax",
+ "libfastrand",
+ "libeither",
+ "libaho_corasick",
+ "liblibc",
+ "libcfg_if",
+ "liblog_rust",
+ "libgetrandom",
+ "libremove_dir_all",
+ "libahash",
+ "libhashbrown",
+ "libindexmap",
+ "libaconfig_protos",
+ "libpaste",
+ "aconfig",
+
// ext
"tagsoup",
@@ -858,6 +909,12 @@
"hal_unit_tests",
"merge_annotation_zips_test",
+
+ // bouncycastle dep
+ "platform-test-annotations",
+
+ // java_resources with multiple resource_dirs
+ "emma",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -881,6 +938,20 @@
// the "prebuilt_" prefix to the name, so that it's differentiable from
// the source versions within Soong's module graph.
Bp2buildModuleDoNotConvertList = []string{
+ // rust modules that have cc deps
+ "liblogger",
+ "libbssl_ffi",
+ "libbssl_ffi_nostd",
+ "pull_rust",
+ "libstatslog_rust",
+ "libstatslog_rust_header",
+ "libflatbuffers",
+ "liblog_event_list",
+ "libminijail_rust",
+ "libminijail_sys",
+ "libfsverity_rs",
+ "libtombstoned_client_rust",
+
// TODO(b/263326760): Failed already.
"minijail_compiler_unittest",
"minijail_parser_unittest",
@@ -1546,6 +1617,7 @@
"permissive_mte_test",
"ICU4CTestRunner",
"DeviceLongPollingStubTest",
+ "FastDeployHostTests",
"libprotobuf-full-test", // TODO(b/246997908): cannot convert proto_libraries which implicitly include other srcs in the same directory
"libprotobuf-lite-test", // TODO(b/246997908): cannot convert proto_libraries which implicitly include other srcs in the same directory
diff --git a/android/api_levels.go b/android/api_levels.go
index 44c8640..3f538c0 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -19,6 +19,7 @@
"encoding/json"
"fmt"
"strconv"
+ "strings"
)
func init() {
@@ -237,6 +238,14 @@
}
}
+func uncheckedFinalIncrementalApiLevel(num int, increment int) ApiLevel {
+ return ApiLevel{
+ value: strconv.Itoa(num) + "." + strconv.Itoa(increment),
+ number: num,
+ isPreview: false,
+ }
+}
+
var NoneApiLevel = ApiLevel{
value: "(no version)",
// Not 0 because we don't want this to compare equal with the first preview.
@@ -371,6 +380,22 @@
return FutureApiLevel
}
+ if strings.Contains(raw, ".") {
+ // Check prebuilt incremental API format MM.m for major (API level) and minor (incremental) revisions
+ parts := strings.Split(raw, ".")
+ if len(parts) != 2 {
+ panic(fmt.Errorf("Found unexpected version '%s' for incremental API - expect MM.m format for incremental API with both major (MM) an minor (m) revision.", raw))
+ }
+ sdk, sdk_err := strconv.Atoi(parts[0])
+ qpr, qpr_err := strconv.Atoi(parts[1])
+ if sdk_err != nil || qpr_err != nil {
+ panic(fmt.Errorf("Unable to read version number for incremental api '%s'", raw))
+ }
+
+ apiLevel := uncheckedFinalIncrementalApiLevel(sdk, qpr)
+ return apiLevel
+ }
+
asInt, err := strconv.Atoi(raw)
if err != nil {
panic(fmt.Errorf("%q could not be parsed as an integer and is not a recognized codename", raw))
diff --git a/android/bazel.go b/android/bazel.go
index 94b36e3..e764b18 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -510,12 +510,6 @@
}
module := p.module
- // In api_bp2build mode, all soong modules that can provide API contributions should be converted
- // This is irrespective of its presence/absence in bp2build allowlists
- if ctx.Config().BuildMode == ApiBp2build {
- _, providesApis := module.(ApiProvider)
- return providesApis
- }
propValue := b.bazelProperties.Bazel_module.Bp2build_available
packagePath := moduleDirWithPossibleOverride(ctx, module, p.moduleDir)
@@ -533,13 +527,13 @@
moduleTypeAllowed := allowlist.moduleTypeAlwaysConvert[p.moduleType]
allowlistConvert := moduleNameAllowed || moduleTypeAllowed
if moduleNameAllowed && moduleTypeAllowed {
- ctx.ModuleErrorf("A module cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert")
+ ctx.ModuleErrorf("A module %q of type %q cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert", moduleName, p.moduleType)
return false
}
if allowlist.moduleDoNotConvert[moduleName] {
if moduleNameAllowed {
- ctx.ModuleErrorf("a module cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert")
+ ctx.ModuleErrorf("a module %q cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert", moduleName)
}
return false
}
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 42ba9b4..4b98345 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -1382,10 +1382,7 @@
WriteFileRuleVerbatim(ctx, out, "")
case "FileWrite", "SourceSymlinkManifest":
out := PathForBazelOut(ctx, buildStatement.OutputPaths[0])
- // TODO(b/297366783) This is a hack to make files from skylib's diff_test executable.
- // We need to update bazel to have aquery tell us whether a file is supposed to be
- // executable or not.
- if strings.HasSuffix(buildStatement.OutputPaths[0], "-test.sh") {
+ if buildStatement.IsExecutable {
WriteExecutableFileRuleVerbatim(ctx, out, buildStatement.FileContents)
} else {
WriteFileRuleVerbatim(ctx, out, buildStatement.FileContents)
diff --git a/android/bazel_test.go b/android/bazel_test.go
index 194a6b3..15d3a6b 100644
--- a/android/bazel_test.go
+++ b/android/bazel_test.go
@@ -252,7 +252,7 @@
{
description: "module in name allowlist and type allowlist fails",
shouldConvert: false,
- expectedErrors: []string{"A module cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert"},
+ expectedErrors: []string{"A module \"foo\" of type \"rule1\" cannot be in moduleAlwaysConvert and also be in moduleTypeAlwaysConvert"},
module: TestBazelModule{
TestModuleInfo: bazel.TestModuleInfo{
ModuleName: "foo",
@@ -273,7 +273,7 @@
{
description: "module in allowlist and denylist fails",
shouldConvert: false,
- expectedErrors: []string{"a module cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert"},
+ expectedErrors: []string{"a module \"foo\" cannot be in moduleDoNotConvert and also be in moduleAlwaysConvert"},
module: TestBazelModule{
TestModuleInfo: bazel.TestModuleInfo{
ModuleName: "foo",
diff --git a/android/config.go b/android/config.go
index 3e7bb14..645a263 100644
--- a/android/config.go
+++ b/android/config.go
@@ -87,7 +87,6 @@
SymlinkForestMarker string
Bp2buildMarker string
BazelQueryViewDir string
- BazelApiBp2buildDir string
ModuleGraphFile string
ModuleActionsFile string
DocFile string
@@ -121,9 +120,6 @@
// express build semantics.
GenerateQueryView
- // Generate BUILD files for API contributions to API surfaces
- ApiBp2build
-
// Create a JSON representation of the module graph and exit.
GenerateModuleGraph
@@ -641,7 +637,6 @@
setBuildMode(cmdArgs.SymlinkForestMarker, SymlinkForest)
setBuildMode(cmdArgs.Bp2buildMarker, Bp2build)
setBuildMode(cmdArgs.BazelQueryViewDir, GenerateQueryView)
- setBuildMode(cmdArgs.BazelApiBp2buildDir, ApiBp2build)
setBuildMode(cmdArgs.ModuleGraphFile, GenerateModuleGraph)
setBuildMode(cmdArgs.DocFile, GenerateDocFile)
setBazelMode(cmdArgs.BazelMode, "--bazel-mode", BazelProdMode)
@@ -1662,11 +1657,18 @@
return HasAnyPrefix(path, c.productVariables.MemtagHeapSyncIncludePaths) && !c.MemtagHeapDisabledForPath(path)
}
+func (c *config) HWASanDisabledForPath(path string) bool {
+ if len(c.productVariables.HWASanExcludePaths) == 0 {
+ return false
+ }
+ return HasAnyPrefix(path, c.productVariables.HWASanExcludePaths)
+}
+
func (c *config) HWASanEnabledForPath(path string) bool {
if len(c.productVariables.HWASanIncludePaths) == 0 {
return false
}
- return HasAnyPrefix(path, c.productVariables.HWASanIncludePaths)
+ return HasAnyPrefix(path, c.productVariables.HWASanIncludePaths) && !c.HWASanDisabledForPath(path)
}
func (c *config) VendorConfig(name string) VendorConfig {
@@ -1792,30 +1794,6 @@
return c.PlatformSepolicyVersion()
}
-func (c *deviceConfig) BoardPlatVendorPolicy() []string {
- return c.config.productVariables.BoardPlatVendorPolicy
-}
-
-func (c *deviceConfig) BoardReqdMaskPolicy() []string {
- 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) SystemExtSepolicyPrebuiltApiDir() string {
return String(c.config.productVariables.SystemExtSepolicyPrebuiltApiDir)
}
@@ -2081,3 +2059,7 @@
func (c *config) GetApiLibraries() map[string]struct{} {
return c.apiLibraries
}
+
+func (c *deviceConfig) CheckVendorSeappViolations() bool {
+ return Bool(c.config.productVariables.CheckVendorSeappViolations)
+}
diff --git a/android/defs.go b/android/defs.go
index 682111e..b28d2fa 100644
--- a/android/defs.go
+++ b/android/defs.go
@@ -107,8 +107,8 @@
Cat = pctx.AndroidStaticRule("Cat",
blueprint.RuleParams{
- Command: "cat $in > $out",
- Description: "concatenate licenses $out",
+ Command: "rm -f $out && cat $in > $out",
+ Description: "concatenate files to $out",
})
// ubuntu 14.04 offcially use dash for /bin/sh, and its builtin echo command
@@ -116,7 +116,7 @@
// content to file.
writeFile = pctx.AndroidStaticRule("writeFile",
blueprint.RuleParams{
- Command: `/bin/bash -c 'echo -e -n "$$0" > $out' $content`,
+ Command: `rm -f $out && /bin/bash -c 'echo -e -n "$$0" > $out' $content`,
Description: "writing file $out",
},
"content")
diff --git a/android/module.go b/android/module.go
index 19502ba..516810f 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1371,7 +1371,7 @@
for _, axis := range enabledPropertyOverrides.SortedConfigurationAxes() {
configToBools := enabledPropertyOverrides.ConfigurableValues[axis]
for cfg, val := range configToBools {
- if axis != bazel.OsConfigurationAxis || osSupport[cfg] {
+ if axis != bazel.OsConfigurationAxis || osSupport[cfg] || val /*If enabled is explicitly requested via overrides */ {
enabledProperty.SetSelectValue(axis, cfg, &val)
}
}
@@ -1418,10 +1418,42 @@
moduleEnableConstraints := bazel.LabelListAttribute{}
moduleEnableConstraints.Append(platformEnabledAttribute)
moduleEnableConstraints.Append(productConfigEnabledAttribute)
+ addCompatibilityConstraintForCompileMultilib(ctx, &moduleEnableConstraints)
return constraintAttributes{Target_compatible_with: moduleEnableConstraints}
}
+var (
+ incompatible = bazel.LabelList{[]bazel.Label{{Label: "@platforms//:incompatible"}}, nil}
+)
+
+// If compile_mulitilib is set to
+// 1. 32: Add an incompatibility constraint for non-32 arches
+// 1. 64: Add an incompatibility constraint for non-64 arches
+func addCompatibilityConstraintForCompileMultilib(ctx *topDownMutatorContext, enabled *bazel.LabelListAttribute) {
+ mod := ctx.Module().base()
+ multilib, _ := decodeMultilib(mod, mod.commonProperties.CompileOS, ctx.Config().IgnorePrefer32OnDevice())
+
+ switch multilib {
+ case "32":
+ // Add an incompatibility constraint for all known 64-bit arches
+ enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm64", incompatible)
+ enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86_64", incompatible)
+ enabled.SetSelectValue(bazel.ArchConfigurationAxis, "riscv64", incompatible)
+ case "64":
+ // Add an incompatibility constraint for all known 32-bit arches
+ enabled.SetSelectValue(bazel.ArchConfigurationAxis, "arm", incompatible)
+ enabled.SetSelectValue(bazel.ArchConfigurationAxis, "x86", incompatible)
+ case "both":
+ // Do nothing: "both" is trivially compatible with 32-bit and 64-bit
+ // The top level rule (e.g. apex/partition) will be responsible for building this module in both variants via an
+ // outgoing_transition.
+ default: // e.g. first, common
+ // TODO - b/299135307: Add bp2build support for these properties.
+ }
+
+}
+
// Check product variables for `enabled: true` flag override.
// Returns a list of the constraint_value targets who enable this override.
func productVariableConfigEnableAttribute(ctx *topDownMutatorContext) bazel.LabelListAttribute {
diff --git a/android/mutator.go b/android/mutator.go
index 6bcac93..41477b8 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -231,6 +231,7 @@
BazelConversionPathContext
CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
+ CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
}
// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
diff --git a/android/proto.go b/android/proto.go
index 6887900..fc21d01 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -17,6 +17,7 @@
import (
"path/filepath"
"strings"
+ "sync"
"android/soong/bazel"
@@ -281,6 +282,13 @@
}
}
+ if p, ok := m.module.(PkgPathInterface); ok && p.PkgPath(ctx) != nil {
+ // python_library with pkg_path
+ // proto_library for this module should have the pkg_path as the import_prefix
+ attrs.Import_prefix = p.PkgPath(ctx)
+ attrs.Strip_import_prefix = proptools.StringPtr("")
+ }
+
tags := ApexAvailableTagsWithoutTestApexes(ctx.(TopDownMutatorContext), ctx.Module())
moduleDir := ctx.ModuleDir()
@@ -323,7 +331,8 @@
Label: l,
})
}
- protoLibrariesInIncludeDir := createProtoLibraryTargetsForIncludeDirs(ctx, protoIncludeDirs)
+ // Partitioning by packages can create dupes of protoIncludeDirs, so dedupe it first.
+ protoLibrariesInIncludeDir := createProtoLibraryTargetsForIncludeDirs(ctx, SortedUniqueStrings(protoIncludeDirs))
transitiveProtoLibraries.Append(protoLibrariesInIncludeDir)
}
@@ -333,15 +342,20 @@
return info, true
}
+// PkgPathInterface is used as a type assertion in bp2build to get pkg_path property of python_library_host
+type PkgPathInterface interface {
+ PkgPath(ctx BazelConversionContext) *string
+}
+
var (
protoIncludeDirGeneratedSuffix = ".include_dir_bp2build_generated_proto"
protoIncludeDirsBp2buildKey = NewOnceKey("protoIncludeDirsBp2build")
)
-func getProtoIncludeDirsBp2build(config Config) *map[protoIncludeDirKey]bool {
+func getProtoIncludeDirsBp2build(config Config) *sync.Map {
return config.Once(protoIncludeDirsBp2buildKey, func() interface{} {
- return &map[protoIncludeDirKey]bool{}
- }).(*map[protoIncludeDirKey]bool)
+ return &sync.Map{}
+ }).(*sync.Map)
}
// key for dynamically creating proto_library per proto.include_dirs
@@ -371,11 +385,10 @@
Label: "//" + pkg + ":" + label,
})
key := protoIncludeDirKey{dir: dir, subpackgeInDir: pkg}
- if _, exists := (*dirMap)[key]; exists {
+ if _, exists := dirMap.LoadOrStore(key, true); exists {
// A proto_library has already been created for this package relative to this include dir
continue
}
- (*dirMap)[key] = true
srcs := protoLabelelsPartitionedByPkg[pkg]
rel, err := filepath.Rel(dir, pkg)
if err != nil {
@@ -389,7 +402,18 @@
if rel != "." {
attrs.Import_prefix = proptools.StringPtr(rel)
}
- ctx.CreateBazelTargetModule(
+
+ // If a specific directory is listed in proto.include_dirs of two separate modules (one host-specific and another device-specific),
+ // we do not want to create the proto_library with target_compatible_with of the first visited of these two modules
+ // As a workarounds, delete `target_compatible_with`
+ alwaysEnabled := bazel.BoolAttribute{}
+ alwaysEnabled.Value = proptools.BoolPtr(true)
+ // Add android and linux explicitly so that fillcommonbp2buildmoduleattrs can override these configs
+ // When we extend b support for other os'es (darwin/windows), we should add those configs here as well
+ alwaysEnabled.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsAndroid, proptools.BoolPtr(true))
+ alwaysEnabled.SetSelectValue(bazel.OsConfigurationAxis, bazel.OsLinux, proptools.BoolPtr(true))
+
+ ctx.CreateBazelTargetModuleWithRestrictions(
bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
CommonAttributes{
Name: label,
@@ -399,6 +423,7 @@
Tags: bazel.MakeStringListAttribute([]string{"manual"}),
},
&attrs,
+ alwaysEnabled,
)
}
}
diff --git a/android/register.go b/android/register.go
index 64b0207..df97c75 100644
--- a/android/register.go
+++ b/android/register.go
@@ -197,13 +197,6 @@
RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators)
}
-// RegisterForApiBazelConversion is similar to RegisterForBazelConversion except that
-// it only generates API targets in the generated workspace
-func (ctx *Context) RegisterForApiBazelConversion() {
- registerModuleTypes(ctx)
- RegisterMutatorsForApiBazelConversion(ctx, bp2buildPreArchMutators)
-}
-
// Register the pipeline of singletons, module types, and mutators for
// generating build.ninja and other files for Kati, from Android.bp files.
func (ctx *Context) Register() {
diff --git a/android/testing.go b/android/testing.go
index 5ad7ad0..32357db 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -467,12 +467,6 @@
RegisterMutatorsForBazelConversion(ctx.Context, ctx.bp2buildPreArch)
}
-// RegisterForApiBazelConversion prepares a test context for API bp2build conversion.
-func (ctx *TestContext) RegisterForApiBazelConversion() {
- ctx.config.BuildMode = ApiBp2build
- RegisterMutatorsForApiBazelConversion(ctx.Context, ctx.bp2buildPreArch)
-}
-
func (ctx *TestContext) ParseFileList(rootDir string, filePaths []string) (deps []string, errs []error) {
// This function adapts the old style ParseFileList calls that are spread throughout the tests
// to the new style that takes a config.
diff --git a/android/variable.go b/android/variable.go
index ca9a221..02eff25 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -315,6 +315,7 @@
MemtagHeapSyncIncludePaths []string `json:",omitempty"`
HWASanIncludePaths []string `json:",omitempty"`
+ HWASanExcludePaths []string `json:",omitempty"`
VendorPath *string `json:",omitempty"`
OdmPath *string `json:",omitempty"`
@@ -372,17 +373,11 @@
MultitreeUpdateMeta bool `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"`
+ BoardVendorSepolicyDirs []string `json:",omitempty"`
+ BoardOdmSepolicyDirs []string `json:",omitempty"`
+ SystemExtPublicSepolicyDirs []string `json:",omitempty"`
+ SystemExtPrivateSepolicyDirs []string `json:",omitempty"`
+ BoardSepolicyM4Defs []string `json:",omitempty"`
BoardSepolicyVers *string `json:",omitempty"`
PlatformSepolicyVersion *string `json:",omitempty"`
@@ -486,6 +481,8 @@
ReleaseAconfigFlagDefaultPermission string `json:",omitempty"`
KeepVndk *bool `json:",omitempty"`
+
+ CheckVendorSeappViolations *bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 52a5e20..1e65b0f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2008,6 +2008,9 @@
// If a module is directly included and also transitively depended on
// consider it as directly included.
e.transitiveDep = e.transitiveDep && f.transitiveDep
+ // If a module is added as both a JNI library and a regular shared library, consider it as a
+ // JNI library.
+ e.isJniLib = e.isJniLib || f.isJniLib
encountered[dest] = e
}
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 1717f3e..9475f5d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -7977,7 +7977,8 @@
apex {
name: "myapex",
key: "myapex.key",
- jni_libs: ["mylib", "libfoo.rust"],
+ binaries: ["mybin"],
+ jni_libs: ["mylib", "mylib3", "libfoo.rust"],
updatable: false,
}
@@ -8004,6 +8005,24 @@
apex_available: [ "myapex" ],
}
+ // Used as both a JNI library and a regular shared library.
+ cc_library {
+ name: "mylib3",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
+ cc_binary {
+ name: "mybin",
+ srcs: ["mybin.cpp"],
+ shared_libs: ["mylib3"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ }
+
rust_ffi_shared {
name: "libfoo.rust",
crate_name: "foo",
@@ -8027,10 +8046,12 @@
rule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexManifestRule")
// Notice mylib2.so (transitive dep) is not added as a jni_lib
- ensureEquals(t, rule.Args["opt"], "-a jniLibs libfoo.rust.so mylib.so")
+ ensureEquals(t, rule.Args["opt"], "-a jniLibs libfoo.rust.so mylib.so mylib3.so")
ensureExactContents(t, ctx, "myapex", "android_common_myapex", []string{
+ "bin/mybin",
"lib64/mylib.so",
"lib64/mylib2.so",
+ "lib64/mylib3.so",
"lib64/libfoo.rust.so",
"lib64/libc++.so", // auto-added to libfoo.rust by Soong
"lib64/liblog.so", // auto-added to libfoo.rust by Soong
diff --git a/bazel/aquery.go b/bazel/aquery.go
index d77d59a..76cd972 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -123,6 +123,7 @@
// Unlike most properties in BuildStatement, these paths must be relative to the root of
// the whole out/ folder, instead of relative to ctx.Config().BazelContext.OutputBase()
ImplicitDeps []string
+ IsExecutable bool
}
// A helper type for aquery processing which facilitates retrieval of path IDs from their
@@ -560,6 +561,7 @@
Mnemonic: actionEntry.Mnemonic,
InputDepsetHashes: depsetHashes,
FileContents: actionEntry.FileContents,
+ IsExecutable: actionEntry.IsExecutable,
}, nil
}
diff --git a/bazel/configurability.go b/bazel/configurability.go
index aa58fdc..1fe8442 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -39,7 +39,7 @@
// Targets in arch.go
osArchAndroidArm = "android_arm"
- osArchAndroidArm64 = "android_arm64"
+ OsArchAndroidArm64 = "android_arm64"
osArchAndroidRiscv64 = "android_riscv64"
osArchAndroidX86 = "android_x86"
osArchAndroidX86_64 = "android_x86_64"
@@ -170,7 +170,7 @@
platformOsArchMap = map[string]string{
osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm",
- osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
+ OsArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64",
osArchAndroidRiscv64: "//build/bazel/platforms/os_arch:android_riscv64",
osArchAndroidX86: "//build/bazel/platforms/os_arch:android_x86",
osArchAndroidX86_64: "//build/bazel/platforms/os_arch:android_x86_64",
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index c104833..b675e5e 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -32,6 +32,7 @@
"soong-genrule",
"soong-linkerconfig",
"soong-python",
+ "soong-rust",
"soong-sh",
"soong-shared",
"soong-starlark-format",
@@ -61,7 +62,6 @@
"cc_test_conversion_test.go",
"cc_yasm_conversion_test.go",
"conversion_test.go",
- "droidstubs_conversion_test.go",
"filegroup_conversion_test.go",
"genrule_conversion_test.go",
"gensrcs_conversion_test.go",
@@ -82,6 +82,10 @@
"python_binary_conversion_test.go",
"python_library_conversion_test.go",
"python_test_conversion_test.go",
+ "rust_binary_conversion_test.go",
+ "rust_library_conversion_test.go",
+ "rust_proc_macro_conversion_test.go",
+ "rust_protobuf_conversion_test.go",
"sh_conversion_test.go",
"sh_test_conversion_test.go",
"soong_config_module_type_conversion_test.go",
diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go
index 09d9dc1..a24378c 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -37,19 +37,19 @@
},
Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
android_library {
- name: "TestLib",
- srcs: ["lib.java"],
- arch: {
- arm: {
- srcs: ["arm.java"],
- },
- x86: {
- srcs: ["x86.java"],
- }
+ name: "TestLib",
+ srcs: ["lib.java"],
+ arch: {
+ arm: {
+ srcs: ["arm.java"],
},
- manifest: "manifest/AndroidManifest.xml",
- static_libs: ["static_lib_dep"],
- java_version: "7",
+ x86: {
+ srcs: ["x86.java"],
+ }
+ },
+ manifest: "manifest/AndroidManifest.xml",
+ static_libs: ["static_lib_dep"],
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -66,12 +66,9 @@
"resource_files": `["res/res.png"]`,
"deps": `[":static_lib_dep"]`,
"exports": `[":static_lib_dep"]`,
- "java_version": `"7"`,
+ "sdk_version": `"current"`, // use as default
}),
- MakeNeverlinkDuplicateTargetWithAttrs(
- "android_library",
- "TestLib",
- AttrNameToString{"java_version": `"7"`}),
+ MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
}
@@ -87,10 +84,11 @@
},
Blueprint: simpleModuleDoNotConvertBp2build("android_library", "lib_dep") + `
android_library {
- name: "TestLib",
- srcs: [],
- manifest: "AndroidManifest.xml",
- libs: ["lib_dep"],
+ name: "TestLib",
+ srcs: [],
+ manifest: "AndroidManifest.xml",
+ libs: ["lib_dep"],
+ sdk_version: "current",
}
`,
ExpectedErr: fmt.Errorf("Module has direct dependencies but no sources. Bazel will not allow this."),
@@ -121,6 +119,7 @@
name: "TestImport",
aars: ["import.aar"],
static_libs: ["static_lib_dep", "static_import_dep"],
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -133,7 +132,8 @@
":static_lib_dep",
":static_import_dep",
]`,
- "exports": `[":static_import_dep"]`,
+ "exports": `[":static_import_dep"]`,
+ "sdk_version": `"current"`, // use as default
},
),
MakeNeverlinkDuplicateTarget("android_library", "TestImport"),
@@ -153,9 +153,10 @@
},
Blueprint: `
android_library {
- name: "TestLib",
- srcs: ["a.java", "b.kt"],
- common_srcs: ["c.kt"],
+ name: "TestLib",
+ srcs: ["a.java", "b.kt"],
+ common_srcs: ["c.kt"],
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -170,6 +171,7 @@
"common_srcs": `["c.kt"]`,
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
@@ -186,9 +188,10 @@
},
Blueprint: `
android_library {
- name: "TestLib",
- srcs: ["a.java", "b.kt"],
- kotlincflags: ["-flag1", "-flag2"],
+ name: "TestLib",
+ srcs: ["a.java", "b.kt"],
+ kotlincflags: ["-flag1", "-flag2"],
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -206,6 +209,7 @@
]`,
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index 8ed94b4..f2ee322 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -44,9 +44,14 @@
},
Blueprint: `
android_app {
- name: "TestApp",
- srcs: ["app.java"],
- sdk_version: "current",
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
+ optimize: {
+ shrink: true,
+ optimize: true,
+ obfuscate: true,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -75,17 +80,25 @@
},
Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + `
android_app {
- name: "TestApp",
- srcs: ["app.java"],
- sdk_version: "current",
- package_name: "com.google",
- resource_dirs: ["resa", "resb"],
- manifest: "manifest/AndroidManifest.xml",
- static_libs: ["static_lib_dep"],
- java_version: "7",
- certificate: "foocert",
- required: ["static_lib_dep"],
- asset_dirs: ["assets_"],
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
+ package_name: "com.google",
+ resource_dirs: ["resa", "resb"],
+ manifest: "manifest/AndroidManifest.xml",
+ static_libs: ["static_lib_dep"],
+ java_version: "7",
+ certificate: "foocert",
+ required: ["static_lib_dep"],
+ asset_dirs: ["assets_"],
+ optimize: {
+ enabled: true,
+ optimize: false,
+ proguard_flags_files: ["proguard.flags"],
+ shrink: false,
+ obfuscate: false,
+ ignore_warnings: true,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -103,6 +116,14 @@
"java_version": `"7"`,
"sdk_version": `"current"`,
"certificate_name": `"foocert"`,
+ "proguard_specs": `[
+ "proguard.flags",
+ ":TestApp_proguard_flags",
+ ]`,
+ }),
+ MakeBazelTarget("genrule", "TestApp_proguard_flags", AttrNameToString{
+ "outs": `["TestApp_proguard.flags"]`,
+ "cmd": `"echo -ignorewarning -dontshrink -dontoptimize -dontobfuscate > $(OUTS)"`,
}),
}})
}
@@ -120,16 +141,19 @@
},
Blueprint: `
android_app {
- name: "TestApp",
- sdk_version: "current",
- arch: {
- arm: {
- srcs: ["arm.java"],
- },
- x86: {
- srcs: ["x86.java"],
- }
+ name: "TestApp",
+ sdk_version: "current",
+ arch: {
+ arm: {
+ srcs: ["arm.java"],
+ },
+ x86: {
+ srcs: ["x86.java"],
}
+ },
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -142,6 +166,7 @@
"manifest": `"AndroidManifest.xml"`,
"resource_files": `["res/res.png"]`,
"sdk_version": `"current"`,
+ "optimize": `False`,
}),
}})
}
@@ -154,8 +179,12 @@
Filesystem: map[string]string{},
Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
android_app {
- name: "TestApp",
- certificate: ":foocert",
+ name: "TestApp",
+ certificate: ":foocert",
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -163,6 +192,8 @@
"certificate": `":foocert"`,
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -177,8 +208,12 @@
},
Blueprint: `
android_app {
- name: "TestApp",
- certificate: "foocert",
+ name: "TestApp",
+ certificate: "foocert",
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -186,6 +221,8 @@
"certificate": `"foocert"`,
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -200,8 +237,12 @@
},
Blueprint: `
android_app {
- name: "TestApp",
- certificate: "foocert",
+ name: "TestApp",
+ certificate: "foocert",
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -209,6 +250,8 @@
"certificate_name": `"foocert"`,
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -219,22 +262,23 @@
ModuleTypeUnderTest: "android_app",
ModuleTypeUnderTestFactory: java.AndroidAppFactory,
Filesystem: map[string]string{},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
android_app {
- name: "foo",
- libs: ["barLib"]
-}
-java_library{
- name: "barLib",
+ name: "foo",
+ libs: ["barLib"],
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
- MakeBazelTarget("java_library", "barLib", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "barLib"),
MakeBazelTarget("android_binary", "foo", AttrNameToString{
"manifest": `"AndroidManifest.xml"`,
"resource_files": `[]`,
"deps": `[":barLib-neverlink"]`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -247,21 +291,21 @@
Filesystem: map[string]string{
"res/res.png": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") +
+ simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
android_app {
- name: "foo",
- srcs: ["a.java", "b.kt"],
- certificate: ":foocert",
- manifest: "fooManifest.xml",
- libs: ["barLib"]
-}
-java_library{
- name: "barLib",
+ name: "foo",
+ srcs: ["a.java", "b.kt"],
+ certificate: ":foocert",
+ manifest: "fooManifest.xml",
+ libs: ["barLib"],
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
- MakeBazelTarget("java_library", "barLib", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "barLib"),
MakeBazelTarget("android_library", "foo_kt", AttrNameToString{
"srcs": `[
"a.java",
@@ -270,11 +314,14 @@
"manifest": `"fooManifest.xml"`,
"resource_files": `["res/res.png"]`,
"deps": `[":barLib-neverlink"]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeBazelTarget("android_binary", "foo", AttrNameToString{
"deps": `[":foo_kt"]`,
"certificate": `":foocert"`,
"manifest": `"fooManifest.xml"`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -287,33 +334,37 @@
Filesystem: map[string]string{
"res/res.png": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: `
android_app {
- name: "foo",
- srcs: ["a.java"],
- common_srcs: ["b.kt"],
- certificate: "foocert",
- manifest: "fooManifest.xml",
- libs: ["barLib"],
+ name: "foo",
+ srcs: ["a.java"],
+ common_srcs: ["b.kt"],
+ manifest: "fooManifest.xml",
+ libs: ["barLib"],
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
java_library{
- name: "barLib",
+ name: "barLib",
+ bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
- MakeBazelTarget("java_library", "barLib", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "barLib"),
MakeBazelTarget("android_library", "foo_kt", AttrNameToString{
"srcs": `["a.java"]`,
"common_srcs": `["b.kt"]`,
"manifest": `"fooManifest.xml"`,
"resource_files": `["res/res.png"]`,
"deps": `[":barLib-neverlink"]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeBazelTarget("android_binary", "foo", AttrNameToString{
- "deps": `[":foo_kt"]`,
- "certificate_name": `"foocert"`,
- "manifest": `"fooManifest.xml"`,
+ "deps": `[":foo_kt"]`,
+ "manifest": `"fooManifest.xml"`,
+ "sdk_version": `"current"`, // use as default
+ "optimize": `False`,
}),
}})
}
@@ -326,13 +377,16 @@
Filesystem: map[string]string{
"res/res.png": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: `
android_app {
- name: "foo",
- srcs: ["a.java", "b.kt"],
- certificate: ":foocert",
- manifest: "fooManifest.xml",
- kotlincflags: ["-flag1", "-flag2"],
+ name: "foo",
+ srcs: ["a.java", "b.kt"],
+ manifest: "fooManifest.xml",
+ kotlincflags: ["-flag1", "-flag2"],
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -347,11 +401,13 @@
"-flag1",
"-flag2",
]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeBazelTarget("android_binary", "foo", AttrNameToString{
"deps": `[":foo_kt"]`,
- "certificate": `":foocert"`,
"manifest": `"fooManifest.xml"`,
+ "sdk_version": `"current"`,
+ "optimize": `False`,
}),
}})
}
@@ -362,13 +418,16 @@
ModuleTypeUnderTest: "android_app",
ModuleTypeUnderTestFactory: java.AndroidAppFactory,
Filesystem: map[string]string{},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: `
android_app {
- name: "foo",
- sdk_version: "current",
- min_sdk_version: "24",
- max_sdk_version: "30",
- target_sdk_version: "29",
+ name: "foo",
+ sdk_version: "current",
+ min_sdk_version: "24",
+ max_sdk_version: "30",
+ target_sdk_version: "29",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -381,6 +440,7 @@
"targetSdkVersion": "29",
}`,
"sdk_version": `"current"`,
+ "optimize": `False`,
}),
}})
}
@@ -391,10 +451,13 @@
ModuleTypeUnderTest: "android_app",
ModuleTypeUnderTestFactory: java.AndroidAppFactory,
Filesystem: map[string]string{},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ Blueprint: `
android_app {
- name: "foo",
- sdk_version: "30",
+ name: "foo",
+ sdk_version: "30",
+ optimize: {
+ enabled: false,
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -406,6 +469,7 @@
"targetSdkVersion": "30",
}`,
"sdk_version": `"30"`,
+ "optimize": `False`,
}),
}})
}
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index e8c2ef7..7717993 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -1,9 +1,6 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/android/soongconfig"
- "android/soong/starlark_import"
"encoding/json"
"fmt"
"os"
@@ -11,6 +8,10 @@
"reflect"
"strings"
+ "android/soong/android"
+ "android/soong/android/soongconfig"
+ "android/soong/starlark_import"
+
"github.com/google/blueprint/proptools"
"go.starlark.net/starlark"
)
@@ -258,12 +259,16 @@
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_page_size_agnostic=%t\n", proptools.Bool(productVariables.DevicePageSizeAgnostic)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_platform=%s\n", label))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enforce_vintf_manifest=%t\n", proptools.Bool(productVariables.Enforce_vintf_manifest)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:eng=%t\n", proptools.Bool(productVariables.Eng)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_pattern_fill_contents=%t\n", proptools.Bool(productVariables.Malloc_pattern_fill_contents)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_zero_contents=%t\n", proptools.Bool(productVariables.Malloc_zero_contents)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_exclude_paths=%s\n", strings.Join(productVariables.MemtagHeapExcludePaths, ",")))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_async_include_paths=%s\n", strings.Join(productVariables.MemtagHeapAsyncIncludePaths, ",")))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:memtag_heap_sync_include_paths=%s\n", strings.Join(productVariables.MemtagHeapSyncIncludePaths, ",")))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index cd1bc7f..9060363 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -175,9 +175,6 @@
// This mode is used for discovering and introspecting the existing Soong
// module graph.
QueryView
-
- // ApiBp2build - generate BUILD files for API contribution targets
- ApiBp2build
)
type unconvertedDepsMode int
@@ -196,8 +193,6 @@
return "Bp2Build"
case QueryView:
return "QueryView"
- case ApiBp2build:
- return "ApiBp2build"
default:
return fmt.Sprintf("%d", mode)
}
@@ -774,10 +769,6 @@
errs = append(errs, err)
}
targets = append(targets, t)
- case ApiBp2build:
- if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
- targets, errs = generateBazelTargets(bpCtx, aModule)
- }
default:
errs = append(errs, fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
return
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 8ee0439..3887c5d 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -1879,30 +1879,6 @@
})
}
-func TestGenerateApiBazelTargets(t *testing.T) {
- bp := `
- custom {
- name: "foo",
- api: "foo.txt",
- }
- `
- expectedBazelTarget := MakeBazelTarget(
- "custom_api_contribution",
- "foo",
- AttrNameToString{
- "api": `"foo.txt"`,
- },
- )
- registerCustomModule := func(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
- }
- RunApiBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
- Blueprint: bp,
- ExpectedBazelTargets: []string{expectedBazelTarget},
- Description: "Generating API contribution Bazel targets for custom module",
- })
-}
-
func TestGenerateConfigSetting(t *testing.T) {
bp := `
custom {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 6501217..246f169 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -2839,205 +2839,6 @@
)
}
-func TestCcApiContributionsWithHdrs(t *testing.T) {
- bp := `
- cc_library {
- name: "libfoo",
- stubs: { symbol_file: "libfoo.map.txt", versions: ["28", "29", "current"] },
- llndk: { symbol_file: "libfoo.map.txt", override_export_include_dirs: ["dir2"]},
- export_include_dirs: ["dir1"],
- }
- `
- expectedBazelTargets := []string{
- MakeBazelTarget(
- "cc_api_library_headers",
- "libfoo.module-libapi.headers",
- AttrNameToString{
- "export_includes": `["dir1"]`,
- }),
- MakeBazelTarget(
- "cc_api_library_headers",
- "libfoo.vendorapi.headers",
- AttrNameToString{
- "export_includes": `["dir2"]`,
- }),
- MakeBazelTarget(
- "cc_api_contribution",
- "libfoo.contribution",
- AttrNameToString{
- "api": `"libfoo.map.txt"`,
- "library_name": `"libfoo"`,
- "api_surfaces": `[
- "module-libapi",
- "vendorapi",
- ]`,
- "hdrs": `[
- ":libfoo.module-libapi.headers",
- ":libfoo.vendorapi.headers",
- ]`,
- }),
- }
- RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
- Blueprint: bp,
- Description: "cc API contributions to module-libapi and vendorapi",
- ExpectedBazelTargets: expectedBazelTargets,
- })
-}
-
-func TestCcApiSurfaceCombinations(t *testing.T) {
- testCases := []struct {
- bp string
- expectedApi string
- expectedApiSurfaces string
- description string
- }{
- {
- bp: `
- cc_library {
- name: "a",
- stubs: {symbol_file: "a.map.txt"},
- }`,
- expectedApi: `"a.map.txt"`,
- expectedApiSurfaces: `["module-libapi"]`,
- description: "Library that contributes to module-libapi",
- },
- {
- bp: `
- cc_library {
- name: "a",
- llndk: {symbol_file: "a.map.txt"},
- }`,
- expectedApi: `"a.map.txt"`,
- expectedApiSurfaces: `["vendorapi"]`,
- description: "Library that contributes to vendorapi",
- },
- {
- bp: `
- cc_library {
- name: "a",
- llndk: {symbol_file: "a.map.txt"},
- stubs: {symbol_file: "a.map.txt"},
- }`,
- expectedApi: `"a.map.txt"`,
- expectedApiSurfaces: `[
- "module-libapi",
- "vendorapi",
- ]`,
- description: "Library that contributes to module-libapi and vendorapi",
- },
- }
- for _, testCase := range testCases {
- expectedBazelTargets := []string{
- MakeBazelTarget(
- "cc_api_contribution",
- "a.contribution",
- AttrNameToString{
- "library_name": `"a"`,
- "hdrs": `[]`,
- "api": testCase.expectedApi,
- "api_surfaces": testCase.expectedApiSurfaces,
- },
- ),
- }
- RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
- Blueprint: testCase.bp,
- Description: testCase.description,
- ExpectedBazelTargets: expectedBazelTargets,
- })
- }
-}
-
-// llndk struct property in Soong provides users with several options to configure the exported include dirs
-// Test the generated bazel targets for the different configurations
-func TestCcVendorApiHeaders(t *testing.T) {
- testCases := []struct {
- bp string
- expectedIncludes string
- expectedSystemIncludes string
- description string
- }{
- {
- bp: `
- cc_library {
- name: "a",
- export_include_dirs: ["include"],
- export_system_include_dirs: ["base_system_include"],
- llndk: {
- symbol_file: "a.map.txt",
- export_headers_as_system: true,
- },
- }
- `,
- expectedIncludes: "",
- expectedSystemIncludes: `[
- "base_system_include",
- "include",
- ]`,
- description: "Headers are exported as system to API surface",
- },
- {
- bp: `
- cc_library {
- name: "a",
- export_include_dirs: ["include"],
- export_system_include_dirs: ["base_system_include"],
- llndk: {
- symbol_file: "a.map.txt",
- override_export_include_dirs: ["llndk_include"],
- },
- }
- `,
- expectedIncludes: `["llndk_include"]`,
- expectedSystemIncludes: `["base_system_include"]`,
- description: "Non-system Headers are ovverriden before export to API surface",
- },
- {
- bp: `
- cc_library {
- name: "a",
- export_include_dirs: ["include"],
- export_system_include_dirs: ["base_system_include"],
- llndk: {
- symbol_file: "a.map.txt",
- override_export_include_dirs: ["llndk_include"],
- export_headers_as_system: true,
- },
- }
- `,
- expectedIncludes: "", // includes are set to nil
- expectedSystemIncludes: `[
- "base_system_include",
- "llndk_include",
- ]`,
- description: "System Headers are extended before export to API surface",
- },
- }
- for _, testCase := range testCases {
- attrs := AttrNameToString{}
- if testCase.expectedIncludes != "" {
- attrs["export_includes"] = testCase.expectedIncludes
- }
- if testCase.expectedSystemIncludes != "" {
- attrs["export_system_includes"] = testCase.expectedSystemIncludes
- }
-
- expectedBazelTargets := []string{
- MakeBazelTarget("cc_api_library_headers", "a.vendorapi.headers", attrs),
- // Create a target for cc_api_contribution target
- MakeBazelTarget("cc_api_contribution", "a.contribution", AttrNameToString{
- "api": `"a.map.txt"`,
- "api_surfaces": `["vendorapi"]`,
- "hdrs": `[":a.vendorapi.headers"]`,
- "library_name": `"a"`,
- }),
- }
- RunApiBp2BuildTestCase(t, cc.RegisterLibraryBuildComponents, Bp2buildTestCase{
- Blueprint: testCase.bp,
- ExpectedBazelTargets: expectedBazelTargets,
- })
- }
-}
-
func TestCcLibraryStubsAcrossConfigsDuplicatesRemoved(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
Description: "stub target generation of the same lib across configs should not result in duplicates",
@@ -5120,7 +4921,7 @@
// bar dir
tc.Dir = "bar"
tc.ExpectedBazelTargets = []string{
- MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+ MakeBazelTargetNoRestrictions("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
"srcs": `["bar.proto"]`,
"strip_import_prefix": `""`,
"tags": `["manual"]`,
@@ -5131,7 +4932,7 @@
// bar/baz dir
tc.Dir = "bar/baz"
tc.ExpectedBazelTargets = []string{
- MakeBazelTarget("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
+ MakeBazelTargetNoRestrictions("proto_library", "bar.include_dir_bp2build_generated_proto", AttrNameToString{
"srcs": `["//bar/baz:baz.proto"]`,
"strip_import_prefix": `""`,
"import_prefix": `"baz"`,
@@ -5141,6 +4942,52 @@
runCcLibraryTestCase(t, tc)
}
+func TestProtoIncludeDirsWithSrcsInMultiplePackages(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "cc_library has srcs in multiple bazel packages and uses proto.include_dirs",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library_static {
+ name: "foo",
+ srcs: [
+ "foo.proto",
+ "bar/bar.proto",
+ ],
+ proto: {
+ include_dirs: ["baz"],
+ }
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+ Filesystem: map[string]string{
+ "bar/Android.bp": "", // package boundary
+ "baz/Android.bp": "",
+ "baz/baz.proto": "",
+ },
+ }
+
+ tc.ExpectedBazelTargets = []string{
+ MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
+ "local_includes": `["."]`,
+ "deps": `[":libprotobuf-cpp-lite"]`,
+ "implementation_whole_archive_deps": `[":foo_cc_proto_lite"]`,
+ }),
+ MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+ "srcs": `["foo.proto"]`,
+ "tags": `["manual"]`,
+ }),
+ MakeBazelTarget("cc_lite_proto_library", "foo_cc_proto_lite", AttrNameToString{
+ "deps": `[
+ ":foo_proto",
+ "//bar:foo_proto",
+ ]`,
+ "transitive_deps": `["//baz:baz.include_dir_bp2build_generated_proto"]`,
+ }),
+ }
+ runCcLibraryTestCase(t, tc)
+
+}
+
func TestProtoLocalIncludeDirs(t *testing.T) {
tc := Bp2buildTestCase{
Description: "cc_library depends on .proto files using proto.local_include_dirs",
@@ -5187,7 +5034,7 @@
// foo/foo_subdir
tc.Dir = "foo/foo_subdir"
tc.ExpectedBazelTargets = []string{
- MakeBazelTarget("proto_library", "foo.foo_subdir.include_dir_bp2build_generated_proto", AttrNameToString{
+ MakeBazelTargetNoRestrictions("proto_library", "foo.foo_subdir.include_dir_bp2build_generated_proto", AttrNameToString{
"srcs": `["foo_subdir.proto"]`,
"strip_import_prefix": `""`,
"tags": `["manual"]`,
@@ -5195,3 +5042,96 @@
}
runCcLibraryTestCase(t, tc)
}
+
+// `foo_device` and `bar_host` can depend on .proto files of a specific dir,
+// the dynamically generated proto_library should not have any target_compatible_with
+func TestProtoLibraryForIncludeDirsIsOsAgnostic(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "proto_library generated for proto.include_dirs is compatible for all axes",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite") + `
+cc_library {
+ name: "foo_device",
+ device_supported: true, // this is the default behavior, but added explicitly here for illustration
+ host_supported: false,
+ proto: {include_dirs: ["dir"]},
+}
+cc_library {
+ name: "bar_host",
+ device_supported: false,
+ host_supported: true,
+ srcs: ["bar.proto"],
+ proto: {include_dirs: ["dir"]},
+}
+`,
+ Filesystem: map[string]string{
+ "dir/Android.bp": "",
+ "dir/dir.proto": "",
+ },
+ Dir: "dir", // check for the generated proto_library
+ ExpectedBazelTargets: []string{
+ MakeBazelTargetNoRestrictions("proto_library", "dir.include_dir_bp2build_generated_proto", AttrNameToString{
+ "srcs": `["dir.proto"]`,
+ "strip_import_prefix": `""`,
+ "tags": `["manual"]`,
+ }),
+ },
+ }
+ runCcLibraryTestCase(t, tc)
+}
+
+func TestCcCompileMultilibConversion(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "cc_library with compile_multilib",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "lib32",
+ compile_multilib: "32",
+}
+cc_library {
+ name: "lib64",
+ compile_multilib: "64",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTargetNoRestrictions("cc_library_shared", "lib32", AttrNameToString{
+ "local_includes": `["."]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"] + select({
+ "//build/bazel/platforms/arch:arm64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:riscv64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:x86_64": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTargetNoRestrictions("cc_library_static", "lib32_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"] + select({
+ "//build/bazel/platforms/arch:arm64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:riscv64": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:x86_64": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTargetNoRestrictions("cc_library_shared", "lib64", AttrNameToString{
+ "local_includes": `["."]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"] + select({
+ "//build/bazel/platforms/arch:arm": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:x86": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTargetNoRestrictions("cc_library_static", "lib64_bp2build_cc_library_static", AttrNameToString{
+ "local_includes": `["."]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"] + select({
+ "//build/bazel/platforms/arch:arm": ["@platforms//:incompatible"],
+ "//build/bazel/platforms/arch:x86": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ },
+ }
+ runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 072f5b3..a592ca9 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -123,69 +123,6 @@
})
}
-func TestCcApiHeaders(t *testing.T) {
- fs := map[string]string{
- "bar/Android.bp": `cc_library_headers { name: "bar_headers", }`,
- }
- bp := `
- cc_library_headers {
- name: "foo_headers",
- export_include_dirs: ["dir1", "dir2"],
- export_header_lib_headers: ["bar_headers"],
-
- arch: {
- arm: {
- export_include_dirs: ["dir_arm"],
- },
- x86: {
- export_include_dirs: ["dir_x86"],
- },
- },
-
- target: {
- android: {
- export_include_dirs: ["dir1", "dir_android"],
- },
- windows: {
- export_include_dirs: ["dir_windows"],
- },
- }
- }
- `
- expectedBazelTargets := []string{
- MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.arm", AttrNameToString{
- "export_includes": `["dir_arm"]`,
- "arch": `"arm"`,
- }),
- MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.x86", AttrNameToString{
- "export_includes": `["dir_x86"]`,
- "arch": `"x86"`,
- }),
- MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution.androidos", AttrNameToString{
- "export_includes": `["dir_android"]`, // common includes are deduped
- }),
- // Windows headers are not exported
- MakeBazelTarget("cc_api_library_headers", "foo_headers.contribution", AttrNameToString{
- "export_includes": `[
- "dir1",
- "dir2",
- ]`,
- "deps": `[
- "//bar:bar_headers.contribution",
- ":foo_headers.contribution.arm",
- ":foo_headers.contribution.x86",
- ":foo_headers.contribution.androidos",
- ]`,
- }),
- }
- RunApiBp2BuildTestCase(t, cc.RegisterLibraryHeadersBuildComponents, Bp2buildTestCase{
- Blueprint: bp,
- Description: "Header library contributions to API surfaces",
- ExpectedBazelTargets: expectedBazelTargets,
- Filesystem: fs,
- })
-}
-
// header_libs has "variant_prepend" tag. In bp2build output,
// variant info(select) should go before general info.
func TestCcLibraryHeadersOsSpecificHeader(t *testing.T) {
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
index 76bbb57..9639ab9 100644
--- a/bp2build/cc_test_conversion_test.go
+++ b/bp2build/cc_test_conversion_test.go
@@ -139,6 +139,13 @@
"host_without_device",
"device",
]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -166,6 +173,13 @@
"host_without_device",
"device",
]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -197,6 +211,13 @@
"host_without_device",
"device",
]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -228,6 +249,13 @@
":libgtest",
]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -260,6 +288,13 @@
":libgtest",
]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -297,6 +332,13 @@
"deps": `[":libgtest_isolated_main"]`,
"dynamic_deps": `[":liblog"]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -324,6 +366,13 @@
":libgtest_main",
]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -350,6 +399,13 @@
"deps": `[":libgtest_isolated_main"]`,
"dynamic_deps": `[":liblog"]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
@@ -381,6 +437,13 @@
"gtest": "True",
"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
{"cc_test", "mytest_with_no_gtest", AttrNameToString{
@@ -388,6 +451,166 @@
"gtest": "False",
"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
"runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_DisableMemtagHeap(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that disable memtag_heap",
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ isolated: true,
+ sanitize: {
+ cfi: true,
+ memtag_heap: false,
+ },
+}
+` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
+ simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "deps": `[":libgtest_isolated_main"]`,
+ "dynamic_deps": `[":liblog"]`,
+ "runs_on": `["device"]`,
+ "features": `["android_cfi"] + select({
+ "//build/bazel/platforms/os_arch:android_arm64": ["-memtag_heap"],
+ "//conditions:default": [],
+ })`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_RespectArm64MemtagHeap(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that disable memtag_heap",
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ isolated: true,
+ target: {
+ android_arm64: {
+ sanitize: {
+ memtag_heap: false,
+ }
+ }
+ },
+}
+` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
+ simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "deps": `[":libgtest_isolated_main"]`,
+ "dynamic_deps": `[":liblog"]`,
+ "runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": ["-memtag_heap"],
+ "//conditions:default": [],
+ })`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_IgnoreNoneArm64MemtagHeap(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that disable memtag_heap",
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ isolated: true,
+ arch: {
+ x86: {
+ sanitize: {
+ memtag_heap: false,
+ }
+ }
+ },
+}
+` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
+ simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "deps": `[":libgtest_isolated_main"]`,
+ "dynamic_deps": `[":liblog"]`,
+ "runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "memtag_heap",
+ "diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
+ },
+ },
+ },
+ })
+}
+
+func TestCcTest_Arm64MemtagHeapOverrideNoConfigOne(t *testing.T) {
+ runCcTestTestCase(t, ccTestBp2buildTestCase{
+ description: "cc test that disable memtag_heap",
+ blueprint: `
+cc_test {
+ name: "mytest",
+ srcs: ["test.cpp"],
+ isolated: true,
+ sanitize: {
+ memtag_heap: true,
+ },
+ target: {
+ android_arm64: {
+ sanitize: {
+ memtag_heap: false,
+ diag: {
+ memtag_heap: false,
+ },
+ }
+ }
+ },
+}
+` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
+ simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+ targets: []testBazelTarget{
+ {"cc_test", "mytest", AttrNameToString{
+ "local_includes": `["."]`,
+ "srcs": `["test.cpp"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ "deps": `[":libgtest_isolated_main"]`,
+ "dynamic_deps": `[":liblog"]`,
+ "runs_on": `["device"]`,
+ "features": `select({
+ "//build/bazel/platforms/os_arch:android_arm64": [
+ "-memtag_heap",
+ "-diag_memtag_heap",
+ ],
+ "//conditions:default": [],
+ })`,
},
},
},
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 7791419..da4b5cf 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -48,7 +48,11 @@
}
files = append(files, newFile("apex_toolchain", "constants.bzl", apexToolchainVars))
- files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.Serialize().ConvertedModules, "\n")))
+ if buf, err := json.MarshalIndent(metrics.convertedModuleWithType, "", " "); err != nil {
+ return []BazelFile{}, err
+ } else {
+ files = append(files, newFile("metrics", "converted_modules.json", string(buf)))
+ }
convertedModulePathMap, err := json.MarshalIndent(metrics.convertedModulePathMap, "", "\t")
if err != nil {
@@ -141,7 +145,7 @@
targets.sort()
var content string
- if mode == Bp2Build || mode == ApiBp2build {
+ if mode == Bp2Build {
content = `# READ THIS FIRST:
# This file was automatically generated by bp2build for the Bazel migration project.
# Feel free to edit or test it, but do *not* check it into your version control system.
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index cbffaa0..89dd38e 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -134,7 +134,7 @@
},
{
dir: "metrics",
- basename: "converted_modules.txt",
+ basename: "converted_modules.json",
},
{
dir: "metrics",
diff --git a/bp2build/droidstubs_conversion_test.go b/bp2build/droidstubs_conversion_test.go
deleted file mode 100644
index 12c1cfe..0000000
--- a/bp2build/droidstubs_conversion_test.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2022 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 bp2build
-
-import (
- "testing"
-
- "android/soong/android"
- "android/soong/java"
-)
-
-func registerJavaApiModules(ctx android.RegistrationContext) {
- java.RegisterSdkLibraryBuildComponents(ctx)
- java.RegisterStubsBuildComponents(ctx)
-}
-
-func TestDroidstubsApiContributions(t *testing.T) {
- bp := `
- droidstubs {
- name: "framework-stubs",
- check_api: {
- current: {
- api_file: "framework.current.txt",
- },
- },
- }
-
- // Modules without check_api should not generate a Bazel API target
- droidstubs {
- name: "framework-docs",
- }
-
- // java_sdk_library is a macro that creates droidstubs
- java_sdk_library {
- name: "module-stubs",
- srcs: ["A.java"],
-
- // These api surfaces are added by default, but add them explicitly to make
- // this test hermetic
- public: {
- enabled: true,
- },
- system: {
- enabled: true,
- },
-
- // Disable other api surfaces to keep unit test scope limited
- module_lib: {
- enabled: false,
- },
- test: {
- enabled: false,
- },
- }
- `
- expectedBazelTargets := []string{
- MakeBazelTargetNoRestrictions(
- "java_api_contribution",
- "framework-stubs.contribution",
- AttrNameToString{
- "api": `"framework.current.txt"`,
- "api_surface": `"publicapi"`,
- "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
- }),
- MakeBazelTargetNoRestrictions(
- "java_api_contribution",
- "module-stubs.stubs.source.contribution",
- AttrNameToString{
- "api": `"api/current.txt"`,
- "api_surface": `"publicapi"`,
- "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
- }),
- MakeBazelTargetNoRestrictions(
- "java_api_contribution",
- "module-stubs.stubs.source.system.contribution",
- AttrNameToString{
- "api": `"api/system-current.txt"`,
- "api_surface": `"systemapi"`,
- "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
- }),
- }
- RunApiBp2BuildTestCase(t, registerJavaApiModules, Bp2buildTestCase{
- Blueprint: bp,
- ExpectedBazelTargets: expectedBazelTargets,
- Filesystem: map[string]string{
- "api/current.txt": "",
- "api/removed.txt": "",
- "api/system-current.txt": "",
- "api/system-removed.txt": "",
- },
- })
-}
diff --git a/bp2build/java_host_for_device_conversion_test.go b/bp2build/java_host_for_device_conversion_test.go
index 448cba4..1fa7126 100644
--- a/bp2build/java_host_for_device_conversion_test.go
+++ b/bp2build/java_host_for_device_conversion_test.go
@@ -48,6 +48,7 @@
name: "java-lib-2",
srcs: ["b.java"],
bazel_module: { bp2build_available: true },
+ sdk_version: "current",
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_host_for_device", "java-lib-1", AttrNameToString{
@@ -57,7 +58,8 @@
"sdk_version": `"none"`,
}),
MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{
- "srcs": `["b.java"]`,
+ "srcs": `["b.java"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"),
},
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index c501a7b..7429ae6 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -42,22 +42,26 @@
srcs: ["a.java", "b.java"],
exclude_srcs: ["b.java"],
libs: ["java-lib-2"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}
java_library {
name: "java-lib-2",
srcs: ["b.java"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
- "srcs": `["a.java"]`,
- "deps": `[":java-lib-2-neverlink"]`,
+ "srcs": `["a.java"]`,
+ "deps": `[":java-lib-2-neverlink"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{
- "srcs": `["b.java"]`,
+ "srcs": `["b.java"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"),
},
@@ -71,18 +75,21 @@
srcs: ["a.java"],
libs: ["java-lib-2"],
static_libs: ["java-lib-3"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}
java_library {
name: "java-lib-2",
srcs: ["b.java"],
+ sdk_version: "current",
bazel_module: { bp2build_available: false },
}
java_library {
name: "java-lib-3",
srcs: ["c.java"],
+ sdk_version: "current",
bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
@@ -92,7 +99,8 @@
":java-lib-2-neverlink",
":java-lib-3",
]`,
- "exports": `[":java-lib-3"]`,
+ "exports": `[":java-lib-3"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -104,6 +112,7 @@
Blueprint: `java_library {
name: "java-lib-1",
static_libs: ["java-lib-2"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}
@@ -114,25 +123,40 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
- "exports": `[":java-lib-2"]`,
+ "exports": `[":java-lib-2"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
+func TestJavaLibraryFailsToConvertNoSdkVersion(t *testing.T) {
+ runJavaLibraryTestCase(t, Bp2buildTestCase{
+ Blueprint: `
+java_library {
+ name: "lib",
+ bazel_module: { bp2build_available: true },
+}
+`,
+ ExpectedBazelTargets: []string{}, // no targets expected because sdk_version is not set
+ })
+}
+
func TestJavaLibraryFailsToConvertLibsWithNoSrcs(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
ExpectedErr: fmt.Errorf("Module has direct dependencies but no sources. Bazel will not allow this."),
Blueprint: `java_library {
name: "java-lib-1",
libs: ["java-lib-2"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}
java_library {
name: "java-lib-2",
srcs: ["a.java"],
+ sdk_version: "current",
bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{},
@@ -144,6 +168,7 @@
Blueprint: `java_library {
name: "java-lib-1",
plugins: ["java-plugin-1"],
+ sdk_version: "current",
bazel_module: { bp2build_available: true },
}
@@ -154,7 +179,8 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
- "plugins": `[":java-plugin-1"]`,
+ "plugins": `[":java-plugin-1"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -169,16 +195,21 @@
name: "java-lib-1",
srcs: ["a.java"],
java_version: "11",
+ sdk_version: "current",
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"srcs": `["a.java"]`,
"java_version": `"11"`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTargetWithAttrs(
"java_library",
"java-lib-1",
- AttrNameToString{"java_version": `"11"`}),
+ AttrNameToString{
+ "java_version": `"11"`,
+ "sdk_version": `"current"`,
+ }),
},
})
}
@@ -189,6 +220,7 @@
name: "java-lib-1",
srcs: ["a.java"],
javacflags: ["-Xsuper-fast"],
+ sdk_version: "current",
errorprone: {
enabled: true,
javacflags: ["-Xep:SpeedLimit:OFF"],
@@ -209,6 +241,7 @@
"plugins": `[":plugin2"]`,
"srcs": `["a.java"]`,
"errorprone_force_enable": `True`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -222,6 +255,7 @@
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java"],
+ sdk_version: "current",
javacflags: ["-Xsuper-fast"],
errorprone: {
javacflags: ["-Xep:SpeedLimit:OFF"],
@@ -229,8 +263,9 @@
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
- "javacopts": `["-Xsuper-fast"]`,
- "srcs": `["a.java"]`,
+ "javacopts": `["-Xsuper-fast"]`,
+ "srcs": `["a.java"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -243,6 +278,7 @@
name: "java-lib-1",
srcs: ["a.java"],
javacflags: ["-Xsuper-fast"],
+ sdk_version: "current",
errorprone: {
enabled: false,
},
@@ -253,7 +289,8 @@
"-Xsuper-fast",
"-XepDisableAllChecks",
]`,
- "srcs": `["a.java"]`,
+ "srcs": `["a.java"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -266,14 +303,15 @@
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `java_library {
- name: "example_lib",
- srcs: [
- "a.java",
- "b.java",
- "a.logtag",
- "b.logtag",
- ],
- bazel_module: { bp2build_available: true },
+ name: "example_lib",
+ srcs: [
+ "a.java",
+ "b.java",
+ "a.logtag",
+ "b.logtag",
+ ],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("event_log_tags", "example_lib_logtags", AttrNameToString{
@@ -288,6 +326,7 @@
"b.java",
":example_lib_logtags",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
}})
@@ -301,9 +340,10 @@
"adir/res/b.res": "",
"adir/res/dir1/b.res": "",
"adir/Android.bp": `java_library {
- name: "java-lib-1",
- java_resources: ["res/a.res", "res/b.res"],
- bazel_module: { bp2build_available: true },
+ name: "java-lib-1",
+ java_resources: ["res/a.res", "res/b.res"],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
}`,
},
Blueprint: "",
@@ -314,6 +354,7 @@
"res/b.res",
]`,
"resource_strip_prefix": `"adir"`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -328,8 +369,9 @@
"res/dir1/b.res": "",
},
Blueprint: `java_library {
- name: "java-lib-1",
+ name: "java-lib-1",
java_resource_dirs: ["res"],
+ sdk_version: "current",
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
@@ -339,6 +381,7 @@
"res/b.res",
"res/dir1/b.res",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -352,14 +395,16 @@
"res/exclude/b.res": "",
},
Blueprint: `java_library {
- name: "java-lib-1",
+ name: "java-lib-1",
java_resource_dirs: ["res"],
+ sdk_version: "current",
exclude_java_resource_dirs: ["res/exclude"],
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"resource_strip_prefix": `"res"`,
"resources": `["res/a.res"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -374,8 +419,9 @@
"res/dir1/exclude.res": "",
},
Blueprint: `java_library {
- name: "java-lib-1",
+ name: "java-lib-1",
java_resource_dirs: ["res"],
+ sdk_version: "current",
exclude_java_resources: ["res/dir1/exclude.res"],
}`,
ExpectedBazelTargets: []string{
@@ -385,24 +431,67 @@
"res/a.res",
"res/dir1/b.res",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
-func TestJavaLibraryResourcesFailsWithMultipleDirs(t *testing.T) {
+func TestJavaLibraryResourcesWithMultipleDirs(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
Filesystem: map[string]string{
"res/a.res": "",
- "res1/a.res": "",
+ "res1/b.res": "",
},
Blueprint: `java_library {
- name: "java-lib-1",
+ name: "java-lib-1",
java_resource_dirs: ["res", "res1"],
+ sdk_version: "current",
}`,
- ExpectedErr: fmt.Errorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)"),
- ExpectedBazelTargets: []string{},
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_resources", "java-lib-1_resource_dir_res1", AttrNameToString{
+ "resource_strip_prefix": `"res1"`,
+ "resources": `["res1/b.res"]`,
+ }),
+ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+ "additional_resources": `["java-lib-1_resource_dir_res1"]`,
+ "resources": `["res/a.res"]`,
+ "resource_strip_prefix": `"res"`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
+ },
+ })
+}
+
+func TestJavaLibraryJavaResourcesAndResourceDirs(t *testing.T) {
+ runJavaLibraryTestCase(t, Bp2buildTestCase{
+ Filesystem: map[string]string{
+ "resdir/a.res": "",
+ },
+ Blueprint: `java_library {
+ name: "java-lib-1",
+ java_resources: ["res1", "res2"],
+ java_resource_dirs: ["resdir"],
+ sdk_version: "current",
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_resources", "java-lib-1_resource_dir_resdir", AttrNameToString{
+ "resource_strip_prefix": `"resdir"`,
+ "resources": `["resdir/a.res"]`,
+ }),
+ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+ "additional_resources": `["java-lib-1_resource_dir_resdir"]`,
+ "resource_strip_prefix": `"."`,
+ "resources": `[
+ "res1",
+ "res2",
+ ]`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
+ },
})
}
@@ -412,14 +501,15 @@
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `java_library {
- name: "example_lib",
- srcs: [
- "a.java",
- "b.java",
- "a.aidl",
- "b.aidl",
- ],
- bazel_module: { bp2build_available: true },
+ name: "example_lib",
+ srcs: [
+ "a.java",
+ "b.java",
+ "a.aidl",
+ "b.aidl",
+ ],
+ bazel_module: { bp2build_available: true },
+ sdk_version: "current",
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
@@ -438,6 +528,7 @@
"a.java",
"b.java",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
}})
@@ -450,12 +541,13 @@
ModuleTypeUnderTestFactory: java.LibraryFactory,
Blueprint: `
java_library {
- name: "example_lib",
- srcs: [
- "a.java",
- "b.aidl",
- ],
- bazel_module: { bp2build_available: true },
+ name: "example_lib",
+ srcs: [
+ "a.java",
+ "b.aidl",
+ ],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("aidl_library", "example_lib_aidl_library", AttrNameToString{
@@ -465,9 +557,10 @@
"deps": `[":example_lib_aidl_library"]`,
}),
MakeBazelTarget("java_library", "example_lib", AttrNameToString{
- "deps": `[":example_lib_java_aidl_library"]`,
- "exports": `[":example_lib_java_aidl_library"]`,
- "srcs": `["a.java"]`,
+ "deps": `[":example_lib_java_aidl_library"]`,
+ "exports": `[":example_lib_java_aidl_library"]`,
+ "srcs": `["a.java"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
},
@@ -497,14 +590,15 @@
],
}
java_library {
- name: "example_lib",
- srcs: [
- "a.java",
- "b.java",
- ":aidl_files",
- ":random_other_files",
- ],
- bazel_module: { bp2build_available: true },
+ name: "example_lib",
+ srcs: [
+ "a.java",
+ "b.java",
+ ":aidl_files",
+ ":random_other_files",
+ ],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
}`,
ExpectedBazelTargets: []string{
MakeBazelTargetNoRestrictions("aidl_library", "aidl_files", AttrNameToString{
@@ -525,6 +619,7 @@
"b.java",
":random_other_files",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
MakeBazelTargetNoRestrictions("filegroup", "random_other_files", AttrNameToString{
@@ -547,24 +642,26 @@
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
- name: "A_aidl",
- srcs: ["aidl/A.aidl"],
- path: "aidl",
+ name: "A_aidl",
+ srcs: ["aidl/A.aidl"],
+ path: "aidl",
}`,
},
Blueprint: `
java_library {
- name: "foo",
- srcs: [
- ":A_aidl",
- ],
+ name: "foo",
+ srcs: [
+ ":A_aidl",
+ ],
+ sdk_version: "current",
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_aidl_library", "foo_java_aidl_library", AttrNameToString{
"deps": `["//path/to/A:A_aidl"]`,
}),
MakeBazelTarget("java_library", "foo", AttrNameToString{
- "exports": `[":foo_java_aidl_library"]`,
+ "exports": `[":foo_java_aidl_library"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "foo"),
},
@@ -581,16 +678,17 @@
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
android_library {
- name: "TestLib",
- manifest: "manifest/AndroidManifest.xml",
- srcs: ["lib.java"],
- arch: {
- arm: {
- neon: {
- srcs: ["arm_neon.java"],
- },
- },
- },
+ name: "TestLib",
+ manifest: "manifest/AndroidManifest.xml",
+ srcs: ["lib.java"],
+ sdk_version: "current",
+ arch: {
+ arm: {
+ neon: {
+ srcs: ["arm_neon.java"],
+ },
+ },
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -604,6 +702,7 @@
})`,
"manifest": `"manifest/AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
@@ -617,19 +716,20 @@
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
android_library {
- name: "TestLib",
- manifest: "manifest/AndroidManifest.xml",
- srcs: ["lib.java"],
- arch: {
- x86: {
- ssse3: {
- srcs: ["ssse3.java"],
- },
- sse4_1: {
- srcs: ["sse4_1.java"],
- },
- },
- },
+ name: "TestLib",
+ manifest: "manifest/AndroidManifest.xml",
+ srcs: ["lib.java"],
+ sdk_version: "current",
+ arch: {
+ x86: {
+ ssse3: {
+ srcs: ["ssse3.java"],
+ },
+ sse4_1: {
+ srcs: ["sse4_1.java"],
+ },
+ },
+ },
}
`,
ExpectedBazelTargets: []string{
@@ -648,6 +748,7 @@
})`,
"manifest": `"manifest/AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
@@ -661,17 +762,18 @@
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
android_library {
- name: "TestLib",
- manifest: "manifest/AndroidManifest.xml",
- srcs: ["lib.java"],
- arch: {
- arm: {
- srcs: ["arm_non_neon.java"],
- neon: {
- exclude_srcs: ["arm_non_neon.java"],
- },
- },
- },
+ name: "TestLib",
+ manifest: "manifest/AndroidManifest.xml",
+ srcs: ["lib.java"],
+ arch: {
+ arm: {
+ srcs: ["arm_non_neon.java"],
+ neon: {
+ exclude_srcs: ["arm_non_neon.java"],
+ },
+ },
+ },
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -686,6 +788,7 @@
})`,
"manifest": `"manifest/AndroidManifest.xml"`,
"resource_files": `[]`,
+ "sdk_version": `"current"`, // use as default
}),
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
@@ -698,6 +801,7 @@
name: "java-lib-1",
srcs: ["a.java", "b.java", "c.kt"],
bazel_module: { bp2build_available: true },
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -707,6 +811,7 @@
"b.java",
"c.kt",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("kt_jvm_library", "java-lib-1"),
},
@@ -721,6 +826,7 @@
srcs: [ "a.kt"],
kotlincflags: ["-flag1", "-flag2"],
bazel_module: { bp2build_available: true },
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -730,6 +836,7 @@
"-flag1",
"-flag2",
]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("kt_jvm_library", "java-lib-1"),
},
@@ -744,6 +851,7 @@
srcs: ["a.java", "b.java"],
common_srcs: ["c.kt"],
bazel_module: { bp2build_available: true },
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -753,6 +861,7 @@
"b.java",
]`,
"common_srcs": `["c.kt"]`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("kt_jvm_library", "java-lib-1"),
},
@@ -766,6 +875,7 @@
name: "java-lib-1",
srcs: ["a.java"],
libs: ["java-lib-2"],
+ sdk_version: "current",
target: {
android: {
libs: ["java-lib-3"],
@@ -775,16 +885,19 @@
bazel_module: { bp2build_available: true },
}
- java_library{
- name: "java-lib-2",
+ java_library{
+ name: "java-lib-2",
+ bazel_module: { bp2build_available: false },
}
- java_library{
- name: "java-lib-3",
+ java_library{
+ name: "java-lib-3",
+ bazel_module: { bp2build_available: false },
}
- java_library{
- name: "java-lib-4",
+ java_library{
+ name: "java-lib-4",
+ bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
@@ -801,14 +914,9 @@
],
"//conditions:default": [],
})`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
- MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"),
- MakeBazelTarget("java_library", "java-lib-3", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "java-lib-3"),
- MakeBazelTarget("java_library", "java-lib-4", AttrNameToString{}),
- MakeNeverlinkDuplicateTarget("java_library", "java-lib-4"),
},
})
}
@@ -819,6 +927,7 @@
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java", "b.java"],
+ sdk_version: "current",
target: {
android: {
exclude_srcs: ["a.java"],
@@ -833,6 +942,7 @@
"//build/bazel/platforms/os:android": [],
"//conditions:default": ["a.java"],
})`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
@@ -850,6 +960,7 @@
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java"],
+ sdk_version: "current",
java_resources: [":filegroup1"],
bazel_module: { bp2build_available: true },
}
@@ -866,6 +977,7 @@
"srcs": `["a.java"]`,
"resources": `[":filegroup1"]`,
"resource_strip_prefix": `"foo"`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
MakeBazelTargetNoRestrictions("filegroup", "filegroup1", AttrNameToString{
@@ -878,3 +990,59 @@
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
})
}
+
+func TestJavaLibraryJavaResourcesMultipleFilegroup(t *testing.T) {
+ runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+ Filesystem: map[string]string{
+ "a.res": "",
+ },
+ Description: "with java_resources that has multiple filegroups",
+ Blueprint: `java_library {
+ name: "java-lib-1",
+ srcs: ["a.java"],
+ java_resources: ["a.res", ":filegroup1", ":filegroup2"],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
+}
+
+filegroup {
+ name: "filegroup1",
+ path: "foo",
+ srcs: ["foo/a"],
+}
+
+filegroup {
+ name: "filegroup2",
+ path: "bar",
+ srcs: ["bar/a"],
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_resources", "java-lib-1_filegroup_resources_filegroup1", AttrNameToString{
+ "resource_strip_prefix": `"foo"`,
+ "resources": `[":filegroup1"]`,
+ }),
+ MakeBazelTarget("java_resources", "java-lib-1_filegroup_resources_filegroup2", AttrNameToString{
+ "resource_strip_prefix": `"bar"`,
+ "resources": `[":filegroup2"]`,
+ }),
+ MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
+ "srcs": `["a.java"]`,
+ "resources": `["a.res"]`,
+ "resource_strip_prefix": `"."`,
+ "additional_resources": `[
+ "java-lib-1_filegroup_resources_filegroup1",
+ "java-lib-1_filegroup_resources_filegroup2",
+ ]`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
+ MakeBazelTargetNoRestrictions("filegroup", "filegroup1", AttrNameToString{
+ "srcs": `["foo/a"]`}),
+ MakeBazelTargetNoRestrictions("filegroup", "filegroup2", AttrNameToString{
+ "srcs": `["bar/a"]`}),
+ },
+ }, func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+ })
+}
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index f546cf4..5d6b088 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -68,6 +68,7 @@
type: "%s",
},
srcs: ["a.proto"],
+ sdk_version: "current",
}`
protoLibrary := MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
@@ -86,10 +87,12 @@
tc.javaLibraryType,
javaLibraryName,
AttrNameToString{
- "deps": `[":java-protos_proto"]`,
+ "deps": `[":java-protos_proto"]`,
+ "sdk_version": `"current"`,
}),
MakeBazelTarget("java_library", "java-protos", AttrNameToString{
- "exports": fmt.Sprintf(`[":%s"]`, javaLibraryName),
+ "exports": fmt.Sprintf(`[":%s"]`, javaLibraryName),
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTarget("java_library", "java-protos"),
},
@@ -104,6 +107,7 @@
name: "java-protos",
srcs: ["a.proto"],
java_version: "7",
+ sdk_version: "current",
}
`,
ExpectedBazelTargets: []string{
@@ -116,15 +120,20 @@
AttrNameToString{
"deps": `[":java-protos_proto"]`,
"java_version": `"7"`,
+ "sdk_version": `"current"`,
}),
MakeBazelTarget("java_library", "java-protos", AttrNameToString{
"exports": `[":java-protos_java_proto_lite"]`,
"java_version": `"7"`,
+ "sdk_version": `"current"`,
}),
MakeNeverlinkDuplicateTargetWithAttrs(
"java_library",
"java-protos",
- AttrNameToString{"java_version": `"7"`}),
+ AttrNameToString{
+ "java_version": `"7"`,
+ "sdk_version": `"current"`,
+ }),
},
})
}
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
index 00f21c8..20002c6 100644
--- a/bp2build/metrics.go
+++ b/bp2build/metrics.go
@@ -9,11 +9,17 @@
"android/soong/android"
"android/soong/shared"
"android/soong/ui/metrics/bp2build_metrics_proto"
+
"google.golang.org/protobuf/proto"
"github.com/google/blueprint"
)
+type moduleInfo struct {
+ Name string `json:"name"`
+ Type string `json:"type"`
+}
+
// CodegenMetrics represents information about the Blueprint-to-BUILD
// conversion process.
// Use CreateCodegenMetrics() to get a properly initialized instance
@@ -30,6 +36,9 @@
// Map of converted modules and paths to call
// NOTE: NOT in the .proto
convertedModulePathMap map[string]string
+
+ // Name and type of converted modules
+ convertedModuleWithType []moduleInfo
}
func CreateCodegenMetrics() CodegenMetrics {
@@ -191,6 +200,10 @@
// Undo prebuilt_ module name prefix modifications
moduleName := android.RemoveOptionalPrebuiltPrefix(m.Name())
metrics.serialized.ConvertedModules = append(metrics.serialized.ConvertedModules, moduleName)
+ metrics.convertedModuleWithType = append(metrics.convertedModuleWithType, moduleInfo{
+ moduleName,
+ moduleType,
+ })
metrics.convertedModulePathMap[moduleName] = "//" + dir
metrics.serialized.ConvertedModuleTypeCount[moduleType] += 1
metrics.serialized.TotalModuleTypeCount[moduleType] += 1
diff --git a/bp2build/python_library_conversion_test.go b/bp2build/python_library_conversion_test.go
index a53371d..595acd2 100644
--- a/bp2build/python_library_conversion_test.go
+++ b/bp2build/python_library_conversion_test.go
@@ -348,3 +348,43 @@
},
})
}
+
+func TestPythonLibraryWithProtobufsAndPkgPath(t *testing.T) {
+ t.Parallel()
+ runBp2BuildTestCaseWithPythonLibraries(t, Bp2buildTestCase{
+ Description: "test python_library protobuf with pkg_path",
+ Filesystem: map[string]string{
+ "dir/foo.proto": "",
+ "dir/bar.proto": "", // bar contains "import dir/foo.proto"
+ "dir/Android.bp": `
+python_library {
+ name: "foo",
+ pkg_path: "dir",
+ srcs: [
+ "foo.proto",
+ "bar.proto",
+ ],
+ bazel_module: {bp2build_available: true},
+}`,
+ },
+ Dir: "dir",
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("proto_library", "foo_proto", AttrNameToString{
+ "import_prefix": `"dir"`,
+ "strip_import_prefix": `""`,
+ "srcs": `[
+ "foo.proto",
+ "bar.proto",
+ ]`,
+ }),
+ MakeBazelTarget("py_proto_library", "foo_py_proto", AttrNameToString{
+ "deps": `[":foo_proto"]`,
+ }),
+ MakeBazelTarget("py_library", "foo", AttrNameToString{
+ "srcs_version": `"PY3"`,
+ "imports": `[".."]`,
+ "deps": `[":foo_py_proto"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/rust_binary_conversion_test.go b/bp2build/rust_binary_conversion_test.go
new file mode 100644
index 0000000..a5abbdb
--- /dev/null
+++ b/bp2build/rust_binary_conversion_test.go
@@ -0,0 +1,88 @@
+// Copyright 2023 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/rust"
+ "testing"
+)
+
+func runRustBinaryTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ RunBp2BuildTestCase(t, registerRustBinaryModuleTypes, tc)
+}
+
+func registerRustBinaryModuleTypes(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("rust_binary_host", rust.RustBinaryHostFactory)
+ ctx.RegisterModuleType("rust_library_host", rust.RustLibraryHostFactory)
+ ctx.RegisterModuleType("rust_proc_macro", rust.ProcMacroFactory)
+
+}
+
+func TestRustBinaryHost(t *testing.T) {
+ runRustBinaryTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/src/helper.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_binary_host {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["src/main.rs"],
+ edition: "2021",
+ features: ["bah-enabled"],
+ cfgs: ["baz"],
+ rustlibs: ["libbar"],
+ proc_macros: ["libbah"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ "external/rust/crates/bar/Android.bp": `
+rust_library_host {
+ name: "libbar",
+ crate_name: "bar",
+ srcs: ["src/lib.rs"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ "external/rust/crates/bah/Android.bp": `
+rust_proc_macro {
+ name: "libbah",
+ crate_name: "bah",
+ srcs: ["src/lib.rs"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ },
+ ExpectedBazelTargets: []string{
+ makeBazelTargetHostOrDevice("rust_binary", "libfoo", AttrNameToString{
+ "crate_name": `"foo"`,
+ "srcs": `[
+ "src/helper.rs",
+ "src/lib.rs",
+ ]`,
+ "deps": `["//external/rust/crates/bar:libbar"]`,
+ "proc_macro_deps": `["//external/rust/crates/bah:libbah"]`,
+ "edition": `"2021"`,
+ "crate_features": `["bah-enabled"]`,
+ "rustc_flags": `["--cfg=baz"]`,
+ }, android.HostSupported),
+ },
+ },
+ )
+}
diff --git a/bp2build/rust_library_conversion_test.go b/bp2build/rust_library_conversion_test.go
new file mode 100644
index 0000000..0bc80df
--- /dev/null
+++ b/bp2build/rust_library_conversion_test.go
@@ -0,0 +1,110 @@
+// Copyright 2023 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/rust"
+ "testing"
+)
+
+func runRustLibraryTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ RunBp2BuildTestCase(t, registerRustLibraryModuleTypes, tc)
+}
+
+func registerRustLibraryModuleTypes(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("rust_library", rust.RustLibraryFactory)
+ ctx.RegisterModuleType("rust_library_host", rust.RustLibraryHostFactory)
+}
+
+func TestLibProtobuf(t *testing.T) {
+ runRustLibraryTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_library_host {
+ name: "libprotobuf",
+ crate_name: "protobuf",
+ srcs: ["src/lib.rs"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ },
+ ExpectedBazelTargets: []string{
+ // TODO(b/290790800): Remove the restriction when rust toolchain for android is implemented
+ makeBazelTargetHostOrDevice("rust_library", "libprotobuf", AttrNameToString{
+ "crate_name": `"protobuf"`,
+ "srcs": `["src/lib.rs"]`,
+ "deps": `[":libprotobuf_build_script"]`,
+ }, android.HostSupported),
+ makeBazelTargetHostOrDevice("cargo_build_script", "libprotobuf_build_script", AttrNameToString{
+ "srcs": `["build.rs"]`,
+ }, android.HostSupported),
+ },
+ },
+ )
+}
+
+func TestRustLibrary(t *testing.T) {
+ expectedAttrs := AttrNameToString{
+ "crate_name": `"foo"`,
+ "srcs": `[
+ "src/helper.rs",
+ "src/lib.rs",
+ ]`,
+ "crate_features": `["bah-enabled"]`,
+ "edition": `"2021"`,
+ "rustc_flags": `["--cfg=baz"]`,
+ }
+
+ runRustLibraryTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/src/helper.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ host_supported: true,
+ srcs: ["src/lib.rs"],
+ edition: "2021",
+ features: ["bah-enabled"],
+ cfgs: ["baz"],
+ bazel_module: { bp2build_available: true },
+}
+rust_library_host {
+ name: "libfoo_host",
+ crate_name: "foo",
+ srcs: ["src/lib.rs"],
+ edition: "2021",
+ features: ["bah-enabled"],
+ cfgs: ["baz"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ },
+ ExpectedBazelTargets: []string{
+ // TODO(b/290790800): Remove the restriction when rust toolchain for android is implemented
+ makeBazelTargetHostOrDevice("rust_library", "libfoo", expectedAttrs, android.HostSupported),
+ makeBazelTargetHostOrDevice("rust_library", "libfoo_host", expectedAttrs, android.HostSupported),
+ },
+ },
+ )
+}
diff --git a/bp2build/rust_proc_macro_conversion_test.go b/bp2build/rust_proc_macro_conversion_test.go
new file mode 100644
index 0000000..7df37ec
--- /dev/null
+++ b/bp2build/rust_proc_macro_conversion_test.go
@@ -0,0 +1,76 @@
+// Copyright 2023 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/rust"
+ "testing"
+)
+
+func rustRustProcMacroTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ RunBp2BuildTestCase(t, registerRustProcMacroModuleTypes, tc)
+}
+
+func registerRustProcMacroModuleTypes(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("rust_library_host", rust.RustLibraryHostFactory)
+ ctx.RegisterModuleType("rust_proc_macro", rust.ProcMacroFactory)
+}
+
+func TestRustProcMacroLibrary(t *testing.T) {
+ rustRustProcMacroTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/src/helper.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_proc_macro {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["src/lib.rs"],
+ edition: "2021",
+ features: ["bah-enabled"],
+ cfgs: ["baz"],
+ rustlibs: ["libbar"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ "external/rust/crates/bar/src/lib.rs": "",
+ "external/rust/crates/bar/Android.bp": `
+rust_library_host {
+ name: "libbar",
+ crate_name: "bar",
+ srcs: ["src/lib.rs"],
+ bazel_module: { bp2build_available: true },
+}`,
+ },
+ ExpectedBazelTargets: []string{
+ makeBazelTargetHostOrDevice("rust_proc_macro", "libfoo", AttrNameToString{
+ "crate_name": `"foo"`,
+ "srcs": `[
+ "src/helper.rs",
+ "src/lib.rs",
+ ]`,
+ "crate_features": `["bah-enabled"]`,
+ "edition": `"2021"`,
+ "rustc_flags": `["--cfg=baz"]`,
+ "deps": `["//external/rust/crates/bar:libbar"]`,
+ }, android.HostSupported),
+ },
+ },
+ )
+}
diff --git a/bp2build/rust_protobuf_conversion_test.go b/bp2build/rust_protobuf_conversion_test.go
new file mode 100644
index 0000000..cf256aa
--- /dev/null
+++ b/bp2build/rust_protobuf_conversion_test.go
@@ -0,0 +1,60 @@
+// Copyright 2023 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 bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/rust"
+ "testing"
+)
+
+func runRustProtobufTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ RunBp2BuildTestCase(t, registerRustProtobufModuleTypes, tc)
+}
+
+func registerRustProtobufModuleTypes(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("rust_protobuf_host", rust.RustProtobufHostFactory)
+
+}
+
+func TestRustProtobufHostTestCase(t *testing.T) {
+ runRustProtobufTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/src/helper.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_protobuf_host {
+ name: "libfoo",
+ crate_name: "foo",
+ protos: ["src/foo.proto"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ },
+ ExpectedBazelTargets: []string{
+ makeBazelTargetHostOrDevice("proto_library", "libfoo_proto", AttrNameToString{
+ "srcs": `["src/foo.proto"]`,
+ }, android.HostSupported),
+ makeBazelTargetHostOrDevice("rust_proto_library", "libfoo", AttrNameToString{
+ "crate_name": `"foo"`,
+ "deps": `[":libfoo_proto"]`,
+ }, android.HostSupported),
+ },
+ },
+ )
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 18ae82d..997df64 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -108,15 +108,6 @@
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
}
-func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
- t.Helper()
- apiBp2BuildSetup := android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(registerModuleTypes),
- SetApiBp2BuildTestRunner,
- )
- runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
-}
-
func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
t.Helper()
dir := "."
@@ -180,27 +171,14 @@
}
// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
-var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{Bp2Build})
+var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{})
-// SetApiBp2BuildTestRunner customizes the test fixture mechanism to run tests in ApiBp2build mode.
-var SetApiBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{ApiBp2build})
-
-// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build and
-// apiBp2build build modes.
-type bazelTestRunner struct {
- mode CodegenMode
-}
+// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode.
+type bazelTestRunner struct{}
func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
ctx := result.TestContext
- switch b.mode {
- case Bp2Build:
- ctx.RegisterForBazelConversion()
- case ApiBp2build:
- ctx.RegisterForApiBazelConversion()
- default:
- panic(fmt.Errorf("unknown build mode: %d", b.mode))
- }
+ ctx.RegisterForBazelConversion()
return &BazelTestResult{TestResult: result}
}
@@ -214,11 +192,7 @@
return
}
- codegenMode := Bp2Build
- if ctx.Config().BuildMode == android.ApiBp2build {
- codegenMode = ApiBp2build
- }
- codegenCtx := NewCodegenContext(config, ctx.Context, codegenMode, "")
+ codegenCtx := NewCodegenContext(config, ctx.Context, Bp2Build, "")
res, errs := GenerateBazelTargets(codegenCtx, false)
if bazelResult.CollateErrs(errs) {
return
@@ -688,7 +662,9 @@
}
func MakeNeverlinkDuplicateTarget(moduleType string, name string) string {
- return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{})
+ return MakeNeverlinkDuplicateTargetWithAttrs(moduleType, name, AttrNameToString{
+ "sdk_version": `"current"`, // use as default
+ })
}
func MakeNeverlinkDuplicateTargetWithAttrs(moduleType string, name string, extraAttrs AttrNameToString) string {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index ce35b5c..e0e543f 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -530,9 +530,9 @@
entries.SubName = ""
- if c.isSanitizerEnabled(cfi) {
+ if c.IsSanitizerEnabled(cfi) {
entries.SubName += ".cfi"
- } else if c.isSanitizerEnabled(Hwasan) {
+ } else if c.IsSanitizerEnabled(Hwasan) {
entries.SubName += ".hwasan"
}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 7f78e28..83553c8 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -851,7 +851,7 @@
return ret
}
-// bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module..
+// bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module.
func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes {
archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{})
archVariantLinkerProps := module.GetArchVariantProperties(ctx, &BaseLinkerProperties{})
@@ -1936,6 +1936,8 @@
sanitizerFeatures := bazel.StringListAttribute{}
sanitizerCopts := bazel.StringListAttribute{}
sanitizerCompilerInputs := bazel.LabelListAttribute{}
+ memtagFeatures := bazel.StringListAttribute{}
+ memtagFeature := ""
bp2BuildPropParseHelper(ctx, m, &SanitizeProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
var features []string
if sanitizerProps, ok := props.(*SanitizeProperties); ok {
@@ -1960,9 +1962,18 @@
features = append(features, "android_cfi_assembly_support")
}
}
+
+ if sanitizerProps.Sanitize.Memtag_heap != nil {
+ if (axis == bazel.NoConfigAxis && memtagFeature == "") ||
+ (axis == bazel.OsArchConfigurationAxis && config == bazel.OsArchAndroidArm64) {
+ memtagFeature = setMemtagValue(sanitizerProps, &memtagFeatures)
+ }
+ }
sanitizerFeatures.SetSelectValue(axis, config, features)
}
})
+ sanitizerFeatures.Append(memtagFeatures)
+
return sanitizerValues{
features: sanitizerFeatures,
copts: sanitizerCopts,
@@ -1970,6 +1981,26 @@
}
}
+func setMemtagValue(sanitizerProps *SanitizeProperties, memtagFeatures *bazel.StringListAttribute) string {
+ var features []string
+ if proptools.Bool(sanitizerProps.Sanitize.Memtag_heap) {
+ features = append(features, "memtag_heap")
+ } else {
+ features = append(features, "-memtag_heap")
+ }
+ // Logic comes from: https://cs.android.com/android/platform/superproject/main/+/32ea1afbd1148b0b78553f24fa61116c999eb968:build/soong/cc/sanitize.go;l=910
+ if sanitizerProps.Sanitize.Diag.Memtag_heap != nil {
+ if proptools.Bool(sanitizerProps.Sanitize.Diag.Memtag_heap) {
+ features = append(features, "diag_memtag_heap")
+ } else {
+ features = append(features, "-diag_memtag_heap")
+ }
+ }
+ memtagFeatures.SetSelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64, features)
+
+ return features[0]
+}
+
func bp2buildLtoFeatures(ctx android.BazelConversionPathContext, m *Module) bazel.StringListAttribute {
lto_feature_name := "android_thin_lto"
ltoBoolFeatures := bazel.BoolAttribute{}
diff --git a/cc/config/OWNERS b/cc/config/OWNERS
index 580f215..c78b6d5 100644
--- a/cc/config/OWNERS
+++ b/cc/config/OWNERS
@@ -1,3 +1,3 @@
per-file vndk.go = smoreland@google.com, victoryang@google.com
-per-file clang.go,global.go,tidy.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
+per-file clang.go,global.go,tidy.go = appujee@google.com, pirama@google.com, srhines@google.com, yabinc@google.com, yikong@google.com, zijunzhao@google.com
diff --git a/cc/config/global.go b/cc/config/global.go
index 23a05be..174b12c 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -45,7 +45,6 @@
"-UDEBUG",
"-fno-exceptions",
- "-Wno-multichar",
"-O2",
"-fdebug-default-version=5",
@@ -140,6 +139,9 @@
"-Werror=format-security",
"-nostdlibinc",
+ // Enable MLGO for register allocation.
+ "-mllvm -regalloc-enable-advisor=release",
+
// Emit additional debug info for AutoFDO
"-fdebug-info-for-profiling",
}
@@ -167,6 +169,8 @@
"-Wl,--exclude-libs,libgcc_stripped.a",
"-Wl,--exclude-libs,libunwind_llvm.a",
"-Wl,--exclude-libs,libunwind.a",
+ // Enable MLGO for register allocation.
+ "-Wl,-mllvm,-regalloc-enable-advisor=release",
}
deviceGlobalLldflags = append(deviceGlobalLdflags, commonGlobalLldflags...)
@@ -251,9 +255,6 @@
noOverrideExternalGlobalCflags = []string{
// http://b/191699019
"-Wno-format-insufficient-args",
- // http://b/296422292
- // Usually signals a mistake and should be a hard error.
- "-Wno-sizeof-array-div",
// http://b/296321145
// Indicates potential memory or stack corruption, so should be changed
// to a hard error. Currently triggered by some vendor code.
@@ -320,7 +321,7 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r498229"
+ ClangDefaultVersion = "clang-r498229b"
ClangDefaultShortVersion = "17"
// Directories with warnings from Android.bp files.
diff --git a/cc/linkable.go b/cc/linkable.go
index 2099399..5b5b856 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -95,6 +95,18 @@
// IsSnapshotPrebuilt returns true if this module is a snapshot prebuilt.
IsSnapshotPrebuilt() bool
+
+ // IsSnapshotSanitizer returns true if this snapshot module implements SnapshotSanitizer.
+ IsSnapshotSanitizer() bool
+
+ // IsSnapshotSanitizerAvailable returns true if this snapshot module has a sanitizer source available (cfi, hwasan).
+ IsSnapshotSanitizerAvailable(t SanitizerType) bool
+
+ // SetSnapshotSanitizerVariation sets the sanitizer variation type for this snapshot module.
+ SetSnapshotSanitizerVariation(t SanitizerType, enabled bool)
+
+ // IsSnapshotUnsanitizedVariant returns true if this is the unsanitized snapshot module variant.
+ IsSnapshotUnsanitizedVariant() bool
}
// LinkableInterface is an interface for a type of module that is linkable in a C++ library.
diff --git a/cc/lto.go b/cc/lto.go
index 820c1f0..df9ca0a 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -162,7 +162,7 @@
}
func GlobalThinLTO(ctx android.BaseModuleContext) bool {
- return ctx.Config().IsEnvTrue("GLOBAL_THINLTO")
+ return !ctx.Config().IsEnvFalse("GLOBAL_THINLTO")
}
// Propagate lto requirements down from binaries
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 8eea7db..0abdafc 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -553,7 +553,9 @@
}
if found, globalSanitizers = removeFromList("hwaddress", globalSanitizers); found && s.Hwaddress == nil {
- s.Hwaddress = proptools.BoolPtr(true)
+ if !ctx.Config().HWASanDisabledForPath(ctx.ModuleDir()) {
+ s.Hwaddress = proptools.BoolPtr(true)
+ }
}
if found, globalSanitizers = removeFromList("writeonly", globalSanitizers); found && s.Writeonly == nil {
@@ -1189,7 +1191,7 @@
if sanitizeable, ok := ctx.Module().(Sanitizeable); ok {
enabled := sanitizeable.IsSanitizerEnabled(ctx.Config(), s.sanitizer.name())
ctx.VisitDirectDeps(func(dep android.Module) {
- if c, ok := dep.(*Module); ok && c.sanitize.isSanitizerEnabled(s.sanitizer) {
+ if c, ok := dep.(PlatformSanitizeable); ok && c.IsSanitizerEnabled(s.sanitizer) {
enabled = true
}
})
@@ -1243,12 +1245,10 @@
}
}
- if c, ok := ctx.Module().(*Module); ok {
- //TODO: When Rust modules have vendor support, enable this path for PlatformSanitizeable
-
+ if c, ok := ctx.Module().(LinkableInterface); ok {
// Check if it's a snapshot module supporting sanitizer
- if ss, ok := c.linker.(snapshotSanitizer); ok {
- if ss.isSanitizerAvailable(s.sanitizer) {
+ if c.IsSnapshotSanitizer() {
+ if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
return []string{"", s.sanitizer.variationName()}
} else {
return []string{""}
@@ -1280,8 +1280,8 @@
func (s *sanitizerSplitMutator) IncomingTransition(ctx android.IncomingTransitionContext, incomingVariation string) string {
if d, ok := ctx.Module().(PlatformSanitizeable); ok {
- if dm, ok := ctx.Module().(*Module); ok {
- if ss, ok := dm.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
+ if dm, ok := ctx.Module().(LinkableInterface); ok {
+ if dm.IsSnapshotSanitizerAvailable(s.sanitizer) {
return incomingVariation
}
}
@@ -1396,19 +1396,19 @@
if sanitizerVariation {
sanitizeable.AddSanitizerDependencies(mctx, s.sanitizer.name())
}
- } else if c, ok := mctx.Module().(*Module); ok {
- if ss, ok := c.linker.(snapshotSanitizer); ok && ss.isSanitizerAvailable(s.sanitizer) {
- if !ss.isUnsanitizedVariant() {
+ } else if c, ok := mctx.Module().(LinkableInterface); ok {
+ if c.IsSnapshotSanitizerAvailable(s.sanitizer) {
+ if !c.IsSnapshotUnsanitizedVariant() {
// Snapshot sanitizer may have only one variantion.
// Skip exporting the module if it already has a sanitizer variation.
c.SetPreventInstall()
c.SetHideFromMake()
return
}
- c.linker.(snapshotSanitizer).setSanitizerVariation(s.sanitizer, sanitizerVariation)
+ c.SetSnapshotSanitizerVariation(s.sanitizer, sanitizerVariation)
// Export the static lib name to make
- if c.static() && c.ExportedToMake() {
+ if c.Static() && c.ExportedToMake() {
// use BaseModuleName which is the name for Make.
if s.sanitizer == cfi {
cfiStaticLibs(mctx.Config()).add(c, c.BaseModuleName())
@@ -1420,6 +1420,35 @@
}
}
+func (c *Module) IsSnapshotSanitizer() bool {
+ if _, ok := c.linker.(SnapshotSanitizer); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) IsSnapshotSanitizerAvailable(t SanitizerType) bool {
+ if ss, ok := c.linker.(SnapshotSanitizer); ok {
+ return ss.IsSanitizerAvailable(t)
+ }
+ return false
+}
+
+func (c *Module) SetSnapshotSanitizerVariation(t SanitizerType, enabled bool) {
+ if ss, ok := c.linker.(SnapshotSanitizer); ok {
+ ss.SetSanitizerVariation(t, enabled)
+ } else {
+ panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", c.Name()))
+ }
+}
+
+func (c *Module) IsSnapshotUnsanitizedVariant() bool {
+ if ss, ok := c.linker.(SnapshotSanitizer); ok {
+ return ss.IsUnsanitizedVariant()
+ }
+ return false
+}
+
func (c *Module) SanitizeNever() bool {
return Bool(c.sanitize.Properties.SanitizeMutated.Never)
}
diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go
index bb13310..e29c446 100644
--- a/cc/snapshot_prebuilt.go
+++ b/cc/snapshot_prebuilt.go
@@ -403,11 +403,11 @@
Sanitize_minimal_dep *bool `android:"arch_variant"`
}
-type snapshotSanitizer interface {
- isSanitizerAvailable(t SanitizerType) bool
- setSanitizerVariation(t SanitizerType, enabled bool)
- isSanitizerEnabled(t SanitizerType) bool
- isUnsanitizedVariant() bool
+type SnapshotSanitizer interface {
+ IsSanitizerAvailable(t SanitizerType) bool
+ SetSanitizerVariation(t SanitizerType, enabled bool)
+ IsSanitizerEnabled(t SanitizerType) bool
+ IsUnsanitizedVariant() bool
}
type snapshotLibraryDecorator struct {
@@ -460,9 +460,9 @@
return p.libraryDecorator.link(ctx, flags, deps, objs)
}
- if p.isSanitizerEnabled(cfi) {
+ if p.IsSanitizerEnabled(cfi) {
p.properties = p.sanitizerProperties.Cfi
- } else if p.isSanitizerEnabled(Hwasan) {
+ } else if p.IsSanitizerEnabled(Hwasan) {
p.properties = p.sanitizerProperties.Hwasan
}
@@ -526,9 +526,9 @@
return false
}
-var _ snapshotSanitizer = (*snapshotLibraryDecorator)(nil)
+var _ SnapshotSanitizer = (*snapshotLibraryDecorator)(nil)
-func (p *snapshotLibraryDecorator) isSanitizerAvailable(t SanitizerType) bool {
+func (p *snapshotLibraryDecorator) IsSanitizerAvailable(t SanitizerType) bool {
switch t {
case cfi:
return p.sanitizerProperties.Cfi.Src != nil
@@ -539,23 +539,23 @@
}
}
-func (p *snapshotLibraryDecorator) setSanitizerVariation(t SanitizerType, enabled bool) {
- if !enabled || p.isSanitizerEnabled(t) {
+func (p *snapshotLibraryDecorator) SetSanitizerVariation(t SanitizerType, enabled bool) {
+ if !enabled || p.IsSanitizerEnabled(t) {
return
}
- if !p.isUnsanitizedVariant() {
+ if !p.IsUnsanitizedVariant() {
panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
}
p.sanitizerProperties.SanitizerVariation = t
}
-func (p *snapshotLibraryDecorator) isSanitizerEnabled(t SanitizerType) bool {
+func (p *snapshotLibraryDecorator) IsSanitizerEnabled(t SanitizerType) bool {
return p.sanitizerProperties.SanitizerVariation == t
}
-func (p *snapshotLibraryDecorator) isUnsanitizedVariant() bool {
- return !p.isSanitizerEnabled(Asan) &&
- !p.isSanitizerEnabled(Hwasan)
+func (p *snapshotLibraryDecorator) IsUnsanitizedVariant() bool {
+ return !p.IsSanitizerEnabled(Asan) &&
+ !p.IsSanitizerEnabled(Hwasan)
}
func snapshotLibraryFactory(image SnapshotImage, moduleSuffix string) (*Module, *snapshotLibraryDecorator) {
diff --git a/cc/test.go b/cc/test.go
index adc80c2..ae62128 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -395,7 +395,7 @@
useVendor := ctx.inVendor() || ctx.useVndk()
testInstallBase := getTestInstallBase(useVendor)
- configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx))
+ configs := getTradefedConfigOptions(ctx, &test.Properties, test.isolated(ctx), ctx.Device())
test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{
TestConfigProp: test.Properties.Test_config,
@@ -435,22 +435,24 @@
return testInstallBase
}
-func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool) []tradefed.Config {
+func getTradefedConfigOptions(ctx android.EarlyModuleContext, properties *TestBinaryProperties, isolated bool, device bool) []tradefed.Config {
var configs []tradefed.Config
for _, module := range properties.Test_mainline_modules {
configs = append(configs, tradefed.Option{Name: "config-descriptor:metadata", Key: "mainline-param", Value: module})
}
- if Bool(properties.Require_root) {
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
- } else {
- var options []tradefed.Option
- options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
- }
- if Bool(properties.Disable_framework) {
- var options []tradefed.Option
- configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
+ if device {
+ if Bool(properties.Require_root) {
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
+ } else {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "force-root", Value: "false"})
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
+ }
+ if Bool(properties.Disable_framework) {
+ var options []tradefed.Option
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.StopServicesSetup", options})
+ }
}
if isolated {
configs = append(configs, tradefed.Option{Name: "not-shardable", Value: "true"})
@@ -720,6 +722,21 @@
}
}
+ // The logic comes from https://cs.android.com/android/platform/superproject/main/+/0df8153267f96da877febc5332240fa06ceb8533:build/soong/cc/sanitize.go;l=488
+ var features bazel.StringListAttribute
+ curFeatures := testBinaryAttrs.binaryAttributes.Features.SelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64)
+ var newFeatures []string
+ if !android.InList("memtag_heap", curFeatures) && !android.InList("-memtag_heap", curFeatures) {
+ newFeatures = append(newFeatures, "memtag_heap")
+ if !android.InList("diag_memtag_heap", curFeatures) && !android.InList("-diag_memtag_heap", curFeatures) {
+ newFeatures = append(newFeatures, "diag_memtag_heap")
+ }
+ }
+
+ features.SetSelectValue(bazel.OsArchConfigurationAxis, bazel.OsArchAndroidArm64, newFeatures)
+ testBinaryAttrs.binaryAttributes.Features.Append(features)
+ testBinaryAttrs.binaryAttributes.Features.DeduplicateAxesFromBase()
+
m.convertTidyAttributes(ctx, &testBinaryAttrs.tidyAttributes)
testBinary := m.linker.(*testBinary)
@@ -745,7 +762,7 @@
p.Auto_gen_config,
p.Test_options.Test_suite_tag,
p.Test_config_template,
- getTradefedConfigOptions(ctx, p, gtestIsolated),
+ getTradefedConfigOptions(ctx, p, gtestIsolated, true),
&testInstallBase,
)
testBinaryAttrs.TestConfigAttributes = testConfigAttributes
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 20e366e..626f076 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -27,7 +27,6 @@
"android/soong/android"
"android/soong/android/allowlists"
- "android/soong/bazel"
"android/soong/bp2build"
"android/soong/shared"
"android/soong/ui/metrics/bp2build_metrics_proto"
@@ -76,7 +75,6 @@
flag.StringVar(&cmdlineArgs.ModuleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
flag.StringVar(&cmdlineArgs.DocFile, "soong_docs", "", "build documentation file to output")
flag.StringVar(&cmdlineArgs.BazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
- flag.StringVar(&cmdlineArgs.BazelApiBp2buildDir, "bazel_api_bp2build_dir", "", "path to the bazel api_bp2build directory relative to --top")
flag.StringVar(&cmdlineArgs.Bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
flag.StringVar(&cmdlineArgs.SymlinkForestMarker, "symlink_forest_marker", "", "If set, create the bp2build symlink forest, touch the specified marker file, then exit")
flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
@@ -169,120 +167,6 @@
touch(shared.JoinPath(topDir, queryviewMarker))
}
-// Run the code-generation phase to convert API contributions to BUILD files.
-// Return marker file for the new synthetic workspace
-func runApiBp2build(ctx *android.Context, extraNinjaDeps []string) string {
- ctx.EventHandler.Begin("api_bp2build")
- defer ctx.EventHandler.End("api_bp2build")
- // api_bp2build does not run the typical pipeline of soong mutators.
- // Hoevever, it still runs the defaults mutator which can create dependencies.
- // These dependencies might not always exist (e.g. in tests)
- ctx.SetAllowMissingDependencies(ctx.Config().AllowMissingDependencies())
- ctx.RegisterForApiBazelConversion()
-
- // Register the Android.bp files in the tree
- // Add them to the workspace's .d file
- ctx.SetModuleListFile(cmdlineArgs.ModuleListFile)
- if paths, err := ctx.ListModulePaths("."); err == nil {
- extraNinjaDeps = append(extraNinjaDeps, paths...)
- } else {
- panic(err)
- }
-
- // Run the loading and analysis phase
- ninjaDeps, err := bootstrap.RunBlueprint(cmdlineArgs.Args,
- bootstrap.StopBeforePrepareBuildActions,
- ctx.Context,
- ctx.Config())
- maybeQuit(err, "")
- ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
-
- // Add the globbed dependencies
- ninjaDeps = append(ninjaDeps, writeBuildGlobsNinjaFile(ctx)...)
-
- // Run codegen to generate BUILD files
- codegenContext := bp2build.NewCodegenContext(ctx.Config(), ctx, bp2build.ApiBp2build, topDir)
- absoluteApiBp2buildDir := shared.JoinPath(topDir, cmdlineArgs.BazelApiBp2buildDir)
- // Always generate bp2build_all_srcs filegroups in api_bp2build.
- // This is necessary to force each Android.bp file to create an equivalent BUILD file
- // and prevent package boundray issues.
- // e.g.
- // Source
- // f/b/Android.bp
- // java_library{
- // name: "foo",
- // api: "api/current.txt",
- // }
- //
- // f/b/api/Android.bp <- will cause package boundary issues
- //
- // Gen
- // f/b/BUILD
- // java_contribution{
- // name: "foo.contribution",
- // api: "//f/b/api:current.txt",
- // }
- //
- // If we don't generate f/b/api/BUILD, foo.contribution will be unbuildable.
- err = createBazelWorkspace(codegenContext, absoluteApiBp2buildDir, true)
- maybeQuit(err, "")
- ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
-
- // Create soong_injection repository
- soongInjectionFiles, workspaceFiles, err := bp2build.CreateSoongInjectionDirFiles(codegenContext, bp2build.CreateCodegenMetrics())
- maybeQuit(err, "")
- absoluteSoongInjectionDir := shared.JoinPath(topDir, ctx.Config().SoongOutDir(), bazel.SoongInjectionDirName)
- for _, file := range soongInjectionFiles {
- // The API targets in api_bp2build workspace do not have any dependency on api_bp2build.
- // But we need to create these files to prevent errors during Bazel analysis.
- // These need to be created in Read-Write mode.
- // This is because the subsequent step (bp2build in api domain analysis) creates them in Read-Write mode
- // to allow users to edit/experiment in the synthetic workspace.
- writeReadWriteFile(absoluteSoongInjectionDir, file)
- }
- for _, file := range workspaceFiles {
- writeReadWriteFile(absoluteApiBp2buildDir, file)
- }
-
- workspace := shared.JoinPath(ctx.Config().SoongOutDir(), "api_bp2build")
- // Create the symlink forest
- symlinkDeps, _, _ := bp2build.PlantSymlinkForest(
- ctx.Config().IsEnvTrue("BP2BUILD_VERBOSE"),
- topDir,
- workspace,
- cmdlineArgs.BazelApiBp2buildDir,
- apiBuildFileExcludes(ctx))
- ninjaDeps = append(ninjaDeps, symlinkDeps...)
-
- workspaceMarkerFile := workspace + ".marker"
- writeDepFile(workspaceMarkerFile, ctx.EventHandler, ninjaDeps)
- touch(shared.JoinPath(topDir, workspaceMarkerFile))
- return workspaceMarkerFile
-}
-
-// With some exceptions, api_bp2build does not have any dependencies on the checked-in BUILD files
-// Exclude them from the generated workspace to prevent unrelated errors during the loading phase
-func apiBuildFileExcludes(ctx *android.Context) []string {
- ret := bazelArtifacts()
- srcs, err := getExistingBazelRelatedFiles(topDir)
- maybeQuit(err, "Error determining existing Bazel-related files")
- for _, src := range srcs {
- // Exclude all src BUILD files
- if src != "WORKSPACE" &&
- src != "BUILD" &&
- src != "BUILD.bazel" &&
- !strings.HasPrefix(src, "build/bazel") &&
- !strings.HasPrefix(src, "external/bazel-skylib") &&
- !strings.HasPrefix(src, "prebuilts/clang") {
- ret = append(ret, src)
- }
- }
- // Android.bp files for api surfaces are mounted to out/, but out/ should not be a
- // dep for api_bp2build. Otherwise, api_bp2build will be run every single time
- ret = append(ret, ctx.Config().OutDir())
- return ret
-}
-
func writeNinjaHint(ctx *android.Context) error {
ctx.BeginEvent("ninja_hint")
defer ctx.EndEvent("ninja_hint")
@@ -551,9 +435,6 @@
// Run the alternate pipeline of bp2build mutators and singleton to convert
// Blueprint to BUILD files before everything else.
finalOutputFile = runBp2Build(ctx, extraNinjaDeps, metricsDir)
- case android.ApiBp2build:
- finalOutputFile = runApiBp2build(ctx, extraNinjaDeps)
- writeMetrics(configuration, ctx.EventHandler, metricsDir)
default:
ctx.Register()
isMixedBuildsEnabled := configuration.IsMixedBuildsEnabled()
diff --git a/etc/Android.bp b/etc/Android.bp
index c670236..cefd717 100644
--- a/etc/Android.bp
+++ b/etc/Android.bp
@@ -14,10 +14,12 @@
srcs: [
"prebuilt_etc.go",
"snapshot_etc.go",
+ "install_symlink.go",
],
testSrcs: [
"prebuilt_etc_test.go",
"snapshot_etc_test.go",
+ "install_symlink_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/etc/install_symlink.go b/etc/install_symlink.go
new file mode 100644
index 0000000..2182b86
--- /dev/null
+++ b/etc/install_symlink.go
@@ -0,0 +1,92 @@
+// Copyright 2023 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 etc
+
+import (
+ "android/soong/android"
+ "path/filepath"
+ "strings"
+)
+
+func init() {
+ RegisterInstallSymlinkBuildComponents(android.InitRegistrationContext)
+}
+
+func RegisterInstallSymlinkBuildComponents(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("install_symlink", InstallSymlinkFactory)
+}
+
+// install_symlink can be used to install an symlink with an arbitrary target to an arbitrary path
+// on the device.
+func InstallSymlinkFactory() android.Module {
+ module := &InstallSymlink{}
+ module.AddProperties(&module.properties)
+ android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ return module
+}
+
+type InstallSymlinkProperties struct {
+ // Where to install this symlink, relative to the partition it's installed on.
+ // Which partition it's installed on can be controlled by the vendor, system_ext, ramdisk, etc.
+ // properties.
+ Installed_location string
+ // The target of the symlink, aka where the symlink points.
+ Symlink_target string
+}
+
+type InstallSymlink struct {
+ android.ModuleBase
+ properties InstallSymlinkProperties
+
+ output android.Path
+ installedPath android.InstallPath
+}
+
+func (m *InstallSymlink) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if filepath.Clean(m.properties.Symlink_target) != m.properties.Symlink_target {
+ ctx.PropertyErrorf("symlink_target", "Should be a clean filepath")
+ return
+ }
+ if filepath.Clean(m.properties.Installed_location) != m.properties.Installed_location {
+ ctx.PropertyErrorf("installed_location", "Should be a clean filepath")
+ return
+ }
+ if strings.HasPrefix(m.properties.Installed_location, "../") || strings.HasPrefix(m.properties.Installed_location, "/") {
+ ctx.PropertyErrorf("installed_location", "Should not start with / or ../")
+ return
+ }
+
+ out := android.PathForModuleOut(ctx, "out.txt")
+ android.WriteFileRuleVerbatim(ctx, out, "")
+ m.output = out
+
+ name := filepath.Base(m.properties.Installed_location)
+ installDir := android.PathForModuleInstall(ctx, filepath.Dir(m.properties.Installed_location))
+ m.installedPath = ctx.InstallAbsoluteSymlink(installDir, name, m.properties.Symlink_target)
+}
+
+func (m *InstallSymlink) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{{
+ Class: "FAKE",
+ // Need at least one output file in order for this to take effect.
+ OutputFile: android.OptionalPathForPath(m.output),
+ Include: "$(BUILD_PHONY_PACKAGE)",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+ entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", m.installedPath.String())
+ },
+ },
+ }}
+}
diff --git a/etc/install_symlink_test.go b/etc/install_symlink_test.go
new file mode 100644
index 0000000..d7165e5
--- /dev/null
+++ b/etc/install_symlink_test.go
@@ -0,0 +1,135 @@
+// Copyright 2023 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 etc
+
+import (
+ "android/soong/android"
+ "strings"
+ "testing"
+)
+
+var prepareForInstallSymlinkTest = android.GroupFixturePreparers(
+ android.PrepareForTestWithArchMutator,
+ android.FixtureRegisterWithContext(RegisterInstallSymlinkBuildComponents),
+)
+
+func TestInstallSymlinkBasic(t *testing.T) {
+ result := prepareForInstallSymlinkTest.RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "bin/foo",
+ symlink_target: "/system/system_ext/bin/foo",
+ }
+ `)
+
+ foo_variants := result.ModuleVariantsForTests("foo")
+ if len(foo_variants) != 1 {
+ t.Fatalf("expected 1 variant, got %#v", foo_variants)
+ }
+
+ foo := result.ModuleForTests("foo", "android_common").Module()
+ androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo)
+ if len(androidMkEntries) != 1 {
+ t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries))
+ }
+
+ symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"]
+ if len(symlinks) != 1 {
+ t.Fatalf("Expected 1 symlink, got %d", len(symlinks))
+ }
+
+ if !strings.HasSuffix(symlinks[0], "system/bin/foo") {
+ t.Fatalf("Expected symlink install path to end in system/bin/foo, got: %s", symlinks[0])
+ }
+}
+
+func TestInstallSymlinkToRecovery(t *testing.T) {
+ result := prepareForInstallSymlinkTest.RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "bin/foo",
+ symlink_target: "/system/system_ext/bin/foo",
+ recovery: true,
+ }
+ `)
+
+ foo_variants := result.ModuleVariantsForTests("foo")
+ if len(foo_variants) != 1 {
+ t.Fatalf("expected 1 variant, got %#v", foo_variants)
+ }
+
+ foo := result.ModuleForTests("foo", "android_common").Module()
+ androidMkEntries := android.AndroidMkEntriesForTest(t, result.TestContext, foo)
+ if len(androidMkEntries) != 1 {
+ t.Fatalf("expected 1 androidmkentry, got %d", len(androidMkEntries))
+ }
+
+ symlinks := androidMkEntries[0].EntryMap["LOCAL_SOONG_INSTALL_SYMLINKS"]
+ if len(symlinks) != 1 {
+ t.Fatalf("Expected 1 symlink, got %d", len(symlinks))
+ }
+
+ if !strings.HasSuffix(symlinks[0], "recovery/root/system/bin/foo") {
+ t.Fatalf("Expected symlink install path to end in recovery/root/system/bin/foo, got: %s", symlinks[0])
+ }
+}
+
+func TestErrorOnNonCleanTarget(t *testing.T) {
+ prepareForInstallSymlinkTest.
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")).
+ RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "bin/foo",
+ symlink_target: "/system/system_ext/../bin/foo",
+ }
+ `)
+}
+
+func TestErrorOnNonCleanInstalledLocation(t *testing.T) {
+ prepareForInstallSymlinkTest.
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should be a clean filepath")).
+ RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "bin/../foo",
+ symlink_target: "/system/system_ext/bin/foo",
+ }
+ `)
+}
+
+func TestErrorOnInstalledPathStartingWithDotDot(t *testing.T) {
+ prepareForInstallSymlinkTest.
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")).
+ RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "../bin/foo",
+ symlink_target: "/system/system_ext/bin/foo",
+ }
+ `)
+}
+
+func TestErrorOnInstalledPathStartingWithSlash(t *testing.T) {
+ prepareForInstallSymlinkTest.
+ ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern("Should not start with / or \\.\\./")).
+ RunTestWithBp(t, `
+ install_symlink {
+ name: "foo",
+ installed_location: "/bin/foo",
+ symlink_target: "/system/system_ext/bin/foo",
+ }
+ `)
+}
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index df7664d..5c4e222 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -83,7 +83,7 @@
baz_variants := result.ModuleVariantsForTests("baz.conf")
if len(baz_variants) != 1 {
- t.Errorf("expected 1, got %#v", bar_variants)
+ t.Errorf("expected 1, got %#v", baz_variants)
}
}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 8e3f278..d1c2f13 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -912,7 +912,7 @@
Out []string
}
-type bazelGenruleAttributes struct {
+type BazelGenruleAttributes struct {
Srcs bazel.LabelListAttribute
Outs []string
Tools bazel.LabelListAttribute
@@ -1036,7 +1036,7 @@
break
}
}
- attrs := &bazelGenruleAttributes{
+ attrs := &BazelGenruleAttributes{
Srcs: srcs,
Outs: outs,
Cmd: cmdProp,
diff --git a/java/app.go b/java/app.go
index 7cf86c0..d71cd77 100755
--- a/java/app.go
+++ b/java/app.go
@@ -29,6 +29,7 @@
"android/soong/bazel"
"android/soong/cc"
"android/soong/dexpreopt"
+ "android/soong/genrule"
"android/soong/tradefed"
)
@@ -1059,6 +1060,7 @@
module.Module.dexProperties.Optimize.EnabledByDefault = true
module.Module.dexProperties.Optimize.Shrink = proptools.BoolPtr(true)
+ module.Module.dexProperties.Optimize.Proguard_compatibility = proptools.BoolPtr(false)
module.Module.properties.Instrument = true
module.Module.properties.Supports_static_instrumentation = true
@@ -1613,6 +1615,8 @@
Certificate bazel.LabelAttribute
Certificate_name bazel.StringAttribute
Manifest_values *manifestValueAttribute
+ Optimize *bool
+ Proguard_specs bazel.LabelListAttribute
}
// ConvertWithBp2build is used to convert android_app to Bazel.
@@ -1664,6 +1668,41 @@
Manifest_values: manifestValues,
}
+ if !BoolDefault(a.dexProperties.Optimize.Enabled, true) {
+ appAttrs.Optimize = proptools.BoolPtr(false)
+ } else {
+ handCraftedFlags := ""
+ if Bool(a.dexProperties.Optimize.Ignore_warnings) {
+ handCraftedFlags += "-ignorewarning "
+ }
+ if !Bool(a.dexProperties.Optimize.Shrink) {
+ handCraftedFlags += "-dontshrink "
+ }
+ if !Bool(a.dexProperties.Optimize.Optimize) {
+ handCraftedFlags += "-dontoptimize "
+ }
+ if !Bool(a.dexProperties.Optimize.Obfuscate) {
+ handCraftedFlags += "-dontobfuscate "
+ }
+ appAttrs.Proguard_specs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, a.dexProperties.Optimize.Proguard_flags_files))
+ if handCraftedFlags != "" {
+ generatedFlagFileRuleName := a.Name() + "_proguard_flags"
+ ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
+ Rule_class: "genrule",
+ }, android.CommonAttributes{
+ Name: generatedFlagFileRuleName,
+ SkipData: proptools.BoolPtr(true),
+ }, &genrule.BazelGenruleAttributes{
+ Outs: []string{a.Name() + "_proguard.flags"},
+ Cmd: bazel.StringAttribute{
+ Value: proptools.StringPtr("echo " + handCraftedFlags + "> $(OUTS)"),
+ },
+ })
+ appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName))
+ }
+
+ }
+
props := bazel.BazelTargetModuleProperties{
Rule_class: "android_binary",
Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
diff --git a/java/dex.go b/java/dex.go
index df501bf..21937e1 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -45,8 +45,8 @@
// Whether to continue building even if warnings are emitted. Defaults to true.
Ignore_warnings *bool
- // If true, runs R8 in Proguard compatibility mode (default).
- // Otherwise, runs R8 in full mode.
+ // If true, runs R8 in Proguard compatibility mode, otherwise runs R8 in full mode.
+ // Defaults to false for apps, true for libraries and tests.
Proguard_compatibility *bool
// If true, optimize for size by removing unused code. Defaults to true for apps,
@@ -217,8 +217,9 @@
// Note: Targets with a min SDK kind of core_platform (e.g., framework.jar) or unspecified (e.g.,
// services.jar), are not classified as stable, which is WAI.
// TODO(b/232073181): Expand to additional min SDK cases after validation.
+ var addAndroidPlatformBuildFlag = false
if !dexParams.sdkVersion.Stable() {
- flags = append(flags, "--android-platform-build")
+ addAndroidPlatformBuildFlag = true
}
effectiveVersion, err := dexParams.minSdkVersion.EffectiveVersion(ctx)
@@ -226,7 +227,18 @@
ctx.PropertyErrorf("min_sdk_version", "%s", err)
}
- flags = append(flags, "--min-api "+strconv.Itoa(effectiveVersion.FinalOrFutureInt()))
+ // If the specified SDK level is 10000, then configure the compiler to use the
+ // current platform SDK level and to compile the build as a platform build.
+ var minApiFlagValue = effectiveVersion.FinalOrFutureInt()
+ if minApiFlagValue == 10000 {
+ minApiFlagValue = ctx.Config().PlatformSdkVersion().FinalInt()
+ addAndroidPlatformBuildFlag = true
+ }
+ flags = append(flags, "--min-api "+strconv.Itoa(minApiFlagValue))
+
+ if addAndroidPlatformBuildFlag {
+ flags = append(flags, "--android-platform-build")
+ }
return flags, deps
}
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
index 1cab6ac..578237e 100644
--- a/java/generated_java_library.go
+++ b/java/generated_java_library.go
@@ -22,6 +22,10 @@
Library
callbacks GeneratedJavaLibraryCallbacks
moduleName string
+
+ // true if we've already called DepsMutator. Can't call AddLibrary or AddSharedLibrary
+ // after DepsMutator.
+ depsMutatorDone bool
}
type GeneratedJavaLibraryCallbacks interface {
@@ -59,8 +63,25 @@
return module
}
+// Add a java shared library as a dependency, as if they had said `libs: [ "name" ]`
+func (module *GeneratedJavaLibraryModule) AddSharedLibrary(name string) {
+ if module.depsMutatorDone {
+ panic("GeneratedJavaLibraryModule.AddLibrary called after DepsMutator")
+ }
+ module.Library.properties.Libs = append(module.Library.properties.Libs, name)
+}
+
+// Add a java shared library as a dependency, as if they had said `libs: [ "name" ]`
+func (module *GeneratedJavaLibraryModule) AddStaticLibrary(name string) {
+ if module.depsMutatorDone {
+ panic("GeneratedJavaLibraryModule.AddStaticLibrary called after DepsMutator")
+ }
+ module.Library.properties.Static_libs = append(module.Library.properties.Static_libs, name)
+}
+
func (module *GeneratedJavaLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) {
module.callbacks.DepsMutator(module, ctx)
+ module.depsMutatorDone = true
module.Library.DepsMutator(ctx)
}
diff --git a/java/java.go b/java/java.go
index fe7f88f..521aef3 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,6 +21,7 @@
import (
"fmt"
"path/filepath"
+ "sort"
"strings"
"android/soong/bazel"
@@ -1734,7 +1735,6 @@
cmd.Flag("--color").
Flag("--quiet").
- Flag("--format=v2").
Flag("--include-annotations").
// The flag makes nullability issues as warnings rather than errors by replacing
// @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull,
@@ -1746,14 +1746,13 @@
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
- // Force metalava to ignore classes on the classpath when an API file contains missing classes.
- // See b/285140653 for more information.
+ // The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
+ // classes on the classpath when an API file contains missing classes. However, as this command
+ // does not specify `--classpath` this is not needed for that. However, this is also used as a
+ // signal to the special metalava code for generating stubs from text files that it needs to add
+ // some additional items into the API (e.g. default constructors).
cmd.FlagWithArg("--api-class-resolution ", "api")
- // Force metalava to sort overloaded methods by their order in the source code.
- // See b/285312164 for more information.
- cmd.FlagWithArg("--api-overloaded-method-order ", "source")
-
return cmd
}
@@ -1915,7 +1914,7 @@
FlagWithArg("-C ", stubsDir.String()).
FlagWithArg("-D ", stubsDir.String())
- rule.Build("metalava", "metalava merged")
+ rule.Build("metalava", "metalava merged text")
if depApiSrcsStubsJar == nil {
var flags javaBuilderFlags
@@ -2756,32 +2755,41 @@
type javaResourcesAttributes struct {
Resources bazel.LabelListAttribute
Resource_strip_prefix *string
+ Additional_resources bazel.LabelListAttribute
}
-func (m *Library) javaResourcesGetSingleFilegroupStripPrefix(ctx android.TopDownMutatorContext) (string, bool) {
- if otherM, ok := ctx.ModuleFromName(m.properties.Java_resources[0]); ok && len(m.properties.Java_resources) == 1 {
+func (m *Library) getResourceFilegroupStripPrefix(ctx android.TopDownMutatorContext, resourceFilegroup string) (*string, bool) {
+ if otherM, ok := ctx.ModuleFromName(resourceFilegroup); ok {
if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup {
- return filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx)), true
+ return proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true
}
}
- return "", false
+ return proptools.StringPtr(""), false
}
func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes {
var resources bazel.LabelList
var resourceStripPrefix *string
- if m.properties.Java_resources != nil && len(m.properties.Java_resource_dirs) > 0 {
- ctx.ModuleErrorf("bp2build doesn't support both java_resources and java_resource_dirs being set on the same module.")
- }
+ additionalJavaResourcesMap := make(map[string]*javaResourcesAttributes)
if m.properties.Java_resources != nil {
- if prefix, ok := m.javaResourcesGetSingleFilegroupStripPrefix(ctx); ok {
- resourceStripPrefix = proptools.StringPtr(prefix)
- } else {
+ for _, res := range m.properties.Java_resources {
+ if prefix, isFilegroup := m.getResourceFilegroupStripPrefix(ctx, res); isFilegroup {
+ otherM, _ := ctx.ModuleFromName(res)
+ resourcesTargetName := ctx.ModuleName() + "_filegroup_resources_" + otherM.Name()
+ additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{
+ Resources: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{res})),
+ Resource_strip_prefix: prefix,
+ }
+ } else {
+ resources.Append(android.BazelLabelForModuleSrc(ctx, []string{res}))
+ }
+ }
+
+ if !resources.IsEmpty() {
resourceStripPrefix = proptools.StringPtr(ctx.ModuleDir())
}
- resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources))
}
//TODO(b/179889880) handle case where glob includes files outside package
@@ -2792,23 +2800,51 @@
m.properties.Exclude_java_resources,
)
- for i, resDep := range resDeps {
+ for _, resDep := range resDeps {
dir, files := resDep.dir, resDep.files
- resources.Append(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files)))
-
// Bazel includes the relative path from the WORKSPACE root when placing the resource
// inside the JAR file, so we need to remove that prefix
- resourceStripPrefix = proptools.StringPtr(dir.String())
- if i > 0 {
- // TODO(b/226423379) allow multiple resource prefixes
- ctx.ModuleErrorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)")
+ prefix := proptools.StringPtr(dir.String())
+ resourcesTargetName := ctx.ModuleName() + "_resource_dir_" + dir.String()
+ additionalJavaResourcesMap[resourcesTargetName] = &javaResourcesAttributes{
+ Resources: bazel.MakeLabelListAttribute(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))),
+ Resource_strip_prefix: prefix,
}
}
+ var additionalResourceLabels bazel.LabelList
+ if len(additionalJavaResourcesMap) > 0 {
+ var additionalResources []string
+ for resName, _ := range additionalJavaResourcesMap {
+ additionalResources = append(additionalResources, resName)
+ }
+ sort.Strings(additionalResources)
+
+ for i, resName := range additionalResources {
+ resAttr := additionalJavaResourcesMap[resName]
+ if resourceStripPrefix == nil && i == 0 {
+ resourceStripPrefix = resAttr.Resource_strip_prefix
+ resources = resAttr.Resources.Value
+ } else {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "java_resources",
+ Bzl_load_location: "//build/bazel/rules/java:java_resources.bzl",
+ },
+ android.CommonAttributes{Name: resName},
+ resAttr,
+ )
+ additionalResourceLabels.Append(android.BazelLabelForModuleSrc(ctx, []string{resName}))
+ }
+ }
+
+ }
+
return &javaResourcesAttributes{
Resources: bazel.MakeLabelListAttribute(resources),
Resource_strip_prefix: resourceStripPrefix,
+ Additional_resources: bazel.MakeLabelListAttribute(additionalResourceLabels),
}
}
@@ -2867,6 +2903,11 @@
var deps bazel.LabelListAttribute
var staticDeps bazel.LabelListAttribute
+ if proptools.String(m.deviceProperties.Sdk_version) == "" && m.DeviceSupported() {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version unset")
+ return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false
+ }
+
archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{})
for axis, configToProps := range archVariantProps {
for config, _props := range configToProps {
diff --git a/java/prebuilt_apis.go b/java/prebuilt_apis.go
index 044802e..99cb99b 100644
--- a/java/prebuilt_apis.go
+++ b/java/prebuilt_apis.go
@@ -55,6 +55,11 @@
// If set to true, compile dex for java_import modules. Defaults to false.
Imports_compile_dex *bool
+
+ // If set to true, allow incremental platform API of the form MM.m where MM is the major release
+ // version corresponding to the API level/SDK_INT and m is an incremental release version
+ // (e.g. API changes associated with QPR). Defaults to false.
+ Allow_incremental_platform_api *bool
}
type prebuiltApis struct {
@@ -69,6 +74,8 @@
// parsePrebuiltPath parses the relevant variables out of a variety of paths, e.g.
// <version>/<scope>/<module>.jar
// <version>/<scope>/api/<module>.txt
+// *Note when using incremental platform API, <version> may be of the form MM.m where MM is the
+// API level and m is an incremental release, otherwise <version> is a single integer corresponding to the API level only.
// extensions/<version>/<scope>/<module>.jar
// extensions/<version>/<scope>/api/<module>.txt
func parsePrebuiltPath(ctx android.LoadHookContext, p string) (module string, version string, scope string) {
@@ -90,8 +97,25 @@
}
// parseFinalizedPrebuiltPath is like parsePrebuiltPath, but verifies the version is numeric (a finalized version).
-func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string) (module string, version int, scope string) {
+func parseFinalizedPrebuiltPath(ctx android.LoadHookContext, p string, allowIncremental bool) (module string, version int, release int, scope string) {
module, v, scope := parsePrebuiltPath(ctx, p)
+ if allowIncremental {
+ parts := strings.Split(v, ".")
+ if len(parts) != 2 {
+ ctx.ModuleErrorf("Found unexpected version '%v' for incremental prebuilts - expect MM.m format for incremental API with both major (MM) an minor (m) revision.", v)
+ return
+ }
+ sdk, sdk_err := strconv.Atoi(parts[0])
+ qpr, qpr_err := strconv.Atoi(parts[1])
+ if sdk_err != nil || qpr_err != nil {
+ ctx.ModuleErrorf("Unable to read version number for incremental prebuilt api '%v'", v)
+ return
+ }
+ version = sdk
+ release = qpr
+ return
+ }
+ release = 0
version, err := strconv.Atoi(v)
if err != nil {
ctx.ModuleErrorf("Found finalized API files in non-numeric dir '%v'", v)
@@ -268,29 +292,35 @@
}
// Create modules for all (<module>, <scope, <version>) triplets,
+ allowIncremental := proptools.BoolDefault(p.properties.Allow_incremental_platform_api, false)
for _, f := range apiLevelFiles {
- module, version, scope := parseFinalizedPrebuiltPath(mctx, f)
- createApiModule(mctx, PrebuiltApiModuleName(module, scope, strconv.Itoa(version)), f)
+ module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f, allowIncremental)
+ if allowIncremental {
+ incrementalVersion := strconv.Itoa(version) + "." + strconv.Itoa(release)
+ createApiModule(mctx, PrebuiltApiModuleName(module, scope, incrementalVersion), f)
+ } else {
+ createApiModule(mctx, PrebuiltApiModuleName(module, scope, strconv.Itoa(version)), f)
+ }
}
// Figure out the latest version of each module/scope
type latestApiInfo struct {
module, scope, path string
- version int
+ version, release int
isExtensionApiFile bool
}
getLatest := func(files []string, isExtensionApiFile bool) map[string]latestApiInfo {
m := make(map[string]latestApiInfo)
for _, f := range files {
- module, version, scope := parseFinalizedPrebuiltPath(mctx, f)
+ module, version, release, scope := parseFinalizedPrebuiltPath(mctx, f, allowIncremental)
if strings.HasSuffix(module, "incompatibilities") {
continue
}
key := module + "." + scope
info, exists := m[key]
- if !exists || version > info.version {
- m[key] = latestApiInfo{module, scope, f, version, isExtensionApiFile}
+ if !exists || version > info.version || (version == info.version && release > info.release) {
+ m[key] = latestApiInfo{module, scope, f, version, release, isExtensionApiFile}
}
}
return m
diff --git a/java/prebuilt_apis_test.go b/java/prebuilt_apis_test.go
index 2b84353..b6fb2c6 100644
--- a/java/prebuilt_apis_test.go
+++ b/java/prebuilt_apis_test.go
@@ -99,3 +99,26 @@
android.AssertStringEquals(t, "Expected latest bar = extension level 2", "prebuilts/sdk/extensions/2/public/api/bar.txt", bar_input)
android.AssertStringEquals(t, "Expected latest baz = api level 32", "prebuilts/sdk/32/public/api/baz.txt", baz_input)
}
+
+func TestPrebuiltApis_WithIncrementalApi(t *testing.T) {
+ runTestWithIncrementalApi := func() (foo_input, bar_input, baz_input string) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ FixtureWithPrebuiltIncrementalApis(map[string][]string{
+ "33.0": {"foo"},
+ "33.1": {"foo", "bar", "baz"},
+ "33.2": {"foo", "bar"},
+ "current": {"foo", "bar"},
+ }),
+ ).RunTest(t)
+ foo_input = result.ModuleForTests("foo.api.public.latest", "").Rule("generator").Implicits[0].String()
+ bar_input = result.ModuleForTests("bar.api.public.latest", "").Rule("generator").Implicits[0].String()
+ baz_input = result.ModuleForTests("baz.api.public.latest", "").Rule("generator").Implicits[0].String()
+ return
+ }
+ // 33.1 is the latest for baz, 33.2 is the latest for both foo & bar
+ foo_input, bar_input, baz_input := runTestWithIncrementalApi()
+ android.AssertStringEquals(t, "Expected latest foo = api level 33.2", "prebuilts/sdk/33.2/public/api/foo.txt", foo_input)
+ android.AssertStringEquals(t, "Expected latest bar = api level 33.2", "prebuilts/sdk/33.2/public/api/bar.txt", bar_input)
+ android.AssertStringEquals(t, "Expected latest baz = api level 33.1", "prebuilts/sdk/33.1/public/api/baz.txt", baz_input)
+}
diff --git a/java/proto.go b/java/proto.go
index c732d98..2ed7b27 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -143,7 +143,14 @@
}
type protoAttributes struct {
- Deps bazel.LabelListAttribute
+ Deps bazel.LabelListAttribute
+
+ // A list of proto_library targets that the proto_library in `deps` depends on
+ // This list is overestimation.
+ // Overestimation is necessary since Soong includes other protos via proto.include_dirs and not
+ // a specific .proto file module explicitly.
+ Transitive_deps bazel.LabelListAttribute
+
Sdk_version bazel.StringAttribute
Java_version bazel.StringAttribute
}
@@ -176,11 +183,11 @@
ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
}
- protoLabel := bazel.Label{Label: ":" + m.Name() + "_proto"}
protoAttrs := &protoAttributes{
- Deps: bazel.MakeSingleLabelListAttribute(protoLabel),
- Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
- Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
+ Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs),
+ Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs),
+ Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
+ Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
}
name := m.Name() + suffix
diff --git a/java/testing.go b/java/testing.go
index 3a238d7..f2bcccf 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -225,6 +225,29 @@
)
}
+func FixtureWithPrebuiltIncrementalApis(apiLevel2Modules map[string][]string) android.FixturePreparer {
+ mockFS := android.MockFS{}
+ path := "prebuilts/sdk/Android.bp"
+
+ bp := fmt.Sprintf(`
+ prebuilt_apis {
+ name: "sdk",
+ api_dirs: ["%s"],
+ allow_incremental_platform_api: true,
+ imports_sdk_version: "none",
+ imports_compile_dex: true,
+ }
+ `, strings.Join(android.SortedKeys(apiLevel2Modules), `", "`))
+
+ for release, modules := range apiLevel2Modules {
+ mockFS.Merge(prebuiltApisFilesForModules([]string{release}, modules))
+ }
+ return android.GroupFixturePreparers(
+ android.FixtureAddTextFile(path, bp),
+ android.FixtureMergeMockFs(mockFS),
+ )
+}
+
func prebuiltApisFilesForModules(apiLevels []string, modules []string) map[string][]byte {
libs := append([]string{"android"}, modules...)
@@ -385,6 +408,8 @@
"kotlin-stdlib-jdk8",
"kotlin-annotations",
"stub-annotations",
+
+ "aconfig-annotations-lib",
}
for _, extra := range extraModules {
diff --git a/provenance/provenance_singleton.go b/provenance/provenance_singleton.go
index 5d27c0c..97345af 100644
--- a/provenance/provenance_singleton.go
+++ b/provenance/provenance_singleton.go
@@ -38,7 +38,9 @@
Command: `rm -rf $out && ` +
`echo "# proto-file: build/soong/provenance/proto/provenance_metadata.proto" > $out && ` +
`echo "# proto-message: ProvenanceMetaDataList" >> $out && ` +
- `for file in $in; do echo '' >> $out; echo 'metadata {' | cat - $$file | grep -Ev "^#.*|^$$" >> $out; echo '}' >> $out; done`,
+ `cat $out.rsp | tr ' ' '\n' | while read -r file || [ -n "$$file" ]; do echo '' >> $out; echo 'metadata {' | cat - $$file | grep -Ev "^#.*|^$$" >> $out; echo '}' >> $out; done`,
+ Rspfile: `$out.rsp`,
+ RspfileContent: `$in`,
})
)
diff --git a/python/python.go b/python/python.go
index e6bdeee..7d77ca7 100644
--- a/python/python.go
+++ b/python/python.go
@@ -197,6 +197,14 @@
return String(p.properties.Pkg_path)
}
+// PkgPath is the "public" version of `getPkgPath` that is only available during bp2build
+func (p *PythonLibraryModule) PkgPath(ctx android.BazelConversionContext) *string {
+ if ctx.Config().BuildMode != android.Bp2build {
+ ctx.ModuleErrorf("PkgPath is only supported in bp2build mode")
+ }
+ return p.properties.Pkg_path
+}
+
func (p *PythonLibraryModule) getBaseProperties() *BaseProperties {
return &p.properties
}
@@ -454,8 +462,7 @@
// generate the zipfile of all source and data files
p.srcsZip = p.createSrcsZip(ctx, pkgPath)
- // TODO(b/278602456): precompilation temporarily disabled for python3.11 upgrade
- p.precompiledSrcsZip = p.srcsZip //p.precompileSrcs(ctx)
+ p.precompiledSrcsZip = p.precompileSrcs(ctx)
}
func isValidPythonPath(path string) error {
diff --git a/rust/binary.go b/rust/binary.go
index e6f1539..1e24beb 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -16,6 +16,8 @@
import (
"android/soong/android"
+ "android/soong/bazel"
+ "fmt"
)
func init() {
@@ -60,6 +62,8 @@
func NewRustBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
module := newModule(hod, android.MultilibFirst)
+ android.InitBazelModule(module)
+
binary := &binaryDecorator{
baseCompiler: NewBaseCompiler("bin", "", InstallInSystem),
}
@@ -183,3 +187,88 @@
func (binary *binaryDecorator) testBinary() bool {
return false
}
+
+type rustBinaryLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Compile_data bazel.LabelListAttribute
+ Crate_name bazel.StringAttribute
+ Edition bazel.StringAttribute
+ Crate_features bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ Proc_macro_deps bazel.LabelListAttribute
+ Rustc_flags bazel.StringListAttribute
+}
+
+func binaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+ binary := m.compiler.(*binaryDecorator)
+
+ var srcs bazel.LabelList
+ var compileData bazel.LabelList
+
+ if binary.baseCompiler.Properties.Srcs[0] == "src/main.rs" {
+ srcs = android.BazelLabelForModuleSrc(ctx, []string{"src/**/*.rs"})
+ compileData = android.BazelLabelForModuleSrc(
+ ctx,
+ []string{
+ "src/**/*.proto",
+ "examples/**/*.rs",
+ "**/*.md",
+ "templates/**/*.template",
+ },
+ )
+ } else {
+ srcs = android.BazelLabelForModuleSrc(ctx, binary.baseCompiler.Properties.Srcs)
+ }
+
+ deps := android.BazelLabelForModuleDeps(ctx, append(
+ binary.baseCompiler.Properties.Rustlibs,
+ ))
+
+ procMacroDeps := android.BazelLabelForModuleDeps(ctx, binary.baseCompiler.Properties.Proc_macros)
+
+ var rustcFLags []string
+ for _, cfg := range binary.baseCompiler.Properties.Cfgs {
+ rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
+ }
+
+ attrs := &rustBinaryLibraryAttributes{
+ Srcs: bazel.MakeLabelListAttribute(
+ srcs,
+ ),
+ Compile_data: bazel.MakeLabelListAttribute(
+ compileData,
+ ),
+ Crate_name: bazel.StringAttribute{
+ Value: &binary.baseCompiler.Properties.Crate_name,
+ },
+ Edition: bazel.StringAttribute{
+ Value: binary.baseCompiler.Properties.Edition,
+ },
+ Crate_features: bazel.StringListAttribute{
+ Value: binary.baseCompiler.Properties.Features,
+ },
+ Deps: bazel.MakeLabelListAttribute(
+ deps,
+ ),
+ Proc_macro_deps: bazel.MakeLabelListAttribute(
+ procMacroDeps,
+ ),
+ Rustc_flags: bazel.StringListAttribute{
+ Value: append(
+ rustcFLags,
+ binary.baseCompiler.Properties.Flags...,
+ ),
+ },
+ }
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "rust_binary",
+ Bzl_load_location: "@rules_rust//rust:defs.bzl",
+ },
+ android.CommonAttributes{
+ Name: m.Name(),
+ },
+ attrs,
+ )
+}
diff --git a/rust/config/global.go b/rust/config/global.go
index ca2c9af..4bd495d 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -54,11 +54,11 @@
"-C symbol-mangling-version=v0",
"--color always",
"-Zdylib-lto",
+ "-Z link-native-libraries=no",
}
deviceGlobalRustFlags = []string{
"-C panic=abort",
- "-Z link-native-libraries=no",
// Generate additional debug info for AutoFDO
"-Z debug-info-for-profiling",
}
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 235f517..4c04ce8 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -60,6 +60,25 @@
fuzz.binaryDecorator.baseCompiler.dir64 = "fuzz"
fuzz.binaryDecorator.baseCompiler.location = InstallInData
module.sanitize.SetSanitizer(cc.Fuzzer, true)
+
+ // The fuzzer runtime is not present for darwin or bionic host modules, so disable rust_fuzz modules for these.
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+
+ extraProps := struct {
+ Target struct {
+ Darwin struct {
+ Enabled *bool
+ }
+ Linux_bionic struct {
+ Enabled *bool
+ }
+ }
+ }{}
+ extraProps.Target.Darwin.Enabled = cc.BoolPtr(false)
+ extraProps.Target.Linux_bionic.Enabled = cc.BoolPtr(false)
+ ctx.AppendProperties(&extraProps)
+ })
+
module.compiler = fuzz
return module, fuzz
}
diff --git a/rust/library.go b/rust/library.go
index 419fcfc..3f031c1 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -20,7 +20,10 @@
"strings"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/cc"
+
+ "github.com/google/blueprint/proptools"
)
var (
@@ -398,6 +401,8 @@
func NewRustLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
module := newModule(hod, android.MultilibBoth)
+ android.InitBazelModule(module)
+
library := &libraryDecorator{
MutatedProperties: LibraryMutatedProperties{
BuildDylib: false,
@@ -793,3 +798,155 @@
// TODO(185577950): If support for generated headers is added, they need to be collected here as well.
l.collectedSnapshotHeaders = ret
}
+
+type rustLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Compile_data bazel.LabelListAttribute
+ Crate_name bazel.StringAttribute
+ Edition bazel.StringAttribute
+ Crate_features bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ Rustc_flags bazel.StringListAttribute
+ Proc_macro_deps bazel.LabelListAttribute
+}
+
+func libraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+ lib := m.compiler.(*libraryDecorator)
+
+ srcs, compileData := srcsAndCompileDataAttrs(ctx, *lib.baseCompiler)
+
+ deps := android.BazelLabelForModuleDeps(ctx, append(
+ lib.baseCompiler.Properties.Rustlibs,
+ lib.baseCompiler.Properties.Rlibs...,
+ ))
+
+ cargoBuildScript := cargoBuildScriptBp2build(ctx, m)
+ if cargoBuildScript != nil {
+ deps.Add(&bazel.Label{
+ Label: ":" + *cargoBuildScript,
+ })
+ }
+
+ procMacroDeps := android.BazelLabelForModuleDeps(ctx, lib.baseCompiler.Properties.Proc_macros)
+
+ var rustcFLags []string
+ for _, cfg := range lib.baseCompiler.Properties.Cfgs {
+ rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
+ }
+
+ attrs := &rustLibraryAttributes{
+ Srcs: bazel.MakeLabelListAttribute(
+ srcs,
+ ),
+ Compile_data: bazel.MakeLabelListAttribute(
+ compileData,
+ ),
+ Crate_name: bazel.StringAttribute{
+ Value: &lib.baseCompiler.Properties.Crate_name,
+ },
+ Edition: bazel.StringAttribute{
+ Value: lib.baseCompiler.Properties.Edition,
+ },
+ Crate_features: bazel.StringListAttribute{
+ Value: lib.baseCompiler.Properties.Features,
+ },
+ Deps: bazel.MakeLabelListAttribute(
+ deps,
+ ),
+ Proc_macro_deps: bazel.MakeLabelListAttribute(
+ procMacroDeps,
+ ),
+ Rustc_flags: bazel.StringListAttribute{
+ Value: append(
+ rustcFLags,
+ lib.baseCompiler.Properties.Flags...,
+ ),
+ },
+ }
+
+ // TODO(b/290790800): Remove the restriction when rust toolchain for android is implemented
+ var restriction bazel.BoolAttribute
+ restriction.SetSelectValue(bazel.OsConfigurationAxis, "android", proptools.BoolPtr(false))
+
+ ctx.CreateBazelTargetModuleWithRestrictions(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "rust_library",
+ Bzl_load_location: "@rules_rust//rust:defs.bzl",
+ },
+ android.CommonAttributes{
+ Name: m.Name(),
+ },
+ attrs,
+ restriction,
+ )
+}
+
+type cargoBuildScriptAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Edition bazel.StringAttribute
+ Version bazel.StringAttribute
+}
+
+func cargoBuildScriptBp2build(ctx android.TopDownMutatorContext, m *Module) *string {
+ // Soong treats some crates like libprotobuf as special in that they have
+ // cargo build script ran to produce an out folder and check it into AOSP
+ // For example, https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/out/
+ // is produced by cargo build script https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/build.rs
+ // The out folder is then fed into `rust_library` by a genrule
+ // https://cs.android.com/android/platform/superproject/main/+/main:external/rust/crates/protobuf/Android.bp;l=22
+ // This allows Soong to decouple from cargo completely.
+
+ // Soong decouples from cargo so that it has control over cc compilation.
+ // https://cs.android.com/android/platform/superproject/main/+/main:development/scripts/cargo2android.py;l=1033-1041;drc=8449944a50a0445a5ecaf9b7aed12608c81bf3f1
+ // generates a `cc_library_static` module to have custom cc flags.
+ // Since bp2build will convert the cc modules to cc targets which include the cflags,
+ // Bazel does not need to have this optimization.
+
+ // Performance-wise: rust_library -> cargo_build_script vs rust_library -> genrule (like Soong)
+ // don't have any major difference in build time in Bazel. So using cargo_build_script does not slow
+ // down the build.
+
+ // The benefit of using `cargo_build_script` here is that it would take care of setting correct
+ // `OUT_DIR` for us - similar to what Soong does here
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/soong/rust/builder.go;l=202-218;drc=f29ca58e88c5846bbe8955e5192135e5ab4f14a1
+
+ // TODO(b/297364081): cargo2android.py has logic for when generate/not cc_library_static and out directory
+ // bp2build might be able use the same logic for when to use `cargo_build_script`.
+ // For now, we're building libprotobuf_build_script as a one-off until we have a more principled solution
+ if m.Name() != "libprotobuf" {
+ return nil
+ }
+
+ lib := m.compiler.(*libraryDecorator)
+
+ name := m.Name() + "_build_script"
+ attrs := &cargoBuildScriptAttributes{
+ Srcs: bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleSrc(ctx, []string{"build.rs"}),
+ ),
+ Edition: bazel.StringAttribute{
+ Value: lib.baseCompiler.Properties.Edition,
+ },
+ Version: bazel.StringAttribute{
+ Value: lib.baseCompiler.Properties.Cargo_pkg_version,
+ },
+ }
+
+ // TODO(b/290790800): Remove the restriction when rust toolchain for android is implemented
+ var restriction bazel.BoolAttribute
+ restriction.SetSelectValue(bazel.OsConfigurationAxis, "android", proptools.BoolPtr(false))
+
+ ctx.CreateBazelTargetModuleWithRestrictions(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cargo_build_script",
+ Bzl_load_location: "@rules_rust//cargo:cargo_build_script.bzl",
+ },
+ android.CommonAttributes{
+ Name: name,
+ },
+ attrs,
+ restriction,
+ )
+
+ return &name
+}
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 832b62c..26227d0 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -16,6 +16,8 @@
import (
"android/soong/android"
+ "android/soong/bazel"
+ "fmt"
)
func init() {
@@ -47,6 +49,8 @@
func NewProcMacro(hod android.HostOrDeviceSupported) (*Module, *procMacroDecorator) {
module := newModule(hod, android.MultilibFirst)
+ android.InitBazelModule(module)
+
procMacro := &procMacroDecorator{
baseCompiler: NewBaseCompiler("lib", "lib64", InstallInSystem),
flagExporter: NewFlagExporter(),
@@ -99,3 +103,65 @@
// Proc_macros are never installed
return false
}
+
+type procMacroAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Compile_data bazel.LabelListAttribute
+ Crate_name bazel.StringAttribute
+ Edition bazel.StringAttribute
+ Crate_features bazel.StringListAttribute
+ Deps bazel.LabelListAttribute
+ Rustc_flags bazel.StringListAttribute
+}
+
+func procMacroBp2build(ctx android.TopDownMutatorContext, m *Module) {
+ procMacro := m.compiler.(*procMacroDecorator)
+ srcs, compileData := srcsAndCompileDataAttrs(ctx, *procMacro.baseCompiler)
+ deps := android.BazelLabelForModuleDeps(ctx, append(
+ procMacro.baseCompiler.Properties.Rustlibs,
+ procMacro.baseCompiler.Properties.Rlibs...,
+ ))
+
+ var rustcFLags []string
+ for _, cfg := range procMacro.baseCompiler.Properties.Cfgs {
+ rustcFLags = append(rustcFLags, fmt.Sprintf("--cfg=%s", cfg))
+ }
+
+ attrs := &procMacroAttributes{
+ Srcs: bazel.MakeLabelListAttribute(
+ srcs,
+ ),
+ Compile_data: bazel.MakeLabelListAttribute(
+ compileData,
+ ),
+ Crate_name: bazel.StringAttribute{
+ Value: &procMacro.baseCompiler.Properties.Crate_name,
+ },
+ Edition: bazel.StringAttribute{
+ Value: procMacro.baseCompiler.Properties.Edition,
+ },
+ Crate_features: bazel.StringListAttribute{
+ Value: procMacro.baseCompiler.Properties.Features,
+ },
+ Deps: bazel.MakeLabelListAttribute(
+ deps,
+ ),
+ Rustc_flags: bazel.StringListAttribute{
+ Value: append(
+ rustcFLags,
+ procMacro.baseCompiler.Properties.Flags...,
+ ),
+ },
+ }
+ // m.IsConvertedByBp2build()
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "rust_proc_macro",
+ Bzl_load_location: "@rules_rust//rust:defs.bzl",
+ },
+ android.CommonAttributes{
+ Name: m.Name(),
+ },
+ attrs,
+ )
+}
diff --git a/rust/protobuf.go b/rust/protobuf.go
index a14ebea..ae82844 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -19,6 +19,9 @@
"strings"
"android/soong/android"
+ "android/soong/bazel"
+
+ "github.com/google/blueprint/proptools"
)
var (
@@ -264,5 +267,71 @@
module := NewSourceProviderModule(hod, protobuf, false, false)
+ android.InitBazelModule(module)
+
return module, protobuf
}
+
+type rustProtoAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Crate_name bazel.StringAttribute
+ Deps bazel.LabelListAttribute
+}
+
+type protoLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+}
+
+func protoLibraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+ var protoFiles []string
+
+ for _, propsInterface := range m.sourceProvider.SourceProviderProps() {
+ if possibleProps, ok := propsInterface.(*ProtobufProperties); ok {
+ protoFiles = possibleProps.Protos
+ break
+ }
+ }
+
+ protoLibraryName := m.Name() + "_proto"
+
+ protoDeps := bazel.LabelListAttribute{
+ Value: bazel.LabelList{
+ Includes: []bazel.Label{
+ {
+ Label: ":" + protoLibraryName,
+ OriginalModuleName: m.Name(),
+ },
+ },
+ },
+ }
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "proto_library",
+ },
+ android.CommonAttributes{
+ Name: protoLibraryName,
+ },
+ &protoLibraryAttributes{
+ Srcs: bazel.MakeLabelListAttribute(
+ android.BazelLabelForModuleSrc(ctx, protoFiles),
+ ),
+ },
+ )
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "rust_proto_library",
+ Bzl_load_location: "@rules_rust//proto/protobuf:defs.bzl",
+ },
+ android.CommonAttributes{
+ Name: m.Name(),
+ },
+ &rustProtoAttributes{
+ Crate_name: bazel.StringAttribute{
+ Value: proptools.StringPtr(m.CrateName()),
+ },
+ Deps: protoDeps,
+ },
+ )
+}
diff --git a/rust/rust.go b/rust/rust.go
index 689ff38..1ee99cd 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -15,7 +15,9 @@
package rust
import (
+ "android/soong/bazel"
"android/soong/bloaty"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
"fmt"
"strings"
@@ -169,6 +171,8 @@
apexSdkVersion android.ApiLevel
transitiveAndroidMkSharedLibs *android.DepSet[string]
+
+ android.BazelModuleBase
}
func (mod *Module) Header() bool {
@@ -1841,6 +1845,46 @@
return ""
}
+func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+ if ctx.ModuleType() == "rust_library_host" || ctx.ModuleType() == "rust_library" {
+ libraryBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_proc_macro" {
+ procMacroBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_binary_host" {
+ binaryBp2build(ctx, m)
+ } else if ctx.ModuleType() == "rust_protobuf_host" {
+ protoLibraryBp2build(ctx, m)
+ } else {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
+ }
+}
+
+// This is a workaround by assuming the conventions that rust crate repos are structured
+// while waiting for the sandboxing work to complete.
+// TODO(b/297344471): When crate_root prop is set which enforces inputs sandboxing,
+// always use `srcs` and `compile_data` props to generate `srcs` and `compile_data` attributes
+// instead of using globs.
+func srcsAndCompileDataAttrs(ctx android.TopDownMutatorContext, c baseCompiler) (bazel.LabelList, bazel.LabelList) {
+ var srcs bazel.LabelList
+ var compileData bazel.LabelList
+
+ if c.Properties.Srcs[0] == "src/lib.rs" {
+ srcs = android.BazelLabelForModuleSrc(ctx, []string{"src/**/*.rs"})
+ compileData = android.BazelLabelForModuleSrc(
+ ctx,
+ []string{
+ "src/**/*.proto",
+ "examples/**/*.rs",
+ "**/*.md",
+ },
+ )
+ } else {
+ srcs = android.BazelLabelForModuleSrc(ctx, c.Properties.Srcs)
+ }
+
+ return srcs, compileData
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/rust/sanitize.go b/rust/sanitize.go
index cc19e6e..2f5afd7 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -208,6 +208,11 @@
s.Memtag_heap = nil
}
+ // Disable sanitizers for musl x86 modules, rustc does not support any sanitizers.
+ if ctx.Os() == android.LinuxMusl && ctx.Arch().ArchType == android.X86 {
+ s.Never = boolPtr(true)
+ }
+
// TODO:(b/178369775)
// For now sanitizing is only supported on non-windows targets
if ctx.Os() != android.Windows && (Bool(s.Hwaddress) || Bool(s.Address) || Bool(s.Memtag_heap) || Bool(s.Fuzzer)) {
diff --git a/rust/snapshot_prebuilt.go b/rust/snapshot_prebuilt.go
index 32d3916..42e3cef 100644
--- a/rust/snapshot_prebuilt.go
+++ b/rust/snapshot_prebuilt.go
@@ -15,6 +15,8 @@
package rust
import (
+ "fmt"
+
"android/soong/android"
"android/soong/cc"
@@ -26,17 +28,80 @@
*libraryDecorator
properties cc.SnapshotLibraryProperties
sanitizerProperties struct {
- CfiEnabled bool `blueprint:"mutated"`
+ SanitizerVariation cc.SanitizerType `blueprint:"mutated"`
- // Library flags for cfi variant.
- Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
+ //TODO: Library flags for cfi variant when CFI is supported.
+ //Cfi cc.SnapshotLibraryProperties `android:"arch_variant"`
+
+ // Library flags for hwasan variant.
+ Hwasan cc.SnapshotLibraryProperties `android:"arch_variant"`
}
}
+var _ cc.SnapshotSanitizer = (*snapshotLibraryDecorator)(nil)
+
+func (library *snapshotLibraryDecorator) IsSanitizerAvailable(t cc.SanitizerType) bool {
+ switch t {
+ //TODO: When CFI is supported, add a check here as well
+ case cc.Hwasan:
+ return library.sanitizerProperties.Hwasan.Src != nil
+ default:
+ return false
+ }
+}
+
+func (library *snapshotLibraryDecorator) SetSanitizerVariation(t cc.SanitizerType, enabled bool) {
+ if !enabled || library.IsSanitizerEnabled(t) {
+ return
+ }
+ if !library.IsUnsanitizedVariant() {
+ panic(fmt.Errorf("snapshot Sanitizer must be one of Cfi or Hwasan but not both"))
+ }
+ library.sanitizerProperties.SanitizerVariation = t
+}
+
+func (library *snapshotLibraryDecorator) IsSanitizerEnabled(t cc.SanitizerType) bool {
+ return library.sanitizerProperties.SanitizerVariation == t
+}
+
+func (library *snapshotLibraryDecorator) IsUnsanitizedVariant() bool {
+ //TODO: When CFI is supported, add a check here as well
+ return !library.IsSanitizerEnabled(cc.Hwasan)
+}
+
func init() {
registerRustSnapshotModules(android.InitRegistrationContext)
}
+func (mod *Module) IsSnapshotSanitizerAvailable(t cc.SanitizerType) bool {
+ if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
+ return ss.IsSanitizerAvailable(t)
+ }
+ return false
+}
+
+func (mod *Module) SetSnapshotSanitizerVariation(t cc.SanitizerType, enabled bool) {
+ if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
+ ss.SetSanitizerVariation(t, enabled)
+ } else {
+ panic(fmt.Errorf("Calling SetSnapshotSanitizerVariation on a non-snapshotLibraryDecorator: %s", mod.Name()))
+ }
+}
+
+func (mod *Module) IsSnapshotUnsanitizedVariant() bool {
+ if ss, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
+ return ss.IsUnsanitizedVariant()
+ }
+ return false
+}
+
+func (mod *Module) IsSnapshotSanitizer() bool {
+ if _, ok := mod.compiler.(cc.SnapshotSanitizer); ok {
+ return true
+ }
+ return false
+}
+
func registerRustSnapshotModules(ctx android.RegistrationContext) {
cc.VendorSnapshotImageSingleton.RegisterAdditionalModule(ctx,
"vendor_snapshot_rlib", VendorSnapshotRlibFactory)
@@ -81,6 +146,9 @@
library.SetSnapshotAndroidMkSuffix(ctx, variant)
+ if library.IsSanitizerEnabled(cc.Hwasan) {
+ library.properties = library.sanitizerProperties.Hwasan
+ }
if !library.MatchesWithDevice(ctx.DeviceConfig()) {
return buildOutput{}
}
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 7ccc114..3c0b8ae 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -86,6 +86,98 @@
)
}
+func TestSnapshotWithPartialSystemServerClasspathFragment(t *testing.T) {
+ commonSdk := `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "Tiramisu",
+ systemserverclasspath_fragments: ["mysystemserverclasspathfragment"],
+ }
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ apex_available: ["myapex"],
+ contents: [
+ "mysdklibrary",
+ "mysdklibrary-future",
+ ],
+ }
+ java_sdk_library {
+ name: "mysdklibrary",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ min_sdk_version: "33", // Tiramisu
+ }
+ java_sdk_library {
+ name: "mysdklibrary-future",
+ apex_available: ["myapex"],
+ srcs: ["Test.java"],
+ min_sdk_version: "34", // UpsideDownCake
+ }
+ sdk {
+ name: "mysdk",
+ apexes: ["myapex"],
+ }
+ `
+
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ java.PrepareForTestWithJavaDefaultModules,
+ java.PrepareForTestWithJavaSdkLibraryFiles,
+ java.FixtureWithLastReleaseApis("mysdklibrary", "mysdklibrary-future"),
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:mysdklibrary", "myapex:mysdklibrary-future"),
+ android.FixtureModifyEnv(func(env map[string]string) {
+ // targeting Tiramisu here means that we won't export mysdklibrary-future
+ env["SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE"] = "Tiramisu"
+ }),
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"UpsideDownCake"}
+ }),
+ prepareForSdkTestWithApex,
+ android.FixtureWithRootAndroidBp(commonSdk),
+ ).RunTest(t)
+
+ CheckSnapshot(t, result, "mysdk", "", checkAndroidBpContents(
+ `// This is auto-generated. DO NOT EDIT.
+
+java_sdk_library_import {
+ name: "mysdklibrary",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ shared_library: true,
+ public: {
+ jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/public/mysdklibrary.txt",
+ removed_api: "sdk_library/public/mysdklibrary-removed.txt",
+ sdk_version: "current",
+ },
+ system: {
+ jars: ["sdk_library/system/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/system/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/system/mysdklibrary.txt",
+ removed_api: "sdk_library/system/mysdklibrary-removed.txt",
+ sdk_version: "system_current",
+ },
+ test: {
+ jars: ["sdk_library/test/mysdklibrary-stubs.jar"],
+ stub_srcs: ["sdk_library/test/mysdklibrary_stub_sources"],
+ current_api: "sdk_library/test/mysdklibrary.txt",
+ removed_api: "sdk_library/test/mysdklibrary-removed.txt",
+ sdk_version: "test_current",
+ },
+}
+
+prebuilt_systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["myapex"],
+ contents: ["mysdklibrary"],
+} `))
+}
+
func TestSnapshotWithEmptySystemServerClasspathFragment(t *testing.T) {
commonSdk := `
apex {
diff --git a/sh/Android.bp b/sh/Android.bp
index f9198dc..1deedc7 100644
--- a/sh/Android.bp
+++ b/sh/Android.bp
@@ -10,6 +10,7 @@
"soong",
"soong-android",
"soong-cc",
+ "soong-java",
"soong-tradefed",
],
srcs: [
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
index 5459904..00794cd 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -143,6 +143,9 @@
// Only available for host sh_test modules.
Data_device_libs []string `android:"path,arch_variant"`
+ // list of java modules that provide data that should be installed alongside the test.
+ Java_data []string
+
// Install the test into a folder named for the module in all test suites.
Per_testcase_directory *bool
@@ -307,6 +310,7 @@
shTestDataLibsTag = dependencyTag{name: "dataLibs"}
shTestDataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"}
shTestDataDeviceLibsTag = dependencyTag{name: "dataDeviceLibs"}
+ shTestJavaDataTag = dependencyTag{name: "javaData"}
)
var sharedLibVariations = []blueprint.Variation{{Mutator: "link", Variation: "shared"}}
@@ -322,6 +326,10 @@
ctx.AddFarVariationDependencies(deviceVariations, shTestDataDeviceBinsTag, s.testProperties.Data_device_bins...)
ctx.AddFarVariationDependencies(append(deviceVariations, sharedLibVariations...),
shTestDataDeviceLibsTag, s.testProperties.Data_device_libs...)
+
+ javaDataVariation := []blueprint.Variation{{"arch", android.Common.String()}}
+ ctx.AddVariationDependencies(javaDataVariation, shTestJavaDataTag, s.testProperties.Java_data...)
+
} else if ctx.Target().Os.Class != android.Host {
if len(s.testProperties.Data_device_bins) > 0 {
ctx.PropertyErrorf("data_device_bins", "only available for host modules")
@@ -329,6 +337,9 @@
if len(s.testProperties.Data_device_libs) > 0 {
ctx.PropertyErrorf("data_device_libs", "only available for host modules")
}
+ if len(s.testProperties.Java_data) > 0 {
+ ctx.PropertyErrorf("Java_data", "only available for host modules")
+ }
}
}
@@ -361,7 +372,13 @@
}
s.installedFile = ctx.InstallExecutable(s.installDir, s.outputFilePath.Base(), s.outputFilePath)
- s.data = android.PathsForModuleSrc(ctx, s.testProperties.Data)
+ expandedData := android.PathsForModuleSrc(ctx, s.testProperties.Data)
+
+ // Emulate the data property for java_data dependencies.
+ for _, javaData := range ctx.GetDirectDepsWithTag(shTestJavaDataTag) {
+ expandedData = append(expandedData, android.OutputFilesForModule(ctx, javaData, "")...)
+ }
+ s.data = expandedData
var configs []tradefed.Config
if Bool(s.testProperties.Require_root) {
diff --git a/sh/sh_binary_test.go b/sh/sh_binary_test.go
index 89b8126..5fcb58d 100644
--- a/sh/sh_binary_test.go
+++ b/sh/sh_binary_test.go
@@ -9,6 +9,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/java"
)
func TestMain(m *testing.M) {
@@ -17,6 +18,7 @@
var prepareForShTest = android.GroupFixturePreparers(
cc.PrepareForTestWithCcBuildComponents,
+ java.PrepareForTestWithJavaDefaultModules,
PrepareForTestWithShBuildComponents,
android.FixtureMergeMockFs(android.MockFS{
"test.sh": nil,
@@ -255,3 +257,39 @@
t.Errorf("foo extraConfings %v does not contain %q", autogen.Args["extraConfigs"], expectedBinAutogenConfig)
}
}
+
+func TestShTestHost_javaData(t *testing.T) {
+ ctx, config := testShBinary(t, `
+ sh_test_host {
+ name: "foo",
+ src: "test.sh",
+ filename: "test.sh",
+ data: [
+ "testdata/data1",
+ "testdata/sub/data2",
+ ],
+ java_data: [
+ "javalib",
+ ],
+ }
+
+ java_library_host {
+ name: "javalib",
+ srcs: [],
+ }
+ `)
+ buildOS := ctx.Config().BuildOS.String()
+ mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest)
+ if !mod.Host() {
+ t.Errorf("host bit is not set for a sh_test_host module.")
+ }
+ expectedData := []string{
+ ":testdata/data1",
+ ":testdata/sub/data2",
+ "out/soong/.intermediates/javalib/" + buildOS + "_common/combined/:javalib.jar",
+ }
+
+ entries := android.AndroidMkEntriesForTest(t, ctx, mod)[0]
+ actualData := entries.EntryMap["LOCAL_TEST_DATA"]
+ android.AssertStringPathsRelativeToTopEquals(t, "LOCAL_TEST_DATA", config, expectedData, actualData)
+}
diff --git a/tests/bp2build_bazel_test.sh b/tests/bp2build_bazel_test.sh
index 090114b..8a64a56 100755
--- a/tests/bp2build_bazel_test.sh
+++ b/tests/bp2build_bazel_test.sh
@@ -407,38 +407,6 @@
fi
}
-# Smoke test to verify api_bp2build worksapce does not contain any errors
-function test_api_bp2build_empty_build() {
- setup
- run_soong api_bp2build
- run_bazel build --config=android --config=api_bp2build //:empty
-}
-
-# Verify that an *_api_contribution target can refer to an api file from
-# another Bazel package.
-function test_api_export_from_another_bazel_package() {
- setup
- # Parent dir Android.bp
- mkdir -p foo
- cat > foo/Android.bp << 'EOF'
-cc_library {
- name: "libfoo",
- stubs: {
- symbol_file: "api/libfoo.map.txt",
- },
-}
-EOF
- # Child dir Android.bp
- mkdir -p foo/api
- cat > foo/api/Android.bp << 'EOF'
-package{}
-EOF
- touch foo/api/libfoo.map.txt
- # Run test
- run_soong api_bp2build
- run_bazel build --config=android --config=api_bp2build //foo:libfoo.contribution
-}
-
function test_bazel_standalone_output_paths_contain_product_name {
setup
mkdir -p a
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 9801a8e..9de9b97 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -85,46 +85,7 @@
lz4=$out_dir/host/linux-x86/bin/lz4
declare -A diff_excludes
- diff_excludes[vendor]="\
- -I /vendor/lib64/libkeystore2_crypto.so \
- -I /vendor/lib64/libvsock_utils.so"
- diff_excludes[system]="\
- -I /system/bin/assemble_cvd \
- -I /system/bin/console_forwarder \
- -I /system/bin/kernel_log_monitor \
- -I /system/bin/logcat_receiver \
- -I /system/bin/mkenvimage_slim \
- -I /system/bin/run_cvd \
- -I /system/bin/simg2img \
- -I /system/bin/log_tee \
- -I /system/lib64/android.hardware.confirmationui@1.0.so \
- -I /system/lib64/android.hardware.confirmationui-V1-ndk.so \
- -I /system/lib64/android.hardware.keymaster@4.1.so \
- -I /system/lib64/android.hardware.security.rkp-V3-ndk.so \
- -I /system/lib64/android.hardware.security.sharedsecret-V1-ndk.so \
- -I /system/lib64/android.security.compat-ndk.so \
- -I /system/lib64/libcuttlefish_allocd_utils.so \
- -I /system/lib64/libcuttlefish_device_config_proto.so \
- -I /system/lib64/libcuttlefish_device_config.so \
- -I /system/lib64/libcuttlefish_fs.so \
- -I /system/lib64/libcuttlefish_kernel_log_monitor_utils.so \
- -I /system/lib64/libcuttlefish_utils.so \
- -I /system/lib64/libfruit.so \
- -I /system/lib64/libgflags.so \
- -I /system/lib64/libkeymaster4_1support.so \
- -I /system/lib64/libkeymaster4support.so \
- -I /system/lib64/libkeymint.so \
- -I /system/lib64/libkeystore2_aaid.so \
- -I /system/lib64/libkeystore2_apc_compat.so \
- -I /system/lib64/libkeystore2_crypto.so \
- -I /system/lib64/libkeystore-attestation-application-id.so \
- -I /system/lib64/libkm_compat_service.so \
- -I /system/lib64/libkm_compat.so \
- -I /system/lib64/vndk-29 \
- -I /system/lib64/vndk-sp-29 \
- -I /system/lib/vndk-29 \
- -I /system/lib/vndk-sp-29 \
- -I /system/usr/icu"
+ diff_excludes[system]="-I /system/bin/hwservicemanager"
# Example output of dump.erofs is as below, and the data used in the test start
# at line 11. Column 1 is inode id, column 2 is inode type and column 3 is name.
diff --git a/ui/build/config.go b/ui/build/config.go
index 5d1505a..084d28d 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -70,7 +70,6 @@
checkbuild bool
dist bool
jsonModuleGraph bool
- apiBp2build bool // Generate BUILD files for Soong modules that contribute APIs
bp2build bool
queryview bool
reportMkMetrics bool // Collect and report mk2bp migration progress metrics.
@@ -869,8 +868,6 @@
c.jsonModuleGraph = true
} else if arg == "bp2build" {
c.bp2build = true
- } else if arg == "api_bp2build" {
- c.apiBp2build = true
} else if arg == "queryview" {
c.queryview = true
} else if arg == "soong_docs" {
@@ -970,7 +967,7 @@
return true
}
- if !c.JsonModuleGraph() && !c.Bp2Build() && !c.Queryview() && !c.SoongDocs() && !c.ApiBp2build() {
+ if !c.JsonModuleGraph() && !c.Bp2Build() && !c.Queryview() && !c.SoongDocs() {
// Command line was empty, the default Ninja target is built
return true
}
@@ -1068,10 +1065,6 @@
return shared.JoinPath(c.SoongOutDir(), "queryview.marker")
}
-func (c *configImpl) ApiBp2buildMarkerFile() string {
- return shared.JoinPath(c.SoongOutDir(), "api_bp2build.marker")
-}
-
func (c *configImpl) ModuleGraphFile() string {
return shared.JoinPath(c.SoongOutDir(), "module-graph.json")
}
@@ -1113,10 +1106,6 @@
return c.bp2build
}
-func (c *configImpl) ApiBp2build() bool {
- return c.apiBp2build
-}
-
func (c *configImpl) Queryview() bool {
return c.queryview
}
@@ -1308,7 +1297,7 @@
func (c *configImpl) UseRBE() bool {
// These alternate modes of running Soong do not use RBE / reclient.
- if c.Bp2Build() || c.Queryview() || c.ApiBp2build() || c.JsonModuleGraph() {
+ if c.Bp2Build() || c.Queryview() || c.JsonModuleGraph() {
return false
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index b8543d9..44c20a0 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -41,7 +41,6 @@
bp2buildWorkspaceTag = "bp2build_workspace"
jsonModuleGraphTag = "modulegraph"
queryviewTag = "queryview"
- apiBp2buildTag = "api_bp2build"
soongDocsTag = "soong_docs"
// bootstrapEpoch is used to determine if an incremental build is incompatible with the current
@@ -264,7 +263,6 @@
config.NamedGlobFile(bp2buildFilesTag),
config.NamedGlobFile(jsonModuleGraphTag),
config.NamedGlobFile(queryviewTag),
- config.NamedGlobFile(apiBp2buildTag),
config.NamedGlobFile(soongDocsTag),
}
}
@@ -305,9 +303,6 @@
}
queryviewDir := filepath.Join(config.SoongOutDir(), "queryview")
- // The BUILD files will be generated in out/soong/.api_bp2build (no symlinks to src files)
- // The final workspace will be generated in out/soong/api_bp2build
- apiBp2buildDir := filepath.Join(config.SoongOutDir(), ".api_bp2build")
pbfs := []PrimaryBuilderFactory{
{
@@ -355,15 +350,6 @@
),
},
{
- name: apiBp2buildTag,
- description: fmt.Sprintf("generating BUILD files for API contributions at %s", apiBp2buildDir),
- config: config,
- output: config.ApiBp2buildMarkerFile(),
- specificArgs: append(baseArgs,
- "--bazel_api_bp2build_dir", apiBp2buildDir,
- ),
- },
- {
name: soongDocsTag,
description: fmt.Sprintf("generating Soong docs at %s", config.SoongDocsHtml()),
config: config,
@@ -533,10 +519,6 @@
checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(queryviewTag))
}
- if config.ApiBp2build() {
- checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(apiBp2buildTag))
- }
-
if config.SoongDocs() {
checkEnvironmentFile(ctx, soongBuildEnv, config.UsedEnvFile(soongDocsTag))
}
@@ -608,10 +590,6 @@
targets = append(targets, config.QueryviewMarkerFile())
}
- if config.ApiBp2build() {
- targets = append(targets, config.ApiBp2buildMarkerFile())
- }
-
if config.SoongDocs() {
targets = append(targets, config.SoongDocsHtml())
}
diff --git a/ui/status/ninja.go b/ui/status/ninja.go
index fb760ac..7b25d50 100644
--- a/ui/status/ninja.go
+++ b/ui/status/ninja.go
@@ -40,10 +40,11 @@
}
n := &NinjaReader{
- status: status,
- fifo: fifo,
- done: make(chan bool),
- cancel: make(chan bool),
+ status: status,
+ fifo: fifo,
+ forceClose: make(chan bool),
+ done: make(chan bool),
+ cancelOpen: make(chan bool),
}
go n.run()
@@ -52,10 +53,11 @@
}
type NinjaReader struct {
- status ToolStatus
- fifo string
- done chan bool
- cancel chan bool
+ status ToolStatus
+ fifo string
+ forceClose chan bool
+ done chan bool
+ cancelOpen chan bool
}
const NINJA_READER_CLOSE_TIMEOUT = 5 * time.Second
@@ -63,18 +65,34 @@
// Close waits for NinjaReader to finish reading from the fifo, or 5 seconds.
func (n *NinjaReader) Close() {
// Signal the goroutine to stop if it is blocking opening the fifo.
- close(n.cancel)
+ close(n.cancelOpen)
+ // Ninja should already have exited or been killed, wait 5 seconds for the FIFO to be closed and any
+ // remaining messages to be processed through the NinjaReader.run goroutine.
timeoutCh := time.After(NINJA_READER_CLOSE_TIMEOUT)
-
select {
case <-n.done:
- // Nothing
+ return
case <-timeoutCh:
- n.status.Error(fmt.Sprintf("ninja fifo didn't finish after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
+ // Channel is not closed yet
}
- return
+ n.status.Error(fmt.Sprintf("ninja fifo didn't finish after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
+
+ // Force close the reader even if the FIFO didn't close.
+ close(n.forceClose)
+
+ // Wait again for the reader thread to acknowledge the close before giving up and assuming it isn't going
+ // to send anything else.
+ timeoutCh = time.After(NINJA_READER_CLOSE_TIMEOUT)
+ select {
+ case <-n.done:
+ return
+ case <-timeoutCh:
+ // Channel is not closed yet
+ }
+
+ n.status.Verbose(fmt.Sprintf("ninja fifo didn't finish even after force closing after %s", NINJA_READER_CLOSE_TIMEOUT.String()))
}
func (n *NinjaReader) run() {
@@ -98,7 +116,7 @@
select {
case f = <-fileCh:
// Nothing
- case <-n.cancel:
+ case <-n.cancelOpen:
return
}
@@ -108,33 +126,58 @@
running := map[uint32]*Action{}
+ msgChan := make(chan *ninja_frontend.Status)
+
+ // Read from the ninja fifo and decode the protobuf in a goroutine so the main NinjaReader.run goroutine
+ // can listen
+ go func() {
+ defer close(msgChan)
+ for {
+ size, err := readVarInt(r)
+ if err != nil {
+ if err != io.EOF {
+ n.status.Error(fmt.Sprintf("Got error reading from ninja: %s", err))
+ }
+ return
+ }
+
+ buf := make([]byte, size)
+ _, err = io.ReadFull(r, buf)
+ if err != nil {
+ if err == io.EOF {
+ n.status.Print(fmt.Sprintf("Missing message of size %d from ninja\n", size))
+ } else {
+ n.status.Error(fmt.Sprintf("Got error reading from ninja: %s", err))
+ }
+ return
+ }
+
+ msg := &ninja_frontend.Status{}
+ err = proto.Unmarshal(buf, msg)
+ if err != nil {
+ n.status.Print(fmt.Sprintf("Error reading message from ninja: %v", err))
+ continue
+ }
+
+ msgChan <- msg
+ }
+ }()
+
for {
- size, err := readVarInt(r)
- if err != nil {
- if err != io.EOF {
- n.status.Error(fmt.Sprintf("Got error reading from ninja: %s", err))
- }
- return
+ var msg *ninja_frontend.Status
+ var msgOk bool
+ select {
+ case <-n.forceClose:
+ // Close() has been called, but the reader goroutine didn't get EOF after 5 seconds
+ break
+ case msg, msgOk = <-msgChan:
+ // msg is ready or closed
}
- buf := make([]byte, size)
- _, err = io.ReadFull(r, buf)
- if err != nil {
- if err == io.EOF {
- n.status.Print(fmt.Sprintf("Missing message of size %d from ninja\n", size))
- } else {
- n.status.Error(fmt.Sprintf("Got error reading from ninja: %s", err))
- }
- return
+ if !msgOk {
+ // msgChan is closed
+ break
}
-
- msg := &ninja_frontend.Status{}
- err = proto.Unmarshal(buf, msg)
- if err != nil {
- n.status.Print(fmt.Sprintf("Error reading message from ninja: %v", err))
- continue
- }
-
// Ignore msg.BuildStarted
if msg.TotalEdges != nil {
n.status.SetTotalActions(int(msg.TotalEdges.GetTotalEdges()))