Merge "Support for incremetal platform prebuilt APIs" 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..43859ee 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -488,6 +488,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 +907,9 @@
"hal_unit_tests",
"merge_annotation_zips_test",
+
+ // java_resources with multiple resource_dirs
+ "emma",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -881,6 +933,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",
diff --git a/android/proto.go b/android/proto.go
index 6887900..b9365a7 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -281,6 +281,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()
@@ -333,6 +340,11 @@
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")
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index c501a7b..5c769a5 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -391,18 +391,56 @@
})
}
-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",
java_resource_dirs: ["res", "res1"],
}`,
- 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"`,
+ }),
+ 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"],
+}`,
+ 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",
+ ]`,
+ }),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
+ },
})
}
@@ -878,3 +916,57 @@
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"],
+ 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",
+ ]`,
+ }),
+ 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/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..3364401
--- /dev/null
+++ b/bp2build/rust_binary_conversion_test.go
@@ -0,0 +1,74 @@
+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..b860b76
--- /dev/null
+++ b/bp2build/rust_library_conversion_test.go
@@ -0,0 +1,96 @@
+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..82e080d
--- /dev/null
+++ b/bp2build/rust_proc_macro_conversion_test.go
@@ -0,0 +1,62 @@
+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) {
+ 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_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..a779c36
--- /dev/null
+++ b/bp2build/rust_protobuf_conversion_test.go
@@ -0,0 +1,46 @@
+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/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/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/sanitize.go b/cc/sanitize.go
index 8eea7db..f37b5c7 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1189,7 +1189,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 +1243,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 +1278,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 +1394,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 +1418,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/java/dex.go b/java/dex.go
index df501bf..cd13e39 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -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..4b01c31 100644
--- a/java/java.go
+++ b/java/java.go
@@ -21,6 +21,7 @@
import (
"fmt"
"path/filepath"
+ "sort"
"strings"
"android/soong/bazel"
@@ -2756,32 +2757,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 +2802,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),
}
}
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 9b1493f..f2bcccf 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -408,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..8b31c6c 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
}
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/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{}
}