Merge "Enable restat for kapt stubs rules" into main
diff --git a/README.md b/README.md
index 2d8f0af..22daa95 100644
--- a/README.md
+++ b/README.md
@@ -26,8 +26,6 @@
[bug tracker](https://issuetracker.google.com/issues/new?component=381517) or
or write us at android-building@googlegroups.com .
-For Googlers, see our [internal documentation](http://go/soong).
-
## Android.bp file format
By design, Android.bp files are very simple. There are no conditionals or
diff --git a/aconfig/Android.bp b/aconfig/Android.bp
index d2ddfdf..faa4ddb 100644
--- a/aconfig/Android.bp
+++ b/aconfig/Android.bp
@@ -32,6 +32,8 @@
"aconfig_values_test.go",
"aconfig_value_set_test.go",
"java_aconfig_library_test.go",
+ "cc_aconfig_library_test.go",
+ "rust_aconfig_library_test.go",
],
pluginFor: ["soong_build"],
}
diff --git a/aconfig/aconfig_declarations.go b/aconfig/aconfig_declarations.go
index 5cdf5b6..f19ddb8 100644
--- a/aconfig/aconfig_declarations.go
+++ b/aconfig/aconfig_declarations.go
@@ -15,16 +15,18 @@
package aconfig
import (
- "android/soong/android"
"fmt"
"strings"
+ "android/soong/android"
+ "android/soong/bazel"
"github.com/google/blueprint"
)
type DeclarationsModule struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.BazelModuleBase
// Properties for "aconfig_declarations"
properties struct {
@@ -47,8 +49,7 @@
android.InitAndroidModule(module)
android.InitDefaultableModule(module)
module.AddProperties(&module.properties)
- // TODO: bp2build
- //android.InitBazelModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -73,7 +74,9 @@
// RELEASE_ACONFIG_VALUE_SETS, and add any aconfig_values that
// match our package.
valuesFromConfig := ctx.Config().ReleaseAconfigValueSets()
- ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig...)
+ if valuesFromConfig != "" {
+ ctx.AddDependency(ctx.Module(), implicitValuesTag, valuesFromConfig)
+ }
}
func (module *DeclarationsModule) OutputFiles(tag string) (android.Paths, error) {
@@ -159,3 +162,26 @@
})
}
+
+type bazelAconfigDeclarationsAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Package string
+}
+
+func (module *DeclarationsModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ctx.ModuleType() != "aconfig_declarations" {
+ return
+ }
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, module.properties.Srcs))
+
+ attrs := bazelAconfigDeclarationsAttributes{
+ Srcs: srcs,
+ Package: module.properties.Package,
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "aconfig_declarations",
+ Bzl_load_location: "//build/bazel/rules/aconfig:aconfig_declarations.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, &attrs)
+}
diff --git a/aconfig/aconfig_value_set.go b/aconfig/aconfig_value_set.go
index 252908f..cd178d4 100644
--- a/aconfig/aconfig_value_set.go
+++ b/aconfig/aconfig_value_set.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/bazel"
"github.com/google/blueprint"
)
@@ -23,6 +24,7 @@
type ValueSetModule struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.BazelModuleBase
properties struct {
// aconfig_values modules
@@ -36,8 +38,7 @@
android.InitAndroidModule(module)
android.InitDefaultableModule(module)
module.AddProperties(&module.properties)
- // TODO: bp2build
- //android.InitBazelModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -90,3 +91,23 @@
AvailablePackages: packages,
})
}
+
+type bazelAconfigValueSetAttributes struct {
+ Values bazel.LabelListAttribute
+}
+
+func (module *ValueSetModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ctx.ModuleType() != "aconfig_value_set" {
+ return
+ }
+
+ attrs := bazelAconfigValueSetAttributes{
+ Values: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, module.properties.Values)),
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "aconfig_value_set",
+ Bzl_load_location: "//build/bazel/rules/aconfig:aconfig_value_set.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, &attrs)
+}
diff --git a/aconfig/aconfig_values.go b/aconfig/aconfig_values.go
index 91f1c90..03a930d 100644
--- a/aconfig/aconfig_values.go
+++ b/aconfig/aconfig_values.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/bazel"
"github.com/google/blueprint"
)
@@ -23,6 +24,7 @@
type ValuesModule struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.BazelModuleBase
properties struct {
// aconfig files, relative to this Android.bp file
@@ -39,8 +41,7 @@
android.InitAndroidModule(module)
android.InitDefaultableModule(module)
module.AddProperties(&module.properties)
- // TODO: bp2build
- //android.InitBazelModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -68,3 +69,27 @@
}
ctx.SetProvider(valuesProviderKey, providerData)
}
+
+type bazelAconfigValuesAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Package string
+}
+
+func (module *ValuesModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ctx.ModuleType() != "aconfig_values" {
+ return
+ }
+
+ srcs := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, module.properties.Srcs))
+
+ attrs := bazelAconfigValuesAttributes{
+ Srcs: srcs,
+ Package: module.properties.Package,
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "aconfig_values",
+ Bzl_load_location: "//build/bazel/rules/aconfig:aconfig_values.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: module.Name()}, &attrs)
+}
diff --git a/aconfig/cc_aconfig_library.go b/aconfig/cc_aconfig_library.go
index 14090bc..ec86af7 100644
--- a/aconfig/cc_aconfig_library.go
+++ b/aconfig/cc_aconfig_library.go
@@ -17,7 +17,9 @@
import (
"android/soong/android"
"android/soong/cc"
+
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"fmt"
"strings"
@@ -32,6 +34,9 @@
type CcAconfigLibraryProperties struct {
// name of the aconfig_declarations module to generate a library for
Aconfig_declarations string
+
+ // whether to generate test mode version of the library
+ Test *bool
}
type CcAconfigLibraryCallbacks struct {
@@ -113,6 +118,12 @@
}
declarations := ctx.OtherModuleProvider(declarationsModules[0], declarationsProviderKey).(declarationsProviderData)
+ var mode string
+ if proptools.Bool(this.properties.Test) {
+ mode = "test"
+ } else {
+ mode = "production"
+ }
ctx.Build(pctx, android.BuildParams{
Rule: cppRule,
Input: declarations.IntermediatePath,
@@ -123,6 +134,7 @@
Description: "cc_aconfig_library",
Args: map[string]string{
"gendir": this.generatedDir.String(),
+ "mode": mode,
},
})
}
diff --git a/aconfig/cc_aconfig_library_test.go b/aconfig/cc_aconfig_library_test.go
new file mode 100644
index 0000000..6f17c75
--- /dev/null
+++ b/aconfig/cc_aconfig_library_test.go
@@ -0,0 +1,67 @@
+// 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 aconfig
+
+import (
+ "fmt"
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+var codegenModeTestData = []struct {
+ setting, expected string
+}{
+ {"", "production"},
+ {"test: false,", "production"},
+ {"test: true,", "test"},
+}
+
+func TestCCCodegenMode(t *testing.T) {
+ for _, testData := range codegenModeTestData {
+ testCCCodegenModeHelper(t, testData.setting, testData.expected)
+ }
+}
+
+func testCCCodegenModeHelper(t *testing.T, bpMode string, ruleMode string) {
+ t.Helper()
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithAconfigBuildComponents,
+ cc.PrepareForTestWithCcDefaultModules).
+ ExtendWithErrorHandler(android.FixtureExpectsNoErrors).
+ RunTestWithBp(t, fmt.Sprintf(`
+ aconfig_declarations {
+ name: "my_aconfig_declarations",
+ package: "com.example.package",
+ srcs: ["foo.aconfig"],
+ }
+
+ cc_library {
+ name: "server_configurable_flags",
+ srcs: ["server_configurable_flags.cc"],
+ }
+
+ cc_aconfig_library {
+ name: "my_cc_aconfig_library",
+ aconfig_declarations: "my_aconfig_declarations",
+ %s
+ }
+ `, bpMode))
+
+ module := result.ModuleForTests("my_cc_aconfig_library", "android_arm64_armv8-a_shared")
+ rule := module.Rule("cc_aconfig_library")
+ android.AssertStringEquals(t, "rule must contain test mode", rule.Args["mode"], ruleMode)
+}
diff --git a/aconfig/init.go b/aconfig/init.go
index 797388d..3d62714 100644
--- a/aconfig/init.go
+++ b/aconfig/init.go
@@ -64,13 +64,14 @@
Command: `rm -rf ${gendir}` +
` && mkdir -p ${gendir}` +
` && ${aconfig} create-cpp-lib` +
+ ` --mode ${mode}` +
` --cache ${in}` +
` --out ${gendir}`,
CommandDeps: []string{
"$aconfig",
"$soong_zip",
},
- }, "gendir")
+ }, "gendir", "mode")
rustRule = pctx.AndroidStaticRule("rust_aconfig_library",
blueprint.RuleParams{
@@ -97,12 +98,12 @@
)
func init() {
- registerBuildComponents(android.InitRegistrationContext)
+ RegisterBuildComponents(android.InitRegistrationContext)
pctx.HostBinToolVariable("aconfig", "aconfig")
pctx.HostBinToolVariable("soong_zip", "soong_zip")
}
-func registerBuildComponents(ctx android.RegistrationContext) {
+func RegisterBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("aconfig_declarations", DeclarationsFactory)
ctx.RegisterModuleType("aconfig_values", ValuesFactory)
ctx.RegisterModuleType("aconfig_value_set", ValueSetFactory)
diff --git a/aconfig/rust_aconfig_library_test.go b/aconfig/rust_aconfig_library_test.go
index 17385c3..90b09c8 100644
--- a/aconfig/rust_aconfig_library_test.go
+++ b/aconfig/rust_aconfig_library_test.go
@@ -50,11 +50,11 @@
}
for _, variant := range variants {
- android.AssertStringEquals(
+ android.AssertStringListContains(
t,
"dylib variant builds from generated rust code",
+ variant.Rule("rustc").Implicits.RelativeToTop().Strings(),
"out/soong/.intermediates/libmy_rust_aconfig_library/android_arm64_armv8-a_source/gen/src/lib.rs",
- variant.Rule("rustc").Inputs[0].RelativeToTop().String(),
)
}
}
diff --git a/aconfig/testing.go b/aconfig/testing.go
index 60cefeb..f6489ec 100644
--- a/aconfig/testing.go
+++ b/aconfig/testing.go
@@ -20,7 +20,7 @@
"android/soong/android"
)
-var PrepareForTestWithAconfigBuildComponents = android.FixtureRegisterWithContext(registerBuildComponents)
+var PrepareForTestWithAconfigBuildComponents = android.FixtureRegisterWithContext(RegisterBuildComponents)
func runTest(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult {
return android.GroupFixturePreparers(PrepareForTestWithAconfigBuildComponents).
diff --git a/aidl_library/aidl_library.go b/aidl_library/aidl_library.go
index 7449d67..2c0aef7 100644
--- a/aidl_library/aidl_library.go
+++ b/aidl_library/aidl_library.go
@@ -64,7 +64,7 @@
Deps bazel.LabelListAttribute
}
-func (lib *AidlLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (lib *AidlLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
srcs := bazel.MakeLabelListAttribute(
android.BazelLabelForModuleSrc(
ctx,
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index fb2e0d7..5b77ba9 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -65,6 +65,7 @@
"build/bazel": Bp2BuildDefaultTrueRecursively,
"build/make/target/product/security": Bp2BuildDefaultTrue,
+ "build/make/tools": Bp2BuildDefaultTrue,
"build/make/tools/protos": Bp2BuildDefaultTrue,
"build/make/tools/releasetools": Bp2BuildDefaultTrue,
"build/make/tools/sbom": Bp2BuildDefaultTrue,
@@ -79,6 +80,9 @@
"build/soong/scripts": Bp2BuildDefaultTrueRecursively,
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
+ "cts/libs/json": Bp2BuildDefaultTrueRecursively,
+ "cts/tests/tests/gesture": Bp2BuildDefaultTrueRecursively,
+ "platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively,
"dalvik/tools/dexdeps": Bp2BuildDefaultTrueRecursively,
@@ -127,6 +131,7 @@
"external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively,
"external/auto/common": Bp2BuildDefaultTrueRecursively,
"external/auto/service": Bp2BuildDefaultTrueRecursively,
+ "external/auto/value": Bp2BuildDefaultTrueRecursively,
"external/boringssl": Bp2BuildDefaultTrueRecursively,
"external/bouncycastle": Bp2BuildDefaultTrue,
"external/brotli": Bp2BuildDefaultTrue,
@@ -178,6 +183,7 @@
"external/libjpeg-turbo": Bp2BuildDefaultTrueRecursively,
"external/libmpeg2": Bp2BuildDefaultTrueRecursively,
"external/libpng": Bp2BuildDefaultTrueRecursively,
+ "external/libphonenumber": Bp2BuildDefaultTrueRecursively,
"external/libvpx": Bp2BuildDefaultTrueRecursively,
"external/libyuv": Bp2BuildDefaultTrueRecursively,
"external/lz4/lib": Bp2BuildDefaultTrue,
@@ -221,6 +227,8 @@
"frameworks/av/media/module/foundation": Bp2BuildDefaultTrueRecursively,
"frameworks/av/media/module/minijail": Bp2BuildDefaultTrueRecursively,
"frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively,
+ "frameworks/base/apex/jobscheduler/service/jni": Bp2BuildDefaultTrueRecursively,
+ "frameworks/base/core/java": Bp2BuildDefaultTrue,
"frameworks/base/libs/androidfw": Bp2BuildDefaultTrue,
"frameworks/base/libs/services": Bp2BuildDefaultTrue,
"frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
@@ -231,17 +239,21 @@
"frameworks/base/tools/aapt": Bp2BuildDefaultTrue,
"frameworks/base/tools/aapt2": Bp2BuildDefaultTrue,
"frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively,
+ "frameworks/base/tools/locked_region_code_injection": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively,
"frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue,
"frameworks/libs/modules-utils/build": Bp2BuildDefaultTrueRecursively,
+ "frameworks/libs/modules-utils/java": Bp2BuildDefaultTrue,
"frameworks/libs/net/common/native": Bp2BuildDefaultTrueRecursively, // TODO(b/296014682): Remove this path
"frameworks/native": Bp2BuildDefaultTrue,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/libs/binder": Bp2BuildDefaultTrue,
"frameworks/native/libs/gui": Bp2BuildDefaultTrue,
"frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/nativebase": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/permission": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/libs/ui": Bp2BuildDefaultTrue,
"frameworks/native/libs/vr": Bp2BuildDefaultTrueRecursively,
"frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue,
"frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue,
@@ -285,13 +297,9 @@
"hardware/interfaces/health/2.1": Bp2BuildDefaultTrue,
"hardware/interfaces/health/aidl": Bp2BuildDefaultTrue,
"hardware/interfaces/health/utils": Bp2BuildDefaultTrueRecursively,
- "hardware/interfaces/media/1.0": Bp2BuildDefaultTrue,
- "hardware/interfaces/media/bufferpool": Bp2BuildDefaultTrueRecursively,
+ "hardware/interfaces/media": Bp2BuildDefaultTrueRecursively,
"hardware/interfaces/media/bufferpool/aidl/default/tests": Bp2BuildDefaultFalseRecursively,
- "hardware/interfaces/media/c2/1.0": Bp2BuildDefaultTrue,
- "hardware/interfaces/media/c2/1.1": Bp2BuildDefaultTrue,
- "hardware/interfaces/media/c2/1.2": Bp2BuildDefaultTrue,
- "hardware/interfaces/media/omx/1.0": Bp2BuildDefaultTrue,
+ "hardware/interfaces/media/omx/1.0/vts": Bp2BuildDefaultFalseRecursively,
"hardware/interfaces/neuralnetworks": Bp2BuildDefaultTrueRecursively,
"hardware/interfaces/neuralnetworks/aidl/vts": Bp2BuildDefaultFalseRecursively,
"hardware/interfaces/neuralnetworks/1.0/vts": Bp2BuildDefaultFalseRecursively,
@@ -372,6 +380,7 @@
"system/core/mkbootfs": Bp2BuildDefaultTrueRecursively,
"system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively,
"system/core/property_service/libpropertyinfoserializer": Bp2BuildDefaultTrueRecursively,
+ "system/core/trusty/libtrusty": Bp2BuildDefaultTrue,
"system/extras/f2fs_utils": Bp2BuildDefaultTrueRecursively,
"system/extras/toolchain-extras": Bp2BuildDefaultTrue,
"system/extras/verity": Bp2BuildDefaultTrueRecursively,
@@ -380,6 +389,7 @@
"system/libartpalette": Bp2BuildDefaultTrueRecursively,
"system/libbase": Bp2BuildDefaultTrueRecursively,
"system/libfmq": Bp2BuildDefaultTrue,
+ "system/libhidl": Bp2BuildDefaultTrue,
"system/libhidl/libhidlmemory": Bp2BuildDefaultTrue,
"system/libhidl/transport": Bp2BuildDefaultTrue,
"system/libhidl/transport/allocator/1.0": Bp2BuildDefaultTrue,
@@ -414,17 +424,19 @@
"system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue,
"system/tools/aidl/metadata": Bp2BuildDefaultTrue,
"system/tools/hidl/metadata": Bp2BuildDefaultTrue,
+ "system/tools/hidl/utils": Bp2BuildDefaultTrue,
"system/tools/mkbootimg": Bp2BuildDefaultTrueRecursively,
"system/tools/sysprop": Bp2BuildDefaultTrue,
"system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively,
"system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively,
- "tools/apifinder": Bp2BuildDefaultTrue,
- "tools/apksig": Bp2BuildDefaultTrue,
- "tools/external_updater": Bp2BuildDefaultTrueRecursively,
- "tools/metalava": Bp2BuildDefaultTrue,
- "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
- "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
+ "tools/apifinder": Bp2BuildDefaultTrue,
+ "tools/apksig": Bp2BuildDefaultTrue,
+ "tools/external_updater": Bp2BuildDefaultTrueRecursively,
+ "tools/metalava": Bp2BuildDefaultTrueRecursively,
+ "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
+ "tools/platform-compat/java/androidprocessor": Bp2BuildDefaultTrueRecursively,
+ "tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
}
Bp2buildKeepExistingBuildFile = map[string]bool{
@@ -547,6 +559,7 @@
"remote-color-resources-compile-colors",
// framework-minus-apex
+ "ImmutabilityAnnotationProcessor",
"android.mime.types.minimized",
"debian.mime.types.minimized",
"framework-javastream-protos",
@@ -556,10 +569,8 @@
"apache-commons-math",
"cbor-java",
"icu4j_calendar_astronomer",
- "json",
"remote-color-resources-compile-public",
"statslog-art-java-gen",
- "statslog-framework-java-gen",
"AndroidCommonLint",
"ImmutabilityAnnotation",
@@ -592,10 +603,6 @@
"libandroid_runtime_lazy",
"libandroid_runtime_vm_headers",
"libaudioclient_aidl_conversion_util",
- "libbinder",
- "libbinder_device_interface_sources",
- "libbinder_aidl",
- "libbinder_headers",
"libbinder_headers_platform_shared",
"libbinderthreadstateutils",
"libbluetooth-types-header",
@@ -628,9 +635,6 @@
"libtextclassifier_hash_static",
"libtflite_kernel_utils",
"libtinyxml2",
- "libui",
- "libui-types",
- "libui_headers",
"libvorbisidec",
"media_ndk_headers",
"media_plugin_headers",
@@ -638,8 +642,6 @@
"mediaswcodec.xml",
"neuralnetworks_types",
"libneuralnetworks_common",
- // packagemanager_aidl_interface is created implicitly in packagemanager_aidl module
- "packagemanager_aidl_interface",
"philox_random",
"philox_random_headers",
"server_configurable_flags",
@@ -681,9 +683,6 @@
//external/fec
"libfec_rs",
- //frameworks/base/core/java
- "IDropBoxManagerService_aidl",
-
//system/extras/ext4_utils
"libext4_utils",
"mke2fs_conf",
@@ -704,10 +703,6 @@
"car-ui-androidx-lifecycle-common-nodeps",
"car-ui-androidx-constraintlayout-solver-nodeps",
- //system/libhidl
- "libhidlbase", // needed by cc_hidl_library
- "libhidl_gtest_helper",
-
//frameworks/native/libs/input
"inputconstants_aidl",
@@ -716,11 +711,6 @@
"libusb",
- // needed by liblogd
- "ILogcatManagerService_aidl",
- "libincremental_aidl-cpp",
- "incremental_aidl",
-
//frameworks/native/cmds/cmd
"libcmd",
@@ -866,11 +856,6 @@
"aidl",
"libaidl-common",
- // java_resources containing only a single filegroup
- "libauto_value_plugin",
- "auto_value_plugin_resources",
- "auto_value_extension",
-
// Used by xsd_config
"xsdc",
@@ -910,22 +895,45 @@
"merge_annotation_zips_test",
- // bouncycastle dep
- "platform-test-annotations",
-
// java_resources with multiple resource_dirs
"emma",
+
+ // NDK STL
+ "ndk_libc++abi",
+ "ndk_libunwind",
+ "ndk_libc++_static",
+ "ndk_libc++_shared",
+ "ndk_system",
+
+ // allowlist //prebuilts/common/misc/androidx-test/...
+ "androidx.test.runner",
+ "androidx.test.runner-nodeps",
+ "androidx.test.services.storage",
+ "androidx.test.services.storage-nodeps",
+ "androidx.test.monitor",
+ "androidx.test.monitor-nodeps",
+ "androidx.test.annotation",
+ "androidx.test.annotation-nodeps",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
+ "aconfig_declarations",
+ "aconfig_value_set",
+ "aconfig_values",
"aidl_interface_headers",
"bpf",
+ "cc_prebuilt_library",
+ "cc_prebuilt_library_headers",
+ "cc_prebuilt_library_shared",
+ "cc_prebuilt_library_static",
"combined_apis",
- "license",
- "linker_config",
+ "droiddoc_exported_dir",
"java_import",
"java_import_host",
"java_sdk_library",
+ "java_sdk_library_import",
+ "license",
+ "linker_config",
"sysprop_library",
"xsd_config",
}
@@ -1003,7 +1011,6 @@
"conscrypt-for-host", // TODO(b/210751803), we don't handle path property for filegroups
"host-libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups
"libprotobuf-internal-python-srcs", // TODO(b/210751803), we don't handle path property for filegroups
- "libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups
"libprotobuf-java-util-full", // TODO(b/210751803), we don't handle path property for filegroups
// go deps:
@@ -1016,15 +1023,15 @@
"libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported
// unconverted deps
- "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex
+ "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
"adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
"android_icu4j_srcgen", // depends on unconverted modules: currysrc
"android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc
"apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex
"apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full
+ "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex
"art-script", // depends on unconverted modules: dalvikvm, dex2oat
"bin2c_fastdeployagent", // depends on unconverted modules: deployagent
- "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
"com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
"currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
"dex2oat-script", // depends on unconverted modules: dex2oat
@@ -1034,12 +1041,12 @@
"jacoco-stubs", // b/245767077, depends on droidstubs
"libapexutil", // depends on unconverted modules: apex-info-list-tinyxml
"libart", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
+ "libart-runtime", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
+ "libart-runtime-for-test", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
"libart-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libart-compiler, libdexfile, libprofile, libartbase, libartbase-art-gtest
"libart_headers", // depends on unconverted modules: art_libartbase_headers
"libartbase-art-gtest", // depends on unconverted modules: libgtest_isolated, libart, libart-compiler, libdexfile, libprofile
"libartbased-art-gtest", // depends on unconverted modules: libgtest_isolated, libartd, libartd-compiler, libdexfiled, libprofiled
- "libart-runtime", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
- "libart-runtime-for-test", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
"libartd", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api
"libartd-runtime", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api
"libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest
@@ -1051,6 +1058,7 @@
"libgmock_ndk", // depends on unconverted modules: libgtest_ndk_c++
"libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk
"libnativetesthelper_jni", // depends on unconverted modules: libgtest_ndk_c++
+ "libphonenumber_test", // depends on android.test.mock
"libstatslog", // depends on unconverted modules: libstatspull, statsd-aidl-ndk
"libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h
"linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
@@ -1636,10 +1644,6 @@
// depends on libart-unstripped and new module type llvm_prebuilt_build_tool
"check_cfi",
- // TODO(b/297070571): cannot convert prebuilts_etc module which possess identical name and src properties
- "boringssl_self_test.zygote64.rc",
- "boringssl_self_test.zygote64_32.rc",
-
// depends on unconverted module tradefed
"HelloWorldPerformanceTest",
@@ -1650,6 +1654,27 @@
// Depends on the module defined in the directory not bp2build default allowed
"ota_from_raw_img",
+
+ // TODO(b/299924782): Fix linking error
+ "libbinder_on_trusty_mock",
+
+ // TODO(b/299943581): Depends on aidl filegroups with implicit headers
+ "libdataloader_aidl-cpp",
+ "libincremental_manager_aidl-cpp",
+
+ // TODO(b/299974637) Fix linking error
+ "libbinder_rpc_unstable",
+
+ // TODO(b/297356704) sdk_version is unset.
+ "VendorAtomCodeGenJavaTest",
+
+ // android_test from allowlisted packages, but with unconverted deps
+ "MtsLibnativehelperLazyTestCases",
+ "ObjenesisTck",
+ "DevCodelabTest",
+ "MtsTimeZoneDataTestCases",
+ "NanoAndroidTest",
+ "MtsLibnativehelperTestCases",
}
// Bazel prod-mode allowlist. Modules in this list are built by Bazel
diff --git a/android/apex.go b/android/apex.go
index 6119b08..d84499b 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -934,6 +934,19 @@
})
}
+// Construct ApiLevel object from min_sdk_version string value
+func MinSdkVersionFromValue(ctx EarlyModuleContext, value string) ApiLevel {
+ if value == "" {
+ return NoneApiLevel
+ }
+ apiLevel, err := ApiLevelFromUser(ctx, value)
+ if err != nil {
+ ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
+ return NoneApiLevel
+ }
+ return apiLevel
+}
+
// Implemented by apexBundle.
type ApexTestInterface interface {
// Return true if the apex bundle is an apex_test
diff --git a/android/bazel.go b/android/bazel.go
index 94b36e3..8634dab 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -162,7 +162,7 @@
// Modules must implement this function to be bp2build convertible. The function
// must either create at least one Bazel target module (using ctx.CreateBazelTargetModule or
// its related functions), or declare itself unconvertible using ctx.MarkBp2buildUnconvertible.
- ConvertWithBp2build(ctx TopDownMutatorContext)
+ ConvertWithBp2build(ctx Bp2buildMutatorContext)
// namespacedVariableProps is a map from a soong config variable namespace
// (e.g. acme, android) to a map of interfaces{}, which are really
@@ -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_paths.go b/android/bazel_paths.go
index 86829ce..ac862d4 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -585,7 +585,7 @@
// For the first two cases, they are defined using the label attribute. For the third case,
// it's defined with the string attribute.
func BazelStringOrLabelFromProp(
- ctx TopDownMutatorContext,
+ ctx Bp2buildMutatorContext,
propToDistinguish *string) (bazel.LabelAttribute, bazel.StringAttribute) {
var labelAttr bazel.LabelAttribute
diff --git a/android/bazel_test.go b/android/bazel_test.go
index 194a6b3..e0145b5 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",
@@ -469,7 +469,7 @@
return m
}
-func (m *mixedBuildModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (m *mixedBuildModule) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
}
func (m *mixedBuildModule) DepsMutator(ctx BottomUpMutatorContext) {
diff --git a/android/config.go b/android/config.go
index 1a3b539..445c6cd 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
@@ -201,9 +197,22 @@
return c.config.productVariables.ReleaseVersion
}
-// The flag values files passed to aconfig, derived from RELEASE_VERSION
-func (c Config) ReleaseAconfigValueSets() []string {
- return c.config.productVariables.ReleaseAconfigValueSets
+// The aconfig value set passed to aconfig, derived from RELEASE_VERSION
+func (c Config) ReleaseAconfigValueSets() string {
+ // This logic to handle both Soong module name and bazel target is temporary in order to
+ // provide backward compatibility where aosp and vendor/google both have the release
+ // aconfig value set but can't be updated at the same time to use bazel target
+ value := strings.Split(c.config.productVariables.ReleaseAconfigValueSets, ":")
+ value_len := len(value)
+ if value_len > 2 {
+ // This shouldn't happen as this should be either a module name or a bazel target path.
+ panic(fmt.Errorf("config file: invalid value for release aconfig value sets: %s",
+ c.config.productVariables.ReleaseAconfigValueSets))
+ }
+ if value_len > 0 {
+ return value[value_len-1]
+ }
+ return ""
}
// The flag default permission value passed to aconfig
@@ -641,7 +650,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 +1670,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 {
diff --git a/android/defaults.go b/android/defaults.go
index e0e6e5c..cc723f7 100644
--- a/android/defaults.go
+++ b/android/defaults.go
@@ -180,7 +180,7 @@
// ConvertWithBp2build to fulfill Bazelable interface; however, at this time defaults module are
// *NOT* converted with bp2build
-func (defaultable *DefaultsModuleBase) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (defaultable *DefaultsModuleBase) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
// Defaults types are never convertible.
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
}
diff --git a/android/depset_generic.go b/android/depset_generic.go
index 45c1937..9f07596 100644
--- a/android/depset_generic.go
+++ b/android/depset_generic.go
@@ -95,6 +95,12 @@
}
}
+// AddDirectToDepSet returns a new DepSet with additional elements added to its direct set.
+// The transitive sets remain untouched.
+func AddDirectToDepSet[T depSettableType](d *DepSet[T], direct ...T) *DepSet[T] {
+ return NewDepSet[T](d.order, Concat(d.direct, direct), d.transitive)
+}
+
// DepSetBuilder is used to create an immutable DepSet.
type DepSetBuilder[T depSettableType] struct {
order DepSetOrder
@@ -188,3 +194,14 @@
}
return list
}
+
+// ToListDirect returns the direct elements of a DepSet flattened to a list.
+func (d *DepSet[T]) ToListDirect() []T {
+ if d == nil {
+ return nil
+ }
+ list := make([]T, len(d.direct))
+ copy(list, d.direct)
+ list = firstUniqueInPlace(list)
+ return list
+}
diff --git a/android/filegroup.go b/android/filegroup.go
index 6cc9232..a4bbcae 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -93,7 +93,7 @@
}
// ConvertWithBp2build performs bp2build conversion of filegroup
-func (fg *fileGroup) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (fg *fileGroup) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
srcs := bazel.MakeLabelListAttribute(
BazelLabelForModuleSrcExcludes(ctx, fg.properties.Srcs, fg.properties.Exclude_srcs))
@@ -209,10 +209,10 @@
}
type FileGroupPath interface {
- GetPath(ctx TopDownMutatorContext) string
+ GetPath(ctx Bp2buildMutatorContext) string
}
-func (fg *fileGroup) GetPath(ctx TopDownMutatorContext) string {
+func (fg *fileGroup) GetPath(ctx Bp2buildMutatorContext) string {
if fg.properties.Path != nil {
return *fg.properties.Path
}
diff --git a/android/fixture.go b/android/fixture.go
index 6660afd..5ad47e8 100644
--- a/android/fixture.go
+++ b/android/fixture.go
@@ -275,6 +275,15 @@
})
}
+// Sync the mock filesystem with the current config, then modify the context,
+// This allows context modification that requires filesystem access.
+func FixtureModifyContextWithMockFs(mutator func(ctx *TestContext)) FixturePreparer {
+ return newSimpleFixturePreparer(func(f *fixture) {
+ f.config.mockFileSystem("", f.mockFS)
+ mutator(f.ctx)
+ })
+}
+
func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) FixturePreparer {
return FixtureModifyContext(func(ctx *TestContext) { registeringFunc(ctx) })
}
diff --git a/android/license.go b/android/license.go
index a09422b..76f5115 100644
--- a/android/license.go
+++ b/android/license.go
@@ -71,7 +71,7 @@
Visibility []string
}
-func (m *licenseModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (m *licenseModule) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
attrs := &bazelLicenseAttributes{
License_kinds: m.properties.License_kinds,
Copyright_notice: m.properties.Copyright_notice,
diff --git a/android/license_kind.go b/android/license_kind.go
index 24b91e4..78df938 100644
--- a/android/license_kind.go
+++ b/android/license_kind.go
@@ -50,7 +50,7 @@
Visibility []string
}
-func (m *licenseKindModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (m *licenseKindModule) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
attrs := &bazelLicenseKindAttributes{
Conditions: m.properties.Conditions,
Url: m.properties.Url,
diff --git a/android/module.go b/android/module.go
index f9ea897..f4b51ea 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1418,15 +1418,50 @@
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 {
result := bazel.LabelListAttribute{}
- productVariableProps := ProductVariableProperties(ctx, ctx.Module())
+ productVariableProps, errs := ProductVariableProperties(ctx, ctx.Module())
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
if productConfigProps, exists := productVariableProps["Enabled"]; exists {
for productConfigProp, prop := range productConfigProps {
flag, ok := prop.(*bool)
@@ -1604,15 +1639,23 @@
}
func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
- if m.commonProperties.BazelConversionStatus.UnconvertedReason != nil {
- panic(fmt.Errorf("bp2build: module '%s' marked unconvertible and also is converted", m.Name()))
+ reason := m.commonProperties.BazelConversionStatus.UnconvertedReason
+ if reason != nil {
+ panic(fmt.Errorf("bp2build: internal error trying to convert module '%s' marked unconvertible. Reason type %d: %s",
+ m.Name(),
+ reason.ReasonType,
+ reason.Detail))
}
m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info)
}
func (m *ModuleBase) setBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) {
if len(m.commonProperties.BazelConversionStatus.Bp2buildInfo) > 0 {
- panic(fmt.Errorf("bp2build: module '%s' marked unconvertible and also is converted", m.Name()))
+ fmt.Println(m.commonProperties.BazelConversionStatus.Bp2buildInfo)
+ panic(fmt.Errorf("bp2build: internal error trying to mark converted module '%s' as unconvertible. Reason type %d: %s",
+ m.Name(),
+ reasonType,
+ detail))
}
m.commonProperties.BazelConversionStatus.UnconvertedReason = &UnconvertedReason{
ReasonType: int(reasonType),
diff --git a/android/mutator.go b/android/mutator.go
index 41477b8..0284794 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -15,9 +15,10 @@
package android
import (
+ "path/filepath"
+
"android/soong/bazel"
"android/soong/ui/metrics/bp2build_metrics_proto"
- "path/filepath"
"github.com/google/blueprint"
)
@@ -229,37 +230,8 @@
// A minimal context for Bp2build conversion
type Bp2buildMutatorContext interface {
BazelConversionPathContext
-
- CreateBazelTargetModule(bazel.BazelTargetModuleProperties, CommonAttributes, interface{})
- CreateBazelTargetModuleWithRestrictions(bazel.BazelTargetModuleProperties, CommonAttributes, interface{}, bazel.BoolAttribute)
-}
-
-// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
-// into Bazel BUILD targets that should run prior to deps and conversion.
-func PreArchBp2BuildMutators(f RegisterMutatorFunc) {
- bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
-}
-
-type BaseMutatorContext interface {
- BaseModuleContext
-
- // MutatorName returns the name that this mutator was registered with.
- MutatorName() string
-
- // Rename all variants of a module. The new name is not visible to calls to ModuleName,
- // AddDependency or OtherModuleName until after this mutator pass is complete.
- Rename(name string)
-}
-
-type TopDownMutator func(TopDownMutatorContext)
-
-type TopDownMutatorContext interface {
BaseMutatorContext
- // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
- // the specified property structs to it as if the properties were set in a blueprint file.
- CreateModule(ModuleFactory, ...interface{}) Module
-
// CreateBazelTargetModule creates a BazelTargetModule by calling the
// factory method, just like in CreateModule, but also requires
// BazelTargetModuleProperties containing additional metadata for the
@@ -290,6 +262,34 @@
CreateBazelConfigSetting(csa bazel.ConfigSettingAttributes, ca CommonAttributes, dir string)
}
+// PreArchBp2BuildMutators adds mutators to be register for converting Android Blueprint modules
+// into Bazel BUILD targets that should run prior to deps and conversion.
+func PreArchBp2BuildMutators(f RegisterMutatorFunc) {
+ bp2buildPreArchMutators = append(bp2buildPreArchMutators, f)
+}
+
+type BaseMutatorContext interface {
+ BaseModuleContext
+
+ // MutatorName returns the name that this mutator was registered with.
+ MutatorName() string
+
+ // Rename all variants of a module. The new name is not visible to calls to ModuleName,
+ // AddDependency or OtherModuleName until after this mutator pass is complete.
+ Rename(name string)
+}
+
+type TopDownMutator func(TopDownMutatorContext)
+
+type TopDownMutatorContext interface {
+ BaseMutatorContext
+ Bp2buildMutatorContext
+
+ // CreateModule creates a new module by calling the factory method for the specified moduleType, and applies
+ // the specified property structs to it as if the properties were set in a blueprint file.
+ CreateModule(ModuleFactory, ...interface{}) Module
+}
+
type topDownMutatorContext struct {
bp blueprint.TopDownMutatorContext
baseModuleContext
diff --git a/android/package.go b/android/package.go
index 7fbc700..ce0b150 100644
--- a/android/package.go
+++ b/android/package.go
@@ -54,7 +54,7 @@
var _ Bazelable = &packageModule{}
-func (p *packageModule) ConvertWithBp2build(ctx TopDownMutatorContext) {
+func (p *packageModule) ConvertWithBp2build(ctx Bp2buildMutatorContext) {
defaultPackageMetadata := bazel.MakeLabelListAttribute(BazelLabelForModuleDeps(ctx, p.properties.Default_applicable_licenses))
// If METADATA file exists in the package, add it to package(default_package_metadata=) using a
// filegroup(name="default_metadata_file") which can be accessed later on each module in Bazel
diff --git a/android/paths.go b/android/paths.go
index 325a953..d4b1d6e 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -171,6 +171,9 @@
// Base returns the last element of the path
Base() string
+ // Dir returns a path pointing the directory containing the path
+ Dir() Path
+
// Rel returns the portion of the path relative to the directory it was created from. For
// example, Rel on a PathsForModuleSrc would return the path relative to the module source
// directory, and OutputPath.Join("foo").Rel() would return "foo".
@@ -1012,6 +1015,12 @@
return filepath.Base(p.path)
}
+func (p basePath) Dir() Path {
+ p.path = filepath.Dir(p.path)
+ p.rel = filepath.Dir(p.rel)
+ return p
+}
+
func (p basePath) Rel() string {
if p.rel != "" {
return p.rel
@@ -1046,6 +1055,11 @@
return p
}
+func (p SourcePath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ return p
+}
+
// safePathForSource is for paths that we expect are safe -- only for use by go
// code that is embedding ninja variables in paths
func safePathForSource(ctx PathContext, pathComponents ...string) (SourcePath, error) {
@@ -1248,6 +1262,12 @@
return p
}
+func (p OutputPath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ p.fullPath = filepath.Dir(p.fullPath)
+ return p
+}
+
func (p OutputPath) WithoutRel() OutputPath {
p.basePath.rel = filepath.Base(p.basePath.path)
return p
@@ -1280,6 +1300,11 @@
basePath
}
+func (p toolDepPath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ return p
+}
+
func (t toolDepPath) RelativeToTop() Path {
ensureTestOnly()
return t
@@ -1463,6 +1488,11 @@
OutputPath
}
+func (p ModuleOutPath) Dir() Path {
+ p.OutputPath = p.OutputPath.Dir().(OutputPath)
+ return p
+}
+
func (p ModuleOutPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop()
return p
@@ -1507,6 +1537,11 @@
ModuleOutPath
}
+func (p ModuleGenPath) Dir() Path {
+ p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
+ return p
+}
+
func (p ModuleGenPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop()
return p
@@ -1546,6 +1581,11 @@
ModuleOutPath
}
+func (p ModuleObjPath) Dir() Path {
+ p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
+ return p
+}
+
func (p ModuleObjPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop()
return p
@@ -1570,6 +1610,11 @@
ModuleOutPath
}
+func (p ModuleResPath) Dir() Path {
+ p.ModuleOutPath = p.ModuleOutPath.Dir().(ModuleOutPath)
+ return p
+}
+
func (p ModuleResPath) RelativeToTop() Path {
p.OutputPath = p.outputPathRelativeToTop()
return p
@@ -1606,6 +1651,11 @@
makePath bool
}
+func (p InstallPath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ return p
+}
+
// Will panic if called from outside a test environment.
func ensureTestOnly() {
if PrefixInList(os.Args, "-test.") {
@@ -1922,6 +1972,11 @@
basePath
}
+func (p PhonyPath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ return p
+}
+
func (p PhonyPath) writablePath() {}
func (p PhonyPath) getSoongOutDir() string {
@@ -1947,6 +2002,11 @@
basePath
}
+func (p testPath) Dir() Path {
+ p.basePath = p.basePath.Dir().(basePath)
+ return p
+}
+
func (p testPath) RelativeToTop() Path {
ensureTestOnly()
return p
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index aeae20f..c00b22b 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -14,10 +14,14 @@
package android
-import "path/filepath"
+import (
+ "path/filepath"
+
+ "github.com/google/blueprint"
+)
func init() {
- RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
+ RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool)
}
type prebuiltBuildToolProperties struct {
@@ -55,6 +59,13 @@
}
}
+type PrebuiltBuildToolInfo struct {
+ Src Path
+ Deps Paths
+}
+
+var PrebuiltBuildToolInfoProvider = blueprint.NewProvider(PrebuiltBuildToolInfo{})
+
func (t *prebuiltBuildTool) GenerateAndroidBuildActions(ctx ModuleContext) {
sourcePath := t.prebuilt.SingleSourcePath(ctx)
installedPath := PathForModuleOut(ctx, t.BaseModuleName())
@@ -82,6 +93,11 @@
}
t.toolPath = OptionalPathForPath(installedPath)
+
+ ctx.SetProvider(PrebuiltBuildToolInfoProvider, PrebuiltBuildToolInfo{
+ Src: sourcePath,
+ Deps: deps,
+ })
}
func (t *prebuiltBuildTool) MakeVars(ctx MakeVarsModuleContext) {
@@ -101,10 +117,6 @@
// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
// in genrules with the "tools" property.
-func prebuiltBuildToolFactory() Module {
- return NewPrebuiltBuildTool()
-}
-
func NewPrebuiltBuildTool() Module {
module := &prebuiltBuildTool{}
module.AddProperties(&module.properties)
diff --git a/android/register.go b/android/register.go
index 64b0207..f1c2986 100644
--- a/android/register.go
+++ b/android/register.go
@@ -15,9 +15,13 @@
package android
import (
+ "bufio"
"fmt"
+ "path/filepath"
"reflect"
+ "regexp"
+ "android/soong/shared"
"github.com/google/blueprint"
)
@@ -197,11 +201,54 @@
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)
+// RegisterExistingBazelTargets reads Bazel BUILD.bazel and BUILD files under
+// the workspace, and returns a map containing names of Bazel targets defined in
+// these BUILD files.
+// For example, maps "//foo/bar" to ["baz", "qux"] if `//foo/bar:{baz,qux}` exist.
+func (c *Context) RegisterExistingBazelTargets(topDir string, existingBazelFiles []string) error {
+ result := map[string][]string{}
+
+ // Search for instances of `name = "$NAME"` (with arbitrary spacing).
+ targetNameRegex := regexp.MustCompile(`(?m)^\s*name\s*=\s*\"([^\"]+)\"`)
+
+ parseBuildFile := func(path string) error {
+ fullPath := shared.JoinPath(topDir, path)
+ sourceDir := filepath.Dir(path)
+
+ fileInfo, err := c.Config().fs.Stat(fullPath)
+ if err != nil {
+ return fmt.Errorf("Error accessing Bazel file '%s': %s", path, err)
+ }
+ if !fileInfo.IsDir() &&
+ (fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
+ f, err := c.Config().fs.Open(fullPath)
+ if err != nil {
+ return fmt.Errorf("Error reading Bazel file '%s': %s", path, err)
+ }
+ defer f.Close()
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ line := scanner.Text()
+ matches := targetNameRegex.FindAllStringSubmatch(line, -1)
+ for _, match := range matches {
+ result[sourceDir] = append(result[sourceDir], match[1])
+ }
+ }
+ }
+ return nil
+ }
+
+ for _, path := range existingBazelFiles {
+ if !c.Config().Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(filepath.Dir(path)) {
+ continue
+ }
+ err := parseBuildFile(path)
+ if err != nil {
+ return err
+ }
+ }
+ c.Config().SetBazelBuildFileTargets(result)
+ return nil
}
// Register the pipeline of singletons, module types, and mutators for
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 777c1cf..245b759 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -474,13 +474,23 @@
Inputs(depFiles.Paths())
}
+// BuildWithNinjaVars adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
+// Outputs. This function will not escape Ninja variables, so it may be used to write sandbox manifests using Ninja variables.
+func (r *RuleBuilder) BuildWithUnescapedNinjaVars(name string, desc string) {
+ r.build(name, desc, false)
+}
+
// Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
// Outputs.
func (r *RuleBuilder) Build(name string, desc string) {
+ r.build(name, desc, true)
+}
+
+func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) {
name = ninjaNameEscape(name)
if len(r.missingDeps) > 0 {
- r.ctx.Build(pctx, BuildParams{
+ r.ctx.Build(r.pctx, BuildParams{
Rule: ErrorRule,
Outputs: r.Outputs(),
Description: desc,
@@ -619,12 +629,35 @@
name, r.sboxManifestPath.String(), r.outDir.String())
}
- // Create a rule to write the manifest as a the textproto.
+ // Create a rule to write the manifest as textproto.
pbText, err := prototext.Marshal(&manifest)
if err != nil {
ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err)
}
- WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
+ if ninjaEscapeCommandString {
+ WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
+ } else {
+ // We need to have a rule to write files that is
+ // defined on the RuleBuilder's pctx in order to
+ // write Ninja variables in the string.
+ // The WriteFileRule function above rule can only write
+ // raw strings because it is defined on the android
+ // package's pctx, and it can't access variables defined
+ // in another context.
+ r.ctx.Build(r.pctx, BuildParams{
+ Rule: r.ctx.Rule(r.pctx, "unescapedWriteFile", blueprint.RuleParams{
+ Command: `rm -rf ${out} && cat ${out}.rsp > ${out}`,
+ Rspfile: "${out}.rsp",
+ RspfileContent: "${content}",
+ Description: "write file",
+ }, "content"),
+ Output: r.sboxManifestPath,
+ Description: "write sbox manifest " + r.sboxManifestPath.Base(),
+ Args: map[string]string{
+ "content": string(pbText),
+ },
+ })
+ }
// Generate a new string to use as the command line of the sbox rule. This uses
// a RuleBuilderCommand as a convenience method of building the command line, then
@@ -723,9 +756,13 @@
pool = localPool
}
+ if ninjaEscapeCommandString {
+ commandString = proptools.NinjaEscape(commandString)
+ }
+
r.ctx.Build(r.pctx, BuildParams{
- Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{
- Command: proptools.NinjaEscape(commandString),
+ Rule: r.ctx.Rule(r.pctx, name, blueprint.RuleParams{
+ Command: commandString,
CommandDeps: proptools.NinjaEscapeList(tools.Strings()),
Restat: r.restat,
Rspfile: proptools.NinjaEscape(rspFile),
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 86647eb..a6b3a27 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -28,6 +28,17 @@
"android/soong/shared"
)
+var (
+ pctx_ruleBuilderTest = NewPackageContext("android/soong/rule_builder")
+ pctx_ruleBuilderTestSubContext = NewPackageContext("android/soong/rule_builder/config")
+)
+
+func init() {
+ pctx_ruleBuilderTest.Import("android/soong/rule_builder/config")
+ pctx_ruleBuilderTest.StaticVariable("cmdFlags", "${config.ConfigFlags}")
+ pctx_ruleBuilderTestSubContext.StaticVariable("ConfigFlags", "--some-clang-flag")
+}
+
func builderContext() BuilderContext {
return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{
"ld": nil,
@@ -496,11 +507,13 @@
type testRuleBuilderModule struct {
ModuleBase
properties struct {
- Srcs []string
+ Srcs []string
+ Flags []string
- Restat bool
- Sbox bool
- Sbox_inputs bool
+ Restat bool
+ Sbox bool
+ Sbox_inputs bool
+ Unescape_ninja_vars bool
}
}
@@ -518,8 +531,9 @@
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForModuleOut(ctx, "sbox.textproto")
- testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
- manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs,
+ testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags,
+ out, outDep, outDir,
+ manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
@@ -543,17 +557,18 @@
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
- testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
- manifestPath, true, false, false,
+ testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir,
+ manifestPath, true, false, false, false,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path,
+ flags []string,
out, outDep, outDir, manifestPath WritablePath,
- restat, sbox, sboxInputs bool,
+ restat, sbox, sboxInputs, unescapeNinjaVars bool,
rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) {
- rule := NewRuleBuilder(pctx, ctx)
+ rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx)
if sbox {
rule.Sbox(outDir, manifestPath)
@@ -564,6 +579,7 @@
rule.Command().
Tool(PathForSource(ctx, "cp")).
+ Flags(flags).
Inputs(in).
Implicit(implicit).
OrderOnly(orderOnly).
@@ -577,7 +593,11 @@
rule.Restat()
}
- rule.Build("rule", "desc")
+ if unescapeNinjaVars {
+ rule.BuildWithUnescapedNinjaVars("rule", "desc")
+ } else {
+ rule.Build("rule", "desc")
+ }
}
var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) {
@@ -792,3 +812,47 @@
})
}
}
+
+func TestRuleBuilderWithNinjaVarEscaping(t *testing.T) {
+ bp := `
+ rule_builder_test {
+ name: "foo_sbox_escaped_ninja",
+ flags: ["${cmdFlags}"],
+ sbox: true,
+ sbox_inputs: true,
+ }
+ rule_builder_test {
+ name: "foo_sbox",
+ flags: ["${cmdFlags}"],
+ sbox: true,
+ sbox_inputs: true,
+ unescape_ninja_vars: true,
+ }
+ `
+ result := GroupFixturePreparers(
+ prepareForRuleBuilderTest,
+ FixtureWithRootAndroidBp(bp),
+ ).RunTest(t)
+
+ escapedNinjaMod := result.ModuleForTests("foo_sbox_escaped_ninja", "").Rule("writeFile")
+ AssertStringDoesContain(
+ t,
+ "",
+ escapedNinjaMod.BuildParams.Args["content"],
+ "$${cmdFlags}",
+ )
+
+ unescapedNinjaMod := result.ModuleForTests("foo_sbox", "").Rule("unescapedWriteFile")
+ AssertStringDoesContain(
+ t,
+ "",
+ unescapedNinjaMod.BuildParams.Args["content"],
+ "${cmdFlags}",
+ )
+ AssertStringDoesNotContain(
+ t,
+ "",
+ unescapedNinjaMod.BuildParams.Args["content"],
+ "$${cmdFlags}",
+ )
+}
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/util.go b/android/util.go
index 5375373..7f6af2d 100644
--- a/android/util.go
+++ b/android/util.go
@@ -33,12 +33,17 @@
return append([]T{}, s...)
}
-// Concat returns a new slice concatenated from the two input slices. It does not change the input
+// Concat returns a new slice concatenated from the input slices. It does not change the input
// slices.
-func Concat[T any](s1, s2 []T) []T {
- res := make([]T, 0, len(s1)+len(s2))
- res = append(res, s1...)
- res = append(res, s2...)
+func Concat[T any](slices ...[]T) []T {
+ newLength := 0
+ for _, s := range slices {
+ newLength += len(s)
+ }
+ res := make([]T, 0, newLength)
+ for _, s := range slices {
+ res = append(res, s...)
+ }
return res
}
diff --git a/android/variable.go b/android/variable.go
index 89ac915..d33294c 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"`
@@ -437,16 +438,17 @@
ShippingApiLevel *string `json:",omitempty"`
- BuildBrokenPluginValidation []string `json:",omitempty"`
- BuildBrokenClangAsFlags bool `json:",omitempty"`
- BuildBrokenClangCFlags bool `json:",omitempty"`
- BuildBrokenClangProperty bool `json:",omitempty"`
- GenruleSandboxing *bool `json:",omitempty"`
- BuildBrokenEnforceSyspropOwner bool `json:",omitempty"`
- BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"`
- BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"`
- BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
- BuildBrokenInputDirModules []string `json:",omitempty"`
+ BuildBrokenPluginValidation []string `json:",omitempty"`
+ BuildBrokenClangAsFlags bool `json:",omitempty"`
+ BuildBrokenClangCFlags bool `json:",omitempty"`
+ BuildBrokenClangProperty bool `json:",omitempty"`
+ GenruleSandboxing *bool `json:",omitempty"`
+ BuildBrokenEnforceSyspropOwner bool `json:",omitempty"`
+ BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"`
+ BuildBrokenUsesSoongPython2Modules bool `json:",omitempty"`
+ BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
+ BuildBrokenIncorrectPartitionImages bool `json:",omitempty"`
+ BuildBrokenInputDirModules []string `json:",omitempty"`
BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"`
@@ -474,14 +476,20 @@
ProductBrand string `json:",omitempty"`
BuildVersionTags []string `json:",omitempty"`
- ReleaseVersion string `json:",omitempty"`
- ReleaseAconfigValueSets []string `json:",omitempty"`
+ ReleaseVersion string `json:",omitempty"`
+ ReleaseAconfigValueSets string `json:",omitempty"`
ReleaseAconfigFlagDefaultPermission string `json:",omitempty"`
KeepVndk *bool `json:",omitempty"`
CheckVendorSeappViolations *bool `json:",omitempty"`
+
+ // PartitionsVars are extra variables that are used to define the partition images. They should
+ // not be read from soong modules.
+ PartitionVars struct {
+ ProductDirectory string `json:",omitempty"`
+ } `json:",omitempty"`
}
func boolPtr(v bool) *bool {
@@ -667,7 +675,8 @@
// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
// have been set for the given module.
-func ProductVariableProperties(ctx ArchVariantContext, module Module) ProductConfigProperties {
+func ProductVariableProperties(ctx ArchVariantContext, module Module) (ProductConfigProperties, []error) {
+ var errs []error
moduleBase := module.base()
productConfigProperties := ProductConfigProperties{}
@@ -691,12 +700,15 @@
for namespace, namespacedVariableProps := range m.namespacedVariableProps() {
for _, namespacedVariableProp := range namespacedVariableProps {
variableValues := reflect.ValueOf(namespacedVariableProp).Elem().FieldByName(soongconfig.SoongConfigProperty)
- productConfigProperties.AddSoongConfigProperties(namespace, variableValues)
+ err := productConfigProperties.AddSoongConfigProperties(namespace, variableValues)
+ if err != nil {
+ errs = append(errs, err)
+ }
}
}
}
- return productConfigProperties
+ return productConfigProperties, errs
}
func (p *ProductConfigProperties) AddProductConfigProperty(
@@ -818,7 +830,7 @@
}
-func (productConfigProperties *ProductConfigProperties) AddSoongConfigProperties(namespace string, soongConfigVariablesStruct reflect.Value) {
+func (productConfigProperties *ProductConfigProperties) AddSoongConfigProperties(namespace string, soongConfigVariablesStruct reflect.Value) error {
//
// Example of soong_config_variables:
//
@@ -915,7 +927,7 @@
if propertyName == "Target" {
productConfigProperties.AddSoongConfigPropertiesFromTargetStruct(namespace, variableName, proptools.PropertyNameForField(propertyOrValueName), field.Field(k))
} else if propertyName == "Arch" || propertyName == "Multilib" {
- panic("Arch/Multilib are not currently supported in soong config variable structs")
+ return fmt.Errorf("Arch/Multilib are not currently supported in soong config variable structs")
} else {
productConfigProperties.AddSoongConfigProperty(propertyName, namespace, variableName, proptools.PropertyNameForField(propertyOrValueName), "", field.Field(k).Interface())
}
@@ -926,13 +938,14 @@
if propertyOrValueName == "Target" {
productConfigProperties.AddSoongConfigPropertiesFromTargetStruct(namespace, variableName, "", propertyOrStruct)
} else if propertyOrValueName == "Arch" || propertyOrValueName == "Multilib" {
- panic("Arch/Multilib are not currently supported in soong config variable structs")
+ return fmt.Errorf("Arch/Multilib are not currently supported in soong config variable structs")
} else {
productConfigProperties.AddSoongConfigProperty(propertyOrValueName, namespace, variableName, "", "", propertyOrStruct.Interface())
}
}
}
}
+ return nil
}
func (productConfigProperties *ProductConfigProperties) AddSoongConfigPropertiesFromTargetStruct(namespace, soongConfigVariableName string, soongConfigVariableValue string, targetStruct reflect.Value) {
diff --git a/apex/apex.go b/apex/apex.go
index 52a5e20..090d9c4 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -18,6 +18,7 @@
import (
"fmt"
+ "log"
"path/filepath"
"regexp"
"sort"
@@ -991,6 +992,13 @@
return false
}
}
+
+ //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
+ if useVndk && mctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
+ log.Print("Libbinder is linked from Vendor APEX ", a.Name(), " with module ", parent.Name())
+ return false
+ }
+
// By default, all the transitive dependencies are collected, unless filtered out
// above.
return true
@@ -2008,6 +2016,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
}
}
@@ -2222,6 +2233,11 @@
vctx.requireNativeLibs = append(vctx.requireNativeLibs, ":vndk")
return false
}
+
+ //TODO: b/296491928 Vendor APEX should use libbinder.ndk instead of libbinder once VNDK is fully deprecated.
+ if ch.UseVndk() && ctx.Config().IsVndkDeprecated() && child.Name() == "libbinder" {
+ return false
+ }
af := apexFileForNativeLibrary(ctx, ch, vctx.handleSpecialLibs)
af.transitiveDep = true
@@ -2607,7 +2623,7 @@
return m
}
-func (o *OverrideApex) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (o *OverrideApex) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if ctx.ModuleType() != "override_apex" {
return
}
@@ -2727,13 +2743,13 @@
// Only override the minSdkVersion value on Apexes which already specify
// a min_sdk_version (it's optional for non-updatable apexes), and that its
// min_sdk_version value is lower than the one to override with.
- minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
+ minApiLevel := android.MinSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
if minApiLevel.IsNone() {
return ""
}
overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
- overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
+ overrideApiLevel := android.MinSdkVersionFromValue(ctx, overrideMinSdkValue)
if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
minApiLevel = overrideApiLevel
}
@@ -2748,20 +2764,7 @@
// Returns apex's min_sdk_version ApiLevel, honoring overrides
func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
- return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
-}
-
-// Construct ApiLevel object from min_sdk_version string value
-func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
- if value == "" {
- return android.NoneApiLevel
- }
- apiLevel, err := android.ApiLevelFromUser(ctx, value)
- if err != nil {
- ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
- return android.NoneApiLevel
- }
- return apiLevel
+ return android.MinSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
}
// Ensures that a lib providing stub isn't statically linked
@@ -3258,7 +3261,7 @@
)
// ConvertWithBp2build performs bp2build conversion of an apex
-func (a *apexBundle) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (a *apexBundle) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
// We only convert apex and apex_test modules at this time
if ctx.ModuleType() != "apex" && ctx.ModuleType() != "apex_test" {
return
@@ -3269,7 +3272,7 @@
ctx.CreateBazelTargetModule(props, commonAttrs, &attrs)
}
-func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties, android.CommonAttributes) {
+func convertWithBp2build(a *apexBundle, ctx android.Bp2buildMutatorContext) (bazelApexBundleAttributes, bazel.BazelTargetModuleProperties, android.CommonAttributes) {
var manifestLabelAttribute bazel.LabelAttribute
manifestLabelAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json")))
@@ -3295,7 +3298,10 @@
cannedFsConfigAttribute.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *a.properties.Canned_fs_config))
}
- productVariableProps := android.ProductVariableProperties(ctx, a)
+ productVariableProps, errs := android.ProductVariableProperties(ctx, a)
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
// TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
// given it's coming via config, we probably don't want to put it in here.
var minSdkVersion bazel.StringAttribute
@@ -3426,7 +3432,7 @@
// both, 32/32, 64/none, 32&64/32, 64/32
// first, 32/32, 64/none, 64/32, 64/32
-func convert32Libs(ctx android.TopDownMutatorContext, compileMultilb string,
+func convert32Libs(ctx android.Bp2buildMutatorContext, compileMultilb string,
libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
switch compileMultilb {
@@ -3441,7 +3447,7 @@
}
}
-func convert64Libs(ctx android.TopDownMutatorContext, compileMultilb string,
+func convert64Libs(ctx android.Bp2buildMutatorContext, compileMultilb string,
libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
switch compileMultilb {
@@ -3454,7 +3460,7 @@
}
}
-func convertBothLibs(ctx android.TopDownMutatorContext, compileMultilb string,
+func convertBothLibs(ctx android.Bp2buildMutatorContext, compileMultilb string,
libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
switch compileMultilb {
@@ -3472,7 +3478,7 @@
}
}
-func convertFirstLibs(ctx android.TopDownMutatorContext, compileMultilb string,
+func convertFirstLibs(ctx android.Bp2buildMutatorContext, compileMultilb string,
libs []string, nativeSharedLibs *convertedNativeSharedLibs) {
libsLabelList := android.BazelLabelForModuleDeps(ctx, libs)
switch compileMultilb {
@@ -3515,7 +3521,7 @@
labelListAttr.Append(list)
}
-func invalidCompileMultilib(ctx android.TopDownMutatorContext, value string) {
+func invalidCompileMultilib(ctx android.Bp2buildMutatorContext, value string) {
ctx.PropertyErrorf("compile_multilib", "Invalid value: %s", value)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 1717f3e..3a6af1e 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -948,7 +948,7 @@
// Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// The rust module is linked to the stub cc library
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").RuleParams.Command
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
@@ -1024,7 +1024,7 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").RuleParams.Command
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
}
@@ -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/apex/builder.go b/apex/builder.go
index 4b42b74..1204dbb 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -75,6 +75,8 @@
pctx.HostBinToolVariable("deapexer", "deapexer")
pctx.HostBinToolVariable("debugfs_static", "debugfs_static")
pctx.SourcePathVariable("genNdkUsedbyApexPath", "build/soong/scripts/gen_ndk_usedby_apex.sh")
+ pctx.HostBinToolVariable("conv_linker_config", "conv_linker_config")
+ pctx.HostBinToolVariable("assemble_vintf", "assemble_vintf")
}
var (
@@ -222,6 +224,18 @@
CommandDeps: []string{"${apex_sepolicy_tests}", "${deapexer}", "${debugfs_static}"},
Description: "run apex_sepolicy_tests",
})
+
+ apexLinkerconfigValidationRule = pctx.StaticRule("apexLinkerconfigValidationRule", blueprint.RuleParams{
+ Command: `${conv_linker_config} validate --type apex ${image_dir} && touch ${out}`,
+ CommandDeps: []string{"${conv_linker_config}"},
+ Description: "run apex_linkerconfig_validation",
+ }, "image_dir")
+
+ apexVintfFragmentsValidationRule = pctx.StaticRule("apexVintfFragmentsValidationRule", blueprint.RuleParams{
+ Command: `/bin/bash -c '(shopt -s nullglob; for f in ${image_dir}/etc/vintf/*.xml; do VINTF_IGNORE_TARGET_FCM_VERSION=true ${assemble_vintf} -i "$$f" > /dev/null; done)' && touch ${out}`,
+ CommandDeps: []string{"${assemble_vintf}"},
+ Description: "run apex_vintf_validation",
+ }, "image_dir")
)
// buildManifest creates buile rules to modify the input apex_manifest.json to add information
@@ -843,6 +857,10 @@
args["outCommaList"] = signedOutputFile.String()
}
var validations android.Paths
+ validations = append(validations, runApexLinkerconfigValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath))
+ if !a.testApex && a.SocSpecific() {
+ validations = append(validations, runApexVintfFragmentsValidation(ctx, unsignedOutputFile.OutputPath, imageDir.OutputPath))
+ }
// TODO(b/279688635) deapexer supports [ext4]
if suffix == imageApexSuffix && ext4 == a.payloadFsType {
validations = append(validations, runApexSepolicyTests(ctx, unsignedOutputFile.OutputPath))
@@ -1097,6 +1115,32 @@
return cannedFsConfig.OutputPath
}
+func runApexLinkerconfigValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path {
+ timestamp := android.PathForModuleOut(ctx, "apex_linkerconfig_validation.timestamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apexLinkerconfigValidationRule,
+ Input: apexFile,
+ Output: timestamp,
+ Args: map[string]string{
+ "image_dir": imageDir.String(),
+ },
+ })
+ return timestamp
+}
+
+func runApexVintfFragmentsValidation(ctx android.ModuleContext, apexFile android.OutputPath, imageDir android.OutputPath) android.Path {
+ timestamp := android.PathForModuleOut(ctx, "apex_vintf_fragments_validation.timestamp")
+ ctx.Build(pctx, android.BuildParams{
+ Rule: apexVintfFragmentsValidationRule,
+ Input: apexFile,
+ Output: timestamp,
+ Args: map[string]string{
+ "image_dir": imageDir.String(),
+ },
+ })
+ return timestamp
+}
+
// Runs apex_sepolicy_tests
//
// $ deapexer list -Z {apex_file} > {file_contexts}
diff --git a/apex/key.go b/apex/key.go
index 65e739a..fc1456b 100644
--- a/apex/key.go
+++ b/apex/key.go
@@ -208,11 +208,11 @@
}
// ConvertWithBp2build performs conversion apexKey for bp2build
-func (m *apexKey) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *apexKey) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
apexKeyBp2BuildInternal(ctx, m)
}
-func apexKeyBp2BuildInternal(ctx android.TopDownMutatorContext, module *apexKey) {
+func apexKeyBp2BuildInternal(ctx android.Bp2buildMutatorContext, module *apexKey) {
privateKeyLabelAttribute, privateKeyNameAttribute :=
android.BazelStringOrLabelFromProp(ctx, module.properties.Private_key)
diff --git a/bazel/aquery.go b/bazel/aquery.go
index 76cd972..c355712 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -177,6 +177,21 @@
if err != nil {
return nil, err
}
+ if artifact.IsTreeArtifact &&
+ !strings.HasPrefix(artifactPath, "bazel-out/io_bazel_rules_go/") &&
+ !strings.HasPrefix(artifactPath, "bazel-out/rules_java_builtin/") {
+ // Since we're using ninja as an executor, we can't use tree artifacts. Ninja only
+ // considers a file/directory "dirty" when it's mtime changes. Directories' mtimes will
+ // only change when a file in the directory is added/removed, but not when files in
+ // the directory are changed, or when files in subdirectories are changed/added/removed.
+ // Bazel handles this by walking the directory and generating a hash for it after the
+ // action runs, which we would have to do as well if we wanted to support these
+ // artifacts in mixed builds.
+ //
+ // However, there are some bazel built-in rules that use tree artifacts. Allow those,
+ // but keep in mind that they'll have incrementality issues.
+ return nil, fmt.Errorf("tree artifacts are currently not supported in mixed builds: " + artifactPath)
+ }
artifactIdToPath[artifactId(artifact.Id)] = artifactPath
}
diff --git a/bazel/configurability.go b/bazel/configurability.go
index 1fe8442..a28432c 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -71,6 +71,7 @@
AndroidAndInApex = "android-in_apex"
AndroidPlatform = "system"
+ Unbundled_app = "unbundled_app"
InApex = "in_apex"
NonApex = "non_apex"
@@ -207,6 +208,7 @@
osAndInApexMap = map[string]string{
AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex",
AndroidPlatform: "//build/bazel/rules/apex:system",
+ Unbundled_app: "//build/bazel/rules/apex:unbundled_app",
OsDarwin: "//build/bazel/platforms/os:darwin",
OsLinux: "//build/bazel/platforms/os:linux_glibc",
osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
diff --git a/bp2build/Android.bp b/bp2build/Android.bp
index 6b50a2e..755b7a3 100644
--- a/bp2build/Android.bp
+++ b/bp2build/Android.bp
@@ -62,7 +62,8 @@
"cc_test_conversion_test.go",
"cc_yasm_conversion_test.go",
"conversion_test.go",
- "droidstubs_conversion_test.go",
+ "droiddoc_exported_dir_conversion_test.go",
+ "fdo_profile_conversion_test.go",
"filegroup_conversion_test.go",
"genrule_conversion_test.go",
"gensrcs_conversion_test.go",
@@ -73,6 +74,8 @@
"java_library_host_conversion_test.go",
"java_plugin_conversion_test.go",
"java_proto_conversion_test.go",
+ "java_sdk_library_conversion_test.go",
+ "java_sdk_library_import_conversion_test.go",
"license_conversion_test.go",
"license_kind_conversion_test.go",
"linker_config_conversion_test.go",
diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go
index a24378c..59aacbb 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -15,11 +15,10 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/java"
- "fmt"
-
- "testing"
)
func TestConvertAndroidLibrary(t *testing.T) {
@@ -35,7 +34,8 @@
"res/res.png": "",
"manifest/AndroidManifest.xml": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+ StubbedBuildDefinitions: []string{"static_lib_dep"},
+ Blueprint: simpleModule("android_library", "static_lib_dep") + `
android_library {
name: "TestLib",
srcs: ["lib.java"],
@@ -82,7 +82,7 @@
"res/res.png": "",
"AndroidManifest.xml": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "lib_dep") + `
+ Blueprint: simpleModule("android_library", "lib_dep") + `
android_library {
name: "TestLib",
srcs: [],
@@ -91,7 +91,6 @@
sdk_version: "current",
}
`,
- ExpectedErr: fmt.Errorf("Module has direct dependencies but no sources. Bazel will not allow this."),
ExpectedBazelTargets: []string{},
})
}
@@ -109,18 +108,24 @@
ModuleTypeUnderTestFactory: java.AARImportFactory,
Filesystem: map[string]string{
"import.aar": "",
+ "dep.aar": "",
},
+ StubbedBuildDefinitions: []string{"static_lib_dep", "prebuilt_static_import_dep"},
// Bazel's aar_import can only export *_import targets, so we expect
// only "static_import_dep" in exports, but both "static_lib_dep" and
// "static_import_dep" in deps
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") +
- simpleModuleDoNotConvertBp2build("android_library_import", "static_import_dep") + `
+ Blueprint: simpleModule("android_library", "static_lib_dep") + `
android_library_import {
name: "TestImport",
aars: ["import.aar"],
static_libs: ["static_lib_dep", "static_import_dep"],
sdk_version: "current",
}
+
+// TODO: b/301007952 - This dep is needed because android_library_import must have aars set.
+android_library_import {
+ name: "static_import_dep",
+}
`,
ExpectedBazelTargets: []string{
MakeBazelTarget(
diff --git a/bp2build/aconfig_conversion_test.go b/bp2build/aconfig_conversion_test.go
new file mode 100644
index 0000000..ddb62f7
--- /dev/null
+++ b/bp2build/aconfig_conversion_test.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 bp2build
+
+import (
+ "testing"
+
+ "android/soong/aconfig"
+ "android/soong/android"
+)
+
+func registerAconfigModuleTypes(ctx android.RegistrationContext) {
+ aconfig.RegisterBuildComponents(ctx)
+}
+
+func TestAconfigDeclarations(t *testing.T) {
+ bp := `
+ aconfig_declarations {
+ name: "foo",
+ srcs: [
+ "foo1.aconfig",
+ "test/foo2.aconfig",
+ ],
+ package: "com.android.foo",
+ }
+ `
+ expectedBazelTarget := MakeBazelTargetNoRestrictions(
+ "aconfig_declarations",
+ "foo",
+ AttrNameToString{
+ "srcs": `[
+ "foo1.aconfig",
+ "test/foo2.aconfig",
+ ]`,
+ "package": `"com.android.foo"`,
+ },
+ )
+ RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: []string{expectedBazelTarget},
+ })
+}
+
+func TestAconfigValues(t *testing.T) {
+ bp := `
+ aconfig_values {
+ name: "foo",
+ srcs: [
+ "foo1.textproto",
+ ],
+ package: "com.android.foo",
+ }
+ aconfig_value_set {
+ name: "bar",
+ values: [
+ "foo"
+ ]
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTargetNoRestrictions(
+ "aconfig_values",
+ "foo",
+ AttrNameToString{
+ "srcs": `["foo1.textproto"]`,
+ "package": `"com.android.foo"`,
+ },
+ ),
+ MakeBazelTargetNoRestrictions(
+ "aconfig_value_set",
+ "bar",
+ AttrNameToString{
+ "values": `[":foo"]`,
+ },
+ )}
+ RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ })
+}
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index f2ee322..0daa4fe 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -78,7 +78,8 @@
"manifest/AndroidManifest.xml": "",
"assets_/asset.png": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("android_app", "static_lib_dep") + `
+ StubbedBuildDefinitions: []string{"static_lib_dep"},
+ Blueprint: simpleModule("android_app", "static_lib_dep") + `
android_app {
name: "TestApp",
srcs: ["app.java"],
@@ -177,7 +178,8 @@
ModuleTypeUnderTest: "android_app",
ModuleTypeUnderTestFactory: java.AndroidAppFactory,
Filesystem: map[string]string{},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") + `
+ StubbedBuildDefinitions: []string{"foocert"},
+ Blueprint: simpleModule("filegroup", "foocert") + `
android_app {
name: "TestApp",
certificate: ":foocert",
@@ -262,7 +264,8 @@
ModuleTypeUnderTest: "android_app",
ModuleTypeUnderTestFactory: java.AndroidAppFactory,
Filesystem: map[string]string{},
- Blueprint: simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
+ StubbedBuildDefinitions: []string{"barLib"},
+ Blueprint: simpleModule("java_library", "barLib") + `
android_app {
name: "foo",
libs: ["barLib"],
@@ -291,8 +294,9 @@
Filesystem: map[string]string{
"res/res.png": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "foocert") +
- simpleModuleDoNotConvertBp2build("java_library", "barLib") + `
+ StubbedBuildDefinitions: []string{"foocert", "barLib"},
+ Blueprint: simpleModule("filegroup", "foocert") +
+ simpleModule("java_library", "barLib") + `
android_app {
name: "foo",
srcs: ["a.java", "b.kt"],
@@ -334,6 +338,7 @@
Filesystem: map[string]string{
"res/res.png": "",
},
+ StubbedBuildDefinitions: []string{"barLib"},
Blueprint: `
android_app {
name: "foo",
@@ -348,7 +353,6 @@
}
java_library{
name: "barLib",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index 2383247..2a58d01 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -74,38 +74,34 @@
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.key", "com.android.apogee.certificate", "native_shared_lib_1", "native_shared_lib_2",
+ "prebuilt_1", "prebuilt_2", "com.android.apogee-file_contexts", "cc_binary_1", "sh_binary_2"},
Blueprint: `
apex_key {
name: "com.android.apogee.key",
public_key: "com.android.apogee.avbpubkey",
private_key: "com.android.apogee.pem",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_1",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_2",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_1",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_2",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -113,11 +109,10 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
-cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } }
-sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } }
+cc_binary { name: "cc_binary_1"}
+sh_binary { name: "sh_binary_2"}
apex {
name: "com.android.apogee",
@@ -202,6 +197,7 @@
Description: "apex - file contexts is a module in another Android.bp",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: []string{"//a/b:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"a/b/Android.bp": `
filegroup {
@@ -209,7 +205,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -252,6 +247,7 @@
Description: "apex - file contexts is not specified",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
@@ -259,7 +255,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -281,12 +276,12 @@
Description: "apex - example with compile_multilib=both",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: append(multilibStubNames(), "//system/sepolicy/apex:com.android.apogee-file_contexts"),
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -373,12 +368,12 @@
Description: "apex - example with " + compileMultiLibProp,
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: append(multilibStubNames(), "//system/sepolicy/apex:com.android.apogee-file_contexts"),
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -393,12 +388,12 @@
Description: "apex - example with compile_multilib=32",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: append(multilibStubNames(), "//system/sepolicy/apex:com.android.apogee-file_contexts"),
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -425,12 +420,12 @@
Description: "apex - example with compile_multilib=64",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: append(multilibStubNames(), "//system/sepolicy/apex:com.android.apogee-file_contexts"),
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -458,31 +453,31 @@
}})
}
+func multilibStubNames() []string {
+ return []string{"native_shared_lib_for_both", "native_shared_lib_for_first", "native_shared_lib_for_lib32", "native_shared_lib_for_lib64",
+ "native_shared_lib_for_lib64", "unnested_native_shared_lib"}
+}
+
func createMultilibBlueprint(compile_multilib string) string {
return fmt.Sprintf(`
cc_library {
name: "native_shared_lib_for_both",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_for_first",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_for_lib32",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_for_lib64",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "unnested_native_shared_lib",
- bazel_module: { bp2build_available: false },
}
apex {
@@ -519,12 +514,12 @@
Description: "apex - default property values",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -546,12 +541,12 @@
Description: "apex - has bazel module props",
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}
`,
},
@@ -575,38 +570,35 @@
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.key", "com.android.apogee.certificate", "native_shared_lib_1",
+ "native_shared_lib_2", "prebuilt_1", "prebuilt_2", "com.android.apogee-file_contexts", "cc_binary_1",
+ "sh_binary_2", "com.android.apogee", "com.google.android.apogee.key", "com.google.android.apogee.certificate"},
Blueprint: `
apex_key {
name: "com.android.apogee.key",
public_key: "com.android.apogee.avbpubkey",
private_key: "com.android.apogee.pem",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_1",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_2",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_1",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_2",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -614,11 +606,10 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
-cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } }
-sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } }
+cc_binary { name: "cc_binary_1" }
+sh_binary { name: "sh_binary_2" }
apex {
name: "com.android.apogee",
@@ -643,20 +634,17 @@
"prebuilt_1",
"prebuilt_2",
],
- bazel_module: { bp2build_available: false },
}
apex_key {
name: "com.google.android.apogee.key",
public_key: "com.google.android.apogee.avbpubkey",
private_key: "com.google.android.apogee.pem",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.google.android.apogee.certificate",
certificate: "com.google.android.apogee",
- bazel_module: { bp2build_available: false },
}
override_apex {
@@ -717,28 +705,27 @@
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.certificate", "native_shared_lib_1",
+ "prebuilt_1", "com.android.apogee-file_contexts", "cc_binary_1", "sh_binary_2",
+ "com.android.apogee", "com.google.android.apogee.key", "com.google.android.apogee.certificate", "com.android.apogee.key"},
Blueprint: `
apex_key {
name: "com.android.apogee.key",
public_key: "com.android.apogee.avbpubkey",
private_key: "com.android.apogee.pem",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "native_shared_lib_1",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_1",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -746,11 +733,10 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
-cc_binary { name: "cc_binary_1", bazel_module: { bp2build_available: false } }
-sh_binary { name: "sh_binary_2", bazel_module: { bp2build_available: false } }
+cc_binary { name: "cc_binary_1"}
+sh_binary { name: "sh_binary_2"}
apex_test {
name: "com.android.apogee",
@@ -773,20 +759,17 @@
prebuilts: [
"prebuilt_1",
],
- bazel_module: { bp2build_available: false },
}
apex_key {
name: "com.google.android.apogee.key",
public_key: "com.google.android.apogee.avbpubkey",
private_key: "com.google.android.apogee.pem",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.google.android.apogee.certificate",
certificate: "com.google.android.apogee",
- bazel_module: { bp2build_available: false },
}
override_apex {
@@ -835,12 +818,12 @@
Description: "override_apex - manifest of base apex is empty, base apex and override_apex is in different Android.bp",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
"a/b/Android.bp": `
apex {
@@ -869,12 +852,12 @@
Description: "override_apex - manifest of base apex is set, base apex and override_apex is in different Android.bp",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
"a/b/Android.bp": `
apex {
@@ -904,12 +887,12 @@
Description: "override_apex - manifest of base apex is empty, base apex and override_apex is in same Android.bp",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
@@ -937,12 +920,12 @@
Description: "override_apex - manifest of base apex is set, base apex and override_apex is in same Android.bp",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
@@ -971,12 +954,12 @@
Description: "override_apex - override package name",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
@@ -1006,24 +989,22 @@
Description: "override_apex - no override",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"prebuilt_file", "com.android.apogee", "//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
prebuilt_etc {
name: "prebuilt_file",
- bazel_module: { bp2build_available: false },
}
apex {
name: "com.android.apogee",
- bazel_module: { bp2build_available: false },
- prebuilts: ["prebuilt_file"]
+ prebuilts: ["prebuilt_file"]
}
override_apex {
@@ -1046,35 +1027,32 @@
Description: "override_apex - ooverride",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"prebuilt_file", "prebuilt_file2", "com.android.apogee", "//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
prebuilt_etc {
name: "prebuilt_file",
- bazel_module: { bp2build_available: false },
}
prebuilt_etc {
name: "prebuilt_file2",
- bazel_module: { bp2build_available: false },
}
apex {
name: "com.android.apogee",
- bazel_module: { bp2build_available: false },
- prebuilts: ["prebuilt_file"]
+ prebuilts: ["prebuilt_file"]
}
override_apex {
name: "com.google.android.apogee",
base: ":com.android.apogee",
- prebuilts: ["prebuilt_file2"]
+ prebuilts: ["prebuilt_file2"]
}
`,
ExpectedBazelTargets: []string{
@@ -1092,24 +1070,22 @@
Description: "override_apex - override with empty list",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"prebuilt_file", "com.android.apogee", "//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
prebuilt_etc {
name: "prebuilt_file",
- bazel_module: { bp2build_available: false },
}
apex {
name: "com.android.apogee",
- bazel_module: { bp2build_available: false },
- prebuilts: ["prebuilt_file"]
+ prebuilts: ["prebuilt_file"]
}
override_apex {
@@ -1133,12 +1109,12 @@
Description: "override_apex - logging_parent - no override",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
@@ -1168,12 +1144,12 @@
Description: "override_apex - logging_parent - override",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"//system/sepolicy/apex:com.android.apogee-file_contexts"},
Filesystem: map[string]string{
"system/sepolicy/apex/Android.bp": `
filegroup {
name: "com.android.apogee-file_contexts",
srcs: [ "apogee-file_contexts", ],
- bazel_module: { bp2build_available: false },
}`,
},
Blueprint: `
@@ -1205,11 +1181,11 @@
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.certificate", "com.android.apogee-file_contexts", "com.android.apogee"},
Blueprint: `
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -1217,7 +1193,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
apex {
@@ -1225,7 +1200,6 @@
manifest: "apogee_manifest.json",
file_contexts: ":com.android.apogee-file_contexts",
certificate: ":com.android.apogee.certificate",
- bazel_module: { bp2build_available: false },
}
override_apex {
@@ -1250,11 +1224,11 @@
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee-file_contexts", "com.android.apogee.certificate"},
Blueprint: `
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
apex {
@@ -1263,7 +1237,7 @@
file_contexts: ":com.android.apogee-file_contexts",
certificate: ":com.android.apogee.certificate",
}
-` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"),
+` + simpleModule("filegroup", "com.android.apogee-file_contexts"),
ExpectedBazelTargets: []string{
MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
"certificate": `":com.android.apogee.certificate"`,
@@ -1279,6 +1253,7 @@
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"myapex-file_contexts"},
Blueprint: `
cc_library{
name: "foo",
@@ -1299,7 +1274,7 @@
binaries: ["bar"],
native_shared_libs: ["foo"],
}
-` + simpleModuleDoNotConvertBp2build("filegroup", "myapex-file_contexts"),
+` + simpleModule("filegroup", "myapex-file_contexts"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_binary", "bar", AttrNameToString{
"local_includes": `["."]`,
@@ -1315,6 +1290,7 @@
"tags": `["apex_available=myapex"]`,
}),
MakeBazelTarget("cc_stub_suite", "foo_stub_libs", AttrNameToString{
+ "api_surface": `"module-libapi"`,
"soname": `"foo.so"`,
"source_library_label": `"//:foo"`,
"symbol_file": `"foo.map.txt"`,
@@ -1349,6 +1325,7 @@
ModuleTypeUnderTest: "apex",
ModuleTypeUnderTestFactory: apex.BundleFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee-file_contexts"},
Blueprint: `
apex {
name: "com.android.apogee",
@@ -1356,7 +1333,7 @@
file_contexts: ":com.android.apogee-file_contexts",
certificate: "com.android.apogee.certificate",
}
-` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"),
+` + simpleModule("filegroup", "com.android.apogee-file_contexts"),
ExpectedBazelTargets: []string{
MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
"certificate_name": `"com.android.apogee.certificate"`,
@@ -1372,11 +1349,12 @@
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.certificate", "com.android.apogee-file_contexts",
+ "com.android.apogee", "com.google.android.apogee.certificate"},
Blueprint: `
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -1384,7 +1362,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
apex {
@@ -1392,13 +1369,11 @@
manifest: "apogee_manifest.json",
file_contexts: ":com.android.apogee-file_contexts",
certificate: ":com.android.apogee.certificate",
- bazel_module: { bp2build_available: false },
}
android_app_certificate {
name: "com.google.android.apogee.certificate",
certificate: "com.google.android.apogee",
- bazel_module: { bp2build_available: false },
}
override_apex {
@@ -1423,11 +1398,11 @@
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.certificate", "com.android.apogee", "com.android.apogee-file_contexts"},
Blueprint: `
android_app_certificate {
name: "com.android.apogee.certificate",
certificate: "com.android.apogee",
- bazel_module: { bp2build_available: false },
}
filegroup {
@@ -1435,7 +1410,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
apex {
@@ -1468,8 +1442,9 @@
ModuleTypeUnderTest: "apex_test",
ModuleTypeUnderTestFactory: apex.TestApexBundleFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"cc_test_1"},
Blueprint: `
-cc_test { name: "cc_test_1", bazel_module: { bp2build_available: false } }
+cc_test { name: "cc_test_1"}
apex_test {
name: "test_com.android.apogee",
@@ -1496,6 +1471,7 @@
Description: "apex - overriding a module that uses product vars",
ModuleTypeUnderTest: "override_apex",
ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ StubbedBuildDefinitions: []string{"foo-file_contexts"},
Blueprint: `
soong_config_string_variable {
name: "library_linking_strategy",
@@ -1534,7 +1510,6 @@
srcs: [
"com.android.apogee-file_contexts",
],
- bazel_module: { bp2build_available: false },
}
apex {
diff --git a/bp2build/apex_key_conversion_test.go b/bp2build/apex_key_conversion_test.go
index 1230a48..140afb7 100644
--- a/bp2build/apex_key_conversion_test.go
+++ b/bp2build/apex_key_conversion_test.go
@@ -83,14 +83,15 @@
ModuleTypeUnderTest: "apex_key",
ModuleTypeUnderTestFactory: apex.ApexKeyFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"com.android.apogee.avbpubkey", "com.android.apogee.pem"},
Blueprint: `
apex_key {
name: "com.android.apogee.key",
public_key: ":com.android.apogee.avbpubkey",
private_key: ":com.android.apogee.pem",
}
-` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.avbpubkey") +
- simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee.pem"),
+` + simpleModule("filegroup", "com.android.apogee.avbpubkey") +
+ simpleModule("filegroup", "com.android.apogee.pem"),
ExpectedBazelTargets: []string{MakeBazelTargetNoRestrictions("apex_key", "com.android.apogee.key", AttrNameToString{
"private_key": `":com.android.apogee.pem"`,
"public_key": `":com.android.apogee.avbpubkey"`,
diff --git a/bp2build/api_domain_conversion_test.go b/bp2build/api_domain_conversion_test.go
deleted file mode 100644
index 224008f..0000000
--- a/bp2build/api_domain_conversion_test.go
+++ /dev/null
@@ -1,68 +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/cc"
-)
-
-func registerApiDomainModuleTypes(ctx android.RegistrationContext) {
- android.RegisterApiDomainBuildComponents(ctx)
- cc.RegisterNdkModuleTypes(ctx)
- cc.RegisterLibraryBuildComponents(ctx)
-}
-
-func TestApiDomainContributionsTest(t *testing.T) {
- bp := `
- api_domain {
- name: "system",
- cc_api_contributions: [
- "libfoo.ndk",
- "libbar",
- ],
- }
- `
- fs := map[string]string{
- "libfoo/Android.bp": `
- ndk_library {
- name: "libfoo",
- }
- `,
- "libbar/Android.bp": `
- cc_library {
- name: "libbar",
- }
- `,
- }
- expectedBazelTarget := MakeBazelTargetNoRestrictions(
- "api_domain",
- "system",
- AttrNameToString{
- "cc_api_contributions": `[
- "//libfoo:libfoo.ndk.contribution",
- "//libbar:libbar.contribution",
- ]`,
- "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
- },
- )
- RunApiBp2BuildTestCase(t, registerApiDomainModuleTypes, Bp2buildTestCase{
- Blueprint: bp,
- ExpectedBazelTargets: []string{expectedBazelTarget},
- Filesystem: fs,
- })
-}
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index 5f7b382..6c9d903 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -82,15 +82,25 @@
os.Exit(1)
}
var bp2buildFiles []BazelFile
+ productConfig, err := createProductConfigFiles(ctx, res.metrics)
ctx.Context().EventHandler.Do("CreateBazelFile", func() {
- bp2buildFiles = CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
+ allTargets := make(map[string]BazelTargets)
+ for k, v := range res.buildFileToTargets {
+ allTargets[k] = append(allTargets[k], v...)
+ }
+ for k, v := range productConfig.bp2buildTargets {
+ allTargets[k] = append(allTargets[k], v...)
+ }
+ bp2buildFiles = CreateBazelFiles(nil, allTargets, ctx.mode)
})
- injectionFiles, additionalBp2buildFiles, err := CreateSoongInjectionDirFiles(ctx, res.metrics)
+ bp2buildFiles = append(bp2buildFiles, productConfig.bp2buildFiles...)
+ injectionFiles, err := createSoongInjectionDirFiles(ctx, res.metrics)
if err != nil {
fmt.Printf("%s\n", err.Error())
os.Exit(1)
}
- bp2buildFiles = append(bp2buildFiles, additionalBp2buildFiles...)
+ injectionFiles = append(injectionFiles, productConfig.injectionFiles...)
+
writeFiles(ctx, bp2buildDir, bp2buildFiles)
// Delete files under the bp2build root which weren't just written. An
// alternative would have been to delete the whole directory and write these
@@ -109,26 +119,6 @@
return &res.metrics
}
-// Wrapper function that will be responsible for all files in soong_injection directory
-// This includes
-// 1. config value(s) that are hardcoded in Soong
-// 2. product_config variables
-func CreateSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
- var ret []BazelFile
-
- productConfigInjectionFiles, productConfigBp2BuildDirFiles, err := CreateProductConfigFiles(ctx, metrics)
- if err != nil {
- return nil, nil, err
- }
- ret = append(ret, productConfigInjectionFiles...)
- injectionFiles, err := soongInjectionFiles(ctx.Config(), metrics)
- if err != nil {
- return nil, nil, err
- }
- ret = append(injectionFiles, ret...)
- return ret, productConfigBp2BuildDirFiles, nil
-}
-
// Get the output directory and create it if it doesn't exist.
func getOrCreateOutputDir(outputDir android.OutputPath, ctx android.PathContext, dir string) android.OutputPath {
dirPath := outputDir.Join(ctx, dir)
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index e8c2ef7..3d9cae0 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,13 +8,23 @@
"reflect"
"strings"
+ "android/soong/android"
+ "android/soong/android/soongconfig"
+ "android/soong/starlark_import"
+
"github.com/google/blueprint/proptools"
"go.starlark.net/starlark"
)
-func CreateProductConfigFiles(
+type createProductConfigFilesResult struct {
+ injectionFiles []BazelFile
+ bp2buildFiles []BazelFile
+ bp2buildTargets map[string]BazelTargets
+}
+
+func createProductConfigFiles(
ctx *CodegenContext,
- metrics CodegenMetrics) ([]BazelFile, []BazelFile, error) {
+ metrics CodegenMetrics) (createProductConfigFilesResult, error) {
cfg := &ctx.config
targetProduct := "unknown"
if cfg.HasDeviceProduct() {
@@ -30,68 +37,85 @@
targetBuildVariant = "userdebug"
}
+ var res createProductConfigFilesResult
+
productVariablesFileName := cfg.ProductVariablesFileName
if !strings.HasPrefix(productVariablesFileName, "/") {
productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName)
}
productVariablesBytes, err := os.ReadFile(productVariablesFileName)
if err != nil {
- return nil, nil, err
+ return res, err
}
productVariables := android.ProductVariables{}
err = json.Unmarshal(productVariablesBytes, &productVariables)
if err != nil {
- return nil, nil, err
+ return res, err
}
- // TODO(b/249685973): the name is product_config_platforms because product_config
- // was already used for other files. Deduplicate them.
- currentProductFolder := fmt.Sprintf("product_config_platforms/products/%s-%s", targetProduct, targetBuildVariant)
+ currentProductFolder := fmt.Sprintf("build/bazel/products/%s-%s", targetProduct, targetBuildVariant)
+ if len(productVariables.PartitionVars.ProductDirectory) > 0 {
+ currentProductFolder = fmt.Sprintf("%s%s-%s", productVariables.PartitionVars.ProductDirectory, targetProduct, targetBuildVariant)
+ }
productReplacer := strings.NewReplacer(
"{PRODUCT}", targetProduct,
"{VARIANT}", targetBuildVariant,
"{PRODUCT_FOLDER}", currentProductFolder)
- platformMappingContent, err := platformMappingContent(
- productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"),
- &productVariables,
- ctx.Config().Bp2buildSoongConfigDefinitions,
- metrics.convertedModulePathMap)
- if err != nil {
- return nil, nil, err
- }
-
productsForTestingMap, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
if err != nil {
- return nil, nil, err
+ return res, err
}
productsForTesting := android.SortedKeys(productsForTestingMap)
for i := range productsForTesting {
productsForTesting[i] = fmt.Sprintf(" \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
}
- injectionDirFiles := []BazelFile{
- newFile(
- currentProductFolder,
- "soong.variables.bzl",
- `variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
- newFile(
- currentProductFolder,
- "BUILD",
- productReplacer.Replace(`
-package(default_visibility=[
- "@soong_injection//product_config_platforms:__subpackages__",
- "@//build/bazel/product_config:__subpackages__",
-])
-load(":soong.variables.bzl", _soong_variables = "variables")
-load("@//build/bazel/product_config:android_product.bzl", "android_product")
+ productLabelsToVariables := make(map[string]*android.ProductVariables)
+ productLabelsToVariables[productReplacer.Replace("@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}")] = &productVariables
+ for product, productVariablesStarlark := range productsForTestingMap {
+ productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
+ if err != nil {
+ return res, err
+ }
+ productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables
+ }
-android_product(
+ res.bp2buildTargets = make(map[string]BazelTargets)
+ res.bp2buildTargets[currentProductFolder] = append(res.bp2buildTargets[currentProductFolder], BazelTarget{
+ name: productReplacer.Replace("{PRODUCT}-{VARIANT}"),
+ packageName: currentProductFolder,
+ content: productReplacer.Replace(`android_product(
name = "{PRODUCT}-{VARIANT}",
soong_variables = _soong_variables,
-)
-`)),
+)`),
+ ruleClass: "android_product",
+ loads: []BazelLoad{
+ {
+ file: ":soong.variables.bzl",
+ symbols: []BazelLoadSymbol{{
+ symbol: "variables",
+ alias: "_soong_variables",
+ }},
+ },
+ {
+ file: "//build/bazel/product_config:android_product.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "android_product"}},
+ },
+ },
+ })
+ createTargets(productLabelsToVariables, res.bp2buildTargets)
+
+ platformMappingContent, err := platformMappingContent(
+ productLabelsToVariables,
+ ctx.Config().Bp2buildSoongConfigDefinitions,
+ metrics.convertedModulePathMap)
+ if err != nil {
+ return res, err
+ }
+
+ res.injectionFiles = []BazelFile{
newFile(
"product_config_platforms",
"BUILD.bazel",
@@ -101,7 +125,7 @@
"@soong_injection//product_config_platforms:__subpackages__",
])
-load("//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables")
+load("@//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables")
load("@//build/bazel/product_config:android_product.bzl", "android_product")
# Bazel will qualify its outputs by the platform name. When switching between products, this
@@ -125,53 +149,53 @@
# currently lunched product, they should all be listed here
product_labels = [
"@soong_injection//product_config_platforms:mixed_builds_product-{VARIANT}",
- "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}",
+ "@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}",
`)+strings.Join(productsForTesting, "\n")+"\n]\n"),
newFile(
"product_config_platforms",
"common.bazelrc",
productReplacer.Replace(`
build --platform_mappings=platform_mappings
-build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
+build --platforms @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
-build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
-build:linux_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86
-build:linux_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
-build:linux_bionic_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64
-build:linux_musl_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86
-build:linux_musl_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86_64
+build:android --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
+build:linux_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86
+build:linux_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
+build:linux_bionic_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64
+build:linux_musl_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86
+build:linux_musl_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86_64
`)),
newFile(
"product_config_platforms",
"linux.bazelrc",
productReplacer.Replace(`
-build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
+build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
`)),
newFile(
"product_config_platforms",
"darwin.bazelrc",
productReplacer.Replace(`
-build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64
+build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64
`)),
}
- bp2buildDirFiles := []BazelFile{
+ res.bp2buildFiles = []BazelFile{
newFile(
"",
"platform_mappings",
platformMappingContent),
+ newFile(
+ currentProductFolder,
+ "soong.variables.bzl",
+ `variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
}
- return injectionDirFiles, bp2buildDirFiles, nil
+
+ return res, nil
}
func platformMappingContent(
- mainProductLabel string,
- mainProductVariables *android.ProductVariables,
+ productLabelToVariables map[string]*android.ProductVariables,
soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
convertedModulePathMap map[string]string) (string, error) {
- productsForTesting, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
- if err != nil {
- return "", err
- }
var result strings.Builder
mergedConvertedModulePathMap := make(map[string]string)
@@ -187,13 +211,8 @@
}
result.WriteString("platforms:\n")
- platformMappingSingleProduct(mainProductLabel, mainProductVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
- for product, productVariablesStarlark := range productsForTesting {
- productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
- if err != nil {
- return "", err
- }
- platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
+ for productLabel, productVariables := range productLabelToVariables {
+ platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
}
return result.String(), nil
}
@@ -232,7 +251,7 @@
defaultAppCertificateFilegroup := "//build/bazel/utils:empty_filegroup"
if proptools.String(productVariables.DefaultAppCertificate) != "" {
- defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":android_certificate_directory"
+ defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory"
}
for _, suffix := range bazelPlatformSuffixes {
@@ -245,6 +264,7 @@
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:binder32bit=%t\n", proptools.Bool(productVariables.Binder32bit)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_from_text_stub=%t\n", proptools.Bool(productVariables.Build_from_text_stub)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_broken_incorrect_partition_images=%t\n", productVariables.BuildBrokenIncorrectPartitionImages))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_id=%s\n", proptools.String(productVariables.BuildId)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:build_version_tags=%s\n", strings.Join(productVariables.BuildVersionTags, ",")))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:cfi_exclude_paths=%s\n", strings.Join(productVariables.CFIExcludePaths, ",")))
@@ -258,17 +278,27 @@
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)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_flag_default_permission=%s\n", productVariables.ReleaseAconfigFlagDefaultPermission))
+ // Empty string can't be used as label_flag on the bazel side
+ if len(productVariables.ReleaseAconfigValueSets) > 0 {
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_aconfig_value_sets=%s\n", productVariables.ReleaseAconfigValueSets))
+ }
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:release_version=%s\n", productVariables.ReleaseVersion))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_version=%d\n", platform_sdk_version))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:safestack=%t\n", proptools.Bool(productVariables.Safestack)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:target_build_variant=%s\n", targetBuildVariant))
@@ -398,3 +428,36 @@
return result, nil
}
+
+func createTargets(productLabelsToVariables map[string]*android.ProductVariables, res map[string]BazelTargets) {
+ createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
+}
+
+func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[string]*android.ProductVariables, targets map[string]BazelTargets) {
+ var allDefaultAppCertificateDirs []string
+ for _, productVariables := range productLabelsToVariables {
+ if proptools.String(productVariables.DefaultAppCertificate) != "" {
+ d := filepath.Dir(proptools.String(productVariables.DefaultAppCertificate))
+ if !android.InList(d, allDefaultAppCertificateDirs) {
+ allDefaultAppCertificateDirs = append(allDefaultAppCertificateDirs, d)
+ }
+ }
+ }
+ for _, dir := range allDefaultAppCertificateDirs {
+ content := `filegroup(
+ name = "generated_android_certificate_directory",
+ srcs = glob([
+ "*.pk8",
+ "*.pem",
+ "*.avbpubkey",
+ ]),
+ visibility = ["//visibility:public"],
+)`
+ targets[dir] = append(targets[dir], BazelTarget{
+ name: "generated_android_certificate_directory",
+ packageName: dir,
+ content: content,
+ ruleClass: "filegroup",
+ })
+ }
+}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index cd1bc7f..15b7766 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -39,18 +39,24 @@
Attrs map[string]string
}
-type BazelTarget struct {
- name string
- packageName string
- content string
- ruleClass string
- bzlLoadLocation string
+type BazelLoadSymbol struct {
+ // The name of the symbol in the file being loaded
+ symbol string
+ // The name the symbol wil have in this file. Can be left blank to use the same name as symbol.
+ alias string
}
-// IsLoadedFromStarlark determines if the BazelTarget's rule class is loaded from a .bzl file,
-// as opposed to a native rule built into Bazel.
-func (t BazelTarget) IsLoadedFromStarlark() bool {
- return t.bzlLoadLocation != ""
+type BazelLoad struct {
+ file string
+ symbols []BazelLoadSymbol
+}
+
+type BazelTarget struct {
+ name string
+ packageName string
+ content string
+ ruleClass string
+ loads []BazelLoad
}
// Label is the fully qualified Bazel label constructed from the BazelTarget's
@@ -110,30 +116,62 @@
// LoadStatements return the string representation of the sorted and deduplicated
// Starlark rule load statements needed by a group of BazelTargets.
func (targets BazelTargets) LoadStatements() string {
- bzlToLoadedSymbols := map[string][]string{}
+ // First, merge all the load statements from all the targets onto one list
+ bzlToLoadedSymbols := map[string][]BazelLoadSymbol{}
for _, target := range targets {
- if target.IsLoadedFromStarlark() {
- bzlToLoadedSymbols[target.bzlLoadLocation] =
- append(bzlToLoadedSymbols[target.bzlLoadLocation], target.ruleClass)
+ for _, load := range target.loads {
+ outer:
+ for _, symbol := range load.symbols {
+ alias := symbol.alias
+ if alias == "" {
+ alias = symbol.symbol
+ }
+ for _, otherSymbol := range bzlToLoadedSymbols[load.file] {
+ otherAlias := otherSymbol.alias
+ if otherAlias == "" {
+ otherAlias = otherSymbol.symbol
+ }
+ if symbol.symbol == otherSymbol.symbol && alias == otherAlias {
+ continue outer
+ } else if alias == otherAlias {
+ panic(fmt.Sprintf("Conflicting destination (%s) for loads of %s and %s", alias, symbol.symbol, otherSymbol.symbol))
+ }
+ }
+ bzlToLoadedSymbols[load.file] = append(bzlToLoadedSymbols[load.file], symbol)
+ }
}
}
- var loadStatements []string
- for bzl, ruleClasses := range bzlToLoadedSymbols {
- loadStatement := "load(\""
- loadStatement += bzl
- loadStatement += "\", "
- ruleClasses = android.SortedUniqueStrings(ruleClasses)
- for i, ruleClass := range ruleClasses {
- loadStatement += "\"" + ruleClass + "\""
- if i != len(ruleClasses)-1 {
- loadStatement += ", "
+ var loadStatements strings.Builder
+ for i, bzl := range android.SortedKeys(bzlToLoadedSymbols) {
+ symbols := bzlToLoadedSymbols[bzl]
+ loadStatements.WriteString("load(\"")
+ loadStatements.WriteString(bzl)
+ loadStatements.WriteString("\", ")
+ sort.Slice(symbols, func(i, j int) bool {
+ if symbols[i].symbol < symbols[j].symbol {
+ return true
+ }
+ return symbols[i].alias < symbols[j].alias
+ })
+ for j, symbol := range symbols {
+ if symbol.alias != "" && symbol.alias != symbol.symbol {
+ loadStatements.WriteString(symbol.alias)
+ loadStatements.WriteString(" = ")
+ }
+ loadStatements.WriteString("\"")
+ loadStatements.WriteString(symbol.symbol)
+ loadStatements.WriteString("\"")
+ if j != len(symbols)-1 {
+ loadStatements.WriteString(", ")
}
}
- loadStatement += ")"
- loadStatements = append(loadStatements, loadStatement)
+ loadStatements.WriteString(")")
+ if i != len(bzlToLoadedSymbols)-1 {
+ loadStatements.WriteString("\n")
+ }
}
- return strings.Join(android.SortedUniqueStrings(loadStatements), "\n")
+ return loadStatements.String()
}
type bpToBuildContext interface {
@@ -175,9 +213,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 +231,6 @@
return "Bp2Build"
case QueryView:
return "QueryView"
- case ApiBp2build:
- return "ApiBp2build"
default:
return fmt.Sprintf("%d", mode)
}
@@ -774,10 +807,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
@@ -808,7 +837,7 @@
for dir := range dirs {
buildFileToTargets[dir] = append(buildFileToTargets[dir], BazelTarget{
name: "bp2build_all_srcs",
- content: `filegroup(name = "bp2build_all_srcs", srcs = glob(["**/*"]))`,
+ content: `filegroup(name = "bp2build_all_srcs", srcs = glob(["**/*"]), tags = ["manual"])`,
ruleClass: "filegroup",
})
}
@@ -866,12 +895,19 @@
} else {
content = fmt.Sprintf(unnamedRuleTargetTemplate, ruleClass, attributes)
}
+ var loads []BazelLoad
+ if bzlLoadLocation != "" {
+ loads = append(loads, BazelLoad{
+ file: bzlLoadLocation,
+ symbols: []BazelLoadSymbol{{symbol: ruleClass}},
+ })
+ }
return BazelTarget{
- name: targetName,
- packageName: m.TargetPackage(),
- ruleClass: ruleClass,
- bzlLoadLocation: bzlLoadLocation,
- content: content,
+ name: targetName,
+ packageName: m.TargetPackage(),
+ ruleClass: ruleClass,
+ loads: loads,
+ content: content,
}, nil
}
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index 8ee0439..329c907 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -773,9 +773,12 @@
{
bazelTargets: BazelTargets{
BazelTarget{
- name: "foo",
- ruleClass: "cc_library",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "foo",
+ ruleClass: "cc_library",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
+ }},
},
},
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
@@ -783,14 +786,20 @@
{
bazelTargets: BazelTargets{
BazelTarget{
- name: "foo",
- ruleClass: "cc_library",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "foo",
+ ruleClass: "cc_library",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
+ }},
},
BazelTarget{
- name: "bar",
- ruleClass: "cc_library",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "bar",
+ ruleClass: "cc_library",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
+ }},
},
},
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
@@ -798,14 +807,20 @@
{
bazelTargets: BazelTargets{
BazelTarget{
- name: "foo",
- ruleClass: "cc_library",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "foo",
+ ruleClass: "cc_library",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
+ }},
},
BazelTarget{
- name: "bar",
- ruleClass: "cc_binary",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "bar",
+ ruleClass: "cc_binary",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
+ }},
},
},
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")`,
@@ -813,19 +828,28 @@
{
bazelTargets: BazelTargets{
BazelTarget{
- name: "foo",
- ruleClass: "cc_library",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "foo",
+ ruleClass: "cc_library",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
+ }},
},
BazelTarget{
- name: "bar",
- ruleClass: "cc_binary",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "bar",
+ ruleClass: "cc_binary",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
+ }},
},
BazelTarget{
- name: "baz",
- ruleClass: "java_binary",
- bzlLoadLocation: "//build/bazel/rules:java.bzl",
+ name: "baz",
+ ruleClass: "java_binary",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:java.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "java_binary"}},
+ }},
},
},
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")
@@ -834,19 +858,25 @@
{
bazelTargets: BazelTargets{
BazelTarget{
- name: "foo",
- ruleClass: "cc_binary",
- bzlLoadLocation: "//build/bazel/rules:cc.bzl",
+ name: "foo",
+ ruleClass: "cc_binary",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:cc.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
+ }},
},
BazelTarget{
- name: "bar",
- ruleClass: "java_binary",
- bzlLoadLocation: "//build/bazel/rules:java.bzl",
+ name: "bar",
+ ruleClass: "java_binary",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules:java.bzl",
+ symbols: []BazelLoadSymbol{{symbol: "java_binary"}},
+ }},
},
BazelTarget{
name: "baz",
ruleClass: "genrule",
- // Note: no bzlLoadLocation for native rules
+ // Note: no loads for native rules
},
},
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary")
@@ -1743,7 +1773,8 @@
Description: "Required into data test",
ModuleTypeUnderTest: "filegroup",
ModuleTypeUnderTestFactory: android.FileGroupFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
+ StubbedBuildDefinitions: []string{"reqd"},
+ Blueprint: simpleModule("filegroup", "reqd") + `
filegroup {
name: "fg_foo",
required: ["reqd"],
@@ -1759,7 +1790,8 @@
Description: "Required into data test, cyclic self reference is filtered out",
ModuleTypeUnderTest: "filegroup",
ModuleTypeUnderTestFactory: android.FileGroupFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
+ StubbedBuildDefinitions: []string{"reqd"},
+ Blueprint: simpleModule("filegroup", "reqd") + `
filegroup {
name: "fg_foo",
required: ["reqd", "fg_foo"],
@@ -1775,8 +1807,9 @@
Description: "Required via arch into data test",
ModuleTypeUnderTest: "python_library",
ModuleTypeUnderTestFactory: python.PythonLibraryFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqdx86") +
- simpleModuleDoNotConvertBp2build("python_library", "reqdarm") + `
+ StubbedBuildDefinitions: []string{"reqdx86", "reqdarm"},
+ Blueprint: simpleModule("python_library", "reqdx86") +
+ simpleModule("python_library", "reqdarm") + `
python_library {
name: "fg_foo",
arch: {
@@ -1809,7 +1842,8 @@
"data.bin": "",
"src.py": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("python_library", "reqd") + `
+ StubbedBuildDefinitions: []string{"reqd"},
+ Blueprint: simpleModule("python_library", "reqd") + `
python_library {
name: "fg_foo",
data: ["data.bin"],
@@ -1831,7 +1865,8 @@
Description: "All props-to-attrs at once together test",
ModuleTypeUnderTest: "filegroup",
ModuleTypeUnderTestFactory: android.FileGroupFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("filegroup", "reqd") + `
+ StubbedBuildDefinitions: []string{"reqd"},
+ Blueprint: simpleModule("filegroup", "reqd") + `
filegroup {
name: "fg_foo",
required: ["reqd"],
@@ -1879,30 +1914,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 {
@@ -1950,6 +1961,69 @@
android.AssertStringEquals(t, "Print the common value if all keys in an axis have the same value", `[":libfoo.impl"]`, actual)
}
+func TestAlreadyPresentBuildTarget(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ }
+ custom {
+ name: "bar",
+ }
+ `
+ alreadyPresentBuildFile :=
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{},
+ )
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "bar",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ AlreadyExistingBuildContents: alreadyPresentBuildFile,
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Not duplicating work for an already-present BUILD target.",
+ })
+}
+
+// Verifies that if a module is defined in pkg1/Android.bp, that a target present
+// in pkg2/BUILD.bazel does not result in the module being labeled "already defined
+// in a BUILD file".
+func TestBuildTargetPresentOtherDirectory(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ KeepBuildFileForDirs: []string{"other_pkg"},
+ Filesystem: map[string]string{
+ "other_pkg/BUILD.bazel": MakeBazelTarget("custom", "foo", AttrNameToString{}),
+ },
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Not treating a BUILD target as the bazel definition for a module in another package",
+ })
+}
+
// If CommonAttributes.Dir is set, the bazel target should be created in that dir
func TestCreateBazelTargetInDifferentDir(t *testing.T) {
t.Parallel()
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index 90db365..c679703 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -44,10 +44,11 @@
}
type ccBinaryBp2buildTestCase struct {
- description string
- filesystem map[string]string
- blueprint string
- targets []testBazelTarget
+ description string
+ filesystem map[string]string
+ blueprint string
+ targets []testBazelTarget
+ stubbedBuildDefinitions []string
}
func registerCcBinaryModuleTypes(ctx android.RegistrationContext) {
@@ -81,6 +82,7 @@
Description: description,
Blueprint: binaryReplacer.Replace(testCase.blueprint),
Filesystem: testCase.filesystem,
+ StubbedBuildDefinitions: testCase.stubbedBuildDefinitions,
})
})
}
@@ -97,6 +99,7 @@
Description: description,
Blueprint: hostBinaryReplacer.Replace(testCase.blueprint),
Filesystem: testCase.filesystem,
+ StubbedBuildDefinitions: testCase.stubbedBuildDefinitions,
})
})
}
@@ -107,6 +110,7 @@
filesystem: map[string]string{
soongCcVersionLibBpPath: soongCcVersionLibBp,
},
+ stubbedBuildDefinitions: []string{"//build/soong/cc/libbuildversion:libbuildversion"},
blueprint: `
{rule_name} {
name: "foo",
@@ -264,7 +268,8 @@
func TestCcBinarySplitSrcsByLang(t *testing.T) {
runCcHostBinaryTestCase(t, ccBinaryBp2buildTestCase{
- description: "split srcs by lang",
+ description: "split srcs by lang",
+ stubbedBuildDefinitions: []string{"fg_foo"},
blueprint: `
{rule_name} {
name: "foo",
@@ -276,7 +281,7 @@
],
include_build_directory: false,
}
-` + simpleModuleDoNotConvertBp2build("filegroup", "fg_foo"),
+` + simpleModule("filegroup", "fg_foo"),
targets: []testBazelTarget{
{"cc_binary", "foo", AttrNameToString{
"srcs": `[
@@ -300,17 +305,17 @@
func TestCcBinaryDoNotDistinguishBetweenDepsAndImplementationDeps(t *testing.T) {
runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
description: "no implementation deps",
+ stubbedBuildDefinitions: []string{"generated_hdr", "export_generated_hdr", "static_dep", "implementation_static_dep",
+ "whole_static_dep", "not_explicitly_exported_whole_static_dep", "shared_dep", "implementation_shared_dep"},
blueprint: `
genrule {
name: "generated_hdr",
cmd: "nothing to see here",
- bazel_module: { bp2build_available: false },
}
genrule {
name: "export_generated_hdr",
cmd: "nothing to see here",
- bazel_module: { bp2build_available: false },
}
{rule_name} {
@@ -326,12 +331,12 @@
export_generated_headers: ["export_generated_hdr"],
}
` +
- simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") +
- simpleModuleDoNotConvertBp2build("cc_library", "shared_dep") +
- simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"),
+ simpleModule("cc_library_static", "static_dep") +
+ simpleModule("cc_library_static", "implementation_static_dep") +
+ simpleModule("cc_library_static", "whole_static_dep") +
+ simpleModule("cc_library_static", "not_explicitly_exported_whole_static_dep") +
+ simpleModule("cc_library", "shared_dep") +
+ simpleModule("cc_library", "implementation_shared_dep"),
targets: []testBazelTarget{
{"cc_binary", "foo", AttrNameToString{
"deps": `[
@@ -502,6 +507,7 @@
func TestCcBinarySharedProto(t *testing.T) {
runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+ stubbedBuildDefinitions: []string{"libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
blueprint: soongCcProtoLibraries + `{rule_name} {
name: "foo",
srcs: ["foo.proto"],
@@ -524,6 +530,7 @@
func TestCcBinaryStaticProto(t *testing.T) {
runCcBinaryTests(t, ccBinaryBp2buildTestCase{
+ stubbedBuildDefinitions: []string{"libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
blueprint: soongCcProtoLibraries + `{rule_name} {
name: "foo",
srcs: ["foo.proto"],
@@ -1224,13 +1231,13 @@
func TestCcBinaryStatic_SystemSharedLibUsedAsDep(t *testing.T) {
runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{
- description: "cc_library_static system_shared_lib empty for linux_bionic variant",
+ stubbedBuildDefinitions: []string{"libm", "libc"},
+ description: "cc_library_static system_shared_lib empty for linux_bionic variant",
blueprint: soongCcLibraryStaticPreamble +
- simpleModuleDoNotConvertBp2build("cc_library", "libc") + `
+ simpleModule("cc_library", "libc") + `
cc_library {
name: "libm",
- bazel_module: { bp2build_available: false },
}
cc_binary {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index e50c710..ec603c2 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -35,19 +35,16 @@
soongCcVersionLibBp = `
cc_library_static {
name: "libbuildversion",
- bazel_module: { bp2build_available: false },
}
`
soongCcProtoLibraries = `
cc_library {
name: "libprotobuf-cpp-lite",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "libprotobuf-cpp-full",
- bazel_module: { bp2build_available: false },
}`
soongCcProtoPreamble = soongCcLibraryPreamble + soongCcProtoLibraries
@@ -55,6 +52,7 @@
func runCcLibraryTestCase(t *testing.T, tc Bp2buildTestCase) {
t.Helper()
+ tc.StubbedBuildDefinitions = append(tc.StubbedBuildDefinitions, "libprotobuf-cpp-lite", "libprotobuf-cpp-full")
RunBp2BuildTestCase(t, registerCcLibraryModuleTypes, tc)
}
@@ -65,6 +63,7 @@
ctx.RegisterModuleType("cc_prebuilt_library_static", cc.PrebuiltStaticLibraryFactory)
ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
ctx.RegisterModuleType("aidl_library", aidl_library.AidlLibraryFactory)
+ ctx.RegisterModuleType("ndk_library", cc.NdkLibraryFactory)
}
func TestCcLibrarySimple(t *testing.T) {
@@ -72,6 +71,7 @@
Description: "cc_library - simple example",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"//build/soong/cc/libbuildversion:libbuildversion", "some-headers"},
Filesystem: map[string]string{
soongCcVersionLibBpPath: soongCcVersionLibBp,
"android.cpp": "",
@@ -94,7 +94,7 @@
"foo-dir/a.h": "",
},
Blueprint: soongCcLibraryPreamble +
- simpleModuleDoNotConvertBp2build("cc_library_headers", "some-headers") + `
+ simpleModule("cc_library_headers", "some-headers") + `
cc_library {
name: "foo-lib",
srcs: ["impl.cpp"],
@@ -168,6 +168,7 @@
Description: "cc_library - trimmed example of //bionic/linker:ld-android",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"libc_headers"},
Filesystem: map[string]string{
"ld-android.cpp": "",
"linked_list.h": "",
@@ -176,7 +177,7 @@
"linker_cfi.h": "",
},
Blueprint: soongCcLibraryPreamble +
- simpleModuleDoNotConvertBp2build("cc_library_headers", "libc_headers") + `
+ simpleModule("cc_library_headers", "libc_headers") + `
cc_library {
name: "fake-ld-android",
srcs: ["ld_android.cpp"],
@@ -319,54 +320,49 @@
cc_library_static {
name: "static_dep_for_shared",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep_for_static",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep_for_both",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_for_shared",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_for_static",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_for_both",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_and_static_lib_for_both",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "shared_dep_for_shared",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "shared_dep_for_static",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "shared_dep_for_both",
- bazel_module: { bp2build_available: false },
}
`,
+ StubbedBuildDefinitions: []string{"static_dep_for_shared", "static_dep_for_static",
+ "static_dep_for_both", "whole_static_lib_for_shared", "whole_static_lib_for_static",
+ "whole_static_lib_for_both", "whole_and_static_lib_for_both", "shared_dep_for_shared",
+ "shared_dep_for_static", "shared_dep_for_both",
+ },
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
"copts": `[
@@ -457,24 +453,34 @@
},
include_build_directory: false,
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep_for_both") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep_for_both") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep_for_both") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep_for_both") +
- simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_shared") +
- simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_static") +
- simpleModuleDoNotConvertBp2build("cc_library", "shared_dep_for_both") +
- simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep_for_both"),
+` + simpleModule("cc_library_static", "static_dep_for_shared") +
+ simpleModule("cc_library_static", "implementation_static_dep_for_shared") +
+ simpleModule("cc_library_static", "static_dep_for_static") +
+ simpleModule("cc_library_static", "implementation_static_dep_for_static") +
+ simpleModule("cc_library_static", "static_dep_for_both") +
+ simpleModule("cc_library_static", "implementation_static_dep_for_both") +
+ simpleModule("cc_library_static", "whole_static_dep_for_shared") +
+ simpleModule("cc_library_static", "not_explicitly_exported_whole_static_dep_for_shared") +
+ simpleModule("cc_library_static", "whole_static_dep_for_static") +
+ simpleModule("cc_library_static", "not_explicitly_exported_whole_static_dep_for_static") +
+ simpleModule("cc_library_static", "whole_static_dep_for_both") +
+ simpleModule("cc_library_static", "not_explicitly_exported_whole_static_dep_for_both") +
+ simpleModule("cc_library", "shared_dep_for_shared") +
+ simpleModule("cc_library", "implementation_shared_dep_for_shared") +
+ simpleModule("cc_library", "shared_dep_for_static") +
+ simpleModule("cc_library", "implementation_shared_dep_for_static") +
+ simpleModule("cc_library", "shared_dep_for_both") +
+ simpleModule("cc_library", "implementation_shared_dep_for_both"),
+ StubbedBuildDefinitions: []string{"static_dep_for_shared", "implementation_static_dep_for_shared",
+ "static_dep_for_static", "implementation_static_dep_for_static", "static_dep_for_both",
+ "implementation_static_dep_for_both", "whole_static_dep_for_shared",
+ "not_explicitly_exported_whole_static_dep_for_shared", "whole_static_dep_for_static",
+ "not_explicitly_exported_whole_static_dep_for_static", "whole_static_dep_for_both",
+ "not_explicitly_exported_whole_static_dep_for_both", "shared_dep_for_shared",
+ "implementation_shared_dep_for_shared", "shared_dep_for_static",
+ "implementation_shared_dep_for_static", "shared_dep_for_both",
+ "implementation_shared_dep_for_both",
+ },
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
"copts": `[
@@ -549,6 +555,8 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
+ StubbedBuildDefinitions: []string{"//foo/bar:prebuilt_whole_static_lib_for_shared", "//foo/bar:prebuilt_whole_static_lib_for_static",
+ "//foo/bar:prebuilt_whole_static_lib_for_both"},
Filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
@@ -665,6 +673,10 @@
cc_library_static { name: "android_dep_for_shared" }
`,
},
+ StubbedBuildDefinitions: []string{"//foo/bar:static_dep_for_shared", "//foo/bar:static_dep_for_static",
+ "//foo/bar:static_dep_for_both", "//foo/bar:arm_static_dep_for_shared", "//foo/bar:arm_whole_static_dep_for_shared",
+ "//foo/bar:arm_shared_dep_for_shared", "//foo/bar:x86_dep_for_static", "//foo/bar:android_dep_for_shared",
+ },
Blueprint: soongCcLibraryPreamble,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "a_bp2build_cc_library_static", AttrNameToString{
@@ -746,6 +758,7 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
+ StubbedBuildDefinitions: []string{"//foo/bar:shared_filegroup", "//foo/bar:static_filegroup", "//foo/bar:both_filegroup"},
Filesystem: map[string]string{
"foo/bar/both_source.cpp": "",
"foo/bar/both_source.cc": "",
@@ -1017,10 +1030,10 @@
Description: "cc_library shared_libs",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"mylib"},
Blueprint: soongCcLibraryPreamble + `
cc_library {
name: "mylib",
- bazel_module: { bp2build_available: false },
}
cc_library {
@@ -1181,6 +1194,10 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"arm_whole_static_lib_excludes", "malloc_not_svelte_whole_static_lib",
+ "arm_static_lib_excludes", "malloc_not_svelte_whole_static_lib_excludes", "arm_shared_lib_excludes",
+ "malloc_not_svelte_static_lib_excludes", "arm_shared_lib_excludes", "malloc_not_svelte_shared_lib",
+ },
Blueprint: soongCcLibraryStaticPreamble + `
cc_library {
name: "foo_static",
@@ -1222,37 +1239,30 @@
cc_library {
name: "arm_whole_static_lib_excludes",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_whole_static_lib",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_whole_static_lib_excludes",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "arm_static_lib_excludes",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_static_lib_excludes",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "arm_shared_lib_excludes",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "malloc_not_svelte_shared_lib",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
@@ -1288,6 +1298,7 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"malloc_not_svelte_header_lib"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library {
name: "foo_static",
@@ -1302,7 +1313,6 @@
cc_library {
name: "malloc_not_svelte_header_lib",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: makeCcLibraryTargets("foo_static", AttrNameToString{
@@ -1812,10 +1822,10 @@
Description: "cc_library system_shared_libs empty for linux_bionic variant",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"libc_musl"},
Blueprint: soongCcLibraryPreamble + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library {
@@ -1843,6 +1853,7 @@
Description: "cc_library system_shared_libs empty for bionic variant",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"libc_musl"},
Blueprint: soongCcLibraryPreamble + `
cc_library {
name: "libc_musl",
@@ -1874,10 +1885,10 @@
Description: "cc_library system_shared_lib empty for musl variant",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"libc_musl"},
Blueprint: soongCcLibraryPreamble + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library {
@@ -1927,14 +1938,13 @@
Description: "cc_library system_shared_libs set for shared and root",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"libc", "libm"},
Blueprint: soongCcLibraryPreamble + `
cc_library {
name: "libc",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "libm",
- bazel_module: { bp2build_available: false },
}
cc_library {
@@ -2505,6 +2515,7 @@
runCcLibraryTestCase(t, Bp2buildTestCase{
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"//path/to/A:a_fg_proto"},
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
@@ -2548,11 +2559,12 @@
runCcLibraryTestCase(t, Bp2buildTestCase{
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"a_fg_proto", "b_protos", "c-proto-srcs", "proto-srcs-d"},
Blueprint: soongCcProtoPreamble +
- simpleModuleDoNotConvertBp2build("filegroup", "a_fg_proto") +
- simpleModuleDoNotConvertBp2build("filegroup", "b_protos") +
- simpleModuleDoNotConvertBp2build("filegroup", "c-proto-srcs") +
- simpleModuleDoNotConvertBp2build("filegroup", "proto-srcs-d") + `
+ simpleModule("filegroup", "a_fg_proto") +
+ simpleModule("filegroup", "b_protos") +
+ simpleModule("filegroup", "c-proto-srcs") +
+ simpleModule("filegroup", "proto-srcs-d") + `
cc_library {
name: "a",
srcs: [":a_fg_proto"],
@@ -2809,6 +2821,7 @@
"stubs_symbol_file": `"a.map.txt"`,
})
expectedBazelTargets = append(expectedBazelTargets, makeCcStubSuiteTargets("a", AttrNameToString{
+ "api_surface": `"module-libapi"`,
"soname": `"a.so"`,
"source_library_label": `"//foo/bar:a"`,
"stubs_symbol_file": `"a.map.txt"`,
@@ -2839,205 +2852,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",
@@ -3046,11 +2860,11 @@
Filesystem: map[string]string{
"bar.map.txt": "",
},
+ StubbedBuildDefinitions: []string{"barlib"},
Blueprint: `
cc_library {
name: "barlib",
stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "foolib",
@@ -3066,7 +2880,6 @@
ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
"implementation_dynamic_deps": `select({
"//build/bazel/rules/apex:foo": ["@api_surfaces//module-libapi/current:barlib"],
- "//build/bazel/rules/apex:system": ["@api_surfaces//module-libapi/current:barlib"],
"//conditions:default": [":barlib"],
})`,
"local_includes": `["."]`,
@@ -3082,16 +2895,15 @@
Filesystem: map[string]string{
"bar.map.txt": "",
},
- Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "bazlib") + `
+ StubbedBuildDefinitions: []string{"bazlib", "quxlib", "barlib"},
+ Blueprint: simpleModule("cc_library", "bazlib") + `
cc_library {
name: "quxlib",
stubs: { symbol_file: "bar.map.txt", versions: ["current"] },
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "barlib",
stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "foolib",
@@ -3124,10 +2936,6 @@
"@api_surfaces//module-libapi/current:barlib",
"@api_surfaces//module-libapi/current:quxlib",
],
- "//build/bazel/rules/apex:system": [
- "@api_surfaces//module-libapi/current:barlib",
- "@api_surfaces//module-libapi/current:quxlib",
- ],
"//conditions:default": [
":barlib",
":quxlib",
@@ -3209,18 +3017,18 @@
cc_library {
name: "foo",
- runtime_libs: ["foo"],
+ runtime_libs: ["bar"],
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
- "runtime_deps": `[":foo"]`,
+ "runtime_deps": `[":bar"]`,
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
- "runtime_deps": `[":foo"]`,
+ "runtime_deps": `[":bar"]`,
"local_includes": `["."]`,
}),
},
@@ -3431,6 +3239,7 @@
Description: "cc_library with non aidl filegroup",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"//path/to/A:A_aidl"},
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
@@ -3720,6 +3529,7 @@
Description: "cc_aidl_library depends on libs from parent cc_library_static",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"bar-static", "baz-static", "bar-shared", "baz-shared"},
Blueprint: `
cc_library_static {
name: "foo",
@@ -3741,10 +3551,10 @@
"baz-shared",
],
}` +
- simpleModuleDoNotConvertBp2build("cc_library_static", "bar-static") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "baz-static") +
- simpleModuleDoNotConvertBp2build("cc_library", "bar-shared") +
- simpleModuleDoNotConvertBp2build("cc_library", "baz-shared"),
+ simpleModule("cc_library_static", "bar-static") +
+ simpleModule("cc_library_static", "baz-static") +
+ simpleModule("cc_library", "bar-shared") +
+ simpleModule("cc_library", "baz-shared"),
ExpectedBazelTargets: []string{
MakeBazelTarget("aidl_library", "foo_aidl_library", AttrNameToString{
"srcs": `["Foo.aidl"]`,
@@ -3843,8 +3653,8 @@
{
description: "cc_library with afdo enabled and existing profile",
filesystem: map[string]string{
- "vendor/google_data/pgo_profile/sampling/BUILD": "",
- "vendor/google_data/pgo_profile/sampling/foo.afdo": "",
+ "vendor/google_data/pgo_profile/sampling/Android.bp": "",
+ "vendor/google_data/pgo_profile/sampling/foo.afdo": "",
},
expectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
@@ -3856,8 +3666,8 @@
{
description: "cc_library with afdo enabled and existing profile in AOSP",
filesystem: map[string]string{
- "toolchain/pgo-profiles/sampling/BUILD": "",
- "toolchain/pgo-profiles/sampling/foo.afdo": "",
+ "toolchain/pgo-profiles/sampling/Android.bp": "",
+ "toolchain/pgo-profiles/sampling/foo.afdo": "",
},
expectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
@@ -3869,8 +3679,8 @@
{
description: "cc_library with afdo enabled but profile filename doesn't match with module name",
filesystem: map[string]string{
- "toolchain/pgo-profiles/sampling/BUILD": "",
- "toolchain/pgo-profiles/sampling/bar.afdo": "",
+ "toolchain/pgo-profiles/sampling/Android.bp": "",
+ "toolchain/pgo-profiles/sampling/bar.afdo": "",
},
expectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
@@ -4288,17 +4098,16 @@
Description: "cc_library with in apex with stub shared_libs and export_shared_lib_headers",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"barlib", "bazlib"},
Blueprint: `
cc_library {
name: "barlib",
stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
apex_available: ["//apex_available:platform",],
}
cc_library {
name: "bazlib",
stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
apex_available: ["//apex_available:platform",],
}
cc_library {
@@ -4674,6 +4483,7 @@
Description: "cc_library is built from .y/.yy files",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"staticlib", "sharedlib"},
Blueprint: soongCcLibraryPreamble + `cc_library {
name: "a",
srcs: [
@@ -4690,11 +4500,9 @@
}
cc_library_static {
name: "staticlib",
- bazel_module: { bp2build_available: false },
}
cc_library {
name: "sharedlib",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
@@ -4948,7 +4756,7 @@
canonical_path_from_root: true,
}
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+` + simpleModule("cc_library", "libprotobuf-cpp-lite"),
Filesystem: map[string]string{
"bar/Android.bp": "",
"baz/subbaz/Android.bp": "",
@@ -5016,7 +4824,7 @@
canonical_path_from_root: false,
}
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+` + simpleModule("cc_library", "libprotobuf-cpp-lite"),
Filesystem: map[string]string{
"bar/Android.bp": "",
"baz/subbaz/Android.bp": "",
@@ -5086,7 +4894,7 @@
include_dirs: ["bar"],
}
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+` + simpleModule("cc_library", "libprotobuf-cpp-lite"),
Filesystem: map[string]string{
"bar/Android.bp": "",
"bar/bar.proto": "",
@@ -5157,7 +4965,7 @@
include_dirs: ["baz"],
}
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+` + simpleModule("cc_library", "libprotobuf-cpp-lite"),
Filesystem: map[string]string{
"bar/Android.bp": "", // package boundary
"baz/Android.bp": "",
@@ -5192,7 +5000,14 @@
Description: "cc_library depends on .proto files using proto.local_include_dirs",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+ Blueprint: `
+cc_library {
+ name: "libprotobuf-cpp-lite",
+ // TODO: b/285631638 - A stubbed proto library dependency does not work as a protolib
+ // dependency of cc_library_static.
+ bazel_module: { bp2build_available: false },
+}
+`,
Filesystem: map[string]string{
"foo/Android.bp": `cc_library_static {
name: "foo",
@@ -5249,7 +5064,7 @@
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") + `
+ Blueprint: simpleModule("cc_library", "libprotobuf-cpp-lite") + `
cc_library {
name: "foo_device",
device_supported: true, // this is the default behavior, but added explicitly here for illustration
@@ -5279,3 +5094,93 @@
}
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)
+}
+
+func TestNdkLibraryConversion(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "ndk_library conversion",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `
+cc_library {
+ name: "libfoo",
+ bazel_module: { bp2build_available: false },
+}
+ndk_library {
+ name: "libfoo",
+ first_version: "29",
+ symbol_file: "libfoo.map.txt",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_stub_suite", "libfoo.ndk_stub_libs", AttrNameToString{
+ "api_surface": `"publicapi"`,
+ "soname": `"libfoo.so"`,
+ "source_library_label": `"//:libfoo"`,
+ "symbol_file": `"libfoo.map.txt"`,
+ "versions": `[
+ "29",
+ "30",
+ "S",
+ "Tiramisu",
+ "current",
+ ]`,
+ }),
+ },
+ }
+ runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 072f5b3..bf3351a 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -57,6 +57,7 @@
func registerCcLibraryHeadersModuleTypes(ctx android.RegistrationContext) {
cc.RegisterCCBuildComponents(ctx)
+ cc.RegisterLibraryHeadersBuildComponents(ctx)
}
func runCcLibraryHeadersTestCase(t *testing.T, tc Bp2buildTestCase) {
@@ -66,9 +67,7 @@
func TestCcLibraryHeadersSimple(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers test",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ Description: "cc_library_headers test",
Filesystem: map[string]string{
"lib-1/lib1a.h": "",
"lib-1/lib1b.h": "",
@@ -123,101 +122,32 @@
})
}
-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) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers test with os-specific header_libs props",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers test with os-specific header_libs props",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"android-lib", "base-lib", "darwin-lib",
+ "linux-lib", "linux_bionic-lib", "windows-lib"},
Blueprint: soongCcLibraryPreamble + `
cc_library_headers {
name: "android-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "base-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "darwin-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "linux-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "linux_bionic-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "windows-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "foo_headers",
@@ -264,18 +194,15 @@
func TestCcLibraryHeadersOsSpecficHeaderLibsExportHeaderLibHeaders(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers test with os-specific header_libs and export_header_lib_headers props",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"android-lib", "exported-lib"},
Blueprint: soongCcLibraryPreamble + `
cc_library_headers {
name: "android-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "exported-lib",
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "foo_headers",
@@ -300,10 +227,8 @@
func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers test with arch-specific and target-specific export_system_include_dirs props",
+ Filesystem: map[string]string{},
Blueprint: soongCcLibraryPreamble + `cc_library_headers {
name: "foo_headers",
export_system_include_dirs: [
@@ -359,9 +284,7 @@
func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers test",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
+ Description: "cc_library_headers test",
Filesystem: map[string]string{
"lib-1/lib1a.h": "",
"lib-1/lib1b.h": "",
@@ -392,10 +315,9 @@
func TestCcLibraryHeadersExportedStaticLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers exported_static_lib_headers is reexported",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers exported_static_lib_headers is reexported",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"foo_export"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -403,7 +325,7 @@
static_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -414,10 +336,9 @@
func TestCcLibraryHeadersExportedSharedLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers exported_shared_lib_headers is reexported",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers exported_shared_lib_headers is reexported",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"foo_export"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -425,7 +346,7 @@
shared_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -436,10 +357,9 @@
func TestCcLibraryHeadersExportedHeaderLibHeadersReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers exported_header_lib_headers is reexported",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers exported_header_lib_headers is reexported",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"foo_export"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -447,7 +367,7 @@
header_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -458,17 +378,38 @@
func TestCcLibraryHeadersWholeStaticLibsReexported(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
- Description: "cc_library_headers whole_static_libs is reexported",
- ModuleTypeUnderTest: "cc_library_headers",
- ModuleTypeUnderTestFactory: cc.LibraryHeaderFactory,
- Filesystem: map[string]string{},
+ Description: "cc_library_headers whole_static_libs is reexported",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"foo_export"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
whole_static_libs: ["foo_export"],
bazel_module: { bp2build_available: true },
}
-` + simpleModuleDoNotConvertBp2build("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export"),
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
+ "deps": `[":foo_export"]`,
+ }),
+ },
+ })
+}
+
+func TestPrebuiltCcLibraryHeadersWholeStaticLibsReexported(t *testing.T) {
+ runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_headers whole_static_libs is reexported",
+ Filesystem: map[string]string{
+ "foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"),
+ },
+ StubbedBuildDefinitions: []string{"foo_export"},
+ Blueprint: soongCcLibraryHeadersPreamble + `
+cc_prebuilt_library_headers {
+ name: "foo_headers",
+ whole_static_libs: ["foo_export"],
+ bazel_module: { bp2build_available: true },
+}
+` + simpleModule("cc_library_headers", "foo_export"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 90b13b0..6f600da 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -32,11 +32,13 @@
ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory)
ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("ndk_library", cc.NdkLibraryFactory)
}
func runCcLibrarySharedTestCase(t *testing.T, tc Bp2buildTestCase) {
t.Helper()
t.Parallel()
+ tc.StubbedBuildDefinitions = append(tc.StubbedBuildDefinitions, "libbuildversion", "libprotobuf-cpp-lite", "libprotobuf-cpp-full")
(&tc).ModuleTypeUnderTest = "cc_library_shared"
(&tc).ModuleTypeUnderTestFactory = cc.LibrarySharedFactory
RunBp2BuildTestCase(t, registerCcLibrarySharedModuleTypes, tc)
@@ -44,7 +46,8 @@
func TestCcLibrarySharedSimple(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared simple overall test",
+ Description: "cc_library_shared simple overall test",
+ StubbedBuildDefinitions: []string{"header_lib_1", "header_lib_2", "whole_static_lib_1", "whole_static_lib_2", "shared_lib_1", "shared_lib_2"},
Filesystem: map[string]string{
// NOTE: include_dir headers *should not* appear in Bazel hdrs later (?)
"include_dir_1/include_dir_1_a.h": "",
@@ -69,37 +72,31 @@
cc_library_headers {
name: "header_lib_1",
export_include_dirs: ["header_lib_1"],
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "header_lib_2",
export_include_dirs: ["header_lib_2"],
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "shared_lib_1",
srcs: ["shared_lib_1.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "shared_lib_2",
srcs: ["shared_lib_2.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_1",
srcs: ["whole_static_lib_1.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_2",
srcs: ["whole_static_lib_2.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
@@ -185,16 +182,15 @@
func TestCcLibrarySharedArchSpecificSharedLib(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared arch-specific shared_libs with whole_static_libs",
- Filesystem: map[string]string{},
+ Description: "cc_library_shared arch-specific shared_libs with whole_static_libs",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"static_dep", "shared_dep"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_static {
name: "static_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "shared_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "foo_shared",
@@ -218,12 +214,12 @@
func TestCcLibrarySharedOsSpecificSharedLib(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared os-specific shared_libs",
- Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"shared_dep"},
+ Description: "cc_library_shared os-specific shared_libs",
+ Filesystem: map[string]string{},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "shared_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "foo_shared",
@@ -243,20 +239,18 @@
func TestCcLibrarySharedBaseArchOsSpecificSharedLib(t *testing.T) {
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
- Description: "cc_library_shared base, arch, and os-specific shared_libs",
- Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"shared_dep", "shared_dep2", "shared_dep3"},
+ Description: "cc_library_shared base, arch, and os-specific shared_libs",
+ Filesystem: map[string]string{},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "shared_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "shared_dep2",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "shared_dep3",
- bazel_module: { bp2build_available: false },
}
cc_library_shared {
name: "foo_shared",
@@ -511,6 +505,7 @@
Filesystem: map[string]string{
soongCcVersionLibBpPath: soongCcVersionLibBp,
},
+ StubbedBuildDefinitions: []string{"//build/soong/cc/libbuildversion:libbuildversion"},
Blueprint: soongCcProtoPreamble + `cc_library_shared {
name: "foo",
use_version_lib: true,
@@ -543,6 +538,7 @@
},
Blueprint: soongCcLibraryPreamble,
ExpectedBazelTargets: []string{makeCcStubSuiteTargets("a", AttrNameToString{
+ "api_surface": `"module-libapi"`,
"soname": `"a.so"`,
"source_library_label": `"//foo/bar:a"`,
"stubs_symbol_file": `"a.map.txt"`,
@@ -564,11 +560,11 @@
Description: "cc_library_shared stubs",
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "a",
stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
include_build_directory: false,
apex_available: ["made_up_apex"],
}
@@ -593,11 +589,11 @@
Description: "cc_library_shared stubs",
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "a",
stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
include_build_directory: false,
apex_available: ["apex_a"],
}
@@ -627,19 +623,18 @@
Description: "cc_library_shared stubs",
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"libplatform_stable", "libapexfoo_stable"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "libplatform_stable",
stubs: { symbol_file: "libplatform_stable.map.txt", versions: ["28", "29", "current"] },
apex_available: ["//apex_available:platform"],
- bazel_module: { bp2build_available: false },
include_build_directory: false,
}
cc_library_shared {
name: "libapexfoo_stable",
stubs: { symbol_file: "libapexfoo_stable.map.txt", versions: ["28", "29", "current"] },
apex_available: ["apexfoo"],
- bazel_module: { bp2build_available: false },
include_build_directory: false,
}
cc_library_shared {
@@ -661,7 +656,7 @@
":libapexfoo_stable",
],
"//build/bazel/rules/apex:system": [
- "@api_surfaces//module-libapi/current:libplatform_stable",
+ ":libplatform_stable",
"@api_surfaces//module-libapi/current:libapexfoo_stable",
],
"//conditions:default": [
@@ -684,11 +679,11 @@
Description: "cc_library_shared stubs",
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "a",
stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
include_build_directory: false,
apex_available: ["//apex_available:platform", "apex_a"],
}
@@ -720,11 +715,11 @@
Description: "cc_library depeends on impl for all configurations",
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "a",
stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
apex_available: ["//apex_available:platform"],
}
cc_library_shared {
@@ -747,11 +742,11 @@
runCcLibrarySharedTestCase(t, Bp2buildTestCase{
ModuleTypeUnderTest: "cc_library_shared",
ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: soongCcLibrarySharedPreamble + `
cc_library_shared {
name: "a",
stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
- bazel_module: { bp2build_available: false },
include_build_directory: false,
apex_available: ["//apex_available:platform", "apex_a", "apex_b"],
}
@@ -929,14 +924,14 @@
cc_library_shared {
name: "foo",
- runtime_libs: ["foo"],
+ runtime_libs: ["bar"],
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
- "runtime_deps": `[":foo"]`,
+ "runtime_deps": `[":bar"]`,
"local_includes": `["."]`,
}),
},
@@ -1442,6 +1437,7 @@
`,
ExpectedBazelTargets: []string{
makeCcStubSuiteTargets("a", AttrNameToString{
+ "api_surface": `"module-libapi"`,
"soname": `"a.so"`,
"source_library_label": `"//:a"`,
"stubs_symbol_file": `"a.map.txt"`,
@@ -1456,6 +1452,7 @@
"stubs_symbol_file": `"a.map.txt"`,
}),
makeCcStubSuiteTargets("b", AttrNameToString{
+ "api_surface": `"module-libapi"`,
"soname": `"b.so"`,
"source_library_label": `"//:b"`,
"stubs_symbol_file": `"b.map.txt"`,
@@ -1592,3 +1589,62 @@
]`,
})}})
}
+
+func TestCcLibrarySdkVariantUsesStubs(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared stubs",
+ ModuleTypeUnderTest: "cc_library_shared",
+ ModuleTypeUnderTestFactory: cc.LibrarySharedFactory,
+ Blueprint: soongCcLibrarySharedPreamble + `
+cc_library_shared {
+ name: "libUsesSdk",
+ sdk_version: "current",
+ shared_libs: [
+ "libNoStubs",
+ "libHasApexStubs",
+ "libHasApexAndNdkStubs",
+ ]
+}
+cc_library_shared {
+ name: "libNoStubs",
+ bazel_module: { bp2build_available: false },
+}
+cc_library_shared {
+ name: "libHasApexStubs",
+ stubs: { symbol_file: "a.map.txt", versions: ["28", "29", "current"] },
+ bazel_module: { bp2build_available: false },
+ apex_available: ["apex_a"],
+}
+cc_library_shared {
+ name: "libHasApexAndNdkStubs",
+ stubs: { symbol_file: "b.map.txt", versions: ["28", "29", "current"] },
+ bazel_module: { bp2build_available: false },
+ apex_available: ["apex_b"],
+}
+ndk_library {
+ name: "libHasApexAndNdkStubs",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "libUsesSdk", AttrNameToString{
+ "implementation_dynamic_deps": `[":libNoStubs"] + select({
+ "//build/bazel/rules/apex:system": [
+ "@api_surfaces//module-libapi/current:libHasApexStubs",
+ "@api_surfaces//module-libapi/current:libHasApexAndNdkStubs",
+ ],
+ "//build/bazel/rules/apex:unbundled_app": [
+ ":libHasApexStubs",
+ "//.:libHasApexAndNdkStubs.ndk_stub_libs",
+ ],
+ "//conditions:default": [
+ ":libHasApexStubs",
+ ":libHasApexAndNdkStubs",
+ ],
+ })`,
+ "local_includes": `["."]`,
+ "sdk_version": `"current"`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 89ec8f9..0587aae 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -96,41 +96,37 @@
"implicit_include_1.h": "",
"implicit_include_2.h": "",
},
+ StubbedBuildDefinitions: []string{"header_lib_1", "header_lib_2",
+ "static_lib_1", "static_lib_2", "whole_static_lib_1", "whole_static_lib_2"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library_headers {
name: "header_lib_1",
export_include_dirs: ["header_lib_1"],
- bazel_module: { bp2build_available: false },
}
cc_library_headers {
name: "header_lib_2",
export_include_dirs: ["header_lib_2"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_lib_1",
srcs: ["static_lib_1.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_lib_2",
srcs: ["static_lib_2.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_1",
srcs: ["whole_static_lib_1.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "whole_static_lib_2",
srcs: ["whole_static_lib_2.cc"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -392,16 +388,15 @@
func TestCcLibraryStaticArchSpecificStaticLib(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static arch-specific static_libs",
- Filesystem: map[string]string{},
+ Description: "cc_library_static arch-specific static_libs",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"static_dep", "static_dep2"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "static_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep2",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "foo_static",
@@ -425,16 +420,15 @@
func TestCcLibraryStaticOsSpecificStaticLib(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static os-specific static_libs",
- Filesystem: map[string]string{},
+ Description: "cc_library_static os-specific static_libs",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"static_dep", "static_dep2"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "static_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep2",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "foo_static",
@@ -460,22 +454,20 @@
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
Description: "cc_library_static base, arch and os-specific static_libs",
Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"static_dep", "static_dep2", "static_dep3",
+ "static_dep4"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "static_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep2",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep3",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "static_dep4",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "foo_static",
@@ -756,12 +748,12 @@
func TestCcLibraryStaticMultipleDepSameName(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static multiple dep same name panic",
- Filesystem: map[string]string{},
+ Description: "cc_library_static multiple dep same name panic",
+ Filesystem: map[string]string{},
+ StubbedBuildDefinitions: []string{"static_dep"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library_static {
name: "static_dep",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
name: "foo_static",
@@ -961,17 +953,16 @@
func TestCcLibraryStaticGeneratedHeadersAllPartitions(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"generated_hdr", "export_generated_hdr"},
Blueprint: soongCcLibraryStaticPreamble + `
genrule {
name: "generated_hdr",
cmd: "nothing to see here",
- bazel_module: { bp2build_available: false },
}
genrule {
name: "export_generated_hdr",
cmd: "nothing to see here",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1005,19 +996,18 @@
func TestCcLibraryStaticGeneratedHeadersMultipleExports(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"generated_hdr", "export_generated_hdr"},
Blueprint: soongCcLibraryStaticPreamble + `
genrule {
name: "generated_hdr",
cmd: "nothing to see here",
export_include_dirs: ["foo", "bar"],
- bazel_module: { bp2build_available: false },
}
genrule {
name: "export_generated_hdr",
cmd: "nothing to see here",
export_include_dirs: ["a", "b"],
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1040,22 +1030,26 @@
func TestCcLibraryStaticArchSrcsExcludeSrcsGeneratedFiles(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
Description: "cc_library_static arch srcs/exclude_srcs with generated files",
+ StubbedBuildDefinitions: []string{"//dep:generated_src_other_pkg", "//dep:generated_hdr_other_pkg",
+ "//dep:generated_src_other_pkg_x86", "//dep:generated_hdr_other_pkg_x86", "//dep:generated_hdr_other_pkg_android",
+ "generated_src", "generated_src_not_x86", "generated_src_android", "generated_hdr",
+ },
Filesystem: map[string]string{
"common.cpp": "",
"for-x86.cpp": "",
"not-for-x86.cpp": "",
"not-for-everything.cpp": "",
- "dep/Android.bp": simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_src_other_pkg_x86") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_x86") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_hdr_other_pkg_android"),
+ "dep/Android.bp": simpleModule("genrule", "generated_src_other_pkg") +
+ simpleModule("genrule", "generated_hdr_other_pkg") +
+ simpleModule("genrule", "generated_src_other_pkg_x86") +
+ simpleModule("genrule", "generated_hdr_other_pkg_x86") +
+ simpleModule("genrule", "generated_hdr_other_pkg_android"),
},
Blueprint: soongCcLibraryStaticPreamble +
- simpleModuleDoNotConvertBp2build("genrule", "generated_src") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_src_not_x86") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_src_android") +
- simpleModuleDoNotConvertBp2build("genrule", "generated_hdr") + `
+ simpleModule("genrule", "generated_src") +
+ simpleModule("genrule", "generated_src_not_x86") +
+ simpleModule("genrule", "generated_src_android") +
+ simpleModule("genrule", "generated_hdr") + `
cc_library_static {
name: "foo_static",
srcs: ["common.cpp", "not-for-*.cpp"],
@@ -1340,11 +1334,11 @@
func TestStaticLibrary_SystemSharedLibsBionicEmpty(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static system_shared_lib empty for bionic variant",
+ Description: "cc_library_static system_shared_lib empty for bionic variant",
+ StubbedBuildDefinitions: []string{"libc_musl"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1374,11 +1368,11 @@
// only for linux_bionic, but `android` had `["libc", "libdl", "libm"].
// b/195791252 tracks the fix.
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
+ Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
+ StubbedBuildDefinitions: []string{"libc_musl"},
Blueprint: soongCcLibraryStaticPreamble + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1458,12 +1452,12 @@
func TestStaticLibrary_SystemSharedLibsBionic(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static system_shared_libs set for bionic variant",
+ Description: "cc_library_static system_shared_libs set for bionic variant",
+ StubbedBuildDefinitions: []string{"libc", "libc_musl"},
Blueprint: soongCcLibraryStaticPreamble +
- simpleModuleDoNotConvertBp2build("cc_library", "libc") + `
+ simpleModule("cc_library", "libc") + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1491,13 +1485,13 @@
func TestStaticLibrary_SystemSharedLibsLinuxRootAndLinuxBionic(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static system_shared_libs set for root and linux_bionic variant",
+ Description: "cc_library_static system_shared_libs set for root and linux_bionic variant",
+ StubbedBuildDefinitions: []string{"libc", "libm", "libc_musl"},
Blueprint: soongCcLibraryStaticPreamble +
- simpleModuleDoNotConvertBp2build("cc_library", "libc") +
- simpleModuleDoNotConvertBp2build("cc_library", "libm") + `
+ simpleModule("cc_library", "libc") +
+ simpleModule("cc_library", "libm") + `
cc_library {
name: "libc_musl",
- bazel_module: { bp2build_available: false },
}
cc_library_static {
@@ -1525,9 +1519,10 @@
func TestCcLibrarystatic_SystemSharedLibUsedAsDep(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
- Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
+ Description: "cc_library_static system_shared_lib empty for linux_bionic variant",
+ StubbedBuildDefinitions: []string{"libc", "libm"},
Blueprint: soongCcLibraryStaticPreamble +
- simpleModuleDoNotConvertBp2build("cc_library", "libc") + `
+ simpleModule("cc_library", "libc") + `
cc_library {
name: "libm",
@@ -1535,7 +1530,6 @@
symbol_file: "libm.map.txt",
versions: ["current"],
},
- bazel_module: { bp2build_available: false },
apex_available: ["com.android.runtime"],
}
@@ -1613,6 +1607,7 @@
func TestCcLibraryStaticProto(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
Blueprint: soongCcProtoPreamble + `cc_library_static {
name: "foo",
srcs: ["foo.proto"],
@@ -1639,6 +1634,7 @@
Filesystem: map[string]string{
soongCcVersionLibBpPath: soongCcVersionLibBp,
},
+ StubbedBuildDefinitions: []string{"//build/soong/cc/libbuildversion:libbuildversion", "libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
Blueprint: soongCcProtoPreamble + `cc_library_static {
name: "foo",
use_version_lib: true,
@@ -1658,6 +1654,8 @@
Filesystem: map[string]string{
soongCcVersionLibBpPath: soongCcVersionLibBp,
},
+ StubbedBuildDefinitions: []string{"//build/soong/cc/libbuildversion:libbuildversion", "libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
+
Blueprint: soongCcProtoPreamble + `cc_library_static {
name: "foo",
use_version_lib: true,
@@ -1674,6 +1672,7 @@
func TestCcLibraryStaticStdInFlags(t *testing.T) {
runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"libprotobuf-cpp-full", "libprotobuf-cpp-lite"},
Blueprint: soongCcProtoPreamble + `cc_library_static {
name: "foo",
cflags: ["-std=candcpp"],
@@ -1767,14 +1766,14 @@
cc_library_static {
name: "foo",
- runtime_libs: ["foo"],
+ runtime_libs: ["bar"],
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_shared", "bar", AttrNameToString{
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
- "runtime_deps": `[":foo"]`,
+ "runtime_deps": `[":bar"]`,
"local_includes": `["."]`,
}),
},
@@ -2260,6 +2259,7 @@
Description: "cc_library with a .proto file generated from a genrule",
ModuleTypeUnderTest: "cc_library_static",
ModuleTypeUnderTestFactory: cc.LibraryStaticFactory,
+ StubbedBuildDefinitions: []string{"libprotobuf-cpp-lite"},
Blueprint: soongCcLibraryPreamble + `
cc_library_static {
name: "mylib",
@@ -2269,7 +2269,7 @@
name: "myprotogen",
out: ["myproto.proto"],
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+` + simpleModule("cc_library", "libprotobuf-cpp-lite"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "mylib", AttrNameToString{
"local_includes": `["."]`,
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index ecfcb5a..e1e2f43 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -317,7 +317,8 @@
func TestCcObjectDepsAndLinkerScriptSelects(t *testing.T) {
runCcObjectTestCase(t, Bp2buildTestCase{
- Description: "cc_object setting deps and linker_script across archs",
+ Description: "cc_object setting deps and linker_script across archs",
+ StubbedBuildDefinitions: []string{"x86_obj", "x86_64_obj", "arm_obj"},
Blueprint: `cc_object {
name: "foo",
srcs: ["base.cpp"],
@@ -343,7 +344,6 @@
system_shared_libs: [],
srcs: ["x86.cpp"],
include_build_directory: false,
- bazel_module: { bp2build_available: false },
}
cc_object {
@@ -351,7 +351,6 @@
system_shared_libs: [],
srcs: ["x86_64.cpp"],
include_build_directory: false,
- bazel_module: { bp2build_available: false },
}
cc_object {
@@ -359,7 +358,6 @@
system_shared_libs: [],
srcs: ["arm.cpp"],
include_build_directory: false,
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
diff --git a/bp2build/cc_prebuilt_library_conversion_test.go b/bp2build/cc_prebuilt_library_conversion_test.go
index b88960e..8c33be3 100644
--- a/bp2build/cc_prebuilt_library_conversion_test.go
+++ b/bp2build/cc_prebuilt_library_conversion_test.go
@@ -17,6 +17,7 @@
"fmt"
"testing"
+ "android/soong/android"
"android/soong/cc"
)
@@ -360,3 +361,52 @@
},
})
}
+
+func TestPrebuiltNdkStlConversion(t *testing.T) {
+ registerNdkStlModuleTypes := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("ndk_prebuilt_static_stl", cc.NdkPrebuiltStaticStlFactory)
+ ctx.RegisterModuleType("ndk_prebuilt_shared_stl", cc.NdkPrebuiltSharedStlFactory)
+ }
+ RunBp2BuildTestCase(t, registerNdkStlModuleTypes, Bp2buildTestCase{
+ Description: "TODO",
+ Blueprint: `
+ndk_prebuilt_static_stl {
+ name: "ndk_libfoo_static",
+ export_include_dirs: ["dir1", "dir2"],
+}
+ndk_prebuilt_shared_stl {
+ name: "ndk_libfoo_shared",
+ export_include_dirs: ["dir1", "dir2"],
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_prebuilt_library_static", "ndk_libfoo_static", AttrNameToString{
+ "static_library": `select({
+ "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_static.a",
+ "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_static.a",
+ "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_static.a",
+ "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_static.a",
+ "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_static.a",
+ "//conditions:default": None,
+ })`,
+ "export_system_includes": `[
+ "dir1",
+ "dir2",
+ ]`,
+ }),
+ MakeBazelTarget("cc_prebuilt_library_shared", "ndk_libfoo_shared", AttrNameToString{
+ "shared_library": `select({
+ "//build/bazel/platforms/os_arch:android_arm": "current/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libfoo_shared.so",
+ "//build/bazel/platforms/os_arch:android_arm64": "current/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libfoo_shared.so",
+ "//build/bazel/platforms/os_arch:android_riscv64": "current/sources/cxx-stl/llvm-libc++/libs/riscv64/libfoo_shared.so",
+ "//build/bazel/platforms/os_arch:android_x86": "current/sources/cxx-stl/llvm-libc++/libs/x86/libfoo_shared.so",
+ "//build/bazel/platforms/os_arch:android_x86_64": "current/sources/cxx-stl/llvm-libc++/libs/x86_64/libfoo_shared.so",
+ "//conditions:default": None,
+ })`,
+ "export_system_includes": `[
+ "dir1",
+ "dir2",
+ ]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_test_conversion_test.go b/bp2build/cc_test_conversion_test.go
index 9639ab9..679a364 100644
--- a/bp2build/cc_test_conversion_test.go
+++ b/bp2build/cc_test_conversion_test.go
@@ -24,10 +24,11 @@
)
type ccTestBp2buildTestCase struct {
- description string
- blueprint string
- filesystem map[string]string
- targets []testBazelTarget
+ description string
+ blueprint string
+ filesystem map[string]string
+ targets []testBazelTarget
+ stubbedBuildDefinitions []string
}
func registerCcTestModuleTypes(ctx android.RegistrationContext) {
@@ -52,6 +53,7 @@
ModuleTypeUnderTestFactory: cc.TestFactory,
Description: description,
Blueprint: testCase.blueprint,
+ StubbedBuildDefinitions: testCase.stubbedBuildDefinitions,
})
})
}
@@ -59,6 +61,8 @@
func TestBasicCcTest(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
description: "basic cc_test with commonly used attributes",
+ stubbedBuildDefinitions: []string{"libbuildversion", "libprotobuf-cpp-lite", "libprotobuf-cpp-full",
+ "foolib", "hostlib", "data_mod", "cc_bin", "cc_lib", "cc_test_lib2", "libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest",
@@ -89,14 +93,14 @@
host_supported: true,
include_build_directory: false,
}
-` + simpleModuleDoNotConvertBp2build("cc_library", "foolib") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "hostlib") +
- simpleModuleDoNotConvertBp2build("genrule", "data_mod") +
- simpleModuleDoNotConvertBp2build("cc_binary", "cc_bin") +
- simpleModuleDoNotConvertBp2build("cc_library", "cc_lib") +
- simpleModuleDoNotConvertBp2build("cc_test_library", "cc_test_lib2") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library", "foolib") +
+ simpleModule("cc_library_static", "hostlib") +
+ simpleModule("genrule", "data_mod") +
+ simpleModule("cc_binary", "cc_bin") +
+ simpleModule("cc_library", "cc_lib") +
+ simpleModule("cc_test_library", "cc_test_lib2") +
+ simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_library_shared", "cc_test_lib1", AttrNameToString{}},
{"cc_library_static", "cc_test_lib1_bp2build_cc_library_static", AttrNameToString{}},
@@ -188,7 +192,8 @@
func TestCcTest_TestOptions_Tags(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test with test_options.tags converted to tags",
+ description: "cc test with test_options.tags converted to tags",
+ stubbedBuildDefinitions: []string{"libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest",
@@ -196,8 +201,8 @@
srcs: ["test.cpp"],
test_options: { tags: ["no-remote"] },
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"tags": `["no-remote"]`,
@@ -230,14 +235,15 @@
filesystem: map[string]string{
"test_config.xml": "",
},
+ stubbedBuildDefinitions: []string{"libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest",
srcs: ["test.cpp"],
test_config: "test_config.xml",
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -269,13 +275,14 @@
"AndroidTest.xml": "",
"DynamicConfig.xml": "",
},
+ stubbedBuildDefinitions: []string{"libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest",
srcs: ["test.cpp"],
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -307,6 +314,7 @@
filesystem: map[string]string{
"test_config_template.xml": "",
},
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
@@ -315,8 +323,8 @@
auto_gen_config: true,
isolated: true,
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"auto_generate_test_config": "True",
@@ -347,15 +355,16 @@
func TestCcTest_WithExplicitGTestDepInAndroidBp(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that lists libgtest in Android.bp should not have dups of libgtest in BUILD file",
+ description: "cc test that lists libgtest in Android.bp should not have dups of libgtest in BUILD file",
+ stubbedBuildDefinitions: []string{"libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest",
srcs: ["test.cpp"],
static_libs: ["libgtest"],
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -382,15 +391,16 @@
func TestCcTest_WithIsolatedTurnedOn(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that sets `isolated: true` should run with ligtest_isolated_main instead of libgtest_main",
+ description: "cc test that sets `isolated: true` should run with ligtest_isolated_main instead of libgtest_main",
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
srcs: ["test.cpp"],
isolated: true,
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -415,7 +425,8 @@
func TestCcTest_GtestExplicitlySpecifiedInAndroidBp(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "If `gtest` is explicit in Android.bp, it should be explicit in BUILD files as well",
+ description: "If `gtest` is explicit in Android.bp, it should be explicit in BUILD files as well",
+ stubbedBuildDefinitions: []string{"libgtest_main", "libgtest"},
blueprint: `
cc_test {
name: "mytest_with_gtest",
@@ -425,8 +436,8 @@
name: "mytest_with_no_gtest",
gtest: false,
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_main") +
- simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest"),
+` + simpleModule("cc_library_static", "libgtest_main") +
+ simpleModule("cc_library_static", "libgtest"),
targets: []testBazelTarget{
{"cc_test", "mytest_with_gtest", AttrNameToString{
"local_includes": `["."]`,
@@ -466,7 +477,8 @@
func TestCcTest_DisableMemtagHeap(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that disable memtag_heap",
+ description: "cc test that disable memtag_heap",
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
@@ -477,8 +489,8 @@
memtag_heap: false,
},
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -499,7 +511,8 @@
func TestCcTest_RespectArm64MemtagHeap(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that disable memtag_heap",
+ description: "cc test that disable memtag_heap",
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
@@ -513,8 +526,8 @@
}
},
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -535,7 +548,8 @@
func TestCcTest_IgnoreNoneArm64MemtagHeap(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that disable memtag_heap",
+ description: "cc test that disable memtag_heap",
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
@@ -549,8 +563,8 @@
}
},
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
@@ -574,7 +588,8 @@
func TestCcTest_Arm64MemtagHeapOverrideNoConfigOne(t *testing.T) {
runCcTestTestCase(t, ccTestBp2buildTestCase{
- description: "cc test that disable memtag_heap",
+ description: "cc test that disable memtag_heap",
+ stubbedBuildDefinitions: []string{"libgtest_isolated_main", "liblog"},
blueprint: `
cc_test {
name: "mytest",
@@ -594,8 +609,8 @@
}
},
}
-` + simpleModuleDoNotConvertBp2build("cc_library_static", "libgtest_isolated_main") +
- simpleModuleDoNotConvertBp2build("cc_library", "liblog"),
+` + simpleModule("cc_library_static", "libgtest_isolated_main") +
+ simpleModule("cc_library", "liblog"),
targets: []testBazelTarget{
{"cc_test", "mytest", AttrNameToString{
"local_includes": `["."]`,
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 35a1400..c697235 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -15,6 +15,7 @@
rust_config "android/soong/rust/config"
"android/soong/starlark_fmt"
+ "github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -24,16 +25,28 @@
Contents string
}
-// PRIVATE: Use CreateSoongInjectionDirFiles instead
-func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) ([]BazelFile, error) {
+// createSoongInjectionDirFiles returns most of the files to write to the soong_injection directory.
+// Some other files also come from CreateProductConfigFiles
+func createSoongInjectionDirFiles(ctx *CodegenContext, metrics CodegenMetrics) ([]BazelFile, error) {
+ cfg := ctx.Config()
var files []BazelFile
files = append(files, newFile("android", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg)))
+ // Visit all modules to determine the list of ndk libraries
+ // This list will be used to add additional flags for cc stub generation
+ ndkLibsStringFormatted := []string{}
+ ctx.Context().VisitAllModules(func(m blueprint.Module) {
+ if ctx.Context().ModuleType(m) == "ndk_library" {
+ ndkLibsStringFormatted = append(ndkLibsStringFormatted, fmt.Sprintf(`"%s"`, m.Name())) // name will be `"libc.ndk"`
+ }
+ })
+
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
files = append(files, newFile("cc_toolchain", "config_constants.bzl", cc_config.BazelCcToolchainVars(cfg)))
files = append(files, newFile("cc_toolchain", "sanitizer_constants.bzl", cc.BazelCcSanitizerToolchainVars(cfg)))
+ files = append(files, newFile("cc_toolchain", "ndk_libs.bzl", fmt.Sprintf("ndk_libs = [%v]", strings.Join(ndkLibsStringFormatted, ", "))))
files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package.
files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg)))
@@ -145,7 +158,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 89dd38e..6b10077 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -83,7 +83,8 @@
func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) {
testConfig := android.TestConfig("", make(map[string]string), "", make(map[string][]byte))
- files, err := soongInjectionFiles(testConfig, CreateCodegenMetrics())
+ codegenCtx := NewCodegenContext(testConfig, android.NewTestContext(testConfig).Context, Bp2Build, "")
+ files, err := createSoongInjectionDirFiles(codegenCtx, CreateCodegenMetrics())
if err != nil {
t.Error(err)
}
@@ -106,6 +107,10 @@
},
{
dir: "cc_toolchain",
+ basename: "ndk_libs.bzl",
+ },
+ {
+ dir: "cc_toolchain",
basename: "sanitizer_constants.bzl",
},
{
@@ -182,15 +187,45 @@
},
}
- if len(files) != len(expectedFilePaths) {
- t.Errorf("Expected %d file, got %d", len(expectedFilePaths), len(files))
+ less := func(a bazelFilepath, b bazelFilepath) bool {
+ return a.dir+"/"+a.basename < b.dir+"/"+b.basename
}
- for i := range files {
- actualFile, expectedFile := files[i], expectedFilePaths[i]
+ fileToFilepath := func(a BazelFile) bazelFilepath {
+ return bazelFilepath{basename: a.Basename, dir: a.Dir}
+ }
- if actualFile.Dir != expectedFile.dir || actualFile.Basename != expectedFile.basename {
- t.Errorf("Did not find expected file %s/%s", actualFile.Dir, actualFile.Basename)
+ sort.Slice(expectedFilePaths, func(i, j int) bool {
+ return less(expectedFilePaths[i], expectedFilePaths[j])
+ })
+ sort.Slice(files, func(i, j int) bool {
+ return less(fileToFilepath(files[i]), fileToFilepath(files[j]))
+ })
+
+ i := 0
+ j := 0
+ for i < len(expectedFilePaths) && j < len(files) {
+ expectedFile, actualFile := expectedFilePaths[i], files[j]
+
+ if actualFile.Dir == expectedFile.dir && actualFile.Basename == expectedFile.basename {
+ i++
+ j++
+ } else if less(expectedFile, fileToFilepath(actualFile)) {
+ t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename)
+ i++
+ } else {
+ t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename)
+ j++
}
}
+ for i < len(expectedFilePaths) {
+ expectedFile := expectedFilePaths[i]
+ t.Errorf("Did not find expected file %s/%s", expectedFile.dir, expectedFile.basename)
+ i++
+ }
+ for j < len(files) {
+ actualFile := files[j]
+ t.Errorf("Found unexpected file %s/%s", actualFile.Dir, actualFile.Basename)
+ j++
+ }
}
diff --git a/bp2build/droiddoc_exported_dir_conversion_test.go b/bp2build/droiddoc_exported_dir_conversion_test.go
new file mode 100644
index 0000000..dee67f4
--- /dev/null
+++ b/bp2build/droiddoc_exported_dir_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 (
+ "regexp"
+ "testing"
+
+ "android/soong/java"
+)
+
+func TestDroiddocExportedDir(t *testing.T) {
+ bp := `
+ droiddoc_exported_dir {
+ name: "test-module",
+ path: "docs",
+ }
+ `
+ p := regexp.MustCompile(`\t*\|`)
+ dedent := func(s string) string {
+ return p.ReplaceAllString(s, "")
+ }
+ expectedBazelTargets := []string{
+ MakeBazelTargetNoRestrictions(
+ "droiddoc_exported_dir",
+ "test-module",
+ AttrNameToString{
+ "dir": `"docs"`,
+ "srcs": dedent(`[
+ | "docs/android/1.txt",
+ | "docs/android/nested-1/2.txt",
+ | "//docs/android/nested-2:3.txt",
+ | "//docs/android/nested-2:Android.bp",
+ | ]`),
+ }),
+ //note we are not excluding Android.bp files from subpackages for now
+ }
+ RunBp2BuildTestCase(t, java.RegisterDocsBuildComponents, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Filesystem: map[string]string{
+ "docs/android/1.txt": "",
+ "docs/android/nested-1/2.txt": "",
+ "docs/android/nested-2/Android.bp": "",
+ "docs/android/nested-2/3.txt": "",
+ },
+ })
+}
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/fdo_profile_conversion_test.go b/bp2build/fdo_profile_conversion_test.go
new file mode 100644
index 0000000..4d04283
--- /dev/null
+++ b/bp2build/fdo_profile_conversion_test.go
@@ -0,0 +1,85 @@
+// 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 (
+ "testing"
+
+ "android/soong/android"
+ "android/soong/cc"
+)
+
+func runFdoProfileTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ (&tc).ModuleTypeUnderTest = "fdo_profile"
+ (&tc).ModuleTypeUnderTestFactory = cc.FdoProfileFactory
+ RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+func TestFdoProfile(t *testing.T) {
+ testcases := []struct {
+ name string
+ bp string
+ expectedBazelAttrs AttrNameToString
+ }{
+ {
+ name: "fdo_profile with arch-specific profiles",
+ bp: `
+fdo_profile {
+ name: "foo",
+ arch: {
+ arm: {
+ profile: "foo_arm.afdo",
+ },
+ arm64: {
+ profile: "foo_arm64.afdo",
+ }
+ }
+}`,
+ expectedBazelAttrs: AttrNameToString{
+ "profile": `select({
+ "//build/bazel/platforms/arch:arm": "foo_arm.afdo",
+ "//build/bazel/platforms/arch:arm64": "foo_arm64.afdo",
+ "//conditions:default": None,
+ })`,
+ },
+ },
+ {
+ name: "fdo_profile with arch-agnostic profile",
+ bp: `
+fdo_profile {
+ name: "foo",
+ profile: "foo.afdo",
+}`,
+ expectedBazelAttrs: AttrNameToString{
+ "profile": `"foo.afdo"`,
+ },
+ },
+ }
+
+ for _, test := range testcases {
+ t.Run(test.name, func(t *testing.T) {
+ expectedBazelTargets := []string{
+ // TODO(b/276287371): Add device-only restriction back to fdo_profile targets
+ MakeBazelTargetNoRestrictions("fdo_profile", "foo", test.expectedBazelAttrs),
+ }
+ runFdoProfileTestCase(t, Bp2buildTestCase{
+ Description: test.name,
+ Blueprint: test.bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ })
+ })
+ }
+}
diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go
index 2a10a14..7e9b17b 100644
--- a/bp2build/genrule_conversion_test.go
+++ b/bp2build/genrule_conversion_test.go
@@ -93,7 +93,6 @@
out: ["foo_tool.out"],
srcs: ["foo_tool.in"],
cmd: "cp $(in) $(out)",
- bazel_module: { bp2build_available: false },
}
%s {
@@ -124,6 +123,7 @@
ModuleTypeUnderTestFactory: tc.factory,
Blueprint: fmt.Sprintf(bp, tc.moduleType, tc.moduleType),
ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: []string{"foo.tool", "other.tool"},
})
})
}
@@ -262,6 +262,7 @@
Blueprint: fmt.Sprintf(bp, tc.moduleType),
ExpectedBazelTargets: expectedBazelTargets,
Filesystem: otherGenruleBp(tc.moduleType),
+ StubbedBuildDefinitions: []string{"//other:foo.tool"},
})
})
}
@@ -326,6 +327,7 @@
Blueprint: fmt.Sprintf(bp, tc.moduleType),
ExpectedBazelTargets: expectedBazelTargets,
Filesystem: otherGenruleBp(tc.moduleType),
+ StubbedBuildDefinitions: []string{"//other:foo.tool", "//other:other.tool"},
})
})
}
@@ -390,6 +392,7 @@
Blueprint: fmt.Sprintf(bp, tc.moduleType),
ExpectedBazelTargets: expectedBazelTargets,
Filesystem: otherGenruleBp(tc.moduleType),
+ StubbedBuildDefinitions: []string{"//other:foo.tool", "//other:other.tool"},
})
})
}
@@ -454,6 +457,7 @@
Blueprint: fmt.Sprintf(bp, tc.moduleType),
ExpectedBazelTargets: expectedBazelTargets,
Filesystem: otherGenruleBp(tc.moduleType),
+ StubbedBuildDefinitions: []string{"//other:foo.tool", "//other:other.tool"},
})
})
}
@@ -948,6 +952,7 @@
ModuleTypeUnderTest: "genrule",
ModuleTypeUnderTestFactory: genrule.GenRuleFactory,
ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: []string{"//mynamespace/dir:mymodule"},
})
})
diff --git a/bp2build/java_binary_host_conversion_test.go b/bp2build/java_binary_host_conversion_test.go
index 39e55c4..7d8ab63 100644
--- a/bp2build/java_binary_host_conversion_test.go
+++ b/bp2build/java_binary_host_conversion_test.go
@@ -26,6 +26,7 @@
t.Helper()
(&tc).ModuleTypeUnderTest = "java_binary_host"
(&tc).ModuleTypeUnderTestFactory = java.BinaryHostFactory
+ tc.StubbedBuildDefinitions = append(tc.StubbedBuildDefinitions, "//other:jni-lib-1")
RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_library_host_shared", cc.LibraryHostSharedFactory)
ctx.RegisterModuleType("java_library", java.LibraryFactory)
@@ -81,8 +82,9 @@
func TestJavaBinaryHostRuntimeDeps(t *testing.T) {
runJavaBinaryHostTestCase(t, Bp2buildTestCase{
- Description: "java_binary_host with srcs, exclude_srcs, jni_libs, javacflags, and manifest.",
- Filesystem: testFs,
+ Description: "java_binary_host with srcs, exclude_srcs, jni_libs, javacflags, and manifest.",
+ Filesystem: testFs,
+ StubbedBuildDefinitions: []string{"java-dep-1"},
Blueprint: `java_binary_host {
name: "java-binary-host-1",
static_libs: ["java-dep-1"],
@@ -93,7 +95,6 @@
java_library {
name: "java-dep-1",
srcs: ["a.java"],
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
@@ -111,8 +112,9 @@
func TestJavaBinaryHostLibs(t *testing.T) {
runJavaBinaryHostTestCase(t, Bp2buildTestCase{
- Description: "java_binary_host with srcs, libs.",
- Filesystem: testFs,
+ Description: "java_binary_host with srcs, libs.",
+ Filesystem: testFs,
+ StubbedBuildDefinitions: []string{"prebuilt_java-lib-dep-1"},
Blueprint: `java_binary_host {
name: "java-binary-host-libs",
libs: ["java-lib-dep-1"],
@@ -123,7 +125,6 @@
java_import_host{
name: "java-lib-dep-1",
jars: ["foo.jar"],
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 7429ae6..7e4e44e 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -15,7 +15,6 @@
package bp2build
import (
- "fmt"
"testing"
"android/soong/android"
@@ -70,6 +69,7 @@
func TestJavaLibraryConvertsStaticLibsToDepsAndExports(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"java-lib-2", "java-lib-3"},
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java"],
@@ -83,14 +83,12 @@
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{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
@@ -109,6 +107,7 @@
func TestJavaLibraryConvertsStaticLibsToExportsIfNoSrcs(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"java-lib-2"},
Blueprint: `java_library {
name: "java-lib-1",
static_libs: ["java-lib-2"],
@@ -119,7 +118,6 @@
java_library {
name: "java-lib-2",
srcs: ["a.java"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
@@ -143,28 +141,9 @@
})
}
-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{},
- })
-}
-
func TestJavaLibraryPlugins(t *testing.T) {
runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"java-plugin-1"},
Blueprint: `java_library {
name: "java-lib-1",
plugins: ["java-plugin-1"],
@@ -175,7 +154,6 @@
java_plugin {
name: "java-plugin-1",
srcs: ["a.java"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
@@ -216,6 +194,7 @@
func TestJavaLibraryErrorproneEnabledManually(t *testing.T) {
runJavaLibraryTestCaseWithRegistrationCtxFunc(t, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"plugin2"},
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java"],
@@ -230,7 +209,6 @@
java_plugin {
name: "plugin2",
srcs: ["a.java"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
@@ -639,6 +617,7 @@
Description: "java_library with non adjacent aidl filegroup",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
+ StubbedBuildDefinitions: []string{"A_aidl"},
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
@@ -676,7 +655,7 @@
Description: "Android Library - simple arch feature",
ModuleTypeUnderTest: "android_library",
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+ Blueprint: simpleModule("android_library", "static_lib_dep") + `
android_library {
name: "TestLib",
manifest: "manifest/AndroidManifest.xml",
@@ -714,7 +693,7 @@
Description: "Android Library - multiple arch features",
ModuleTypeUnderTest: "android_library",
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+ Blueprint: simpleModule("android_library", "static_lib_dep") + `
android_library {
name: "TestLib",
manifest: "manifest/AndroidManifest.xml",
@@ -760,7 +739,7 @@
Description: "Android Library - exclude_srcs with arch feature",
ModuleTypeUnderTest: "android_library",
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
- Blueprint: simpleModuleDoNotConvertBp2build("android_library", "static_lib_dep") + `
+ Blueprint: simpleModule("android_library", "static_lib_dep") + `
android_library {
name: "TestLib",
manifest: "manifest/AndroidManifest.xml",
@@ -870,7 +849,8 @@
func TestJavaLibraryArchVariantDeps(t *testing.T) {
runJavaLibraryTestCase(t, Bp2buildTestCase{
- Description: "java_library with arch variant libs",
+ Description: "java_library with arch variant libs",
+ StubbedBuildDefinitions: []string{"java-lib-2", "java-lib-3", "java-lib-4"},
Blueprint: `java_library {
name: "java-lib-1",
srcs: ["a.java"],
@@ -887,17 +867,14 @@
java_library{
name: "java-lib-2",
- bazel_module: { bp2build_available: false },
}
java_library{
name: "java-lib-3",
- bazel_module: { bp2build_available: false },
}
java_library{
name: "java-lib-4",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
diff --git a/bp2build/java_plugin_conversion_test.go b/bp2build/java_plugin_conversion_test.go
index f2b6f20..b284112 100644
--- a/bp2build/java_plugin_conversion_test.go
+++ b/bp2build/java_plugin_conversion_test.go
@@ -32,7 +32,8 @@
func TestJavaPlugin(t *testing.T) {
runJavaPluginTestCase(t, Bp2buildTestCase{
- Description: "java_plugin with srcs, libs, static_libs",
+ Description: "java_plugin with srcs, libs, static_libs",
+ StubbedBuildDefinitions: []string{"java-lib-1", "java-lib-2"},
Blueprint: `java_plugin {
name: "java-plug-1",
srcs: ["a.java", "b.java"],
@@ -45,13 +46,11 @@
java_library {
name: "java-lib-1",
srcs: ["b.java"],
- bazel_module: { bp2build_available: false },
}
java_library {
name: "java-lib-2",
srcs: ["c.java"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("java_plugin", "java-plug-1", AttrNameToString{
@@ -75,7 +74,8 @@
func TestJavaPluginNoSrcs(t *testing.T) {
runJavaPluginTestCase(t, Bp2buildTestCase{
- Description: "java_plugin without srcs converts (static) libs to deps",
+ Description: "java_plugin without srcs converts (static) libs to deps",
+ StubbedBuildDefinitions: []string{"java-lib-1", "java-lib-2"},
Blueprint: `java_plugin {
name: "java-plug-1",
libs: ["java-lib-1"],
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index 5d6b088..b254710 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -137,3 +137,47 @@
},
})
}
+
+func TestJavaLibsAndOnlyProtoSrcs(t *testing.T) {
+ runJavaProtoTestCase(t, Bp2buildTestCase{
+ Description: "java_library that has only proto srcs",
+ Blueprint: `java_library_static {
+ name: "java-protos",
+ srcs: ["a.proto"],
+ libs: ["java-lib"],
+ java_version: "7",
+ sdk_version: "current",
+}
+
+java_library_static {
+ name: "java-lib",
+ bazel_module: { bp2build_available: false },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+ "srcs": `["a.proto"]`,
+ }),
+ MakeBazelTarget(
+ "java_lite_proto_library",
+ "java-protos_java_proto_lite",
+ 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"`,
+ "sdk_version": `"current"`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/java_sdk_library_import_conversion_test.go b/bp2build/java_sdk_library_import_conversion_test.go
new file mode 100644
index 0000000..456f872
--- /dev/null
+++ b/bp2build/java_sdk_library_import_conversion_test.go
@@ -0,0 +1,84 @@
+// 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 (
+ "testing"
+
+ "android/soong/java"
+)
+
+func runJavaSdkLibraryImportTestCase(t *testing.T, tc Bp2buildTestCase) {
+ t.Helper()
+ RunBp2BuildTestCase(t, java.RegisterSdkLibraryBuildComponents, tc)
+}
+
+func TestJavaSdkLibraryImport(t *testing.T) {
+ runJavaSdkLibraryImportTestCase(t, Bp2buildTestCase{
+ Blueprint: `
+java_sdk_library_import {
+ name : "foo",
+ public: {
+ current_api: "foo_current.txt",
+ },
+ system: {
+ current_api: "system_foo_current.txt",
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_sdk_library", "foo", AttrNameToString{
+ "public": `"foo_current.txt"`,
+ "system": `"system_foo_current.txt"`,
+ }),
+ },
+ })
+}
+
+func TestJavaSdkLibraryImportPrebuiltPrefixRemoved(t *testing.T) {
+ runJavaSdkLibraryImportTestCase(t, Bp2buildTestCase{
+ Filesystem: map[string]string{
+ "foobar/Android.bp": `
+java_sdk_library {
+ name: "foo",
+ srcs: ["**/*.java"],
+}
+`,
+ "foobar/api/current.txt": "",
+ "foobar/api/system-current.txt": "",
+ "foobar/api/test-current.txt": "",
+ "foobar/api/removed.txt": "",
+ "foobar/api/system-removed.txt": "",
+ "foobar/api/test-removed.txt": "",
+ },
+ Blueprint: `
+java_sdk_library_import {
+ name : "foo",
+ public: {
+ current_api: "foo_current.txt",
+ },
+ system: {
+ current_api: "system_foo_current.txt",
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("java_sdk_library", "foo", AttrNameToString{
+ "public": `"foo_current.txt"`,
+ "system": `"system_foo_current.txt"`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/platform_compat_config_conversion_test.go b/bp2build/platform_compat_config_conversion_test.go
index 4dfcce3..d74db5d 100644
--- a/bp2build/platform_compat_config_conversion_test.go
+++ b/bp2build/platform_compat_config_conversion_test.go
@@ -37,6 +37,7 @@
name: "foo",
src: ":lib",
}`,
+ StubbedBuildDefinitions: []string{"//a/b:lib"},
Filesystem: map[string]string{
"a/b/Android.bp": `
java_library {
diff --git a/bp2build/prebuilt_etc_conversion_test.go b/bp2build/prebuilt_etc_conversion_test.go
index 5b2d609..e237303 100644
--- a/bp2build/prebuilt_etc_conversion_test.go
+++ b/bp2build/prebuilt_etc_conversion_test.go
@@ -346,3 +346,17 @@
ExpectedErr: fmt.Errorf("label attribute could not be collapsed"),
})
}
+
+func TestPrebuiltEtcNoConversionIfSrcEqualsName(t *testing.T) {
+ runPrebuiltEtcTestCase(t, Bp2buildTestCase{
+ Description: "",
+ Filesystem: map[string]string{},
+ Blueprint: `
+prebuilt_etc {
+ name: "foo",
+ filename: "fooFilename",
+ src: "foo",
+}`,
+ ExpectedBazelTargets: []string{},
+ })
+}
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 1b538d0..b69c4ea 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -30,6 +30,7 @@
"b/e.py": "",
"files/data.txt": "",
},
+ StubbedBuildDefinitions: []string{"bar"},
Blueprint: `python_binary_host {
name: "foo",
main: "a.py",
@@ -42,7 +43,6 @@
python_library_host {
name: "bar",
srcs: ["b/e.py"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("py_binary", "foo", AttrNameToString{
@@ -196,6 +196,7 @@
Description: "python_binary_host main label in same package",
ModuleTypeUnderTest: "python_binary_host",
ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ StubbedBuildDefinitions: []string{"a"},
Blueprint: `python_binary_host {
name: "foo",
main: ":a",
@@ -204,7 +205,6 @@
genrule {
name: "a",
- bazel_module: { bp2build_available: false },
}
`,
ExpectedBazelTargets: []string{
@@ -282,6 +282,7 @@
Description: "python_binary_host duplicates in required attribute of the module and its defaults",
ModuleTypeUnderTest: "python_binary_host",
ModuleTypeUnderTestFactory: python.PythonBinaryHostFactory,
+ StubbedBuildDefinitions: []string{"r1", "r2"},
Blueprint: `python_binary_host {
name: "foo",
main: "a.py",
@@ -298,8 +299,8 @@
"r1",
"r2",
],
-}` + simpleModuleDoNotConvertBp2build("genrule", "r1") +
- simpleModuleDoNotConvertBp2build("genrule", "r2"),
+}` + simpleModule("genrule", "r1") +
+ simpleModule("genrule", "r2"),
ExpectedBazelTargets: []string{
MakeBazelTarget("py_binary", "foo", AttrNameToString{
diff --git a/bp2build/python_library_conversion_test.go b/bp2build/python_library_conversion_test.go
index 595acd2..497df80 100644
--- a/bp2build/python_library_conversion_test.go
+++ b/bp2build/python_library_conversion_test.go
@@ -13,12 +13,13 @@
type PythonLibBp2Build func(ctx android.TopDownMutatorContext)
type pythonLibBp2BuildTestCase struct {
- description string
- filesystem map[string]string
- blueprint string
- expectedBazelTargets []testBazelTarget
- dir string
- expectedError error
+ description string
+ filesystem map[string]string
+ blueprint string
+ expectedBazelTargets []testBazelTarget
+ dir string
+ expectedError error
+ stubbedBuildDefinitions []string
}
func convertPythonLibTestCaseToBp2build_Host(tc pythonLibBp2BuildTestCase) Bp2buildTestCase {
@@ -44,12 +45,13 @@
filesystemCopy[k] = v
}
return Bp2buildTestCase{
- Description: tc.description,
- Filesystem: filesystemCopy,
- Blueprint: tc.blueprint,
- ExpectedBazelTargets: bp2BuildTargets,
- Dir: tc.dir,
- ExpectedErr: tc.expectedError,
+ Description: tc.description,
+ Filesystem: filesystemCopy,
+ Blueprint: tc.blueprint,
+ ExpectedBazelTargets: bp2BuildTargets,
+ Dir: tc.dir,
+ ExpectedErr: tc.expectedError,
+ StubbedBuildDefinitions: tc.stubbedBuildDefinitions,
}
}
@@ -104,6 +106,7 @@
"b/e.py": "",
"files/data.txt": "",
},
+ stubbedBuildDefinitions: []string{"bar"},
blueprint: `%s {
name: "foo",
srcs: ["**/*.py"],
@@ -115,7 +118,6 @@
python_library {
name: "bar",
srcs: ["b/e.py"],
- bazel_module: { bp2build_available: false },
}`,
expectedBazelTargets: []testBazelTarget{
{
diff --git a/bp2build/python_test_conversion_test.go b/bp2build/python_test_conversion_test.go
index 4ff1fa1..fa2e485 100644
--- a/bp2build/python_test_conversion_test.go
+++ b/bp2build/python_test_conversion_test.go
@@ -15,8 +15,9 @@
package bp2build
import (
- "android/soong/python"
"testing"
+
+ "android/soong/python"
)
func TestPythonTestHostSimple(t *testing.T) {
@@ -31,6 +32,7 @@
"b/e.py": "",
"files/data.txt": "",
},
+ StubbedBuildDefinitions: []string{"bar"},
Blueprint: `python_test_host {
name: "foo",
main: "a.py",
@@ -43,7 +45,6 @@
python_library_host {
name: "bar",
srcs: ["b/e.py"],
- bazel_module: { bp2build_available: false },
}`,
ExpectedBazelTargets: []string{
MakeBazelTarget("py_test", "foo", AttrNameToString{
diff --git a/bp2build/soong_config_module_type_conversion_test.go b/bp2build/soong_config_module_type_conversion_test.go
index 8302ce8..5ec6bab 100644
--- a/bp2build/soong_config_module_type_conversion_test.go
+++ b/bp2build/soong_config_module_type_conversion_test.go
@@ -15,10 +15,11 @@
package bp2build
import (
- "android/soong/android"
- "android/soong/cc"
"fmt"
"testing"
+
+ "android/soong/android"
+ "android/soong/cc"
)
func runSoongConfigModuleTypeTest(t *testing.T, tc Bp2buildTestCase) {
@@ -364,9 +365,9 @@
}`
otherDeps := `
-cc_library_static { name: "soc_a_dep", bazel_module: { bp2build_available: false } }
-cc_library_static { name: "soc_b_dep", bazel_module: { bp2build_available: false } }
-cc_library_static { name: "soc_default_static_dep", bazel_module: { bp2build_available: false } }
+cc_library_static { name: "soc_a_dep"}
+cc_library_static { name: "soc_b_dep"}
+cc_library_static { name: "soc_default_static_dep"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -377,6 +378,7 @@
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
},
+ StubbedBuildDefinitions: []string{"//foo/bar:soc_a_dep", "//foo/bar:soc_b_dep", "//foo/bar:soc_default_static_dep"},
ExpectedBazelTargets: []string{`cc_library_static(
name = "foo",
copts = select({
@@ -763,9 +765,9 @@
}`
otherDeps := `
-cc_library { name: "lib_a", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_b", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_default", bazel_module: { bp2build_available: false } }
+cc_library { name: "lib_a"}
+cc_library { name: "lib_b"}
+cc_library { name: "lib_default"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -773,6 +775,7 @@
ModuleTypeUnderTest: "cc_binary",
ModuleTypeUnderTestFactory: cc.BinaryFactory,
Blueprint: bp,
+ StubbedBuildDefinitions: []string{"//foo/bar:lib_a", "//foo/bar:lib_b", "//foo/bar:lib_default"},
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
},
@@ -852,15 +855,16 @@
}`
otherDeps := `
-cc_library { name: "lib_a", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_b", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_c", bazel_module: { bp2build_available: false } }
+cc_library { name: "lib_a"}
+cc_library { name: "lib_b"}
+cc_library { name: "lib_c"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
Description: "soong config variables - generates selects for library_linking_strategy",
ModuleTypeUnderTest: "cc_binary",
ModuleTypeUnderTestFactory: cc.BinaryFactory,
+ StubbedBuildDefinitions: []string{"//foo/bar:lib_a", "//foo/bar:lib_b", "//foo/bar:lib_c"},
Blueprint: bp,
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
@@ -949,9 +953,9 @@
}`
otherDeps := `
-cc_library { name: "lib_a", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_b", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_default", bazel_module: { bp2build_available: false } }
+cc_library { name: "lib_a"}
+cc_library { name: "lib_b"}
+cc_library { name: "lib_default"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -962,6 +966,7 @@
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
},
+ StubbedBuildDefinitions: []string{"//foo/bar:lib_a", "//foo/bar:lib_b", "//foo/bar:lib_default"},
ExpectedBazelTargets: []string{`cc_binary(
name = "library_linking_strategy_sample_binary",
deps = select({
@@ -1031,8 +1036,8 @@
}`
otherDeps := `
-cc_library { name: "lib_a", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_b", bazel_module: { bp2build_available: false } }
+cc_library { name: "lib_a"}
+cc_library { name: "lib_b"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -1040,6 +1045,7 @@
ModuleTypeUnderTest: "cc_binary",
ModuleTypeUnderTestFactory: cc.BinaryFactory,
Blueprint: bp,
+ StubbedBuildDefinitions: []string{"//foo/bar:lib_a", "//foo/bar:lib_b"},
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
},
@@ -1118,9 +1124,9 @@
}`
otherDeps := `
-cc_library { name: "lib_a", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_b", bazel_module: { bp2build_available: false } }
-cc_library { name: "lib_default", bazel_module: { bp2build_available: false } }
+cc_library { name: "lib_a"}
+cc_library { name: "lib_b"}
+cc_library { name: "lib_default"}
`
runSoongConfigModuleTypeTest(t, Bp2buildTestCase{
@@ -1131,6 +1137,7 @@
Filesystem: map[string]string{
"foo/bar/Android.bp": otherDeps,
},
+ StubbedBuildDefinitions: []string{"//foo/bar:lib_a", "//foo/bar:lib_b", "//foo/bar:lib_default"},
ExpectedBazelTargets: []string{`cc_binary(
name = "alphabet_binary",
deps = select({
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index 5c33308..966b94a 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -43,7 +43,7 @@
// clean the whole symlink forest and recreate it. This number can be bumped whenever there's
// an incompatible change to the forest layout or a bug in incrementality that needs to be fixed
// on machines that may still have the bug present in their forest.
-const symlinkForestVersion = 1
+const symlinkForestVersion = 2
type instructionsNode struct {
name string
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 42d955e..a810709 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -21,6 +21,8 @@
import (
"fmt"
+ "path/filepath"
+ "regexp"
"sort"
"strings"
"testing"
@@ -36,6 +38,9 @@
buildDir string
)
+var labelRegex = regexp.MustCompile(`^//([^: ]+):([^ ]+)$`)
+var simpleModuleNameRegex = regexp.MustCompile(`^[^: /]+$`)
+
func checkError(t *testing.T, errs []error, expectedErr error) bool {
t.Helper()
@@ -82,7 +87,19 @@
// ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty).
// Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory.
ExpectedBazelTargets []string
- Filesystem map[string]string
+ // AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file
+ // in the directory under test. The BUILD file has the given contents. This BUILD file
+ // will also be treated as "BUILD file to keep" by the simulated bp2build environment.
+ AlreadyExistingBuildContents string
+
+ // StubbedBuildDefinitions, if non-empty, adds stub definitions to already-present source
+ // BUILD files for each bazel label given. The BUILD files with these stub definitions
+ // are added to the BUILD file given in AlreadyExistingBuildContents.
+ // Labels may be of the form //pkg/to:target_name (which would be defined in pkg/to/BUILD.bazel)
+ // or `target_name` (which would be defined in ./BUILD.bazel).
+ StubbedBuildDefinitions []string
+
+ Filesystem map[string]string
// Dir sets the directory which will be compared against the targets in ExpectedBazelTargets.
// This should used in conjunction with the Filesystem property to check for targets
// generated from a directory that is not the root.
@@ -108,23 +125,53 @@
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 := "."
+ if tc.Filesystem == nil {
+ tc.Filesystem = map[string]string{}
+ }
+ checkDir := "."
+ if tc.Dir != "" {
+ checkDir = tc.Dir
+ }
+ keepExistingBuildDirs := tc.KeepBuildFileForDirs
+ buildFilesToParse := []string{}
+
+ if len(tc.StubbedBuildDefinitions) > 0 {
+ for _, buildDef := range tc.StubbedBuildDefinitions {
+ globalLabelMatch := labelRegex.FindStringSubmatch(buildDef)
+ var dir, targetName string
+ if len(globalLabelMatch) > 0 {
+ dir = globalLabelMatch[1]
+ targetName = globalLabelMatch[2]
+ } else {
+ if !simpleModuleNameRegex.MatchString(buildDef) {
+ t.Errorf("Stubbed build definition '%s' must be either a simple module name or of global target syntax (//foo/bar:baz).", buildDef)
+ return
+ }
+ dir = "."
+ targetName = buildDef
+ }
+ buildFilePath := filepath.Join(dir, "BUILD")
+ tc.Filesystem[buildFilePath] +=
+ MakeBazelTarget(
+ "bp2build_test_stub",
+ targetName,
+ AttrNameToString{})
+ keepExistingBuildDirs = append(keepExistingBuildDirs, dir)
+ buildFilesToParse = append(buildFilesToParse, buildFilePath)
+ }
+ }
+ if len(tc.AlreadyExistingBuildContents) > 0 {
+ buildFilePath := filepath.Join(checkDir, "BUILD")
+ tc.Filesystem[buildFilePath] += tc.AlreadyExistingBuildContents
+ keepExistingBuildDirs = append(keepExistingBuildDirs, checkDir)
+ buildFilesToParse = append(buildFilesToParse, buildFilePath)
+ }
filesystem := make(map[string][]byte)
for f, content := range tc.Filesystem {
filesystem[f] = []byte(content)
}
-
preparers := []android.FixturePreparer{
extraPreparer,
android.FixtureMergeMockFs(filesystem),
@@ -132,7 +179,7 @@
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
}),
- android.FixtureModifyContext(func(ctx *android.TestContext) {
+ android.FixtureModifyContextWithMockFs(func(ctx *android.TestContext) {
// A default configuration for tests to not have to specify bp2build_available on top level
// targets.
bp2buildConfig := android.NewBp2BuildAllowlist().SetDefaultConfig(
@@ -140,7 +187,7 @@
android.Bp2BuildTopLevel: allowlists.Bp2BuildDefaultTrueRecursively,
},
)
- for _, f := range tc.KeepBuildFileForDirs {
+ for _, f := range keepExistingBuildDirs {
bp2buildConfig.SetKeepExistingBuildFile(map[string]bool{
f: /*recursive=*/ false,
})
@@ -150,6 +197,10 @@
// from cloning modules to their original state after mutators run. This
// would lose some data intentionally set by these mutators.
ctx.SkipCloneModulesAfterMutators = true
+ err := ctx.RegisterExistingBazelTargets(".", buildFilesToParse)
+ if err != nil {
+ t.Errorf("error parsing build files in test setup: %s", err)
+ }
}),
android.FixtureModifyEnv(func(env map[string]string) {
if tc.UnconvertedDepsMode == errorModulesUnconvertedDeps {
@@ -168,10 +219,6 @@
return
}
- checkDir := dir
- if tc.Dir != "" {
- checkDir = tc.Dir
- }
expectedTargets := map[string][]string{
checkDir: tc.ExpectedBazelTargets,
}
@@ -180,27 +227,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 +248,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
@@ -467,7 +497,7 @@
return m.props.Dir
}
-func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if p := m.props.One_to_many_prop; p != nil && *p {
customBp2buildOneToMany(ctx, m)
return
@@ -487,7 +517,10 @@
}
}
}
- productVariableProps := android.ProductVariableProperties(ctx, ctx.Module())
+ productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module())
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
if props, ok := productVariableProps["String_literal_prop"]; ok {
for c, p := range props {
if val, ok := p.(*string); ok {
@@ -522,7 +555,7 @@
}
-func (m *customModule) createConfigSetting(ctx android.TopDownMutatorContext) {
+func (m *customModule) createConfigSetting(ctx android.Bp2buildMutatorContext) {
csa := bazel.ConfigSettingAttributes{
Flag_values: bazel.StringMapAttribute{
"//build/bazel/rules/my_string_setting": m.Name(),
@@ -557,7 +590,7 @@
// A bp2build mutator that uses load statements and creates a 1:M mapping from
// module to target.
-func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) {
+func customBp2buildOneToMany(ctx android.Bp2buildMutatorContext, m *customModule) {
baseName := m.Name()
attrs := &customBazelModuleAttributes{}
@@ -596,11 +629,10 @@
ctx.RegisterForBazelConversion()
}
-func simpleModuleDoNotConvertBp2build(typ, name string) string {
+func simpleModule(typ, name string) string {
return fmt.Sprintf(`
%s {
name: "%s",
- bazel_module: { bp2build_available: false },
}`, typ, name)
}
@@ -670,6 +702,7 @@
return ""
}
STUB_SUITE_ATTRS := map[string]string{
+ "api_surface": "api_surface",
"stubs_symbol_file": "symbol_file",
"stubs_versions": "versions",
"soname": "soname",
diff --git a/bpf/bpf.go b/bpf/bpf.go
index d135d5f..38777ff 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -313,7 +313,7 @@
}
// bpf bp2build converter
-func (b *bpf) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (b *bpf) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if ctx.ModuleType() != "bpf" {
return
}
diff --git a/cc/binary.go b/cc/binary.go
index 4606b62..0722f81 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -599,7 +599,7 @@
handler.module.setAndroidMkVariablesFromCquery(info.CcAndroidMkInfo)
}
-func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes {
+func binaryBp2buildAttrs(ctx android.Bp2buildMutatorContext, m *Module) binaryAttributes {
baseAttrs := bp2BuildParseBaseProps(ctx, m)
binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
@@ -661,7 +661,7 @@
return attrs
}
-func binaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func binaryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
// shared with cc_test
binaryAttrs := binaryBp2buildAttrs(ctx, m)
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 83553c8..6a49915 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -944,7 +944,10 @@
nativeCoverage = BoolPtr(false)
}
- productVariableProps := android.ProductVariableProperties(ctx, ctx.Module())
+ productVariableProps, errs := android.ProductVariableProperties(ctx, ctx.Module())
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
(&compilerAttrs).convertProductVariables(ctx, productVariableProps)
(&linkerAttrs).convertProductVariables(ctx, productVariableProps)
@@ -1000,6 +1003,8 @@
if module.afdo != nil && module.afdo.Properties.Afdo {
fdoProfileDep := bp2buildFdoProfile(ctx, module)
if fdoProfileDep != nil {
+ // TODO(b/276287371): Only set fdo_profile for android platform
+ // https://cs.android.com/android/platform/superproject/main/+/main:build/soong/cc/afdo.go;l=105;drc=2dbe160d1af445de32725098570ec594e3944fc5
(&compilerAttrs).fdoProfile.SetValue(*fdoProfileDep)
}
}
@@ -1109,22 +1114,15 @@
ctx android.Bp2buildMutatorContext,
m *Module,
) *bazel.Label {
+ // TODO(b/267229066): Convert to afdo boolean attribute and let Bazel handles finding
+ // fdo_profile target from AfdoProfiles product var
for _, project := range globalAfdoProfileProjects {
- // Ensure handcrafted BUILD file exists in the project
- BUILDPath := android.ExistentPathForSource(ctx, project, "BUILD")
- if BUILDPath.Valid() {
- // We handcraft a BUILD file with fdo_profile targets that use the existing profiles in the project
- // This implementation is assuming that every afdo profile in globalAfdoProfileProjects already has
- // an associated fdo_profile target declared in the same package.
+ // Ensure it's a Soong package
+ bpPath := android.ExistentPathForSource(ctx, project, "Android.bp")
+ if bpPath.Valid() {
// TODO(b/260714900): Handle arch-specific afdo profiles (e.g. `<module-name>-arm<64>.afdo`)
path := android.ExistentPathForSource(ctx, project, m.Name()+".afdo")
if path.Valid() {
- // FIXME: Some profiles only exist internally and are not released to AOSP.
- // When generated BUILD files are checked in, we'll run into merge conflict.
- // The cc_library_shared target in AOSP won't have reference to an fdo_profile target because
- // the profile doesn't exist. Internally, the same cc_library_shared target will
- // have reference to the fdo_profile.
- // For more context, see b/258682955#comment2
fdoProfileLabel := "//" + strings.TrimSuffix(project, "/") + ":" + m.Name()
return &bazel.Label{
Label: fdoProfileLabel,
@@ -1380,10 +1378,10 @@
// having stubs or not, so Bazel select() statement can be used to choose
// source/stub variants of them.
apexAvailable := module.ApexAvailable()
- setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false)
- setStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false)
if len(systemSharedLibs) > 0 {
- setStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true)
}
}
@@ -1583,7 +1581,13 @@
}
}
-func setStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
+// hasNdkStubs returns true for libfoo if there exists a libfoo.ndk of type ndk_library
+func hasNdkStubs(ctx android.BazelConversionPathContext, c *Module) bool {
+ mod, exists := ctx.ModuleFromName(c.Name() + ndkLibrarySuffix)
+ return exists && ctx.OtherModuleType(mod) == "ndk_library"
+}
+
+func SetStubsForDynamicDeps(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis,
config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {
// Create a config_setting for each apex_available.
@@ -1624,6 +1628,11 @@
if linkable, ok := ctx.Module().(LinkableInterface); ok && linkable.Bootstrap() {
sameApiDomain = true
}
+ // If dependency has `apex_available: ["//apex_available:platform]`, then the platform variant of rdep should link against its impl.
+ // https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/cc.go;l=3617;bpv=1;bpt=0;drc=c6a93d853b37ec90786e745b8d282145e6d3b589
+ if depApexAvailable := dep.(*Module).ApexAvailable(); len(depApexAvailable) == 1 && depApexAvailable[0] == android.AvailableToPlatform {
+ sameApiDomain = true
+ }
} else {
sameApiDomain = android.InList(apiDomain, dep.(*Module).ApexAvailable())
}
@@ -1638,6 +1647,27 @@
useStubOrImplInApexWithName(ssi)
}
}
+
+ // If the library has an sdk variant, create additional selects to build this variant against the ndk
+ // The config setting for this variant will be //build/bazel/rules/apex:unbundled_app
+ if c, ok := ctx.Module().(*Module); ok && c.Properties.Sdk_version != nil {
+ for _, l := range dynamicLibs.Includes {
+ dep, _ := ctx.ModuleFromName(l.OriginalModuleName)
+ label := l // use the implementation by default
+ if depC, ok := dep.(*Module); ok && hasNdkStubs(ctx, depC) {
+ // If the dependency has ndk stubs, build against the ndk stubs
+ // https://cs.android.com/android/_/android/platform/build/soong/+/main:cc/cc.go;l=2642-2643;drc=e12d252e22dd8afa654325790d3298a0d67bd9d6;bpv=1;bpt=0
+ ndkLibModule, _ := ctx.ModuleFromName(dep.Name() + ndkLibrarySuffix)
+ label = bazel.Label{
+ Label: "//" + ctx.OtherModuleDir(ndkLibModule) + ":" + ndkLibModule.Name() + "_stub_libs",
+ }
+ }
+ // add the ndk lib label to this axis
+ existingValue := dynamicDeps.SelectValue(bazel.OsAndInApexAxis, "unbundled_app")
+ existingValue.Append(bazel.MakeLabelList([]bazel.Label{label}))
+ dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, "unbundled_app", bazel.FirstUniqueBazelLabelList(existingValue))
+ }
+ }
}
func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
diff --git a/cc/cc.go b/cc/cc.go
index 3b92696..9aa0cac 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -879,16 +879,16 @@
installer installer
bazelHandler BazelHandler
- features []feature
- stl *stl
- sanitize *sanitize
- coverage *coverage
- fuzzer *fuzzer
- sabi *sabi
- vndkdep *vndkdep
- lto *lto
- afdo *afdo
- pgo *pgo
+ features []feature
+ stl *stl
+ sanitize *sanitize
+ coverage *coverage
+ fuzzer *fuzzer
+ sabi *sabi
+ vndkdep *vndkdep
+ lto *lto
+ afdo *afdo
+ pgo *pgo
orderfile *orderfile
library libraryInterface
@@ -1104,6 +1104,16 @@
return false
}
+func (c *Module) IsNdkPrebuiltStl() bool {
+ if c.linker == nil {
+ return false
+ }
+ if _, ok := c.linker.(*ndkPrebuiltStlLinker); ok {
+ return true
+ }
+ return false
+}
+
func (c *Module) RlibStd() bool {
panic(fmt.Errorf("RlibStd called on non-Rust module: %q", c.BaseModuleName()))
}
@@ -4158,6 +4168,7 @@
headerLibrary
testBin // testBinary already declared
ndkLibrary
+ ndkPrebuiltStl
)
func (c *Module) typ() moduleType {
@@ -4196,12 +4207,14 @@
return sharedLibrary
} else if c.isNDKStubLibrary() {
return ndkLibrary
+ } else if c.IsNdkPrebuiltStl() {
+ return ndkPrebuiltStl
}
return unknownType
}
// ConvertWithBp2build converts Module to Bazel for bp2build.
-func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (c *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
prebuilt := c.IsPrebuilt()
switch c.typ() {
case binary:
@@ -4240,6 +4253,10 @@
} else {
sharedOrStaticLibraryBp2Build(ctx, c, false)
}
+ case ndkPrebuiltStl:
+ ndkPrebuiltStlBp2build(ctx, c)
+ case ndkLibrary:
+ ndkLibraryBp2build(ctx, c)
default:
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
}
diff --git a/cc/config/global.go b/cc/config/global.go
index 34e0aa7..a586a3f 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",
@@ -68,10 +67,6 @@
// not emit the table by default on Android since NDK still uses GNU binutils.
"-faddrsig",
- // Turn on -fcommon explicitly, since Clang now defaults to -fno-common. The cleanup bug
- // tracking this is http://b/151457797.
- "-fcommon",
-
// Help catch common 32/64-bit errors.
"-Werror=int-conversion",
@@ -254,6 +249,8 @@
// (anything for which IsThirdPartyPath() in build/soong/android/paths.go
// returns true - includes external/, most of vendor/ and most of hardware/)
noOverrideExternalGlobalCflags = []string{
+ // http://b/151457797
+ "-fcommon",
// http://b/191699019
"-Wno-format-insufficient-args",
// http://b/296321145
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index 40919c0..e048622 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -26,14 +26,14 @@
// Help catch common 32/64-bit errors.
"-Werror=implicit-function-declaration",
"-fno-emulated-tls",
- "-march=rv64gc_zba_zbb_zbs",
+ "-march=rv64gcv_zba_zbb_zbs",
}
riscv64ArchVariantCflags = map[string][]string{}
riscv64Ldflags = []string{
"-Wl,--hash-style=gnu",
- "-march=rv64gc_zba_zbb_zbs",
+ "-march=rv64gcv_zba_zbb_zbs",
}
riscv64Lldflags = append(riscv64Ldflags,
diff --git a/cc/fdo_profile.go b/cc/fdo_profile.go
index 7fbe719..05a8f46 100644
--- a/cc/fdo_profile.go
+++ b/cc/fdo_profile.go
@@ -16,8 +16,10 @@
import (
"android/soong/android"
+ "android/soong/bazel"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -25,11 +27,12 @@
}
func RegisterFdoProfileBuildComponents(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("fdo_profile", fdoProfileFactory)
+ ctx.RegisterModuleType("fdo_profile", FdoProfileFactory)
}
type fdoProfile struct {
android.ModuleBase
+ android.BazelModuleBase
properties fdoProfileProperties
}
@@ -38,6 +41,49 @@
Profile *string `android:"arch_variant"`
}
+type bazelFdoProfileAttributes struct {
+ Profile bazel.StringAttribute
+}
+
+func (fp *fdoProfile) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ var profileAttr bazel.StringAttribute
+
+ archVariantProps := fp.GetArchVariantProperties(ctx, &fdoProfileProperties{})
+ for axis, configToProps := range archVariantProps {
+ for config, _props := range configToProps {
+ if archProps, ok := _props.(*fdoProfileProperties); ok {
+ if axis.String() == "arch" || axis.String() == "no_config" {
+ if archProps.Profile != nil {
+ profileAttr.SetSelectValue(axis, config, archProps.Profile)
+ }
+ }
+ }
+ }
+ }
+
+ // Ideally, cc_library_shared's fdo_profile attr can be a select statement so that we
+ // don't lift the restriction here. However, in cc_library_shared macro, fdo_profile
+ // is used as a string, we need to temporarily lift the host restriction until we can
+ // pass use fdo_profile attr with select statement
+ // https://cs.android.com/android/platform/superproject/+/master:build/bazel/rules/cc/cc_library_shared.bzl;l=127;drc=cc01bdfd39857eddbab04ef69ab6db22dcb1858a
+ // TODO(b/276287371): Drop the restriction override after fdo_profile path is handled properly
+ var noRestriction bazel.BoolAttribute
+ noRestriction.SetSelectValue(bazel.NoConfigAxis, "", proptools.BoolPtr(true))
+
+ ctx.CreateBazelTargetModuleWithRestrictions(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "fdo_profile",
+ },
+ android.CommonAttributes{
+ Name: fp.Name(),
+ },
+ &bazelFdoProfileAttributes{
+ Profile: profileAttr,
+ },
+ noRestriction,
+ )
+}
+
// FdoProfileInfo is provided by FdoProfileProvider
type FdoProfileInfo struct {
Path android.Path
@@ -77,9 +123,10 @@
}
}
-func fdoProfileFactory() android.Module {
+func FdoProfileFactory() android.Module {
m := &fdoProfile{}
m.AddProperties(&m.properties)
android.InitAndroidMultiTargetsArchModule(m, android.DeviceSupported, android.MultilibBoth)
+ android.InitBazelModule(m)
return m
}
diff --git a/cc/library.go b/cc/library.go
index 2d4d604..b9dc71b 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -308,7 +308,7 @@
}
}
-func libraryBp2Build(ctx android.TopDownMutatorContext, m *Module) {
+func libraryBp2Build(ctx android.Bp2buildMutatorContext, m *Module) {
sharedAttrs := bp2BuildParseSharedProps(ctx, m)
staticAttrs := bp2BuildParseStaticProps(ctx, m)
baseAttributes := bp2BuildParseBaseProps(ctx, m)
@@ -480,7 +480,7 @@
createStubsBazelTargetIfNeeded(ctx, m, compilerAttrs, exportedIncludes, baseAttributes)
}
-func createStubsBazelTargetIfNeeded(ctx android.TopDownMutatorContext, m *Module, compilerAttrs compilerAttributes, exportedIncludes BazelIncludes, baseAttributes baseAttributes) {
+func createStubsBazelTargetIfNeeded(ctx android.Bp2buildMutatorContext, m *Module, compilerAttrs compilerAttributes, exportedIncludes BazelIncludes, baseAttributes baseAttributes) {
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
stubSuitesProps := bazel.BazelTargetModuleProperties{
Rule_class: "cc_stub_suite",
@@ -494,6 +494,7 @@
Soname: &soname,
Source_library_label: proptools.StringPtr(m.GetBazelLabel(ctx, m)),
Deps: baseAttributes.deps,
+ Api_surface: proptools.StringPtr("module-libapi"),
}
ctx.CreateBazelTargetModule(stubSuitesProps,
android.CommonAttributes{Name: m.Name() + "_stub_libs"},
@@ -2885,7 +2886,7 @@
return outputFile
}
-func bp2buildParseAbiCheckerProps(ctx android.TopDownMutatorContext, module *Module) bazelCcHeaderAbiCheckerAttributes {
+func bp2buildParseAbiCheckerProps(ctx android.Bp2buildMutatorContext, module *Module) bazelCcHeaderAbiCheckerAttributes {
lib, ok := module.linker.(*libraryDecorator)
if !ok {
return bazelCcHeaderAbiCheckerAttributes{}
@@ -2908,7 +2909,7 @@
return abiCheckerAttrs
}
-func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module, isStatic bool) {
+func sharedOrStaticLibraryBp2Build(ctx android.Bp2buildMutatorContext, module *Module, isStatic bool) {
baseAttributes := bp2BuildParseBaseProps(ctx, module)
compilerAttrs := baseAttributes.compilerAttributes
linkerAttrs := baseAttributes.linkerAttributes
@@ -3121,6 +3122,7 @@
Source_library_label *string
Soname *string
Deps bazel.LabelListAttribute
+ Api_surface *string
}
type bazelCcHeaderAbiCheckerAttributes struct {
diff --git a/cc/library_headers.go b/cc/library_headers.go
index ce9c4aa..5eba6ab 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -129,7 +129,7 @@
sdkAttributes
}
-func libraryHeadersBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+func libraryHeadersBp2Build(ctx android.Bp2buildMutatorContext, module *Module) {
baseAttributes := bp2BuildParseBaseProps(ctx, module)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, &baseAttributes.includes)
linkerAttrs := baseAttributes.linkerAttributes
@@ -153,8 +153,13 @@
tags := android.ApexAvailableTagsWithoutTestApexes(ctx, module)
+ name := module.Name()
+ if module.IsPrebuilt() {
+ name = android.RemoveOptionalPrebuiltPrefix(name)
+ }
+
ctx.CreateBazelTargetModule(props, android.CommonAttributes{
- Name: module.Name(),
+ Name: name,
Tags: tags,
}, attrs)
}
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index d0ae4a5..1a8e90f 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -82,6 +82,7 @@
properties headerProperties
+ srcPaths android.Paths
installPaths android.Paths
licensePath android.Path
}
@@ -125,8 +126,8 @@
m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))
- srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
- for _, header := range srcFiles {
+ m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
+ for _, header := range m.srcPaths {
installDir := getHeaderInstallDir(ctx, header, String(m.properties.From),
String(m.properties.To))
installedPath := ctx.InstallFile(installDir, header.Base(), header)
@@ -193,6 +194,7 @@
properties versionedHeaderProperties
+ srcPaths android.Paths
installPaths android.Paths
licensePath android.Path
}
@@ -211,9 +213,9 @@
fromSrcPath := android.PathForModuleSrc(ctx, String(m.properties.From))
toOutputPath := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
- srcFiles := ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil)
+ m.srcPaths = ctx.GlobFiles(headerGlobPattern(fromSrcPath.String()), nil)
var installPaths []android.WritablePath
- for _, header := range srcFiles {
+ for _, header := range m.srcPaths {
installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To))
installPath := installDir.Join(ctx, header.Base())
installPaths = append(installPaths, installPath)
@@ -224,11 +226,11 @@
ctx.ModuleErrorf("glob %q matched zero files", String(m.properties.From))
}
- processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
+ processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, m.srcPaths, installPaths)
}
func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
- srcFiles android.Paths, installPaths []android.WritablePath) android.Path {
+ srcPaths android.Paths, installPaths []android.WritablePath) android.Path {
// The versioner depends on a dependencies directory to simplify determining include paths
// when parsing headers. This directory contains architecture specific directories as well
// as a common directory, each of which contains symlinks to the actually directories to
@@ -253,7 +255,7 @@
Rule: versionBionicHeaders,
Description: "versioner preprocess " + srcDir.Rel(),
Output: timestampFile,
- Implicits: append(srcFiles, depsGlob...),
+ Implicits: append(srcPaths, depsGlob...),
ImplicitOutputs: installPaths,
Args: map[string]string{
"depsPath": depsPath.String(),
@@ -317,6 +319,7 @@
properties preprocessedHeadersProperties
+ srcPaths android.Paths
installPaths android.Paths
licensePath android.Path
}
@@ -329,9 +332,9 @@
preprocessor := android.PathForModuleSrc(ctx, String(m.properties.Preprocessor))
m.licensePath = android.PathForModuleSrc(ctx, String(m.properties.License))
- srcFiles := android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
+ m.srcPaths = android.PathsForModuleSrcExcludes(ctx, m.properties.Srcs, m.properties.Exclude_srcs)
installDir := getCurrentIncludePath(ctx).Join(ctx, String(m.properties.To))
- for _, src := range srcFiles {
+ for _, src := range m.srcPaths {
installPath := installDir.Join(ctx, src.Base())
m.installPaths = append(m.installPaths, installPath)
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 9281aeb..b3bb2da 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -43,11 +43,17 @@
CommandDeps: []string{"$ndkStubGenerator"},
}, "arch", "apiLevel", "apiMap", "flags")
+ // $headersList should include paths to public headers. All types
+ // that are defined outside of public headers will be excluded from
+ // ABI monitoring.
+ //
+ // STG tool doesn't access content of files listed in $headersList,
+ // so there is no need to add them to dependencies.
stg = pctx.AndroidStaticRule("stg",
blueprint.RuleParams{
- Command: "$stg -S :$symbolList --elf $in -o $out",
+ Command: "$stg -S :$symbolList --file-filter :$headersList --elf $in -o $out",
CommandDeps: []string{"$stg"},
- }, "symbolList")
+ }, "symbolList", "headersList")
stgdiff = pctx.AndroidStaticRule("stgdiff",
blueprint.RuleParams{
@@ -347,14 +353,19 @@
this.abiDumpPath = getNdkAbiDumpInstallBase(ctx).Join(ctx,
this.apiLevel.String(), ctx.Arch().ArchType.String(),
this.libraryName(ctx), "abi.stg")
+ headersList := getNdkABIHeadersFile(ctx)
ctx.Build(pctx, android.BuildParams{
Rule: stg,
Description: fmt.Sprintf("stg %s", implementationLibrary),
Input: implementationLibrary,
- Implicit: symbolList,
- Output: this.abiDumpPath,
+ Implicits: []android.Path{
+ symbolList,
+ headersList,
+ },
+ Output: this.abiDumpPath,
Args: map[string]string{
- "symbolList": symbolList.String(),
+ "symbolList": symbolList.String(),
+ "headersList": headersList.String(),
},
})
}
@@ -404,7 +415,7 @@
// Also ensure that the ABI of the next API level (if there is one) matches
// this API level. *New* ABI is allowed, but any changes to APIs that exist
// in this API level are disallowed.
- if !this.apiLevel.IsCurrent() {
+ if !this.apiLevel.IsCurrent() && prebuiltAbiDump.Valid() {
nextApiLevel := findNextApiLevel(ctx, this.apiLevel)
if nextApiLevel == nil {
panic(fmt.Errorf("could not determine which API level follows "+
@@ -424,10 +435,12 @@
} else {
ctx.Build(pctx, android.BuildParams{
Rule: stgdiff,
- Description: fmt.Sprintf("abidiff %s %s", this.abiDumpPath,
- nextAbiDump),
+ Description: fmt.Sprintf(
+ "Comparing ABI to the next API level %s %s",
+ prebuiltAbiDump, nextAbiDump),
Output: nextAbiDiffPath,
- Inputs: android.Paths{this.abiDumpPath, nextAbiDump.Path()},
+ Inputs: android.Paths{
+ prebuiltAbiDump.Path(), nextAbiDump.Path()},
Args: map[string]string{
"args": "--format=small --ignore=interface_addition",
},
@@ -570,3 +583,40 @@
}
return android.BazelLabelForModuleDepsWithFn(ctx, hdrLibs, addSuffix)
}
+
+func ndkLibraryBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
+ ndk, _ := c.linker.(*stubDecorator)
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_stub_suite",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_stub_library.bzl",
+ }
+ sourceLibraryName := strings.TrimSuffix(c.Name(), ".ndk")
+ fromApiLevel, err := android.ApiLevelFromUser(ctx, proptools.String(ndk.properties.First_version))
+ if err != nil {
+ ctx.PropertyErrorf("first_version", "error converting first_version %v", proptools.String(ndk.properties.First_version))
+ }
+ symbolFileLabel := android.BazelLabelForModuleSrcSingle(ctx, proptools.String(ndk.properties.Symbol_file))
+ attrs := &bazelCcStubSuiteAttributes{
+ // TODO - b/300504837 Add ndk headers
+ Symbol_file: proptools.StringPtr(symbolFileLabel.Label),
+ Soname: proptools.StringPtr(sourceLibraryName + ".so"),
+ Api_surface: proptools.StringPtr(android.PublicApi.String()),
+ }
+ if sourceLibrary, exists := ctx.ModuleFromName(sourceLibraryName); exists {
+ // the source library might not exist in minimal/unbuildable branches like kernel-build-tools.
+ // check for its existence
+ attrs.Source_library_label = proptools.StringPtr(c.GetBazelLabel(ctx, sourceLibrary))
+ }
+ if ctx.Config().RawPlatformSdkVersion() != nil {
+ // This is a hack to populate `versions` only on branches that set a platform_sdk_version
+ // This prevents errors on branches such as kernel-build-tools
+ // This hack is acceptable since we are not required to support NDK Bazel builds on those branches
+ attrs.Versions = bazel.MakeStringListAttribute(ndkLibraryVersions(ctx, fromApiLevel))
+ }
+
+ ctx.CreateBazelTargetModule(
+ props,
+ android.CommonAttributes{Name: c.Name() + "_stub_libs"},
+ attrs,
+ )
+}
diff --git a/cc/ndk_prebuilt.go b/cc/ndk_prebuilt.go
index d3a0a00..c3e6510 100644
--- a/cc/ndk_prebuilt.go
+++ b/cc/ndk_prebuilt.go
@@ -15,9 +15,11 @@
package cc
import (
+ "path/filepath"
"strings"
"android/soong/android"
+ "android/soong/bazel"
)
func init() {
@@ -64,6 +66,7 @@
module.Properties.Sdk_version = StringPtr("minimum")
module.Properties.AlwaysSdk = true
module.stl.Properties.Stl = StringPtr("none")
+ module.bazelable = true
return module.Init()
}
@@ -84,12 +87,16 @@
module.Properties.AlwaysSdk = true
module.Properties.Sdk_version = StringPtr("current")
module.stl.Properties.Stl = StringPtr("none")
+ module.bazelable = true
return module.Init()
}
+const (
+ libDir = "current/sources/cxx-stl/llvm-libc++/libs"
+)
+
func getNdkStlLibDir(ctx android.ModuleContext) android.SourcePath {
- libDir := "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs"
- return android.PathForSource(ctx, libDir).Join(ctx, ctx.Arch().Abi[0])
+ return android.PathForSource(ctx, ctx.ModuleDir(), libDir).Join(ctx, ctx.Arch().Abi[0])
}
func (ndk *ndkPrebuiltStlLinker) link(ctx ModuleContext, flags Flags,
@@ -128,3 +135,81 @@
return lib
}
+
+var (
+ archToAbiDirMap = map[string]string{
+ "android_arm": "armeabi-v7a",
+ "android_arm64": "arm64-v8a",
+ "android_riscv64": "riscv64",
+ "android_x86": "x86",
+ "android_x86_64": "x86_64",
+ }
+)
+
+// stlSrcBp2build returns a bazel label for the checked-in .so/.a file
+// It contains a select statement for each ABI
+func stlSrcBp2build(ctx android.Bp2buildMutatorContext, c *Module) bazel.LabelAttribute {
+ libName := strings.TrimPrefix(c.Name(), "ndk_")
+ libExt := ".so" // TODO - b/201079053: Support windows
+ if ctx.ModuleType() == "ndk_prebuilt_static_stl" {
+ libExt = ".a"
+ }
+ src := bazel.LabelAttribute{}
+ for arch, abiDir := range archToAbiDirMap {
+ srcPath := filepath.Join(libDir, abiDir, libName+libExt)
+ src.SetSelectValue(
+ bazel.OsArchConfigurationAxis,
+ arch,
+ android.BazelLabelForModuleSrcSingle(ctx, srcPath),
+ )
+ }
+ return src
+}
+
+// stlIncludesBp2build returns the includes exported by the STL
+func stlIncludesBp2build(c *Module) bazel.StringListAttribute {
+ linker, _ := c.linker.(*ndkPrebuiltStlLinker)
+ includeDirs := append(
+ []string{},
+ linker.libraryDecorator.flagExporter.Properties.Export_include_dirs...,
+ )
+ includeDirs = append(
+ includeDirs,
+ linker.libraryDecorator.flagExporter.Properties.Export_system_include_dirs...,
+ )
+ return bazel.MakeStringListAttribute(android.FirstUniqueStrings(includeDirs))
+}
+
+func ndkPrebuiltStlBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
+ if ctx.ModuleType() == "ndk_prebuilt_static_stl" {
+ ndkPrebuiltStaticStlBp2build(ctx, c)
+ } else {
+ ndkPrebuiltSharedStlBp2build(ctx, c)
+ }
+}
+
+func ndkPrebuiltStaticStlBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_prebuilt_library_static",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_static.bzl",
+ }
+ attrs := &bazelPrebuiltLibraryStaticAttributes{
+ Static_library: stlSrcBp2build(ctx, c),
+ Export_system_includes: stlIncludesBp2build(c), // The exports are always as system
+ }
+ // TODO: min_sdk_version
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs)
+}
+
+func ndkPrebuiltSharedStlBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_prebuilt_library_shared",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl",
+ }
+ attrs := &bazelPrebuiltLibrarySharedAttributes{
+ Shared_library: stlSrcBp2build(ctx, c),
+ Export_system_includes: stlIncludesBp2build(c), // The exports are always as system
+ }
+ // TODO: min_sdk_version
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: c.Name()}, attrs)
+}
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index feb3880..9ec2ae4 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -54,6 +54,7 @@
import (
"android/soong/android"
+ "strings"
)
func init() {
@@ -96,15 +97,56 @@
return android.PathForOutput(ctx, "ndk.timestamp")
}
+// The list of all NDK headers as they are located in the repo.
+// Used for ABI monitoring to track only structures defined in NDK headers.
+func getNdkABIHeadersFile(ctx android.PathContext) android.WritablePath {
+ return android.PathForOutput(ctx, "ndk_abi_headers.txt")
+}
+
func NdkSingleton() android.Singleton {
return &ndkSingleton{}
}
+// Collect all NDK exported headers paths into a file that is used to
+// detect public types that should be ABI monitored.
+//
+// Assume that we have the following code in exported header:
+//
+// typedef struct Context Context;
+// typedef struct Output {
+// ...
+// } Output;
+// void DoSomething(Context* ctx, Output* output);
+//
+// If none of public headers exported to end-users contain definition of
+// "struct Context", then "struct Context" layout and members shouldn't be
+// monitored. However we use DWARF information from a real library, which
+// may have access to the definition of "string Context" from
+// implementation headers, and it will leak to ABI.
+//
+// STG tool doesn't access source and header files, only DWARF information
+// from compiled library. And the DWARF contains file name where a type is
+// defined. So we need a rule to build a list of paths to public headers,
+// so STG can distinguish private types from public and do not monitor
+// private types that are not accessible to library users.
+func writeNdkAbiSrcFilter(ctx android.BuilderContext,
+ headerSrcPaths android.Paths, outputFile android.WritablePath) {
+ var filterBuilder strings.Builder
+ filterBuilder.WriteString("[decl_file_allowlist]\n")
+ for _, headerSrcPath := range headerSrcPaths {
+ filterBuilder.WriteString(headerSrcPath.String())
+ filterBuilder.WriteString("\n")
+ }
+
+ android.WriteFileRule(ctx, outputFile, filterBuilder.String())
+}
+
type ndkSingleton struct{}
func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var staticLibInstallPaths android.Paths
- var headerPaths android.Paths
+ var headerSrcPaths android.Paths
+ var headerInstallPaths android.Paths
var installPaths android.Paths
var licensePaths android.Paths
ctx.VisitAllModules(func(module android.Module) {
@@ -113,19 +155,22 @@
}
if m, ok := module.(*headerModule); ok {
- headerPaths = append(headerPaths, m.installPaths...)
+ headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
+ headerInstallPaths = append(headerInstallPaths, m.installPaths...)
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
if m, ok := module.(*versionedHeaderModule); ok {
- headerPaths = append(headerPaths, m.installPaths...)
+ headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
+ headerInstallPaths = append(headerInstallPaths, m.installPaths...)
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
if m, ok := module.(*preprocessedHeadersModule); ok {
- headerPaths = append(headerPaths, m.installPaths...)
+ headerSrcPaths = append(headerSrcPaths, m.srcPaths...)
+ headerInstallPaths = append(headerInstallPaths, m.installPaths...)
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath)
}
@@ -175,9 +220,11 @@
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Output: getNdkHeadersTimestampFile(ctx),
- Implicits: headerPaths,
+ Implicits: headerInstallPaths,
})
+ writeNdkAbiSrcFilter(ctx, headerSrcPaths, getNdkABIHeadersFile(ctx))
+
fullDepPaths := append(staticLibInstallPaths, getNdkBaseTimestampFile(ctx))
// There's a phony "ndk" rule defined in core/main.mk that depends on this.
diff --git a/cc/object.go b/cc/object.go
index ca14845..a3000e0 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -156,7 +156,7 @@
// objectBp2Build is the bp2build converter from cc_object modules to the
// Bazel equivalent target, plus any necessary include deps for the cc_object.
-func objectBp2Build(ctx android.TopDownMutatorContext, m *Module) {
+func objectBp2Build(ctx android.Bp2buildMutatorContext, m *Module) {
if m.compiler == nil {
// a cc_object must have access to the compiler decorator for its props.
ctx.ModuleErrorf("compiler must not be nil for a cc_object module")
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index a4ca590..b4819b0 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -363,12 +363,12 @@
// all variants
//
// In all cases, cc_prebuilt_library_static target names will be appended with "_bp2build_cc_library_static".
-func prebuiltLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+func prebuiltLibraryBp2Build(ctx android.Bp2buildMutatorContext, module *Module) {
prebuiltLibraryStaticBp2Build(ctx, module, true)
prebuiltLibrarySharedBp2Build(ctx, module)
}
-func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Module, fullBuild bool) {
+func prebuiltLibraryStaticBp2Build(ctx android.Bp2buildMutatorContext, module *Module, fullBuild bool) {
prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, true)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, nil)
@@ -404,7 +404,7 @@
Export_system_includes bazel.StringListAttribute
}
-func prebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+func prebuiltLibrarySharedBp2Build(ctx android.Bp2buildMutatorContext, module *Module) {
prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, false)
exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, nil)
@@ -637,7 +637,7 @@
Src bazel.LabelAttribute
}
-func prebuiltObjectBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+func prebuiltObjectBp2Build(ctx android.Bp2buildMutatorContext, module *Module) {
prebuiltAttrs := bp2BuildParsePrebuiltObjectProps(ctx, module)
attrs := &bazelPrebuiltObjectAttributes{
@@ -797,7 +797,7 @@
Strip stripAttributes
}
-func prebuiltBinaryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+func prebuiltBinaryBp2Build(ctx android.Bp2buildMutatorContext, module *Module) {
prebuiltAttrs := bp2BuildParsePrebuiltBinaryProps(ctx, module)
var la linkerAttributes
diff --git a/cc/sanitize.go b/cc/sanitize.go
index f37b5c7..9ceb1c8 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 {
@@ -677,12 +679,6 @@
s.Integer_overflow = nil
}
- // TODO(b/254713216): CFI doesn't work for riscv64 yet because LTO doesn't work.
- if ctx.Arch().ArchType == android.Riscv64 {
- s.Cfi = nil
- s.Diag.Cfi = nil
- }
-
// Disable CFI for musl
if ctx.toolchain().Musl() {
s.Cfi = nil
diff --git a/cc/stl.go b/cc/stl.go
index 8f92dcb..a31a585 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -172,6 +172,7 @@
// The system STL doesn't have a prebuilt (it uses the system's libstdc++), but it does have
// its own includes. The includes are handled in CCBase.Flags().
deps.SharedLibs = append([]string{"libstdc++"}, deps.SharedLibs...)
+ deps.HeaderLibs = append([]string{"ndk_system"}, deps.HeaderLibs...)
case "ndk_libc++_shared", "ndk_libc++_static":
if stl.Properties.SelectedStl == "ndk_libc++_shared" {
deps.SharedLibs = append(deps.SharedLibs, stl.Properties.SelectedStl)
@@ -219,8 +220,7 @@
case "libstdc++":
// Nothing
case "ndk_system":
- ndkSrcRoot := android.PathForSource(ctx, "prebuilts/ndk/current/sources/cxx-stl/system/include")
- flags.Local.CFlags = append(flags.Local.CFlags, "-isystem "+ndkSrcRoot.String())
+ // Nothing: The exports of ndk_system will be added automatically to the local cflags
case "ndk_libc++_shared", "ndk_libc++_static":
if ctx.Arch().ArchType == android.Arm {
// Make sure the _Unwind_XXX symbols are not re-exported.
diff --git a/cc/test.go b/cc/test.go
index ae62128..7a6cf1b 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -700,7 +700,7 @@
// TODO(b/244432609): handle `isolated` property.
// TODO(b/244432134): handle custom runpaths for tests that assume runfile layouts not
// default to bazel. (see linkerInit function)
-func testBinaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func testBinaryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
var testBinaryAttrs testBinaryAttributes
testBinaryAttrs.binaryAttributes = binaryBp2buildAttrs(ctx, m)
diff --git a/cc/testing.go b/cc/testing.go
index d1632aa..21745c3 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -35,6 +35,7 @@
multitree.RegisterApiImportsModule(ctx)
+ ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
ctx.RegisterModuleType("cc_object", ObjectFactory)
ctx.RegisterModuleType("cc_genrule", GenRuleFactory)
@@ -67,6 +68,26 @@
func commonDefaultModules() string {
return `
+ prebuilt_build_tool {
+ name: "clang++",
+ src: "bin/clang++",
+ }
+ prebuilt_build_tool {
+ name: "clang++.real",
+ src: "bin/clang++.real",
+ }
+ prebuilt_build_tool {
+ name: "lld",
+ src: "bin/lld",
+ }
+ prebuilt_build_tool {
+ name: "ld.lld",
+ src: "bin/ld.lld",
+ }
+ prebuilt_build_tool {
+ name: "llvm-ar",
+ src: "bin/llvm-ar",
+ }
cc_defaults {
name: "toolchain_libs_defaults",
host_supported: true,
@@ -558,7 +579,7 @@
// This includes files that are needed by all, or at least most, instances of a cc module type.
android.MockFS{
// Needed for ndk_prebuilt_(shared|static)_stl.
- "prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs": nil,
+ "defaults/cc/common/current/sources/cxx-stl/llvm-libc++/libs": nil,
}.AddToFixture(),
)
@@ -568,6 +589,12 @@
// Additional files needed in tests that disallow non-existent source.
android.MockFS{
+ "defaults/cc/common/bin/clang++": nil,
+ "defaults/cc/common/bin/clang++.real": nil,
+ "defaults/cc/common/bin/lld": nil,
+ "defaults/cc/common/bin/ld.lld": nil,
+ "defaults/cc/common/bin/llvm-ar": nil,
+
"defaults/cc/common/libc.map.txt": nil,
"defaults/cc/common/libdl.map.txt": nil,
"defaults/cc/common/libm.map.txt": nil,
@@ -671,7 +698,7 @@
// PrepareForTestWithFdoProfile registers module types to test with fdo_profile
var PrepareForTestWithFdoProfile = android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("soong_namespace", android.NamespaceFactory)
- ctx.RegisterModuleType("fdo_profile", fdoProfileFactory)
+ ctx.RegisterModuleType("fdo_profile", FdoProfileFactory)
})
// TestConfig is the legacy way of creating a test Config for testing cc modules.
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index fc56dd5..3364f50 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -119,6 +119,9 @@
}
manifest, err := readManifest(manifestFile)
+ if err != nil {
+ return err
+ }
if len(manifest.Commands) == 0 {
return fmt.Errorf("at least one commands entry is required in %q", manifestFile)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 20e366e..d20847b 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -21,13 +21,11 @@
"fmt"
"os"
"path/filepath"
- "regexp"
"strings"
"time"
"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 +74,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 +166,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 +434,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()
@@ -736,43 +616,6 @@
return excluded
}
-// buildTargetsByPackage parses Bazel BUILD.bazel and BUILD files under
-// the workspace, and returns a map containing names of Bazel targets defined in
-// these BUILD files.
-// For example, maps "//foo/bar" to ["baz", "qux"] if `//foo/bar:{baz,qux}` exist.
-func buildTargetsByPackage(ctx *android.Context) map[string][]string {
- existingBazelFiles, err := getExistingBazelRelatedFiles(topDir)
- maybeQuit(err, "Error determining existing Bazel-related files")
-
- result := map[string][]string{}
-
- // Search for instances of `name = "$NAME"` (with arbitrary spacing).
- targetNameRegex := regexp.MustCompile(`(?m)^\s*name\s*=\s*\"([^\"]+)\"`)
-
- for _, path := range existingBazelFiles {
- if !ctx.Config().Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(filepath.Dir(path)) {
- continue
- }
- fullPath := shared.JoinPath(topDir, path)
- sourceDir := filepath.Dir(path)
- fileInfo, err := os.Stat(fullPath)
- maybeQuit(err, "Error accessing Bazel file '%s'", fullPath)
-
- if !fileInfo.IsDir() &&
- (fileInfo.Name() == "BUILD" || fileInfo.Name() == "BUILD.bazel") {
- // Process this BUILD file.
- buildFileContent, err := os.ReadFile(fullPath)
- maybeQuit(err, "Error reading Bazel file '%s'", fullPath)
-
- matches := targetNameRegex.FindAllStringSubmatch(string(buildFileContent), -1)
- for _, match := range matches {
- result[sourceDir] = append(result[sourceDir], match[1])
- }
- }
- }
- return result
-}
-
// Run Soong in the bp2build mode. This creates a standalone context that registers
// an alternate pipeline of mutators and singletons specifically for generating
// Bazel BUILD files instead of Ninja files.
@@ -781,7 +624,11 @@
ctx.EventHandler.Do("bp2build", func() {
ctx.EventHandler.Do("read_build", func() {
- ctx.Config().SetBazelBuildFileTargets(buildTargetsByPackage(ctx))
+ existingBazelFiles, err := getExistingBazelRelatedFiles(topDir)
+ maybeQuit(err, "Error determining existing Bazel-related files")
+
+ err = ctx.RegisterExistingBazelTargets(topDir, existingBazelFiles)
+ maybeQuit(err, "Error parsing existing Bazel-related files")
})
// Propagate "allow misssing dependencies" bit. This is normally set in
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 4097e8a..3b8f4f5 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -289,10 +289,7 @@
}
}
- // Fix up the source tree due to a repo bug where it doesn't remove
- // linkfiles that have been removed
- fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.bp")
- fixBadDanglingLink(buildCtx, "hardware/qcom/sdm710/Android.mk")
+ removeBadTargetRename(buildCtx, config)
// Create a source finder.
f := build.NewSourceFinder(buildCtx, config)
@@ -300,16 +297,26 @@
build.FindSources(buildCtx, config, f)
}
-func fixBadDanglingLink(ctx build.Context, name string) {
- _, err := os.Lstat(name)
+func removeBadTargetRename(ctx build.Context, config build.Config) {
+ log := ctx.ContextImpl.Logger
+ // find bad paths
+ m, err := filepath.Glob(filepath.Join(config.OutDir(), "bazel", "output", "execroot", "__main__", "bazel-out", "mixed_builds_product-*", "bin", "tools", "metalava", "metalava"))
if err != nil {
- return
+ log.Fatalf("Glob for invalid file failed %s", err)
}
- _, err = os.Stat(name)
- if os.IsNotExist(err) {
- err = os.Remove(name)
+ for _, f := range m {
+ info, err := os.Stat(f)
if err != nil {
- ctx.Fatalf("Failed to remove dangling link %q: %v", name, err)
+ log.Fatalf("Stat of invalid file %q failed %s", f, err)
+ }
+ // if it's a directory, leave it, but remove the files
+ if !info.IsDir() {
+ err = os.Remove(f)
+ if err != nil {
+ log.Fatalf("Remove of invalid file %q failed %s", f, err)
+ } else {
+ log.Verbosef("Removed %q", f)
+ }
}
}
}
diff --git a/compliance/OWNERS b/compliance/OWNERS
deleted file mode 100644
index f52e201..0000000
--- a/compliance/OWNERS
+++ /dev/null
@@ -1,8 +0,0 @@
-# OSEP Build
-bbadour@google.com
-kanouche@google.com
-napier@google.com
-
-# Open Source Compliance Tools
-rtp@google.com
-austinyuan@google.com
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.go b/etc/prebuilt_etc.go
index 370a423..9423531 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -40,6 +40,7 @@
"android/soong/bazel"
"android/soong/bazel/cquery"
"android/soong/snapshot"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
)
var pctx = android.NewPackageContext("android/soong/etc")
@@ -711,7 +712,7 @@
// Bp2buildHelper returns a bazelPrebuiltFileAttributes used for the conversion
// of prebuilt_* modules. bazelPrebuiltFileAttributes has the common attributes
// used by both prebuilt_etc_xml and other prebuilt_* moodules
-func (module *PrebuiltEtc) Bp2buildHelper(ctx android.TopDownMutatorContext) *bazelPrebuiltFileAttributes {
+func (module *PrebuiltEtc) Bp2buildHelper(ctx android.Bp2buildMutatorContext) (*bazelPrebuiltFileAttributes, bool) {
var src bazel.LabelAttribute
for axis, configToProps := range module.GetArchVariantProperties(ctx, &prebuiltEtcProperties{}) {
for config, p := range configToProps {
@@ -720,12 +721,20 @@
continue
}
if props.Src != nil {
- label := android.BazelLabelForModuleSrcSingle(ctx, *props.Src)
+ srcStr := proptools.String(props.Src)
+ if srcStr == ctx.ModuleName() {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "src == name")
+ return &bazelPrebuiltFileAttributes{}, false
+ }
+ label := android.BazelLabelForModuleSrcSingle(ctx, srcStr)
src.SetSelectValue(axis, config, label)
}
}
-
- for propName, productConfigProps := range android.ProductVariableProperties(ctx, ctx.Module()) {
+ productVarProperties, errs := android.ProductVariableProperties(ctx, ctx.Module())
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
+ for propName, productConfigProps := range productVarProperties {
for configProp, propVal := range productConfigProps {
if propName == "Src" {
props, ok := propVal.(*string)
@@ -779,21 +788,23 @@
attrs.Filename_from_src = bazel.BoolAttribute{Value: moduleProps.Filename_from_src}
}
- return attrs
-
+ return attrs, true
}
// ConvertWithBp2build performs bp2build conversion of PrebuiltEtc
// prebuilt_* modules (except prebuilt_etc_xml) are PrebuiltEtc,
// which we treat as *PrebuiltFile*
-func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (module *PrebuiltEtc) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
var dir = module.installDirBase
// prebuilt_file supports only `etc` or `usr/share`
if !(dir == "etc" || dir == "usr/share") {
return
}
- attrs := module.Bp2buildHelper(ctx)
+ attrs, convertible := module.Bp2buildHelper(ctx)
+ if !convertible {
+ return
+ }
props := bazel.BazelTargetModuleProperties{
Rule_class: "prebuilt_file",
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/filesystem/avb_add_hash_footer.go b/filesystem/avb_add_hash_footer.go
index f3fecd0..dabbc46 100644
--- a/filesystem/avb_add_hash_footer.go
+++ b/filesystem/avb_add_hash_footer.go
@@ -68,6 +68,9 @@
// List of properties to add to the footer
Props []avbProp
+ // The index used to prevent rollback of the image on device.
+ Rollback_index *int64
+
// Include descriptors from images
Include_descriptors_from_images []string `android:"path,arch_variant"`
}
@@ -128,6 +131,14 @@
addAvbProp(ctx, cmd, prop)
}
+ if a.properties.Rollback_index != nil {
+ rollbackIndex := proptools.Int(a.properties.Rollback_index)
+ if rollbackIndex < 0 {
+ ctx.PropertyErrorf("rollback_index", "Rollback index must be non-negative")
+ }
+ cmd.Flag(fmt.Sprintf(" --rollback_index %x", rollbackIndex))
+ }
+
cmd.FlagWithOutput("--image ", a.output)
builder.Build("avbAddHashFooter", fmt.Sprintf("avbAddHashFooter %s", ctx.ModuleName()))
diff --git a/genrule/genrule.go b/genrule/genrule.go
index d1c2f13..01cac5b 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -920,7 +920,7 @@
}
// ConvertWithBp2build converts a Soong module -> Bazel target.
-func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
// Bazel only has the "tools" attribute.
tools_prop := android.BazelLabelForModuleDeps(ctx, m.properties.Tools)
tool_files_prop := android.BazelLabelForModuleSrc(ctx, m.properties.Tool_files)
@@ -993,7 +993,10 @@
var cmdProp bazel.StringAttribute
cmdProp.SetValue(replaceVariables(proptools.String(m.properties.Cmd)))
- allProductVariableProps := android.ProductVariableProperties(ctx, m)
+ allProductVariableProps, errs := android.ProductVariableProperties(ctx, m)
+ for _, err := range errs {
+ ctx.ModuleErrorf("ProductVariableProperties error: %s", err)
+ }
if productVariableProps, ok := allProductVariableProps["Cmd"]; ok {
for productVariable, value := range productVariableProps {
var cmd string
diff --git a/java/aar.go b/java/aar.go
index 0216196..f28d971 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -993,7 +993,7 @@
`jni_files=$$(find $outDir/jni -type f) && ` +
// print error message if there are no JNI libs for this arch
`[ -n "$$jni_files" ] || (echo "ERROR: no JNI libs found for arch ${archString}" && exit 1) && ` +
- `${config.SoongZipCmd} -o $out -P 'lib/${archString}' ` +
+ `${config.SoongZipCmd} -o $out -L 0 -P 'lib/${archString}' ` +
`-C $outDir/jni/${archString} $$(echo $$jni_files | xargs -n1 printf " -f %s")`,
CommandDeps: []string{"${config.SoongZipCmd}"},
},
@@ -1239,7 +1239,7 @@
Sdk_version bazel.StringAttribute
}
-func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.TopDownMutatorContext) (*bazelAapt, bool) {
+func (a *aapt) convertAaptAttrsWithBp2Build(ctx android.Bp2buildMutatorContext) (*bazelAapt, bool) {
manifest := proptools.StringDefault(a.aaptProperties.Manifest, "AndroidManifest.xml")
resourceFiles := bazel.LabelList{
@@ -1275,7 +1275,7 @@
}, true
}
-func (a *AARImport) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (a *AARImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
exportableStaticLibs := []string{}
// TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
@@ -1328,7 +1328,7 @@
}
}
-func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (a *AndroidLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
commonAttrs, bp2buildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
if !supported {
return
@@ -1340,7 +1340,10 @@
if !commonAttrs.Srcs.IsEmpty() {
deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
} else if !depLabels.Deps.IsEmpty() {
- ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
+ ctx.MarkBp2buildUnconvertible(
+ bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED,
+ "Module has direct dependencies but no sources. Bazel will not allow this.")
+ return
}
name := a.Name()
props := AndroidLibraryBazelTargetModuleProperties()
diff --git a/java/app.go b/java/app.go
index d71cd77..2edd3f7 100755
--- a/java/app.go
+++ b/java/app.go
@@ -316,6 +316,17 @@
a.generateJavaUsedByApex(ctx)
}
+func (a *AndroidApp) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
+ defaultMinSdkVersion := a.Module.MinSdkVersion(ctx)
+ if proptools.Bool(a.appProperties.Updatable) {
+ overrideApiLevel := android.MinSdkVersionFromValue(ctx, ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride())
+ if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(defaultMinSdkVersion) > 0 {
+ return overrideApiLevel
+ }
+ }
+ return defaultMinSdkVersion
+}
+
func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) {
if a.Updatable() {
if !a.SdkVersion(ctx).Stable() {
@@ -1104,6 +1115,8 @@
testConfig android.Path
extraTestConfigs android.Paths
data android.Paths
+
+ android.BazelModuleBase
}
func (a *AndroidTest) InstallInTestcases() bool {
@@ -1221,6 +1234,8 @@
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.InitDefaultableModule(module)
android.InitOverridableModule(module, &module.overridableAppProperties.Overrides)
+
+ android.InitBazelModule(module)
return module
}
@@ -1579,11 +1594,11 @@
Certificate string
}
-func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *AndroidAppCertificate) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
androidAppCertificateBp2Build(ctx, m)
}
-func androidAppCertificateBp2Build(ctx android.TopDownMutatorContext, module *AndroidAppCertificate) {
+func androidAppCertificateBp2Build(ctx android.Bp2buildMutatorContext, module *AndroidAppCertificate) {
var certificate string
if module.properties.Certificate != nil {
certificate = *module.properties.Certificate
@@ -1619,20 +1634,10 @@
Proguard_specs bazel.LabelListAttribute
}
-// ConvertWithBp2build is used to convert android_app to Bazel.
-func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
- if !supported {
- return
- }
- depLabels := bp2BuildInfo.DepLabels
-
- deps := depLabels.Deps
- deps.Append(depLabels.StaticDeps)
-
+func convertWithBp2build(ctx android.Bp2buildMutatorContext, a *AndroidApp) (bool, android.CommonAttributes, *bazelAndroidAppAttributes) {
aapt, supported := a.convertAaptAttrsWithBp2Build(ctx)
if !supported {
- return
+ return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{}
}
certificate, certificateName := android.BazelStringOrLabelFromProp(ctx, a.overridableAppProperties.Certificate)
@@ -1700,13 +1705,16 @@
})
appAttrs.Proguard_specs.Add(bazel.MakeLabelAttribute(":" + generatedFlagFileRuleName))
}
-
}
- props := bazel.BazelTargetModuleProperties{
- Rule_class: "android_binary",
- Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
+ commonAttrs, bp2BuildInfo, supported := a.convertLibraryAttrsBp2Build(ctx)
+ if !supported {
+ return false, android.CommonAttributes{}, &bazelAndroidAppAttributes{}
}
+ depLabels := bp2BuildInfo.DepLabels
+
+ deps := depLabels.Deps
+ deps.Append(depLabels.StaticDeps)
if !bp2BuildInfo.hasKotlin {
appAttrs.javaCommonAttributes = commonAttrs
@@ -1733,10 +1741,31 @@
}
}
- ctx.CreateBazelTargetModule(
- props,
- android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)},
- appAttrs,
- )
+ return true, android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, appAttrs
+}
+
+// ConvertWithBp2build is used to convert android_app to Bazel.
+func (a *AndroidApp) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, a); ok {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "android_binary",
+ Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs)
+ }
+
+}
+
+// ConvertWithBp2build is used to convert android_test to Bazel.
+func (at *AndroidTest) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, &at.AndroidApp); ok {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "android_test",
+ Bzl_load_location: "//build/bazel/rules/android:android_test.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs)
+ }
}
diff --git a/java/app_import.go b/java/app_import.go
index ad1765e..c5d09fd 100644
--- a/java/app_import.go
+++ b/java/app_import.go
@@ -19,6 +19,7 @@
import (
"fmt"
"reflect"
+ "strings"
"github.com/google/blueprint"
@@ -51,27 +52,11 @@
Description: "Uncompress dex files",
})
- checkDexLibsAreUncompressedRule = pctx.AndroidStaticRule("check-dex-libs-are-uncompressed", blueprint.RuleParams{
- // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed
- Command: "if (zipinfo $in '*.dex' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " +
- "echo $in: Contains compressed JNI libraries and/or dex files >&2;" +
- "exit 1; " +
- "else " +
- "touch $out; " +
- "fi",
- Description: "Check for compressed JNI libs or dex files",
- })
-
- checkJniLibsAreUncompressedRule = pctx.AndroidStaticRule("check-jni-libs-are-uncompressed", blueprint.RuleParams{
- // grep -v ' stor ' will search for lines that don't have ' stor '. stor means the file is stored uncompressed
- Command: "if (zipinfo $in 'lib/*.so' 2>/dev/null | grep -v ' stor ' >/dev/null) ; then " +
- "echo $in: Contains compressed JNI libraries >&2;" +
- "exit 1; " +
- "else " +
- "touch $out; " +
- "fi",
- Description: "Check for compressed JNI libs or dex files",
- })
+ checkPresignedApkRule = pctx.AndroidStaticRule("check-presigned-apk", blueprint.RuleParams{
+ Command: "build/soong/scripts/check_prebuilt_presigned_apk.py --aapt2 ${config.Aapt2Cmd} --zipalign ${config.ZipAlign} $extraArgs $in $out",
+ CommandDeps: []string{"build/soong/scripts/check_prebuilt_presigned_apk.py", "${config.Aapt2Cmd}", "${config.ZipAlign}"},
+ Description: "Check presigned apk",
+ }, "extraArgs")
)
func RegisterAppImportBuildComponents(ctx android.RegistrationContext) {
@@ -277,6 +262,14 @@
a.hideApexVariantFromMake = true
}
+ if Bool(a.properties.Preprocessed) {
+ if a.properties.Presigned != nil && !*a.properties.Presigned {
+ ctx.ModuleErrorf("Setting preprocessed: true implies presigned: true, so you cannot set presigned to false")
+ }
+ t := true
+ a.properties.Presigned = &t
+ }
+
numCertPropsSet := 0
if String(a.properties.Certificate) != "" {
numCertPropsSet++
@@ -288,11 +281,9 @@
numCertPropsSet++
}
if numCertPropsSet != 1 {
- ctx.ModuleErrorf("One and only one of certficate, presigned, and default_dev_cert properties must be set")
+ ctx.ModuleErrorf("One and only one of certficate, presigned (implied by preprocessed), and default_dev_cert properties must be set")
}
- _, _, certificates := collectAppDeps(ctx, a, false, false)
-
// TODO: LOCAL_EXTRACT_APK/LOCAL_EXTRACT_DPI_APK
// TODO: LOCAL_PACKAGE_SPLITS
@@ -346,25 +337,20 @@
// Sign or align the package if package has not been preprocessed
if proptools.Bool(a.properties.Preprocessed) {
- var output android.WritablePath
- if !proptools.Bool(a.properties.Skip_preprocessed_apk_checks) {
- output = android.PathForModuleOut(ctx, "validated-prebuilt", apkFilename)
- a.validatePreprocessedApk(ctx, srcApk, output)
- } else {
- // If using the input APK unmodified, still make a copy of it so that the output filename has the
- // right basename.
- output = android.PathForModuleOut(ctx, apkFilename)
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: srcApk,
- Output: output,
- })
- }
+ validationStamp := a.validatePresignedApk(ctx, srcApk)
+ output := android.PathForModuleOut(ctx, apkFilename)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: srcApk,
+ Output: output,
+ Validation: validationStamp,
+ })
a.outputFile = output
a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
+ _, _, certificates := collectAppDeps(ctx, a, false, false)
a.certificate, certificates = processMainCert(a.ModuleBase, String(a.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", apkFilename)
var lineageFile android.Path
@@ -377,8 +363,9 @@
SignAppPackage(ctx, signed, jnisUncompressed, certificates, nil, lineageFile, rotationMinSdkVersion)
a.outputFile = signed
} else {
+ validationStamp := a.validatePresignedApk(ctx, srcApk)
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
- TransformZipAlign(ctx, alignedApk, jnisUncompressed)
+ TransformZipAlign(ctx, alignedApk, jnisUncompressed, []android.Path{validationStamp})
a.outputFile = alignedApk
a.certificate = PresignedCertificate
}
@@ -394,42 +381,28 @@
// TODO: androidmk converter jni libs
}
-func (a *AndroidAppImport) validatePreprocessedApk(ctx android.ModuleContext, srcApk android.Path, dstApk android.WritablePath) {
- var validations android.Paths
-
- alignmentStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "alignment.stamp")
- ctx.Build(pctx, android.BuildParams{
- Rule: checkZipAlignment,
- Input: srcApk,
- Output: alignmentStamp,
- })
-
- validations = append(validations, alignmentStamp)
- jniCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "jni_compression.stamp")
- ctx.Build(pctx, android.BuildParams{
- Rule: checkJniLibsAreUncompressedRule,
- Input: srcApk,
- Output: jniCompressionStamp,
- })
- validations = append(validations, jniCompressionStamp)
-
+func (a *AndroidAppImport) validatePresignedApk(ctx android.ModuleContext, srcApk android.Path) android.Path {
+ stamp := android.PathForModuleOut(ctx, "validated-prebuilt", "check.stamp")
+ var extraArgs []string
if a.Privileged() {
- // It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides
- dexCompressionStamp := android.PathForModuleOut(ctx, "validated-prebuilt", "dex_compression.stamp")
- ctx.Build(pctx, android.BuildParams{
- Rule: checkDexLibsAreUncompressedRule,
- Input: srcApk,
- Output: dexCompressionStamp,
- })
- validations = append(validations, dexCompressionStamp)
+ extraArgs = append(extraArgs, "--privileged")
+ }
+ if proptools.Bool(a.properties.Skip_preprocessed_apk_checks) {
+ extraArgs = append(extraArgs, "--skip-preprocessed-apk-checks")
+ }
+ if proptools.Bool(a.properties.Preprocessed) {
+ extraArgs = append(extraArgs, "--preprocessed")
}
ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: srcApk,
- Output: dstApk,
- Validations: validations,
+ Rule: checkPresignedApkRule,
+ Input: srcApk,
+ Output: stamp,
+ Args: map[string]string{
+ "extraArgs": strings.Join(extraArgs, " "),
+ },
})
+ return stamp
}
func (a *AndroidAppImport) Prebuilt() *android.Prebuilt {
diff --git a/java/app_import_test.go b/java/app_import_test.go
index bb8fab9..8f29bb3 100644
--- a/java/app_import_test.go
+++ b/java/app_import_test.go
@@ -629,31 +629,21 @@
presigned: true,
preprocessed: true,
}
-
- android_test_import {
- name: "foo_cert",
- apk: "prebuilts/apk/app.apk",
- certificate: "cert/new_cert",
- preprocessed: true,
- }
`)
- testModules := []string{"foo", "foo_cert"}
- for _, m := range testModules {
- apkName := m + ".apk"
- variant := ctx.ModuleForTests(m, "android_common")
- jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
- if jniRule != android.Cp.String() {
- t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
- }
+ apkName := "foo.apk"
+ variant := ctx.ModuleForTests("foo", "android_common")
+ jniRule := variant.Output("jnis-uncompressed/" + apkName).BuildParams.Rule.String()
+ if jniRule != android.Cp.String() {
+ t.Errorf("Unexpected JNI uncompress rule: " + jniRule)
+ }
- // Make sure signing and aligning were skipped.
- if variant.MaybeOutput("signed/"+apkName).Rule != nil {
- t.Errorf("signing rule shouldn't be included for preprocessed.")
- }
- if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
- t.Errorf("aligning rule shouldn't be for preprocessed")
- }
+ // Make sure signing and aligning were skipped.
+ if variant.MaybeOutput("signed/"+apkName).Rule != nil {
+ t.Errorf("signing rule shouldn't be included for preprocessed.")
+ }
+ if variant.MaybeOutput("zip-aligned/"+apkName).Rule != nil {
+ t.Errorf("aligning rule shouldn't be for preprocessed")
}
}
@@ -669,14 +659,19 @@
apkName := "foo.apk"
variant := ctx.ModuleForTests("foo", "android_common")
- outputBuildParams := variant.Output("validated-prebuilt/" + apkName).BuildParams
+ outputBuildParams := variant.Output(apkName).BuildParams
if outputBuildParams.Rule.String() != android.Cp.String() {
t.Errorf("Unexpected prebuilt android_app_import rule: " + outputBuildParams.Rule.String())
}
// Make sure compression and aligning were validated.
- if len(outputBuildParams.Validations) != 2 {
- t.Errorf("Expected compression/alignment validation rules, found %d validations", len(outputBuildParams.Validations))
+ if outputBuildParams.Validation == nil {
+ t.Errorf("Expected validation rule, but was not found")
+ }
+
+ validationBuildParams := variant.Output("validated-prebuilt/check.stamp").BuildParams
+ if validationBuildParams.Rule.String() != checkPresignedApkRule.String() {
+ t.Errorf("Unexpected validation rule: " + validationBuildParams.Rule.String())
}
}
diff --git a/java/app_test.go b/java/app_test.go
index 8474ea7..fc57f44 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -4137,3 +4137,49 @@
"\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml",
)
}
+
+func TestApexGlobalMinSdkVersionOverride(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.ApexGlobalMinSdkVersionOverride = proptools.StringPtr("Tiramisu")
+ }),
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "com.android.bar",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ }
+ android_app {
+ name: "com.android.foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ min_sdk_version: "S",
+ updatable: true,
+ }
+ override_android_app {
+ name: "com.android.go.foo",
+ base: "com.android.foo",
+ }
+ `)
+ foo := result.ModuleForTests("com.android.foo", "android_common").Rule("manifestFixer")
+ fooOverride := result.ModuleForTests("com.android.foo", "android_common_com.android.go.foo").Rule("manifestFixer")
+ bar := result.ModuleForTests("com.android.bar", "android_common").Rule("manifestFixer")
+
+ android.AssertStringDoesContain(t,
+ "expected manifest fixer to set com.android.bar minSdkVersion to S",
+ bar.BuildParams.Args["args"],
+ "--minSdkVersion S",
+ )
+ android.AssertStringDoesContain(t,
+ "com.android.foo: expected manifest fixer to set minSdkVersion to T",
+ foo.BuildParams.Args["args"],
+ "--minSdkVersion T",
+ )
+ android.AssertStringDoesContain(t,
+ "com.android.go.foo: expected manifest fixer to set minSdkVersion to T",
+ fooOverride.BuildParams.Args["args"],
+ "--minSdkVersion T",
+ )
+
+}
diff --git a/java/base.go b/java/base.go
index 2c0b3ea..a110aff 100644
--- a/java/base.go
+++ b/java/base.go
@@ -1077,8 +1077,8 @@
}
-func (module *Module) addGeneratedSrcJars(path android.Path) {
- module.properties.Generated_srcjars = append(module.properties.Generated_srcjars, path)
+func (j *Module) addGeneratedSrcJars(path android.Path) {
+ j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path)
}
func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars android.Paths) {
@@ -1608,7 +1608,7 @@
false, nil, nil)
if *j.dexProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath
- TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
+ TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil)
dexOutputFile = combinedAlignedJar
} else {
dexOutputFile = combinedJar
@@ -2359,7 +2359,7 @@
var _ ModuleWithStem = (*Module)(nil)
-func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (j *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
switch ctx.ModuleType() {
case "java_library", "java_library_host", "java_library_static", "tradefed_java_library_host":
if lib, ok := ctx.Module().(*Library); ok {
diff --git a/java/builder.go b/java/builder.go
index debf49a..ee7e225 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -259,19 +259,6 @@
},
)
- checkZipAlignment = pctx.AndroidStaticRule("checkzipalign",
- blueprint.RuleParams{
- Command: "if ! ${config.ZipAlign} -c -p 4 $in > /dev/null; then " +
- "echo $in: Improper package alignment >&2; " +
- "exit 1; " +
- "else " +
- "touch $out; " +
- "fi",
- CommandDeps: []string{"${config.ZipAlign}"},
- Description: "Check zip alignment",
- },
- )
-
convertImplementationJarToHeaderJarRule = pctx.AndroidStaticRule("convertImplementationJarToHeaderJar",
blueprint.RuleParams{
Command: `${config.Zip2ZipCmd} -i ${in} -o ${out} -x 'META-INF/services/**/*'`,
@@ -689,12 +676,13 @@
android.WriteFileRule(ctx, outputFile, "Main-Class: "+mainClass+"\n")
}
-func TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePath, inputFile android.Path) {
+func TransformZipAlign(ctx android.ModuleContext, outputFile android.WritablePath, inputFile android.Path, validations android.Paths) {
ctx.Build(pctx, android.BuildParams{
Rule: zipalign,
Description: "align",
Input: inputFile,
Output: outputFile,
+ Validations: validations,
})
}
diff --git a/java/device_host_converter.go b/java/device_host_converter.go
index 5460dc9..c5ba245 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -198,7 +198,7 @@
Exports bazel.LabelListAttribute
}
-func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (d *DeviceHostConverter) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "java_host_for_device",
diff --git a/java/dex.go b/java/dex.go
index 21937e1..c1d51c7 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -315,15 +315,14 @@
if BoolDefault(opt.Proguard_compatibility, true) {
r8Flags = append(r8Flags, "--force-proguard-compatibility")
- } else {
+ }
+
+ if Bool(opt.Optimize) || Bool(opt.Obfuscate) {
// TODO(b/213833843): Allow configuration of the prefix via a build variable.
var sourceFilePrefix = "go/retraceme "
var sourceFileTemplate = "\"" + sourceFilePrefix + "%MAP_ID\""
- // TODO(b/200967150): Also tag the source file in compat builds.
- if Bool(opt.Optimize) || Bool(opt.Obfuscate) {
- r8Flags = append(r8Flags, "--map-id-template", "%MAP_HASH")
- r8Flags = append(r8Flags, "--source-file-template", sourceFileTemplate)
- }
+ r8Flags = append(r8Flags, "--map-id-template", "%MAP_HASH")
+ r8Flags = append(r8Flags, "--source-file-template", sourceFileTemplate)
}
// TODO(ccross): Don't shrink app instrumentation tests by default.
@@ -450,7 +449,7 @@
}
if proptools.Bool(d.dexProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", dexParams.jarName).OutputPath
- TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
+ TransformZipAlign(ctx, alignedJavalibJar, javalibJar, nil)
javalibJar = alignedJavalibJar
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 3ba3065..d5547d0 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -22,6 +22,7 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/java/config"
)
@@ -844,6 +845,7 @@
type ExportedDroiddocDir struct {
android.ModuleBase
+ android.BazelModuleBase
properties ExportedDroiddocDirProperties
@@ -856,6 +858,7 @@
module := &ExportedDroiddocDir{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
+ android.InitBazelModule(module)
return module
}
@@ -867,6 +870,28 @@
d.deps = android.PathsForModuleSrc(ctx, []string{filepath.Join(path, "**/*")})
}
+// ConvertWithBp2build implements android.BazelModule.
+func (d *ExportedDroiddocDir) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ props := bazel.BazelTargetModuleProperties{
+ // Use the native py_library rule.
+ Rule_class: "droiddoc_exported_dir",
+ Bzl_load_location: "//build/bazel/rules/droiddoc:droiddoc_exported_dir.bzl",
+ }
+
+ type BazelAttrs struct {
+ Dir *string
+ Srcs bazel.LabelListAttribute
+ }
+
+ attrs := &BazelAttrs{
+ Dir: proptools.StringPtr(*d.properties.Path),
+ Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{filepath.Join(*d.properties.Path, "**/*")})),
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: d.Name()}, attrs)
+
+}
+
// Defaults
type DocDefaults struct {
android.ModuleBase
diff --git a/java/droidstubs.go b/java/droidstubs.go
index f05ef1f..1d5dd76 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -539,7 +539,7 @@
// 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")
+ cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source")
return cmd
}
diff --git a/java/hiddenapi.go b/java/hiddenapi.go
index 4d08b83..fe3fe7b 100644
--- a/java/hiddenapi.go
+++ b/java/hiddenapi.go
@@ -305,7 +305,7 @@
})
if uncompressDex {
- TransformZipAlign(ctx, output, encodeRuleOutput)
+ TransformZipAlign(ctx, output, encodeRuleOutput, nil)
}
return output
diff --git a/java/java.go b/java/java.go
index 521aef3..d5aeb7c 100644
--- a/java/java.go
+++ b/java/java.go
@@ -64,6 +64,7 @@
ctx.RegisterModuleType("dex_import", DexImportFactory)
ctx.RegisterModuleType("java_api_library", ApiLibraryFactory)
ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory)
+ ctx.RegisterModuleType("java_api_contribution_import", ApiContributionImportFactory)
// This mutator registers dependencies on dex2oat for modules that should be
// dexpreopted. This is done late when the final variants have been
@@ -1623,7 +1624,8 @@
}
type JavaApiImportInfo struct {
- ApiFile android.Path
+ ApiFile android.Path
+ ApiSurface string
}
var JavaApiImportProvider = blueprint.NewProvider(JavaApiImportInfo{})
@@ -1635,7 +1637,8 @@
}
ctx.SetProvider(JavaApiImportProvider, JavaApiImportInfo{
- ApiFile: apiFile,
+ ApiFile: apiFile,
+ ApiSurface: proptools.String(ap.properties.Api_surface),
})
}
@@ -1798,6 +1801,7 @@
Flag("-jar").
Flag("-write_if_changed").
Flag("-ignore_missing_files").
+ Flag("-quiet").
FlagWithArg("-C ", unzippedSrcJarDir.String()).
FlagWithInput("-l ", classFilesList).
FlagWithOutput("-o ", al.stubsJarWithoutStaticLibs)
@@ -1820,18 +1824,29 @@
var scopeOrderedSourceFileNames = allApiScopes.Strings(
func(s *apiScope) string { return s.apiFilePrefix + "current.txt" })
-func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFiles android.Paths) android.Paths {
- sortedSrcFiles := android.Paths{}
+func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths {
+ var sortedSrcFiles android.Paths
- for _, scopeSourceFileName := range scopeOrderedSourceFileNames {
- for _, sourceFileName := range srcFiles {
- if sourceFileName.Base() == scopeSourceFileName {
- sortedSrcFiles = append(sortedSrcFiles, sourceFileName)
+ for i, apiScope := range allApiScopes {
+ for _, srcFileInfo := range srcFilesInfo {
+ if srcFileInfo.ApiFile.Base() == scopeOrderedSourceFileNames[i] || srcFileInfo.ApiSurface == apiScope.name {
+ sortedSrcFiles = append(sortedSrcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
+ }
+ }
+ // TODO: b/300964421 - Remove when api_files property is removed
+ for _, apiFileName := range apiFiles {
+ if apiFileName.Base() == scopeOrderedSourceFileNames[i] {
+ sortedSrcFiles = append(sortedSrcFiles, apiFileName)
}
}
}
- if len(srcFiles) != len(sortedSrcFiles) {
- ctx.ModuleErrorf("Unrecognizable source file found within %s", srcFiles)
+
+ if len(srcFilesInfo)+len(apiFiles) != len(sortedSrcFiles) {
+ var srcFiles android.Paths
+ for _, srcFileInfo := range srcFilesInfo {
+ srcFiles = append(srcFiles, srcFileInfo.ApiFile)
+ }
+ ctx.ModuleErrorf("Unrecognizable source file found within %s", append(srcFiles, apiFiles...))
}
return sortedSrcFiles
@@ -1852,7 +1867,7 @@
homeDir := android.PathForModuleOut(ctx, "metalava", "home")
- var srcFiles android.Paths
+ var srcFilesInfo []JavaApiImportInfo
var classPaths android.Paths
var staticLibs android.Paths
var depApiSrcsStubsJar android.Path
@@ -1861,11 +1876,10 @@
switch tag {
case javaApiContributionTag:
provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo)
- providerApiFile := provider.ApiFile
- if providerApiFile == nil && !ctx.Config().AllowMissingDependencies() {
+ if provider.ApiFile == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name())
}
- srcFiles = append(srcFiles, android.PathForSource(ctx, providerApiFile.String()))
+ srcFilesInfo = append(srcFilesInfo, provider)
case libTag:
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
classPaths = append(classPaths, provider.HeaderJars...)
@@ -1879,16 +1893,19 @@
})
// Add the api_files inputs
+ // These are api files in the module subdirectory, which are not provided by
+ // java_api_contribution but provided directly as module property.
+ var apiFiles android.Paths
for _, api := range al.properties.Api_files {
- srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, api))
+ apiFiles = append(apiFiles, android.PathForModuleSrc(ctx, api))
}
+ srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo, apiFiles)
+
if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
- srcFiles = al.sortApiFilesByApiScope(ctx, srcFiles)
-
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
al.stubsFlags(ctx, cmd, stubsDir)
@@ -2758,7 +2775,7 @@
Additional_resources bazel.LabelListAttribute
}
-func (m *Library) getResourceFilegroupStripPrefix(ctx android.TopDownMutatorContext, resourceFilegroup string) (*string, bool) {
+func (m *Library) getResourceFilegroupStripPrefix(ctx android.Bp2buildMutatorContext, resourceFilegroup string) (*string, bool) {
if otherM, ok := ctx.ModuleFromName(resourceFilegroup); ok {
if fg, isFilegroup := otherM.(android.FileGroupPath); isFilegroup {
return proptools.StringPtr(filepath.Join(ctx.OtherModuleDir(otherM), fg.GetPath(ctx))), true
@@ -2767,7 +2784,7 @@
return proptools.StringPtr(""), false
}
-func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes {
+func (m *Library) convertJavaResourcesAttributes(ctx android.Bp2buildMutatorContext) *javaResourcesAttributes {
var resources bazel.LabelList
var resourceStripPrefix *string
@@ -2826,7 +2843,7 @@
if resourceStripPrefix == nil && i == 0 {
resourceStripPrefix = resAttr.Resource_strip_prefix
resources = resAttr.Resources.Value
- } else {
+ } else if !resAttr.Resources.IsEmpty() {
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{
Rule_class: "java_resources",
@@ -2898,14 +2915,19 @@
// which has other non-attribute information needed for bp2build conversion
// that needs different handling depending on the module types, and thus needs
// to be returned to the calling function.
-func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) {
+func (m *Library) convertLibraryAttrsBp2Build(ctx android.Bp2buildMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo, bool) {
var srcs bazel.LabelListAttribute
var deps bazel.LabelListAttribute
var staticDeps bazel.LabelListAttribute
if proptools.String(m.deviceProperties.Sdk_version) == "" && m.DeviceSupported() {
+ // TODO(b/297356704): handle platform apis in bp2build
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version unset")
return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false
+ } else if proptools.String(m.deviceProperties.Sdk_version) == "core_platform" {
+ // TODO(b/297356582): handle core_platform in bp2build
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "sdk_version core_platform")
+ return &javaCommonAttributes{}, &bp2BuildJavaInfo{}, false
}
archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{})
@@ -3114,7 +3136,7 @@
}
}
-func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) {
+func javaLibraryBp2Build(ctx android.Bp2buildMutatorContext, m *Library) {
commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
if !supported {
return
@@ -3122,16 +3144,22 @@
depLabels := bp2BuildInfo.DepLabels
deps := depLabels.Deps
+ exports := depLabels.StaticDeps
if !commonAttrs.Srcs.IsEmpty() {
- deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
+ deps.Append(exports) // we should only append these if there are sources to use them
} else if !deps.IsEmpty() {
- ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.")
+ // java_library does not accept deps when there are no srcs because
+ // there is no compilation happening, but it accepts exports.
+ // The non-empty deps here are unnecessary as deps on the java_library
+ // since they aren't being propagated to any dependencies.
+ // So we can drop deps here.
+ deps = bazel.LabelListAttribute{}
}
var props bazel.BazelTargetModuleProperties
attrs := &javaLibraryAttributes{
javaCommonAttributes: commonAttrs,
Deps: deps,
- Exports: depLabels.StaticDeps,
+ Exports: exports,
}
name := m.Name()
@@ -3164,7 +3192,7 @@
}
// JavaBinaryHostBp2Build is for java_binary_host bp2build.
-func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) {
+func javaBinaryHostBp2Build(ctx android.Bp2buildMutatorContext, m *Binary) {
commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
if !supported {
return
@@ -3251,7 +3279,7 @@
}
// javaTestHostBp2Build is for java_test_host bp2build.
-func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) {
+func javaTestHostBp2Build(ctx android.Bp2buildMutatorContext, m *TestHost) {
commonAttrs, bp2BuildInfo, supported := m.convertLibraryAttrsBp2Build(ctx)
if !supported {
return
@@ -3304,7 +3332,7 @@
// helper function that creates java_library target from java_binary_host or java_test_host,
// and returns the library target name,
-func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string {
+func createLibraryTarget(ctx android.Bp2buildMutatorContext, libInfo libraryCreationInfo) string {
libName := libInfo.baseName + "_lib"
var libProps bazel.BazelTargetModuleProperties
if libInfo.hasKotlin {
@@ -3327,7 +3355,7 @@
}
// java_import bp2Build converter.
-func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (i *Import) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
var jars bazel.LabelListAttribute
archVariantProps := i.GetArchVariantProperties(ctx, &ImportProperties{})
for axis, configToProps := range archVariantProps {
@@ -3363,7 +3391,6 @@
javaLibraryBazelTargetModuleProperties(),
android.CommonAttributes{Name: name + "-neverlink"},
neverlinkAttrs)
-
}
var _ android.MixedBuildBuildable = (*Import)(nil)
@@ -3416,3 +3443,30 @@
func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool {
return true
}
+
+type JavaApiContributionImport struct {
+ JavaApiContribution
+
+ prebuilt android.Prebuilt
+}
+
+func ApiContributionImportFactory() android.Module {
+ module := &JavaApiContributionImport{}
+ android.InitAndroidModule(module)
+ android.InitDefaultableModule(module)
+ android.InitPrebuiltModule(module, &[]string{""})
+ module.AddProperties(&module.properties)
+ return module
+}
+
+func (module *JavaApiContributionImport) Prebuilt() *android.Prebuilt {
+ return &module.prebuilt
+}
+
+func (module *JavaApiContributionImport) Name() string {
+ return module.prebuilt.Name(module.ModuleBase.Name())
+}
+
+func (ap *JavaApiContributionImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ ap.JavaApiContribution.GenerateAndroidBuildActions(ctx)
+}
diff --git a/java/java_test.go b/java/java_test.go
index 27933c3..2ee05ec 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1865,11 +1865,13 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
ctx, _ := testJavaWithFS(t, `
@@ -1919,24 +1921,28 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_c := `
java_api_contribution {
name: "foo3",
- api_file: "current.txt",
+ api_file: "system-current.txt",
+ api_surface: "system",
}
`
provider_bp_d := `
java_api_contribution {
name: "foo4",
- api_file: "current.txt",
+ api_file: "system-current.txt",
+ api_surface: "system",
}
`
ctx, _ := testJavaWithFS(t, `
@@ -1992,8 +1998,9 @@
sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
},
{
- moduleName: "bar3",
- sourceTextFileDirs: []string{"c/current.txt", "a/current.txt", "b/current.txt", "d/current.txt", "api1/current.txt", "api2/current.txt"},
+ moduleName: "bar3",
+ // API text files need to be sorted from the narrower api scope to the wider api scope
+ sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "api1/current.txt", "api2/current.txt", "c/system-current.txt", "d/system-current.txt"},
},
}
for _, c := range testcases {
@@ -2011,12 +2018,14 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
ctx, _ := testJavaWithFS(t, `
@@ -2064,12 +2073,14 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
lib_bp_a := `
@@ -2139,12 +2150,14 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
lib_bp_a := `
@@ -2213,12 +2226,14 @@
java_api_contribution {
name: "foo1",
api_file: "current.txt",
+ api_surface: "public",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "current.txt",
+ api_surface: "public",
}
`
lib_bp_a := `
@@ -2388,3 +2403,23 @@
javac := ctx.ModuleForTests("foo", "android_common").MaybeRule("javac")
android.AssertDeepEquals(t, "javac rule", nil, javac.Rule)
}
+
+func TestJavaApiContributionImport(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_api_library {
+ name: "foo",
+ api_contributions: ["bar"],
+ }
+ java_api_contribution_import {
+ name: "bar",
+ api_file: "current.txt",
+ api_surface: "public",
+ }
+ `)
+ m := ctx.ModuleForTests("foo", "android_common")
+ manifest := m.Output("metalava.sbox.textproto")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
+ manifestCommand := sboxProto.Commands[0].GetCommand()
+ sourceFilesFlag := "--source-files current.txt"
+ android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
+}
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index 1248275..662a2d7 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -130,7 +130,7 @@
Src bazel.LabelAttribute
}
-func (p *platformCompatConfig) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (p *platformCompatConfig) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
props := bazel.BazelTargetModuleProperties{
Rule_class: "platform_compat_config",
Bzl_load_location: "//build/bazel/rules/java:platform_compat_config.bzl",
diff --git a/java/plugin.go b/java/plugin.go
index 5127298..4d4c199 100644
--- a/java/plugin.go
+++ b/java/plugin.go
@@ -64,7 +64,7 @@
}
// ConvertWithBp2build is used to convert android_app to Bazel.
-func (p *Plugin) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (p *Plugin) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
pluginName := p.Name()
commonAttrs, bp2BuildInfo, supported := p.convertLibraryAttrsBp2Build(ctx)
if !supported {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index b1ddde0..27f8626 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1633,7 +1633,7 @@
}{}
props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope))
- props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
+ props.Visibility = []string{"//visibility:override", "//visibility:private"}
// sources are generated from the droiddoc
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
@@ -1829,7 +1829,7 @@
}{}
props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
- props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
+ props.Visibility = []string{"//visibility:override", "//visibility:private"}
apiContributions := []string{}
@@ -2276,27 +2276,25 @@
}
type bazelSdkLibraryAttributes struct {
- Public bazel.StringAttribute
- System bazel.StringAttribute
- Test bazel.StringAttribute
- Module_lib bazel.StringAttribute
- System_server bazel.StringAttribute
+ Public *bazel.Label
+ System *bazel.Label
+ Test *bazel.Label
+ Module_lib *bazel.Label
+ System_server *bazel.Label
}
// java_sdk_library bp2build converter
-func (module *SdkLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (module *SdkLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if ctx.ModuleType() != "java_sdk_library" {
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
return
}
- nameToAttr := make(map[string]bazel.StringAttribute)
+ nameToAttr := make(map[string]*bazel.Label)
for _, scope := range module.getGeneratedApiScopes(ctx) {
- apiSurfaceFile := path.Join(module.getApiDir(), scope.apiFilePrefix+"current.txt")
- var scopeStringAttribute bazel.StringAttribute
- scopeStringAttribute.SetValue(apiSurfaceFile)
- nameToAttr[scope.name] = scopeStringAttribute
+ apiSurfaceFile := android.BazelLabelForModuleSrcSingle(ctx, path.Join(module.getApiDir(), scope.apiFilePrefix+"current.txt"))
+ nameToAttr[scope.name] = &apiSurfaceFile
}
attrs := bazelSdkLibraryAttributes{
@@ -2355,6 +2353,7 @@
type SdkLibraryImport struct {
android.ModuleBase
android.DefaultableModuleBase
+ android.BazelModuleBase
prebuilt android.Prebuilt
android.ApexModuleBase
@@ -2438,6 +2437,7 @@
android.InitPrebuiltModule(module, &[]string{""})
android.InitApexModule(module)
+ android.InitBazelModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
module.SetDefaultableHook(func(mctx android.DefaultableHookContext) {
@@ -2448,6 +2448,33 @@
return module
}
+// java_sdk_library bp2build converter
+func (i *SdkLibraryImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ nameToAttr := make(map[string]*bazel.Label)
+
+ for scope, props := range i.scopeProperties {
+ if api := proptools.String(props.Current_api); api != "" {
+ apiSurfaceFile := android.BazelLabelForModuleSrcSingle(ctx, api)
+ nameToAttr[scope.name] = &apiSurfaceFile
+ }
+ }
+
+ attrs := bazelSdkLibraryAttributes{
+ Public: nameToAttr["public"],
+ System: nameToAttr["system"],
+ Test: nameToAttr["test"],
+ Module_lib: nameToAttr["module-lib"],
+ System_server: nameToAttr["system-server"],
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_sdk_library",
+ Bzl_load_location: "//build/bazel/rules/java:sdk_library.bzl",
+ }
+
+ name := android.RemoveOptionalPrebuiltPrefix(i.Name())
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, &attrs)
+}
+
var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil)
func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string {
@@ -2479,6 +2506,10 @@
if len(scopeProperties.Stub_srcs) > 0 {
module.createPrebuiltStubsSources(mctx, apiScope, scopeProperties)
}
+
+ if scopeProperties.Current_api != nil {
+ module.createPrebuiltApiContribution(mctx, apiScope, scopeProperties)
+ }
}
javaSdkLibraries := javaSdkLibraries(mctx.Config())
@@ -2534,6 +2565,25 @@
mctx.CreateModule(PrebuiltStubsSourcesFactory, &props)
}
+func (module *SdkLibraryImport) createPrebuiltApiContribution(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {
+ api_file := scopeProperties.Current_api
+ api_surface := &apiScope.name
+
+ props := struct {
+ Name *string
+ Api_surface *string
+ Api_file *string
+ Visibility []string
+ }{}
+
+ props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope) + ".api.contribution")
+ props.Api_surface = api_surface
+ props.Api_file = api_file
+ props.Visibility = []string{"//visibility:override", "//visibility:public"}
+
+ mctx.CreateModule(ApiContributionImportFactory, &props)
+}
+
// Add the dependencies on the child module in the component deps mutator so that it
// creates references to the prebuilt and not the source modules.
func (module *SdkLibraryImport) ComponentDepsMutator(ctx android.BottomUpMutatorContext) {
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 118f8b6..0b46919 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -74,6 +74,8 @@
name: "quuz",
public: {
jars: ["c.jar"],
+ current_api: "api/current.txt",
+ removed_api: "api/removed.txt",
},
}
java_sdk_library_import {
@@ -173,6 +175,9 @@
android.AssertDeepEquals(t, "qux exports (optional)", []string{}, optionalSdkLibs)
}
+ // test if quuz have created the api_contribution module
+ result.ModuleForTests(apiScopePublic.stubsSourceModuleName("quuz")+".api.contribution", "")
+
fooDexJar := result.ModuleForTests("foo", "android_common").Rule("d8")
// tests if kotlinc generated files are NOT excluded from output of foo.
android.AssertStringDoesNotContain(t, "foo dex", fooDexJar.BuildParams.Args["mergeZipsFlags"], "-stripFile META-INF/*.kotlin_module")
@@ -1474,3 +1479,32 @@
android.AssertStringEquals(t, "Module expected to contain full api surface api library", c.fullApiSurfaceStub, *m.properties.Full_api_surface_stub)
}
}
+
+func TestStaticDepStubLibrariesVisibility(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo"),
+ android.FixtureMergeMockFs(
+ map[string][]byte{
+ "A.java": nil,
+ "dir/Android.bp": []byte(
+ `
+ java_library {
+ name: "bar",
+ srcs: ["A.java"],
+ libs: ["foo.stubs.from-source"],
+ }
+ `),
+ "dir/A.java": nil,
+ },
+ ).ExtendWithErrorHandler(
+ android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `module "bar" variant "android_common": depends on //.:foo.stubs.from-source which is not visible to this module`)),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["A.java"],
+ }
+ `)
+}
diff --git a/linkerconfig/linkerconfig.go b/linkerconfig/linkerconfig.go
index 165697d..dad5892 100644
--- a/linkerconfig/linkerconfig.go
+++ b/linkerconfig/linkerconfig.go
@@ -107,7 +107,7 @@
Src bazel.LabelAttribute
}
-func (l *linkerConfig) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (l *linkerConfig) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if l.properties.Src == nil {
ctx.PropertyErrorf("src", "empty src is not supported")
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "")
diff --git a/python/bp2build.go b/python/bp2build.go
index 8bc3d0a..3b283e4 100644
--- a/python/bp2build.go
+++ b/python/bp2build.go
@@ -54,7 +54,7 @@
Imports bazel.StringListAttribute
}
-func (m *PythonLibraryModule) makeArchVariantBaseAttributes(ctx android.TopDownMutatorContext) baseAttributes {
+func (m *PythonLibraryModule) makeArchVariantBaseAttributes(ctx android.Bp2buildMutatorContext) baseAttributes {
var attrs baseAttributes
archVariantBaseProps := m.GetArchVariantProperties(ctx, &BaseProperties{})
for axis, configToProps := range archVariantBaseProps {
@@ -123,7 +123,7 @@
return attrs
}
-func (m *PythonLibraryModule) bp2buildPythonVersion(ctx android.TopDownMutatorContext) *string {
+func (m *PythonLibraryModule) bp2buildPythonVersion(ctx android.Bp2buildMutatorContext) *string {
py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true)
py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false)
if py2Enabled && !py3Enabled {
@@ -146,7 +146,7 @@
Imports bazel.StringListAttribute
}
-func (p *PythonLibraryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (p *PythonLibraryModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
// TODO(b/182306917): this doesn't fully handle all nested props versioned
// by the python version, which would have been handled by the version split
// mutator. This is sufficient for very simple python_library modules under
@@ -176,7 +176,7 @@
}, attrs)
}
-func (p *PythonBinaryModule) bp2buildBinaryProperties(ctx android.TopDownMutatorContext) (*bazelPythonBinaryAttributes, bazel.LabelListAttribute) {
+func (p *PythonBinaryModule) bp2buildBinaryProperties(ctx android.Bp2buildMutatorContext) (*bazelPythonBinaryAttributes, bazel.LabelListAttribute) {
// TODO(b/182306917): this doesn't fully handle all nested props versioned
// by the python version, which would have been handled by the version split
// mutator. This is sufficient for very simple python_binary_host modules
@@ -209,7 +209,7 @@
return attrs, baseAttrs.Data
}
-func (p *PythonBinaryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (p *PythonBinaryModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
attrs, data := p.bp2buildBinaryProperties(ctx)
props := bazel.BazelTargetModuleProperties{
@@ -223,7 +223,7 @@
}, attrs)
}
-func (p *PythonTestModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (p *PythonTestModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
// Python tests are currently exactly the same as binaries, but with a different module type
attrs, data := p.bp2buildBinaryProperties(ctx)
diff --git a/rust/afdo_test.go b/rust/afdo_test.go
index 0cdf704..80327af 100644
--- a/rust/afdo_test.go
+++ b/rust/afdo_test.go
@@ -54,8 +54,8 @@
expectedCFlag := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo.afdo")
- if !strings.Contains(foo.Args["rustcFlags"], expectedCFlag) {
- t.Errorf("Expected 'foo' to enable afdo, but did not find %q in cflags %q", expectedCFlag, foo.Args["rustcFlags"])
+ if !strings.Contains(foo.RuleParams.Command, expectedCFlag) {
+ t.Errorf("Expected 'foo' to enable afdo, but did not find %q in command %q", expectedCFlag, foo.RuleParams.Command)
}
}
@@ -96,17 +96,17 @@
rustMockedFiles.AddToFixture(),
).RunTestWithBp(t, bp)
- fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Rule("rustc")
- fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+ fooArm := result.ModuleForTests("foo", "android_arm_armv7-a-neon").Description("rustc")
+ fooArm64 := result.ModuleForTests("foo", "android_arm64_armv8-a").Description("rustc")
expectedCFlagArm := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm.afdo")
expectedCFlagArm64 := fmt.Sprintf(afdoFlagFormat, "afdo_profiles_package/foo_arm64.afdo")
- if !strings.Contains(fooArm.Args["rustcFlags"], expectedCFlagArm) {
- t.Errorf("Expected 'fooArm' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm, fooArm.Args["rustcFlags"])
+ if !strings.Contains(fooArm.RuleParams.Command, expectedCFlagArm) {
+ t.Errorf("Expected 'fooArm' to enable afdo, but did not find %q in command %q", expectedCFlagArm, fooArm.RuleParams.Command)
}
- if !strings.Contains(fooArm64.Args["rustcFlags"], expectedCFlagArm64) {
- t.Errorf("Expected 'fooArm64' to enable afdo, but did not find %q in cflags %q", expectedCFlagArm64, fooArm64.Args["rustcFlags"])
+ if !strings.Contains(fooArm64.RuleParams.Command, expectedCFlagArm64) {
+ t.Errorf("Expected 'fooArm64' to enable afdo, but did not find %q in command %q", expectedCFlagArm64, fooArm.RuleParams.Command)
}
}
diff --git a/rust/binary.go b/rust/binary.go
index 1e24beb..353381d 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -15,9 +15,10 @@
package rust
import (
+ "fmt"
+
"android/soong/android"
"android/soong/bazel"
- "fmt"
)
func init() {
@@ -137,13 +138,17 @@
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
- srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
outputFile := android.PathForModuleOut(ctx, fileName)
ret := buildOutput{outputFile: outputFile}
+ var crateRootPath android.Path
+ if binary.baseCompiler.Properties.Crate_root == nil {
+ crateRootPath, _ = srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+ } else {
+ crateRootPath = android.PathForModuleSrc(ctx, *binary.baseCompiler.Properties.Crate_root)
+ }
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
if binary.stripper.NeedsStrip(ctx) {
strippedOutputFile := outputFile
@@ -154,7 +159,7 @@
}
binary.baseCompiler.unstrippedOutputFile = outputFile
- ret.kytheFile = TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrcToBinary(ctx, binary, crateRootPath, deps, flags, outputFile).kytheFile
return ret
}
@@ -199,7 +204,7 @@
Rustc_flags bazel.StringListAttribute
}
-func binaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func binaryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
binary := m.compiler.(*binaryDecorator)
var srcs bazel.LabelList
diff --git a/rust/binary_test.go b/rust/binary_test.go
index dff94ac..ab1d2bc 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -135,7 +135,7 @@
fizzBuzz := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
- flags := fizzBuzz.Args["rustcFlags"]
+ flags := fizzBuzz.RuleParams.Command
if strings.Contains(flags, "--test") {
t.Errorf("extra --test flag, rustcFlags: %#v", flags)
}
@@ -150,11 +150,11 @@
bootstrap: true,
}`)
- foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink")
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
- if !strings.Contains(foo.Args["linkFlags"], flag) {
- t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"])
+ if !strings.Contains(foo.RuleParams.Command, flag) {
+ t.Errorf("missing link flag to use bootstrap linker, expecting %#v, command: %#v", flag, foo.RuleParams.Command)
}
}
@@ -167,19 +167,17 @@
}`)
fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
- fizzOutLink := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustLink")
fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
- flags := fizzOut.Args["rustcFlags"]
- linkFlags := fizzOutLink.Args["linkFlags"]
+ flags := fizzOut.RuleParams.Command
if !strings.Contains(flags, "-C relocation-model=static") {
- t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
+ t.Errorf("static binary missing '-C relocation-model=static' in command, found: %#v", flags)
}
if !strings.Contains(flags, "-C panic=abort") {
- t.Errorf("static binary missing '-C panic=abort' in rustcFlags, found: %#v", flags)
+ t.Errorf("static binary missing '-C panic=abort' in command, found: %#v", flags)
}
- if !strings.Contains(linkFlags, "-static") {
- t.Errorf("static binary missing '-static' in linkFlags, found: %#v", flags)
+ if !strings.Contains(flags, "-static") {
+ t.Errorf("static binary missing '-static' in command, found: %#v", flags)
}
if !android.InList("libc", fizzMod.Properties.AndroidMkStaticLibs) {
@@ -201,10 +199,9 @@
name: "libfoo",
}`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink")
- linkFlags := fizzBuzz.Args["linkFlags"]
- if !strings.Contains(linkFlags, "/libfoo.so") {
- t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
+ fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc")
+ if !strings.Contains(fizzBuzz.RuleParams.Command, "/libfoo.so") {
+ t.Errorf("missing shared dependency 'libfoo.so' in command: %#v", fizzBuzz.RuleParams.Command)
}
}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 407f275..a80a587 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -29,7 +29,7 @@
defaultBindgenFlags = []string{""}
// bindgen should specify its own Clang revision so updating Clang isn't potentially blocked on bindgen failures.
- bindgenClangVersion = "clang-r498229"
+ bindgenClangVersion = "clang-r498229b"
_ = pctx.VariableFunc("bindgenClangVersion", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("LLVM_BINDGEN_PREBUILTS_VERSION"); override != "" {
diff --git a/rust/builder.go b/rust/builder.go
index b1f049d..0740518 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -15,6 +15,7 @@
package rust
import (
+ "fmt"
"path/filepath"
"strings"
@@ -25,54 +26,6 @@
)
var (
- _ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
- _ = pctx.SourcePathVariable("mkcraterspCmd", "build/soong/scripts/mkcratersp.py")
- rustc = pctx.AndroidStaticRule("rustc",
- blueprint.RuleParams{
- Command: "$envVars $rustcCmd " +
- "-C linker=$mkcraterspCmd " +
- "--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
- " && grep \"^$out:\" $out.d.raw > $out.d",
- CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"},
- // Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
- // Rustc emits unneeded dependency lines for the .d and input .rs files.
- // Those extra lines cause ninja warning:
- // "warning: depfile has multiple output paths"
- // For ninja, we keep/grep only the dependency rule for the rust $out file.
- Deps: blueprint.DepsGCC,
- Depfile: "$out.d",
- },
- "rustcFlags", "libFlags", "envVars")
- rustLink = pctx.AndroidStaticRule("rustLink",
- blueprint.RuleParams{
- Command: "${config.RustLinker} -o $out ${crtBegin} ${earlyLinkFlags} @$in ${linkFlags} ${crtEnd}",
- },
- "earlyLinkFlags", "linkFlags", "crtBegin", "crtEnd")
-
- _ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
- rustdoc = pctx.AndroidStaticRule("rustdoc",
- blueprint.RuleParams{
- Command: "$envVars $rustdocCmd $rustdocFlags $in -o $outDir && " +
- "touch $out",
- CommandDeps: []string{"$rustdocCmd"},
- },
- "rustdocFlags", "outDir", "envVars")
-
- _ = pctx.SourcePathVariable("clippyCmd", "${config.RustBin}/clippy-driver")
- clippyDriver = pctx.AndroidStaticRule("clippy",
- blueprint.RuleParams{
- Command: "$envVars $clippyCmd " +
- // Because clippy-driver uses rustc as backend, we need to have some output even during the linting.
- // Use the metadata output as it has the smallest footprint.
- "--emit metadata -o $out --emit dep-info=$out.d.raw $in ${libFlags} " +
- "$rustcFlags $clippyFlags" +
- " && grep \"^$out:\" $out.d.raw > $out.d",
- CommandDeps: []string{"$clippyCmd"},
- Deps: blueprint.DepsGCC,
- Depfile: "$out.d",
- },
- "rustcFlags", "libFlags", "clippyFlags", "envVars")
-
zip = pctx.AndroidStaticRule("zip",
blueprint.RuleParams{
Command: "cat $out.rsp | tr ' ' '\\n' | tr -d \\' | sort -u > ${out}.tmp && ${SoongZipCmd} -o ${out} -C $$OUT_DIR -l ${out}.tmp",
@@ -81,7 +34,7 @@
RspfileContent: "$in",
})
- cp = pctx.AndroidStaticRule("cp",
+ cpDir = pctx.AndroidStaticRule("cpDir",
blueprint.RuleParams{
Command: "cp `cat $outDir.rsp` $outDir",
Rspfile: "${outDir}.rsp",
@@ -89,6 +42,12 @@
},
"outDir")
+ cp = pctx.AndroidStaticRule("cp",
+ blueprint.RuleParams{
+ Command: "rm -f $out && cp $in $out",
+ Description: "cp $out",
+ })
+
// Cross-referencing:
_ = pctx.SourcePathVariable("rustExtractor",
"prebuilts/build-tools/${config.HostPrebuiltTag}/bin/rust_extractor")
@@ -96,23 +55,6 @@
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() })
_ = pctx.VariableFunc("kytheCuEncoding",
func(ctx android.PackageVarContext) string { return ctx.Config().XrefCuEncoding() })
- _ = pctx.SourcePathVariable("kytheVnames", "build/soong/vnames.json")
- kytheExtract = pctx.AndroidStaticRule("kythe",
- blueprint.RuleParams{
- Command: `KYTHE_CORPUS=${kytheCorpus} ` +
- `KYTHE_OUTPUT_FILE=$out ` +
- `KYTHE_VNAMES=$kytheVnames ` +
- `KYTHE_KZIP_ENCODING=${kytheCuEncoding} ` +
- `KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
- `$rustExtractor $envVars ` +
- `$rustcCmd ` +
- `-C linker=true ` +
- `$in ${libFlags} $rustcFlags`,
- CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
- Rspfile: "${out}.rsp",
- RspfileContent: "$in",
- },
- "rustcFlags", "libFlags", "envVars")
)
type buildOutput struct {
@@ -124,40 +66,40 @@
pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
}
-func TransformSrcToBinary(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
+func TransformSrcToBinary(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "bin")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "bin")
}
-func TransformSrctoRlib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
+func TransformSrctoRlib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "rlib")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "rlib")
}
-func TransformSrctoDylib(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
+func TransformSrctoDylib(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "dylib")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "dylib")
}
-func TransformSrctoStatic(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
+func TransformSrctoStatic(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "staticlib")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "staticlib")
}
-func TransformSrctoShared(ctx ModuleContext, mainSrc android.Path, deps PathDeps, flags Flags,
+func TransformSrctoShared(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath) buildOutput {
flags.GlobalRustFlags = append(flags.GlobalRustFlags, "-C lto=thin")
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "cdylib")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "cdylib")
}
-func TransformSrctoProcMacro(ctx ModuleContext, mainSrc android.Path, deps PathDeps,
+func TransformSrctoProcMacro(ctx ModuleContext, c compiler, mainSrc android.Path, deps PathDeps,
flags Flags, outputFile android.WritablePath) buildOutput {
- return transformSrctoCrate(ctx, mainSrc, deps, flags, outputFile, "proc-macro")
+ return transformSrctoCrate(ctx, c, mainSrc, deps, flags, outputFile, "proc-macro")
}
func rustLibsToPaths(libs RustLibraries) android.Paths {
@@ -168,28 +110,46 @@
return paths
}
-func makeLibFlags(deps PathDeps) []string {
+func makeLibFlags(deps PathDeps, ruleCmd *android.RuleBuilderCommand) []string {
var libFlags []string
// Collect library/crate flags
- for _, lib := range deps.RLibs {
- libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
+ for _, lib := range deps.Rlibs.ToListDirect() {
+ libPath := ruleCmd.PathForInput(lib.Path)
+ libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
}
- for _, lib := range deps.DyLibs {
- libFlags = append(libFlags, "--extern "+lib.CrateName+"="+lib.Path.String())
+ for _, lib := range deps.Dylibs.ToListDirect() {
+ libPath := ruleCmd.PathForInput(lib.Path)
+ libFlags = append(libFlags, "--extern "+lib.CrateName+"="+libPath)
}
- for _, proc_macro := range deps.ProcMacros {
- libFlags = append(libFlags, "--extern "+proc_macro.CrateName+"="+proc_macro.Path.String())
+ for _, procMacro := range deps.ProcMacros.ToListDirect() {
+ procMacroPath := ruleCmd.PathForInput(procMacro.Path)
+ libFlags = append(libFlags, "--extern "+procMacro.CrateName+"="+procMacroPath)
}
for _, path := range deps.linkDirs {
- libFlags = append(libFlags, "-L "+path)
+ libFlags = append(libFlags, "-L "+ruleCmd.PathForInput(path))
}
return libFlags
}
-func rustEnvVars(ctx ModuleContext, deps PathDeps) []string {
+func collectImplicits(deps PathDeps) android.Paths {
+ depPaths := android.Paths{}
+ depPaths = append(depPaths, rustLibsToPaths(deps.Rlibs.ToList())...)
+ depPaths = append(depPaths, rustLibsToPaths(deps.Dylibs.ToList())...)
+ depPaths = append(depPaths, rustLibsToPaths(deps.ProcMacros.ToList())...)
+ depPaths = append(depPaths, deps.AfdoProfiles...)
+ depPaths = append(depPaths, deps.WholeStaticLibs...)
+ depPaths = append(depPaths, deps.SrcDeps...)
+ depPaths = append(depPaths, deps.srcProviderFiles...)
+ depPaths = append(depPaths, deps.LibDeps...)
+ depPaths = append(depPaths, deps.linkObjects...)
+ depPaths = append(depPaths, deps.BuildToolSrcDeps...)
+ return depPaths
+}
+
+func rustEnvVars(ctx ModuleContext, deps PathDeps, cmd *android.RuleBuilderCommand) []string {
var envVars []string
// libstd requires a specific environment variable to be set. This is
@@ -203,15 +163,17 @@
moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
// We must calculate an absolute path for OUT_DIR since Rust's include! macro (which normally consumes this)
// assumes that paths are relative to the source file.
- var outDirPrefix string
- if !filepath.IsAbs(moduleGenDir.String()) {
- // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
- outDirPrefix = "$$PWD/"
- } else {
+ var outDir string
+ if filepath.IsAbs(moduleGenDir.String()) {
// If OUT_DIR is absolute, then moduleGenDir will be an absolute path, so we don't need to set this to anything.
- outDirPrefix = ""
+ outDir = moduleGenDir.String()
+ } else if moduleGenDir.Valid() {
+ // If OUT_DIR is not absolute, we use $$PWD to generate an absolute path (os.Getwd() returns '/')
+ outDir = filepath.Join("$$PWD/", cmd.PathForInput(moduleGenDir.Path()))
+ } else {
+ outDir = "$$PWD/"
}
- envVars = append(envVars, "OUT_DIR="+filepath.Join(outDirPrefix, moduleGenDir.String()))
+ envVars = append(envVars, "OUT_DIR="+outDir)
} else {
// TODO(pcc): Change this to "OUT_DIR=" after fixing crates to not rely on this value.
envVars = append(envVars, "OUT_DIR=out")
@@ -242,7 +204,7 @@
}
}
- envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar")
+ envVars = append(envVars, "AR="+cmd.PathForTool(deps.Llvm_ar))
if ctx.Darwin() {
envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
@@ -251,21 +213,18 @@
return envVars
}
-func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags,
+func transformSrctoCrate(ctx ModuleContext, comp compiler, main android.Path, deps PathDeps, flags Flags,
outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths
- var implicits, linkImplicits, linkOrderOnly android.Paths
var output buildOutput
var rustcFlags, linkFlags []string
- var earlyLinkFlags string
+ var earlyLinkFlags []string
output.outputFile = outputFile
crateName := ctx.RustModule().CrateName()
targetTriple := ctx.toolchain().RustTriple()
- envVars := rustEnvVars(ctx, deps)
-
inputs = append(inputs, main)
// Collect rustc flags
@@ -286,7 +245,6 @@
// Enable incremental compilation if requested by user
if ctx.Config().IsEnvTrue("SOONG_RUSTC_INCREMENTAL") {
incrementalPath := android.PathForOutput(ctx, "rustc").String()
-
rustcFlags = append(rustcFlags, "-Cincremental="+incrementalPath)
}
@@ -298,36 +256,16 @@
// Collect linker flags
if !ctx.Darwin() {
- earlyLinkFlags = "-Wl,--as-needed"
+ earlyLinkFlags = append(earlyLinkFlags, "-Wl,--as-needed")
}
- linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
- linkFlags = append(linkFlags, flags.LinkFlags...)
-
- // Check if this module needs to use the bootstrap linker
- if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
- dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
- if ctx.toolchain().Is64Bit() {
- dynamicLinker += "64"
- }
- linkFlags = append(linkFlags, dynamicLinker)
- }
-
- libFlags := makeLibFlags(deps)
-
// Collect dependencies
- implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
- implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
- implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
- implicits = append(implicits, deps.AfdoProfiles...)
- implicits = append(implicits, deps.srcProviderFiles...)
- implicits = append(implicits, deps.WholeStaticLibs...)
-
- linkImplicits = append(linkImplicits, deps.LibDeps...)
+ var linkImplicits android.Paths
+ implicits := collectImplicits(deps)
+ toolImplicits := android.Concat(deps.BuildToolDeps)
linkImplicits = append(linkImplicits, deps.CrtBegin...)
linkImplicits = append(linkImplicits, deps.CrtEnd...)
-
- linkOrderOnly = append(linkOrderOnly, deps.linkObjects...)
+ implicits = append(implicits, comp.compilationSourcesAndData(ctx)...)
if len(deps.SrcDeps) > 0 {
moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
@@ -342,7 +280,7 @@
}
ctx.Build(pctx, android.BuildParams{
- Rule: cp,
+ Rule: cpDir,
Description: "cp " + moduleGenDir.Path().Rel(),
Outputs: outputs,
Inputs: deps.SrcDeps,
@@ -354,81 +292,176 @@
}
if flags.Clippy {
+ // TODO(b/298461712) remove this hack to let slim manifest branches build
+ if deps.Clippy_driver == nil {
+ deps.Clippy_driver = config.RustPath(ctx, "bin/clippy-driver")
+ }
+
+ clippyRule := getRuleBuilder(ctx, pctx, false, "clippy")
+ clippyCmd := clippyRule.Command()
clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
- ctx.Build(pctx, android.BuildParams{
- Rule: clippyDriver,
- Description: "clippy " + main.Rel(),
- Output: clippyFile,
- Inputs: inputs,
- Implicits: implicits,
- Args: map[string]string{
- "rustcFlags": strings.Join(rustcFlags, " "),
- "libFlags": strings.Join(libFlags, " "),
- "clippyFlags": strings.Join(flags.ClippyFlags, " "),
- "envVars": strings.Join(envVars, " "),
- },
- })
+ clippyDepInfoFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d.raw")
+ clippyDepFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy.d")
+
+ clippyCmd.
+ Flags(rustEnvVars(ctx, deps, clippyCmd)).
+ Tool(deps.Clippy_driver).
+ Flag("--emit metadata").
+ FlagWithOutput("-o ", clippyFile).
+ FlagWithOutput("--emit dep-info=", clippyDepInfoFile).
+ Inputs(inputs).
+ Flags(makeLibFlags(deps, clippyCmd)).
+ Flags(rustcFlags).
+ Flags(flags.ClippyFlags).
+ ImplicitTools(toolImplicits).
+ Implicits(implicits)
+
+ depfileCreationCmd := clippyRule.Command()
+ depfileCreationCmd.
+ Flag(fmt.Sprintf(
+ `grep "^%s:" %s >`,
+ depfileCreationCmd.PathForOutput(clippyFile),
+ depfileCreationCmd.PathForOutput(clippyDepInfoFile),
+ )).
+ DepFile(clippyDepFile)
+
+ clippyRule.BuildWithUnescapedNinjaVars("clippy", "clippy "+main.Rel())
+
// Declare the clippy build as an implicit dependency of the original crate.
implicits = append(implicits, clippyFile)
}
- rustcOutputFile := outputFile
+ sboxDirectory := "rustc"
+ rustSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
+ depFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d")
+ depInfoFile := android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".d.raw")
+ var rustcImplicitOutputs android.WritablePaths
+
+ sandboxedCompilation := comp.crateRoot(ctx) != nil
+ rustcRule := getRuleBuilder(ctx, pctx, sandboxedCompilation, sboxDirectory)
+ rustcCmd := rustcRule.Command()
+
+ linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
+ linkFlags = append(linkFlags, flags.LinkFlags...)
+ linkFlags = append(linkFlags, rustcCmd.PathsForInputs(deps.linkObjects)...)
+
+ // Check if this module needs to use the bootstrap linker
+ if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
+ dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
+ if ctx.toolchain().Is64Bit() {
+ dynamicLinker += "64"
+ }
+ linkFlags = append(linkFlags, dynamicLinker)
+ }
+
+ libFlags := makeLibFlags(deps, rustcCmd)
+
usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
if usesLinker {
- rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp")
+ rustSboxOutputFile = android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".rsp")
+ rustcImplicitOutputs = android.WritablePaths{
+ android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".whole.a"),
+ android.PathForModuleOut(ctx, sboxDirectory, rustSboxOutputFile.Base()+".a"),
+ }
}
- ctx.Build(pctx, android.BuildParams{
- Rule: rustc,
- Description: "rustc " + main.Rel(),
- Output: rustcOutputFile,
- Inputs: inputs,
- Implicits: implicits,
- Args: map[string]string{
- "rustcFlags": strings.Join(rustcFlags, " "),
- "libFlags": strings.Join(libFlags, " "),
- "envVars": strings.Join(envVars, " "),
- },
- })
+ // TODO(b/298461712) remove this hack to let slim manifest branches build
+ if deps.Rustc == nil {
+ deps.Rustc = config.RustPath(ctx, "bin/rustc")
+ }
- if usesLinker {
+ rustcCmd.
+ Flags(rustEnvVars(ctx, deps, rustcCmd)).
+ Tool(deps.Rustc).
+ FlagWithInput("-C linker=", android.PathForSource(ctx, "build", "soong", "scripts", "mkcratersp.py")).
+ Flag("--emit link").
+ Flag("-o").
+ Output(rustSboxOutputFile).
+ FlagWithOutput("--emit dep-info=", depInfoFile).
+ Inputs(inputs).
+ Flags(libFlags).
+ ImplicitTools(toolImplicits).
+ Implicits(implicits).
+ Flags(rustcFlags).
+ ImplicitOutputs(rustcImplicitOutputs)
+
+ depfileCreationCmd := rustcRule.Command()
+ depfileCreationCmd.
+ Flag(fmt.Sprintf(
+ `grep "^%s:" %s >`,
+ depfileCreationCmd.PathForOutput(rustSboxOutputFile),
+ depfileCreationCmd.PathForOutput(depInfoFile),
+ )).
+ DepFile(depFile)
+
+ if !usesLinker {
ctx.Build(pctx, android.BuildParams{
- Rule: rustLink,
- Description: "rustLink " + main.Rel(),
- Output: outputFile,
- Inputs: android.Paths{rustcOutputFile},
- Implicits: linkImplicits,
- OrderOnly: linkOrderOnly,
- Args: map[string]string{
- "earlyLinkFlags": earlyLinkFlags,
- "linkFlags": strings.Join(linkFlags, " "),
- "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
- "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
- },
+ Rule: cp,
+ Input: rustSboxOutputFile,
+ Output: outputFile,
+ })
+ } else {
+ // TODO: delmerico - separate rustLink into its own rule
+ // mkcratersp.py hardcodes paths to files within the sandbox, so
+ // those need to be renamed/symlinked to something in the rustLink sandbox
+ // if we want to separate the rules
+ linkerSboxOutputFile := android.PathForModuleOut(ctx, sboxDirectory, outputFile.Base())
+ rustLinkCmd := rustcRule.Command()
+ rustLinkCmd.
+ Tool(deps.Clang).
+ Flag("-o").
+ Output(linkerSboxOutputFile).
+ Inputs(deps.CrtBegin).
+ Flags(earlyLinkFlags).
+ FlagWithInput("@", rustSboxOutputFile).
+ Flags(linkFlags).
+ Inputs(deps.CrtEnd).
+ ImplicitTools(toolImplicits).
+ Implicits(rustcImplicitOutputs.Paths()).
+ Implicits(implicits).
+ Implicits(linkImplicits)
+ ctx.Build(pctx, android.BuildParams{
+ Rule: cp,
+ Input: linkerSboxOutputFile,
+ Output: outputFile,
})
}
+ rustcRule.BuildWithUnescapedNinjaVars("rustc", "rustc "+main.Rel())
+
if flags.EmitXrefs {
+ kytheRule := getRuleBuilder(ctx, pctx, false, "kythe")
+ kytheCmd := kytheRule.Command()
kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
- ctx.Build(pctx, android.BuildParams{
- Rule: kytheExtract,
- Description: "Xref Rust extractor " + main.Rel(),
- Output: kytheFile,
- Inputs: inputs,
- Implicits: implicits,
- Args: map[string]string{
- "rustcFlags": strings.Join(rustcFlags, " "),
- "libFlags": strings.Join(libFlags, " "),
- "envVars": strings.Join(envVars, " "),
- },
- })
+ kytheCmd.
+ Flag("KYTHE_CORPUS=${kytheCorpus}").
+ FlagWithOutput("KYTHE_OUTPUT_FILE=", kytheFile).
+ FlagWithInput("KYTHE_VNAMES=", android.PathForSource(ctx, "build", "soong", "vnames.json")).
+ Flag("KYTHE_KZIP_ENCODING=${kytheCuEncoding}").
+ Flag("KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative").
+ Tool(ctx.Config().PrebuiltBuildTool(ctx, "rust_extractor")).
+ Flags(rustEnvVars(ctx, deps, kytheCmd)).
+ Tool(deps.Rustc).
+ Flag("-C linker=true").
+ Inputs(inputs).
+ Flags(makeLibFlags(deps, kytheCmd)).
+ Flags(rustcFlags).
+ ImplicitTools(toolImplicits).
+ Implicits(implicits)
+ kytheRule.BuildWithUnescapedNinjaVars("kythe", "Xref Rust extractor "+main.Rel())
output.kytheFile = kytheFile
}
return output
}
-func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps,
- flags Flags) android.ModuleOutPath {
+func Rustdoc(ctx ModuleContext, main android.Path, deps PathDeps, flags Flags) android.ModuleOutPath {
+ // TODO(b/298461712) remove this hack to let slim manifest branches build
+ if deps.Rustdoc == nil {
+ deps.Rustdoc = config.RustPath(ctx, "bin/rustdoc")
+ }
+
+ rustdocRule := getRuleBuilder(ctx, pctx, false, "rustdoc")
+ rustdocCmd := rustdocRule.Command()
rustdocFlags := append([]string{}, flags.RustdocFlags...)
rustdocFlags = append(rustdocFlags, "--sysroot=/dev/null")
@@ -447,7 +480,7 @@
crateName := ctx.RustModule().CrateName()
rustdocFlags = append(rustdocFlags, "--crate-name "+crateName)
- rustdocFlags = append(rustdocFlags, makeLibFlags(deps)...)
+ rustdocFlags = append(rustdocFlags, makeLibFlags(deps, rustdocCmd)...)
docTimestampFile := android.PathForModuleOut(ctx, "rustdoc.timestamp")
// Silence warnings about renamed lints for third-party crates
@@ -463,18 +496,26 @@
// https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/render/write_shared.rs#L144-L146
docDir := android.PathForOutput(ctx, "rustdoc")
- ctx.Build(pctx, android.BuildParams{
- Rule: rustdoc,
- Description: "rustdoc " + main.Rel(),
- Output: docTimestampFile,
- Input: main,
- Implicit: ctx.RustModule().UnstrippedOutputFile(),
- Args: map[string]string{
- "rustdocFlags": strings.Join(rustdocFlags, " "),
- "outDir": docDir.String(),
- "envVars": strings.Join(rustEnvVars(ctx, deps), " "),
- },
- })
+ rustdocCmd.
+ Flags(rustEnvVars(ctx, deps, rustdocCmd)).
+ Tool(deps.Rustdoc).
+ Flags(rustdocFlags).
+ Input(main).
+ Flag("-o "+docDir.String()).
+ FlagWithOutput("&& touch ", docTimestampFile).
+ Implicit(ctx.RustModule().UnstrippedOutputFile())
+ rustdocRule.BuildWithUnescapedNinjaVars("rustdoc", "rustdoc "+main.Rel())
return docTimestampFile
}
+
+func getRuleBuilder(ctx android.ModuleContext, pctx android.PackageContext, sbox bool, sboxDirectory string) *android.RuleBuilder {
+ r := android.NewRuleBuilder(pctx, ctx)
+ if sbox {
+ r = r.Sbox(
+ android.PathForModuleOut(ctx, sboxDirectory),
+ android.PathForModuleOut(ctx, sboxDirectory+".sbox.textproto"),
+ ).SandboxInputs()
+ }
+ return r
+}
diff --git a/rust/clippy_test.go b/rust/clippy_test.go
index bd3bfb1..2703a1c 100644
--- a/rust/clippy_test.go
+++ b/rust/clippy_test.go
@@ -63,14 +63,14 @@
).RunTest(t)
r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- android.AssertStringEquals(t, "libfoo flags", tc.fooFlags, r.Args["clippyFlags"])
+ android.AssertStringDoesContain(t, "libfoo flags", r.RuleParams.Command, tc.fooFlags)
r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
- android.AssertStringEquals(t, "libbar flags", "${config.ClippyDefaultLints}", r.Args["clippyFlags"])
+ android.AssertStringDoesContain(t, "libbar flags", r.RuleParams.Command, "${config.ClippyDefaultLints}")
r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("clippy")
if r.Rule != nil {
- t.Errorf("libfoobar is setup to use clippy when explicitly disabled: clippyFlags=%q", r.Args["clippyFlags"])
+ t.Errorf("libfoobar is setup to use clippy when explicitly disabled: command=%q", r.RuleParams.Command)
}
})
}
diff --git a/rust/compiler.go b/rust/compiler.go
index e6a7a93..3fa3ccd 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -73,6 +73,18 @@
// If no source file is defined, a single generated source module can be defined to be used as the main source.
Srcs []string `android:"path,arch_variant"`
+ // Entry point that is passed to rustc to begin the compilation. E.g. main.rs or lib.rs.
+ // When this property is set,
+ // * sandboxing is enabled for this module, and
+ // * the srcs attribute is interpreted as a list of all source files potentially
+ // used in compilation, including the entrypoint, and
+ // * compile_data can be used to add additional files used in compilation that
+ // not directly used as source files.
+ Crate_root *string `android:"path,arch_variant"`
+
+ // Additional data files that are used during compilation only. These are not accessible at runtime.
+ Compile_data []string `android:"path,arch_variant"`
+
// name of the lint set that should be used to validate this module.
//
// Possible values are "default" (for using a sensible set of lints
@@ -334,6 +346,23 @@
panic(fmt.Errorf("baseCrater doesn't know how to crate things!"))
}
+func (compile *baseCompiler) crateRoot(ctx ModuleContext) android.Path {
+ if compile.Properties.Crate_root != nil {
+ return android.PathForModuleSrc(ctx, *compile.Properties.Crate_root)
+ }
+ return nil
+}
+
+// compilationSourcesAndData returns a list of files necessary to complete the compilation.
+// This includes the rust source files as well as any other data files that
+// are referenced during the build.
+func (compile *baseCompiler) compilationSourcesAndData(ctx ModuleContext) android.Paths {
+ return android.PathsForModuleSrc(ctx, android.Concat(
+ compile.Properties.Srcs,
+ compile.Properties.Compile_data,
+ ))
+}
+
func (compiler *baseCompiler) rustdoc(ctx ModuleContext, flags Flags,
deps PathDeps) android.OptionalPath {
@@ -511,6 +540,8 @@
ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.")
}
+ // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper
+ // entry point file from Srcs rather than taking the first one
paths := android.PathsForModuleSrc(ctx, srcs)
return paths[srcIndex], paths[1:]
}
diff --git a/rust/compiler_test.go b/rust/compiler_test.go
index ec6829a..e5cc888 100644
--- a/rust/compiler_test.go
+++ b/rust/compiler_test.go
@@ -36,9 +36,9 @@
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"fizz\"'") ||
- !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'feature=\"buzz\"'") {
- t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'feature=\"fizz\"'") ||
+ !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'feature=\"buzz\"'") {
+ t.Fatalf("missing fizz and buzz feature flags for libfoo dylib, command: %#v", libfooDylib.RuleParams.Command)
}
}
@@ -57,9 +57,9 @@
libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'std'") ||
- !strings.Contains(libfooDylib.Args["rustcFlags"], "cfg 'cfg1=\"one\"'") {
- t.Fatalf("missing std and cfg1 flags for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'std'") ||
+ !strings.Contains(libfooDylib.RuleParams.Command, "cfg 'cfg1=\"one\"'") {
+ t.Fatalf("missing std and cfg1 flags for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command)
}
}
@@ -146,14 +146,14 @@
fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
- if !strings.Contains(fizz.Args["envVars"], "CARGO_BIN_NAME=fizz") {
- t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual envVars: %#v", fizz.Args["envVars"])
+ if !strings.Contains(fizz.RuleParams.Command, "CARGO_BIN_NAME=fizz") {
+ t.Fatalf("expected 'CARGO_BIN_NAME=fizz' in envVars, actual command: %#v", fizz.RuleParams.Command)
}
- if !strings.Contains(fizz.Args["envVars"], "CARGO_CRATE_NAME=foo") {
- t.Fatalf("expected 'CARGO_CRATE_NAME=foo' in envVars, actual envVars: %#v", fizz.Args["envVars"])
+ if !strings.Contains(fizz.RuleParams.Command, "CARGO_CRATE_NAME=foo") {
+ t.Fatalf("expected 'CARGO_CRATE_NAME=foo' in envVars, actual command: %#v", fizz.RuleParams.Command)
}
- if !strings.Contains(fizz.Args["envVars"], "CARGO_PKG_VERSION=1.0.0") {
- t.Fatalf("expected 'CARGO_PKG_VERSION=1.0.0' in envVars, actual envVars: %#v", fizz.Args["envVars"])
+ if !strings.Contains(fizz.RuleParams.Command, "CARGO_PKG_VERSION=1.0.0") {
+ t.Fatalf("expected 'CARGO_PKG_VERSION=1.0.0' in envVars, actual command: %#v", fizz.RuleParams.Command)
}
}
@@ -230,13 +230,13 @@
).RunTest(t)
r := result.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- android.AssertStringDoesContain(t, "libfoo flags", r.Args["rustcFlags"], tc.fooFlags)
+ android.AssertStringDoesContain(t, "libfoo flags", r.RuleParams.Command, tc.fooFlags)
r = result.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- android.AssertStringDoesContain(t, "libbar flags", r.Args["rustcFlags"], "${config.RustDefaultLints}")
+ android.AssertStringDoesContain(t, "libbar flags", r.RuleParams.Command, "${config.RustDefaultLints}")
r = result.ModuleForTests("libfoobar", "android_arm64_armv8-a_dylib").MaybeRule("rustc")
- android.AssertStringDoesContain(t, "libfoobar flags", r.Args["rustcFlags"], "${config.RustAllowAllLints}")
+ android.AssertStringDoesContain(t, "libfoobar flags", r.RuleParams.Command, "${config.RustAllowAllLints}")
})
}
}
diff --git a/rust/config/arm64_device.go b/rust/config/arm64_device.go
index 08ac2ef..564168b 100644
--- a/rust/config/arm64_device.go
+++ b/rust/config/arm64_device.go
@@ -21,7 +21,9 @@
)
var (
- Arm64RustFlags = []string{}
+ Arm64RustFlags = []string{
+ "-C force-frame-pointers=y",
+ }
Arm64ArchFeatureRustFlags = map[string][]string{}
Arm64LinkFlags = []string{}
diff --git a/rust/config/global.go b/rust/config/global.go
index 4bd495d..0ddc116 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -25,7 +25,7 @@
pctx = android.NewPackageContext("android/soong/rust/config")
exportedVars = android.NewExportedVariables(pctx)
- RustDefaultVersion = "1.71.0"
+ RustDefaultVersion = "1.72.0"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
@@ -81,13 +81,7 @@
func init() {
pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase)
- pctx.VariableConfigMethod("HostPrebuiltTag", func(config android.Config) string {
- if config.UseHostMusl() {
- return "linux-musl-x86"
- } else {
- return config.PrebuiltOS()
- }
- })
+ pctx.VariableConfigMethod("HostPrebuiltTag", HostPrebuiltTag)
pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
@@ -109,6 +103,14 @@
exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
}
+func HostPrebuiltTag(config android.Config) string {
+ if config.UseHostMusl() {
+ return "linux-musl-x86"
+ } else {
+ return config.PrebuiltOS()
+ }
+}
+
func getRustVersionPctx(ctx android.PackageVarContext) string {
return GetRustVersion(ctx)
}
@@ -124,3 +126,27 @@
func BazelRustToolchainVars(config android.Config) string {
return android.BazelToolchainVars(config, exportedVars)
}
+
+func RustPath(ctx android.PathContext, file string) android.SourcePath {
+ type rustToolKey string
+ key := android.NewCustomOnceKey(rustToolKey(file))
+ return ctx.Config().OnceSourcePath(key, func() android.SourcePath {
+ return rustPath(ctx).Join(ctx, file)
+ })
+}
+
+var rustPathKey = android.NewOnceKey("clangPath")
+
+func rustPath(ctx android.PathContext) android.SourcePath {
+ return ctx.Config().OnceSourcePath(rustPathKey, func() android.SourcePath {
+ rustBase := RustDefaultBase
+ if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
+ rustBase = override
+ }
+ rustVersion := RustDefaultVersion
+ if override := ctx.Config().Getenv("RUST_DEFAULT_VERSION"); override != "" {
+ rustVersion = override
+ }
+ return android.PathForSource(ctx, rustBase, ctx.Config().PrebuiltOS(), rustVersion)
+ })
+}
diff --git a/rust/config/riscv64_device.go b/rust/config/riscv64_device.go
index d014dbf..0a9c61a 100644
--- a/rust/config/riscv64_device.go
+++ b/rust/config/riscv64_device.go
@@ -21,9 +21,15 @@
)
var (
- Riscv64RustFlags = []string{}
- Riscv64ArchFeatureRustFlags = map[string][]string{"": {}}
- Riscv64LinkFlags = []string{}
+ Riscv64RustFlags = []string{
+ "-C force-frame-pointers=y",
+ }
+ Riscv64ArchFeatureRustFlags = map[string][]string{
+ "riscv64": {
+ "-C target-feature=+V,+Zba,+Zbb,+Zbs",
+ },
+ }
+ Riscv64LinkFlags = []string{}
Riscv64ArchVariantRustFlags = map[string][]string{"": {}}
)
diff --git a/rust/config/x86_64_device.go b/rust/config/x86_64_device.go
index 3458ec9..45d1fd0 100644
--- a/rust/config/x86_64_device.go
+++ b/rust/config/x86_64_device.go
@@ -21,7 +21,9 @@
)
var (
- x86_64RustFlags = []string{}
+ x86_64RustFlags = []string{
+ "-C force-frame-pointers=y",
+ }
x86_64ArchFeatureRustFlags = map[string][]string{}
x86_64LinkFlags = []string{}
diff --git a/rust/coverage.go b/rust/coverage.go
index 5216d60..b312194 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -17,6 +17,7 @@
import (
"github.com/google/blueprint"
+ "android/soong/android"
"android/soong/cc"
)
@@ -70,7 +71,10 @@
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
profiler_builtins := ctx.GetDirectDepWithTag(ProfilerBuiltins, rlibDepTag).(*Module)
- deps.RLibs = append(deps.RLibs, RustLibrary{Path: profiler_builtins.OutputFile().Path(), CrateName: profiler_builtins.CrateName()})
+ deps.Rlibs = android.AddDirectToDepSet[RustLibrary](deps.Rlibs, RustLibrary{
+ Path: profiler_builtins.OutputFile().Path(),
+ CrateName: profiler_builtins.CrateName(),
+ })
}
if cc.EnableContinuousCoverage(ctx) {
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 64077cf..1466e0c 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -55,27 +55,27 @@
libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
- libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustLink")
- libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustLink")
- fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustLink")
- buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustLink")
+ libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustc")
+ libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
+ fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
+ buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
- if !strings.Contains(fizzCov.Args["rustcFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["rustcFlags"])
+ if !strings.Contains(fizzCov.RuleParams.Command, flag) {
+ t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.RuleParams.Command)
}
- if !strings.Contains(libfooCov.Args["rustcFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["rustcFlags"])
+ if !strings.Contains(libfooCov.RuleParams.Command, flag) {
+ t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.RuleParams.Command)
}
- if strings.Contains(buzzNoCov.Args["rustcFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["rustcFlags"])
+ if strings.Contains(buzzNoCov.RuleParams.Command, flag) {
+ t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.RuleParams.Command)
}
- if strings.Contains(libbarNoCov.Args["rustcFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["rustcFlags"])
+ if strings.Contains(libbarNoCov.RuleParams.Command, flag) {
+ t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.RuleParams.Command)
}
}
@@ -84,17 +84,17 @@
missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
- if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"])
+ if !strings.Contains(fizzCovLink.RuleParams.Command, flag) {
+ t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.RuleParams.Command)
}
- if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"])
+ if !strings.Contains(libfooCovLink.RuleParams.Command, flag) {
+ t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.RuleParams.Command)
}
- if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"])
+ if strings.Contains(buzzNoCovLink.RuleParams.Command, flag) {
+ t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.RuleParams.Command)
}
- if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"])
+ if strings.Contains(libbarNoCovLink.RuleParams.Command, flag) {
+ t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.RuleParams.Command)
}
}
@@ -107,8 +107,8 @@
srcs: ["foo.rs"],
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink")
- if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
- t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
+ fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc")
+ if !strings.Contains(fizz.RuleParams.Command, "libprofile-clang-extras.a") {
+ t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.RuleParams.Command)
}
}
diff --git a/rust/fuzz_test.go b/rust/fuzz_test.go
index ee28c6d..ea35905 100644
--- a/rust/fuzz_test.go
+++ b/rust/fuzz_test.go
@@ -51,23 +51,23 @@
// Check that compiler flags are set appropriately .
fuzz_libtest := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
- if !strings.Contains(fuzz_libtest.Args["rustcFlags"], "-C passes='sancov-module'") ||
- !strings.Contains(fuzz_libtest.Args["rustcFlags"], "--cfg fuzzing") {
+ if !strings.Contains(fuzz_libtest.RuleParams.Command, "-C passes='sancov-module'") ||
+ !strings.Contains(fuzz_libtest.RuleParams.Command, "--cfg fuzzing") {
t.Errorf("rust_fuzz module does not contain the expected flags (sancov-module, cfg fuzzing).")
}
// Check that host modules support fuzzing.
host_fuzzer := ctx.ModuleForTests("fuzz_libtest", "android_arm64_armv8-a_fuzzer").Rule("rustc")
- if !strings.Contains(host_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
- !strings.Contains(host_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
+ if !strings.Contains(host_fuzzer.RuleParams.Command, "-C passes='sancov-module'") ||
+ !strings.Contains(host_fuzzer.RuleParams.Command, "--cfg fuzzing") {
t.Errorf("rust_fuzz_host module does not contain the expected flags (sancov-module, cfg fuzzing).")
}
// Check that dependencies have 'fuzzer' variants produced for them as well.
- libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Output("libtest_fuzzing.rlib")
- if !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "-C passes='sancov-module'") ||
- !strings.Contains(libtest_fuzzer.Args["rustcFlags"], "--cfg fuzzing") {
- t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing).")
+ libtest_fuzzer := ctx.ModuleForTests("libtest_fuzzing", "android_arm64_armv8-a_rlib_rlib-std_fuzzer").Rule("rustc")
+ if !strings.Contains(libtest_fuzzer.RuleParams.Command, "-C passes='sancov-module'") ||
+ !strings.Contains(libtest_fuzzer.RuleParams.Command, "--cfg fuzzing") {
+ t.Errorf("rust_fuzz dependent library does not contain the expected flags (sancov-module, cfg fuzzing). command: %q", libtest_fuzzer.RuleParams.Command)
}
}
diff --git a/rust/image_test.go b/rust/image_test.go
index fb4d9c1..813c5bc 100644
--- a/rust/image_test.go
+++ b/rust/image_test.go
@@ -59,36 +59,36 @@
vendor := ctx.ModuleForTests("libfoo", "android_vendor.29_arm64_armv8-a_static").Rule("rustc")
- if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") {
- t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ if !strings.Contains(vendor.RuleParams.Command, "--cfg 'android_vndk'") {
+ t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command)
}
- if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") {
- t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ if !strings.Contains(vendor.RuleParams.Command, "--cfg 'android_vendor'") {
+ t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command)
}
- if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") {
- t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"])
+ if strings.Contains(vendor.RuleParams.Command, "--cfg 'android_product'") {
+ t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.RuleParams.Command)
}
product := ctx.ModuleForTests("libfoo", "android_product.29_arm64_armv8-a_static").Rule("rustc")
- if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") {
- t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ if !strings.Contains(product.RuleParams.Command, "--cfg 'android_vndk'") {
+ t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command)
}
- if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") {
- t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ if strings.Contains(product.RuleParams.Command, "--cfg 'android_vendor'") {
+ t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command)
}
- if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") {
- t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ if !strings.Contains(product.RuleParams.Command, "--cfg 'android_product'") {
+ t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.RuleParams.Command)
}
system := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Rule("rustc")
- if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") {
- t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
+ if strings.Contains(system.RuleParams.Command, "--cfg 'android_vndk'") {
+ t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.RuleParams.Command)
}
- if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") {
- t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"])
+ if strings.Contains(system.RuleParams.Command, "--cfg 'android_vendor'") {
+ t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.RuleParams.Command)
}
- if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") {
- t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"])
+ if strings.Contains(system.RuleParams.Command, "--cfg 'android_product'") {
+ t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.RuleParams.Command)
}
}
diff --git a/rust/library.go b/rust/library.go
index 3f031c1..7bb82bc 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -485,11 +485,28 @@
return flags
}
+func (library *libraryDecorator) compilationSourcesAndData(ctx ModuleContext) android.Paths {
+ var extraSrcs android.Paths
+ if library.rlib() {
+ extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Rlib.Srcs)
+ } else if library.dylib() {
+ extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Dylib.Srcs)
+ } else if library.static() {
+ extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Static.Srcs)
+ } else if library.shared() {
+ extraSrcs = android.PathsForModuleSrc(ctx, library.Properties.Shared.Srcs)
+ }
+ return android.Concat(
+ library.baseCompiler.compilationSourcesAndData(ctx),
+ extraSrcs,
+ )
+}
+
func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
var outputFile android.ModuleOutPath
var ret buildOutput
var fileName string
- srcPath := library.srcPath(ctx, deps)
+ crateRootPath := library.crateRootPath(ctx, deps)
if library.sourceProvider != nil {
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
@@ -525,7 +542,6 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@@ -536,13 +552,13 @@
// Call the appropriate builder for this library type
if library.rlib() {
- ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoRlib(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.dylib() {
- ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoDylib(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.static() {
- ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoStatic(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.shared() {
- ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoShared(ctx, library, crateRootPath, deps, flags, outputFile).kytheFile
}
if library.rlib() || library.dylib() {
@@ -585,13 +601,15 @@
return ret
}
-func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
+func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path {
if library.sourceProvider != nil {
// Assume the first source from the source provider is the library entry point.
return library.sourceProvider.Srcs()[0]
- } else {
+ } else if library.baseCompiler.Properties.Crate_root == nil {
path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
return path
+ } else {
+ return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root)
}
}
@@ -606,7 +624,7 @@
return android.OptionalPath{}
}
- return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
+ return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps),
deps, flags))
}
@@ -810,7 +828,7 @@
Proc_macro_deps bazel.LabelListAttribute
}
-func libraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func libraryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
lib := m.compiler.(*libraryDecorator)
srcs, compileData := srcsAndCompileDataAttrs(ctx, *lib.baseCompiler)
@@ -887,7 +905,7 @@
Version bazel.StringAttribute
}
-func cargoBuildScriptBp2build(ctx android.TopDownMutatorContext, m *Module) *string {
+func cargoBuildScriptBp2build(ctx android.Bp2buildMutatorContext, 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/
diff --git a/rust/library_test.go b/rust/library_test.go
index 30ef333..dab9381 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -48,23 +48,23 @@
staticCrateType := "staticlib"
// Test crate type for rlib is correct.
- if !strings.Contains(libfooRlib.Args["rustcFlags"], "crate-type="+rlibCrateType) {
- t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.Args["rustcFlags"])
+ if !strings.Contains(libfooRlib.RuleParams.Command, "crate-type="+rlibCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", rlibCrateType, libfooRlib.RuleParams.Command)
}
// Test crate type for dylib is correct.
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "crate-type="+dylibCrateType) {
- t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.RuleParams.Command, "crate-type="+dylibCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", dylibCrateType, libfooDylib.RuleParams.Command)
}
// Test crate type for C static libraries is correct.
- if !strings.Contains(libfooStatic.Args["rustcFlags"], "crate-type="+staticCrateType) {
- t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.Args["rustcFlags"])
+ if !strings.Contains(libfooStatic.RuleParams.Command, "crate-type="+staticCrateType) {
+ t.Errorf("missing crate-type for static variant, expecting %#v, rustcFlags: %#v", staticCrateType, libfooStatic.RuleParams.Command)
}
// Test crate type for C shared libraries is correct.
- if !strings.Contains(libfooShared.Args["rustcFlags"], "crate-type="+sharedCrateType) {
- t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.Args["rustcFlags"])
+ if !strings.Contains(libfooShared.RuleParams.Command, "crate-type="+sharedCrateType) {
+ t.Errorf("missing crate-type for shared variant, expecting %#v, got rustcFlags: %#v", sharedCrateType, libfooShared.RuleParams.Command)
}
}
@@ -78,10 +78,10 @@
crate_name: "foo",
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Description("rustc")
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "prefer-dynamic") {
- t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.RuleParams.Command, "prefer-dynamic") {
+ t.Errorf("missing prefer-dynamic flag for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command)
}
}
@@ -94,10 +94,10 @@
crate_name: "foo",
}`)
- libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Rule("rustc")
+ libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Description("rustc")
- if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") {
- t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"])
+ if !strings.Contains(libfooDylib.RuleParams.Command, "--cfg 'android_dylib'") {
+ t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.RuleParams.Command)
}
}
@@ -148,10 +148,10 @@
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
- libfooOutput := libfoo.Rule("rustLink")
- if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
+ libfooOutput := libfoo.Rule("rustc")
+ if !strings.Contains(libfooOutput.RuleParams.Command, "-Wl,-soname=libfoo.so") {
t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
- libfooOutput.Args["linkFlags"])
+ libfooOutput.RuleParams.Command)
}
if !android.InList("libstd", libfoo.Module().(*Module).Properties.AndroidMkDylibs) {
@@ -237,19 +237,21 @@
// The build system assumes the cc deps will be at the final linkage (either a shared library or binary)
// Hence, these flags are no-op
// TODO: We could consider removing these flags
+ expectedSharedFlag := "-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared"
+ expectedStaticFlag := "-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static"
for _, module := range modules {
- if !strings.Contains(module.Rule("rustc").Args["libFlags"],
- "-L out/soong/.intermediates/shared_cc_dep/android_arm64_armv8-a_shared/") {
+ if !strings.Contains(module.Rule("rustc").RuleParams.Command, expectedSharedFlag) {
t.Errorf(
- "missing -L flag for shared_cc_dep, rustcFlags: %#v",
- rustRlibRlibStd.Rule("rustc").Args["libFlags"],
+ "expected to find shared library linkdir flag %q, rustcFlags: %#v",
+ expectedSharedFlag,
+ rustRlibRlibStd.Rule("rustc").RuleParams.Command,
)
}
- if !strings.Contains(module.Rule("rustc").Args["libFlags"],
- "-L out/soong/.intermediates/static_cc_dep/android_arm64_armv8-a_static/") {
+ if !strings.Contains(module.Rule("rustc").RuleParams.Command, expectedStaticFlag) {
t.Errorf(
- "missing -L flag for static_cc_dep, rustcFlags: %#v",
- rustRlibRlibStd.Rule("rustc").Args["libFlags"],
+ "expected to find static library linkdir flag %q, rustcFlags: %#v",
+ expectedStaticFlag,
+ rustRlibRlibStd.Rule("rustc").RuleParams.Command,
)
}
}
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index fe9d0b5..d012680 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -146,7 +146,10 @@
}
func (prebuilt *prebuiltLibraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
- prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
+ deps.linkDirs = append(deps.linkDirs, android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs)...)
+ prebuilt.flagExporter.exportLinkDirs(deps.linkDirs...)
+ prebuilt.flagExporter.exportLinkObjects(deps.linkObjects...)
+ prebuilt.flagExporter.exportLibDeps(deps.LibDeps...)
prebuilt.flagExporter.setProvider(ctx)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
@@ -203,7 +206,7 @@
}
func (prebuilt *prebuiltProcMacroDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
- prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs).Strings()...)
+ prebuilt.flagExporter.exportLinkDirs(android.PathsForModuleSrc(ctx, prebuilt.Properties.Link_dirs)...)
prebuilt.flagExporter.setProvider(ctx)
srcPath, paths := srcPathFromModuleSrcs(ctx, prebuilt.prebuiltSrcs())
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 26227d0..3f0d17a 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -15,9 +15,10 @@
package rust
import (
+ "fmt"
+
"android/soong/android"
"android/soong/bazel"
- "fmt"
)
func init() {
@@ -79,7 +80,7 @@
outputFile := android.PathForModuleOut(ctx, fileName)
srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
- ret := TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile)
+ ret := TransformSrctoProcMacro(ctx, procMacro, srcPath, deps, flags, outputFile)
procMacro.baseCompiler.unstrippedOutputFile = outputFile
return ret
}
@@ -114,7 +115,7 @@
Rustc_flags bazel.StringListAttribute
}
-func procMacroBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func procMacroBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
procMacro := m.compiler.(*procMacroDecorator)
srcs, compileData := srcsAndCompileDataAttrs(ctx, *procMacro.baseCompiler)
deps := android.BazelLabelForModuleDeps(ctx, append(
diff --git a/rust/proc_macro_test.go b/rust/proc_macro_test.go
index cc81938..a547926 100644
--- a/rust/proc_macro_test.go
+++ b/rust/proc_macro_test.go
@@ -30,7 +30,7 @@
libprocmacro := ctx.ModuleForTests("libprocmacro", "linux_glibc_x86_64").Rule("rustc")
- if !strings.Contains(libprocmacro.Args["rustcFlags"], "--extern proc_macro") {
- t.Errorf("--extern proc_macro flag not being passed to rustc for proc macro %#v", libprocmacro.Args["rustcFlags"])
+ if !strings.Contains(libprocmacro.RuleParams.Command, "--extern proc_macro") {
+ t.Errorf("--extern proc_macro flag not being passed to rustc for proc macro %#v", libprocmacro.RuleParams.Command)
}
}
diff --git a/rust/protobuf.go b/rust/protobuf.go
index ae82844..c8d2bda 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -282,7 +282,7 @@
Srcs bazel.LabelListAttribute
}
-func protoLibraryBp2build(ctx android.TopDownMutatorContext, m *Module) {
+func protoLibraryBp2build(ctx android.Bp2buildMutatorContext, m *Module) {
var protoFiles []string
for _, propsInterface := range m.sourceProvider.SourceProviderProps() {
diff --git a/rust/rust.go b/rust/rust.go
index 1ee99cd..6d6b55e 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -15,11 +15,12 @@
package rust
import (
+ "fmt"
+ "strings"
+
"android/soong/bazel"
"android/soong/bloaty"
"android/soong/ui/metrics/bp2build_metrics_proto"
- "fmt"
- "strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -437,12 +438,18 @@
}
type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
+ Dylibs *android.DepSet[RustLibrary]
+ Rlibs *android.DepSet[RustLibrary]
+ ProcMacros *android.DepSet[RustLibrary]
LibDeps android.Paths
WholeStaticLibs android.Paths
- ProcMacros RustLibraries
AfdoProfiles android.Paths
+ // These paths are files needed to run the build tools and will be located under
+ // __SBOX_SANDBOX_DIR__/tools/...
+ BuildToolDeps android.Paths
+ // These paths are files needed to run the build tools and will be located under
+ // __SBOX_SANDBOX_DIR__/...
+ BuildToolSrcDeps android.Paths
// depFlags and depLinkFlags are rustc and linker (clang) flags.
depFlags []string
@@ -450,7 +457,7 @@
// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
// Both of these are exported and propagate to dependencies.
- linkDirs []string
+ linkDirs android.Paths
linkObjects android.Paths
// Used by bindgen modules which call clang
@@ -465,6 +472,13 @@
// Paths to generated source files
SrcDeps android.Paths
srcProviderFiles android.Paths
+
+ // Paths to specific build tools
+ Rustc android.Path
+ Clang android.Path
+ Llvm_ar android.Path
+ Clippy_driver android.Path
+ Rustdoc android.Path
}
type RustLibraries []RustLibrary
@@ -484,6 +498,8 @@
compilerDeps(ctx DepsContext, deps Deps) Deps
crateName() string
rustdoc(ctx ModuleContext, flags Flags, deps PathDeps) android.OptionalPath
+ crateRoot(ctx ModuleContext) android.Path
+ compilationSourcesAndData(ctx ModuleContext) android.Paths
// Output directory in which source-generated code from dependencies is
// copied. This is equivalent to Cargo's OUT_DIR variable.
@@ -513,7 +529,7 @@
}
type exportedFlagsProducer interface {
- exportLinkDirs(...string)
+ exportLinkDirs(...android.Path)
exportLinkObjects(...android.Path)
}
@@ -522,13 +538,13 @@
}
type flagExporter struct {
- linkDirs []string
+ linkDirs android.Paths
linkObjects android.Paths
libDeps android.Paths
}
-func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
- flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
+func (flagExporter *flagExporter) exportLinkDirs(dirs ...android.Path) {
+ flagExporter.linkDirs = android.FirstUniquePaths(append(flagExporter.linkDirs, dirs...))
}
func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
@@ -555,7 +571,7 @@
type FlagExporterInfo struct {
Flags []string
- LinkDirs []string // TODO: this should be android.Paths
+ LinkDirs android.Paths
LinkObjects android.Paths
LibDeps android.Paths
}
@@ -925,6 +941,14 @@
func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
+type RustInfo struct {
+ TransitiveRlibs *android.DepSet[RustLibrary]
+ TransitiveDylibs *android.DepSet[RustLibrary]
+ TransitiveProcMacros *android.DepSet[RustLibrary]
+}
+
+var RustInfoProvider = blueprint.NewProvider(RustInfo{})
+
func (mod *Module) GenerateAndroidBuildActions(actx android.ModuleContext) {
ctx := &moduleContext{
ModuleContext: actx,
@@ -1034,6 +1058,12 @@
ctx.Phony("rust", ctx.RustModule().OutputFile().Path())
}
+
+ ctx.SetProvider(RustInfoProvider, RustInfo{
+ TransitiveRlibs: deps.Rlibs,
+ TransitiveDylibs: deps.Dylibs,
+ TransitiveProcMacros: deps.ProcMacros,
+ })
}
func (mod *Module) deps(ctx DepsContext) Deps {
@@ -1092,6 +1122,7 @@
var _ android.LicenseAnnotationsDependencyTag = dependencyTag{}
var (
+ buildToolDepTag = dependencyTag{name: "buildToolTag"}
customBindgenDepTag = dependencyTag{name: "customBindgenTag"}
rlibDepTag = dependencyTag{name: "rlibTag", library: true}
dylibDepTag = dependencyTag{name: "dylib", library: true, dynamic: true}
@@ -1225,7 +1256,9 @@
var transitiveAndroidMkSharedLibs []*android.DepSet[string]
var directAndroidMkSharedLibs []string
-
+ transitiveRlibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
+ transitiveDylibs := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
+ transitiveProcMacros := android.NewDepSetBuilder[RustLibrary](android.PREORDER)
ctx.VisitDirectDeps(func(dep android.Module) {
depName := ctx.OtherModuleName(dep)
depTag := ctx.OtherModuleDependencyTag(dep)
@@ -1238,6 +1271,17 @@
return
}
+ rustInfo := ctx.OtherModuleProvider(dep, RustInfoProvider).(RustInfo)
+ if rustInfo.TransitiveDylibs != nil {
+ transitiveDylibs.Transitive(rustInfo.TransitiveDylibs)
+ }
+ if rustInfo.TransitiveRlibs != nil {
+ transitiveRlibs.Transitive(rustInfo.TransitiveRlibs)
+ }
+ if rustInfo.TransitiveProcMacros != nil {
+ transitiveProcMacros.Transitive(rustInfo.TransitiveProcMacros)
+ }
+
if rustDep, ok := dep.(*Module); ok && !rustDep.CcLibraryInterface() {
//Handle Rust Modules
makeLibName := rustMakeLibName(ctx, mod, rustDep, depName+rustDep.Properties.RustSubName)
@@ -1252,9 +1296,12 @@
directDylibDeps = append(directDylibDeps, rustDep)
mod.Properties.AndroidMkDylibs = append(mod.Properties.AndroidMkDylibs, makeLibName)
mod.Properties.SnapshotDylibs = append(mod.Properties.SnapshotDylibs, cc.BaseLibName(depName))
+ transitiveDylibs.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
case rlibDepTag:
-
rlib, ok := rustDep.compiler.(libraryInterface)
if !ok || !rlib.rlib() {
ctx.ModuleErrorf("mod %q not an rlib library", makeLibName)
@@ -1263,10 +1310,18 @@
directRlibDeps = append(directRlibDeps, rustDep)
mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, makeLibName)
mod.Properties.SnapshotRlibs = append(mod.Properties.SnapshotRlibs, cc.BaseLibName(depName))
+ transitiveRlibs.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
+ transitiveProcMacros.Direct(RustLibrary{
+ Path: rustDep.UnstrippedOutputFile(),
+ CrateName: rustDep.CrateName(),
+ })
}
transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
@@ -1302,9 +1357,8 @@
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
linkFile := rustDep.UnstrippedOutputFile()
- linkDir := linkPathFromFilePath(linkFile)
if lib, ok := mod.compiler.(exportedFlagsProducer); ok {
- lib.exportLinkDirs(linkDir)
+ lib.exportLinkDirs(linkFile.Dir())
}
}
@@ -1331,7 +1385,7 @@
return
}
- linkPath := linkPathFromFilePath(linkObject.Path())
+ linkPath := linkObject.Path().Dir()
exportDep := false
switch {
@@ -1385,7 +1439,7 @@
}
return
}
- linkPath = linkPathFromFilePath(linkObject.Path())
+ linkPath = linkObject.Path().Dir()
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
@@ -1420,6 +1474,25 @@
}
} else {
switch {
+ case depTag == buildToolDepTag:
+ buildTool := ctx.OtherModuleProvider(dep, android.PrebuiltBuildToolInfoProvider).(android.PrebuiltBuildToolInfo)
+ depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Src)
+ depPaths.BuildToolDeps = append(depPaths.BuildToolDeps, buildTool.Deps...)
+ switch android.RemoveOptionalPrebuiltPrefix(dep.Name()) {
+ case "rustc":
+ depPaths.Rustc = buildTool.Src
+ // rustc expects the standard cc toolchain libraries (libdl, libm, libc, etc.)
+ // not to be under the __SBOX_SANDBOX_DIR__/ directory
+ depPaths.BuildToolSrcDeps = append(depPaths.BuildToolSrcDeps, buildTool.Deps...)
+ case "clang++":
+ depPaths.Clang = buildTool.Src
+ case "llvm-ar":
+ depPaths.Llvm_ar = buildTool.Src
+ case "clippy-driver":
+ depPaths.Clippy_driver = buildTool.Src
+ case "rustdoc":
+ depPaths.Rustdoc = buildTool.Src
+ }
case depTag == cc.CrtBeginDepTag:
depPaths.CrtBegin = append(depPaths.CrtBegin, android.OutputFileForModule(ctx, dep, ""))
case depTag == cc.CrtEndDepTag:
@@ -1435,21 +1508,6 @@
}
})
- mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
-
- var rlibDepFiles RustLibraries
- for _, dep := range directRlibDeps {
- rlibDepFiles = append(rlibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
- var dylibDepFiles RustLibraries
- for _, dep := range directDylibDeps {
- dylibDepFiles = append(dylibDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
- var procMacroDepFiles RustLibraries
- for _, dep := range directProcMacroDeps {
- procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
- }
-
var libDepFiles android.Paths
for _, dep := range directStaticLibDeps {
libDepFiles = append(libDepFiles, dep.OutputFile().Path())
@@ -1473,20 +1531,22 @@
srcProviderDepFiles = append(srcProviderDepFiles, srcs...)
}
- depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
- depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...)
- depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
// Dedup exported flags from dependencies
- depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
+ depPaths.linkDirs = android.FirstUniquePaths(depPaths.linkDirs)
depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
depPaths.depSystemIncludePaths = android.FirstUniquePaths(depPaths.depSystemIncludePaths)
+ depPaths.Rlibs = transitiveRlibs.Build()
+ depPaths.Dylibs = transitiveDylibs.Build()
+ depPaths.ProcMacros = transitiveProcMacros.Build()
+ mod.transitiveAndroidMkSharedLibs = android.NewDepSet[string](android.PREORDER, directAndroidMkSharedLibs, transitiveAndroidMkSharedLibs)
+
return depPaths
}
@@ -1509,10 +1569,6 @@
return mod.InRecovery()
}
-func linkPathFromFilePath(filepath android.Path) string {
- return strings.Split(filepath.String(), filepath.Base())[0]
-}
-
// usePublicApi returns true if the rust variant should link against NDK (publicapi)
func (r *Module) usePublicApi() bool {
return r.Device() && r.UseSdk()
@@ -1555,6 +1611,15 @@
blueprint.Variation{Mutator: "rust_stdlinkage", Variation: stdLinkage})
}
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "rustc")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clippy-driver")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "rustdoc")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clang++")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "clang++.real")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "lld")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "ld.lld")
+ ctx.AddFarVariationDependencies([]blueprint.Variation{}, buildToolDepTag, "llvm-ar")
+
// rlibs
rlibDepVariations = append(rlibDepVariations, blueprint.Variation{Mutator: "rust_libraries", Variation: rlibVariation})
for _, lib := range deps.Rlibs {
@@ -1845,7 +1910,7 @@
return ""
}
-func (m *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *Module) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if ctx.ModuleType() == "rust_library_host" || ctx.ModuleType() == "rust_library" {
libraryBp2build(ctx, m)
} else if ctx.ModuleType() == "rust_proc_macro" {
@@ -1864,7 +1929,7 @@
// 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) {
+func srcsAndCompileDataAttrs(ctx android.Bp2buildMutatorContext, c baseCompiler) (bazel.LabelList, bazel.LabelList) {
var srcs bazel.LabelList
var compileData bazel.LabelList
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 835114c..576209d 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -15,14 +15,17 @@
package rust
import (
+ "fmt"
"os"
"runtime"
"strings"
"testing"
"github.com/google/blueprint/proptools"
+ "google.golang.org/protobuf/encoding/prototext"
"android/soong/android"
+ "android/soong/cmd/sbox/sbox_proto"
"android/soong/genrule"
)
@@ -64,11 +67,14 @@
// testRust returns a TestContext in which a basic environment has been setup.
// This environment contains a few mocked files. See rustMockedFiles for the list of these files.
-func testRust(t *testing.T, bp string) *android.TestContext {
+func testRust(t *testing.T, bp string, preparers ...android.FixturePreparer) *android.TestContext {
skipTestIfOsNotSupported(t)
result := android.GroupFixturePreparers(
prepareForRustTest,
rustMockedFiles.AddToFixture(),
+ android.GroupFixturePreparers(
+ preparers...,
+ ),
).
RunTestWithBp(t, bp)
return result.TestContext
@@ -202,11 +208,11 @@
// Test that we can extract the link path from a lib path.
func TestLinkPathFromFilePath(t *testing.T) {
barPath := android.PathForTesting("out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/libbar.so")
- libName := linkPathFromFilePath(barPath)
- expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared/"
+ libName := barPath.Dir()
+ expectedResult := "out/soong/.intermediates/external/libbar/libbar/linux_glibc_x86_64_shared"
- if libName != expectedResult {
- t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName)
+ if libName.String() != expectedResult {
+ t.Errorf("libNameFromFilePath returned the wrong name; expected '%#v', got '%#v'", expectedResult, libName.String())
}
}
@@ -256,7 +262,7 @@
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
- rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink")
+ rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustc")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) {
@@ -275,16 +281,16 @@
t.Errorf("Static library dependency not detected (dependency missing from AndroidMkStaticLibs)")
}
- if !strings.Contains(rustc.Args["rustcFlags"], "-lstatic=wholestatic") {
- t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
+ if !strings.Contains(rustc.RuleParams.Command, "-lstatic=wholestatic") {
+ t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.RuleParams.Command)
}
- if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") {
- t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"])
+ if !strings.Contains(rustLink.RuleParams.Command, "cc_stubs_dep.so") {
+ t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.RuleParams.Command)
}
- if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") {
- t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings())
+ if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so") {
+ t.Errorf("shared cc dep not being passed as implicit to rustc %#v", rustLink.OrderOnly.Strings())
}
if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") {
@@ -427,7 +433,7 @@
`)
rustc := ctx.ModuleForTests("libpm", "linux_glibc_x86_64").Rule("rustc")
- if !strings.Contains(rustc.Args["libFlags"], "libbar/linux_glibc_x86_64") {
+ if !strings.Contains(rustc.RuleParams.Command, "libbar/linux_glibc_x86_64") {
t.Errorf("Proc_macro is not using host variant of dependent modules.")
}
}
@@ -480,3 +486,396 @@
t.Errorf("expected %q got %q", expected, got)
}
}
+
+var (
+ sboxCompilationFiles = []string{
+ "out/soong/.intermediates/defaults/rust/libaddr2line/android_arm64_armv8-a_rlib/libaddr2line.rlib",
+ "out/soong/.intermediates/defaults/rust/libadler/android_arm64_armv8-a_rlib/libadler.rlib",
+ "out/soong/.intermediates/defaults/rust/liballoc/android_arm64_armv8-a_rlib/liballoc.rlib",
+ "out/soong/.intermediates/defaults/rust/libcfg_if/android_arm64_armv8-a_rlib/libcfg_if.rlib",
+ "out/soong/.intermediates/defaults/rust/libcompiler_builtins/android_arm64_armv8-a_rlib/libcompiler_builtins.rlib",
+ "out/soong/.intermediates/defaults/rust/libcore/android_arm64_armv8-a_rlib/libcore.rlib",
+ "out/soong/.intermediates/defaults/rust/libgimli/android_arm64_armv8-a_rlib/libgimli.rlib",
+ "out/soong/.intermediates/defaults/rust/libhashbrown/android_arm64_armv8-a_rlib/libhashbrown.rlib",
+ "out/soong/.intermediates/defaults/rust/liblibc/android_arm64_armv8-a_rlib/liblibc.rlib",
+ "out/soong/.intermediates/defaults/rust/libmemchr/android_arm64_armv8-a_rlib/libmemchr.rlib",
+ "out/soong/.intermediates/defaults/rust/libminiz_oxide/android_arm64_armv8-a_rlib/libminiz_oxide.rlib",
+ "out/soong/.intermediates/defaults/rust/libobject/android_arm64_armv8-a_rlib/libobject.rlib",
+ "out/soong/.intermediates/defaults/rust/libpanic_unwind/android_arm64_armv8-a_rlib/libpanic_unwind.rlib",
+ "out/soong/.intermediates/defaults/rust/librustc_demangle/android_arm64_armv8-a_rlib/librustc_demangle.rlib",
+ "out/soong/.intermediates/defaults/rust/librustc_std_workspace_alloc/android_arm64_armv8-a_rlib/librustc_std_workspace_alloc.rlib",
+ "out/soong/.intermediates/defaults/rust/librustc_std_workspace_core/android_arm64_armv8-a_rlib/librustc_std_workspace_core.rlib",
+ "out/soong/.intermediates/defaults/rust/libstd_detect/android_arm64_armv8-a_rlib/libstd_detect.rlib",
+ "build/soong/scripts/mkcratersp.py",
+ "defaults/rust/linux-x86/1.69.0/bin/rustc",
+ "defaults/rust/linux-x86/1.69.0/lib/libstd.so",
+ "defaults/rust/linux-x86/1.69.0/lib64/libc++.so.1",
+ }
+ sboxCompilationFilesWithCc = []string{
+ "defaults/cc/common",
+ "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so",
+ "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc",
+ "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so",
+ "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc",
+ "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so",
+ "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc",
+ "out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so",
+ "out/soong/.intermediates/defaults/rust/liblog/android_arm64_armv8-a_shared/liblog.so.toc",
+ }
+)
+
+func TestSandboxCompilation(t *testing.T) {
+ ctx := testRust(t, `
+ filegroup {
+ name: "libsrcs1",
+ srcs: ["src_filegroup1.rs"],
+ }
+ filegroup {
+ name: "libsrcs2",
+ srcs: ["src_filegroup2.rs"],
+ }
+ rust_library {
+ name: "libfizz_buzz",
+ crate_name:"fizz_buzz",
+ crate_root: "foo.rs",
+ srcs: [
+ "src_lib*.rs",
+ ":libsrcs1",
+ ":libsrcs2",
+ ],
+ compile_data: [
+ "compile_data1.txt",
+ "compile_data2.txt",
+ ],
+ dylib: {
+ srcs: ["dylib_only.rs"],
+ },
+ rlib: {
+ srcs: ["rlib_only.rs"],
+ },
+ }
+ rust_binary {
+ name: "fizz_buzz",
+ crate_name:"fizz_buzz",
+ crate_root: "foo.rs",
+ srcs: [
+ "src_lib*.rs",
+ ":libsrcs1",
+ ":libsrcs2",
+ ],
+ }
+ rust_ffi {
+ name: "librust_ffi",
+ crate_name: "rust_ffi",
+ crate_root: "foo.rs",
+ static: {
+ srcs: ["static_only.rs"],
+ },
+ shared: {
+ srcs: ["shared_only.rs"],
+ },
+ srcs: ["src1.rs"],
+ }
+ cc_library_static {
+ name: "cc_dep_static",
+ }
+ cc_library_shared {
+ name: "cc_dep_shared",
+ }
+ rust_library {
+ name: "libfizz_buzz_cc_deps",
+ crate_name:"fizz_buzz",
+ crate_root: "foo.rs",
+ srcs: ["src*.rs"],
+ shared_libs: ["cc_dep_shared"],
+ static_libs: ["cc_dep_static"],
+ }
+ rust_library {
+ name: "libfizz_buzz_intermediate_cc_deps",
+ crate_name:"fizz_buzz",
+ crate_root: "foo.rs",
+ srcs: ["src*.rs"],
+ rustlibs: ["libfizz_buzz_cc_deps"],
+ }
+ rust_library {
+ name: "libfizz_buzz_transitive_cc_deps",
+ crate_name:"fizz_buzz",
+ crate_root: "foo.rs",
+ srcs: ["src*.rs"],
+ rustlibs: ["libfizz_buzz_intermediate_cc_deps"],
+ }
+ `,
+ android.FixtureMergeMockFs(android.MockFS{
+ "src_lib1.rs": nil,
+ "src_lib2.rs": nil,
+ "src_lib3.rs": nil,
+ "src_lib4.rs": nil,
+ "src_filegroup1.rs": nil,
+ "src_filegroup2.rs": nil,
+ "static_only.rs": nil,
+ "shared_only.rs": nil,
+ }),
+ )
+
+ testcases := []struct {
+ name string
+ moduleName string
+ variant string
+ rustcExpectedFilesToCopy []string
+ expectedFlags []string
+ }{
+ {
+ name: "rust_library (dylib)",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_dylib",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
+ "foo.rs",
+ "src_lib1.rs",
+ "src_lib2.rs",
+ "src_lib3.rs",
+ "src_lib4.rs",
+ "src_filegroup1.rs",
+ "src_filegroup2.rs",
+ "compile_data1.txt",
+ "compile_data2.txt",
+ "dylib_only.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup1.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/out/src_filegroup2.rs",
+
+ "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so",
+ "out/soong/.intermediates/defaults/cc/common/libc/android_arm64_armv8-a_shared/libc.so.toc",
+ "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so",
+ "out/soong/.intermediates/defaults/cc/common/libm/android_arm64_armv8-a_shared/libm.so.toc",
+ "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so",
+ "out/soong/.intermediates/defaults/cc/common/libdl/android_arm64_armv8-a_shared/libdl.so.toc",
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
+ "out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o",
+ "out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.clippy",
+ }),
+ expectedFlags: []string{
+ "-C linker=build/soong/scripts/mkcratersp.py",
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.rsp",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.dylib.so.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_library (rlib dylib-std)",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_rlib_dylib-std",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
+ "foo.rs",
+ "src_lib1.rs",
+ "src_lib2.rs",
+ "src_lib3.rs",
+ "src_lib4.rs",
+ "src_filegroup1.rs",
+ "src_filegroup2.rs",
+ "rlib_only.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup1.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/out/src_filegroup2.rs",
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
+ }),
+ expectedFlags: []string{
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_library (rlib rlib-std)",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_rlib_rlib-std",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
+ "foo.rs",
+ "src_lib1.rs",
+ "src_lib2.rs",
+ "src_lib3.rs",
+ "src_lib4.rs",
+ "src_filegroup1.rs",
+ "src_filegroup2.rs",
+ "rlib_only.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup1.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/out/src_filegroup2.rs",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/libfizz_buzz.rlib.clippy",
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib",
+ }),
+ expectedFlags: []string{
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/libfizz_buzz.rlib.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_binary",
+ moduleName: "fizz_buzz",
+ variant: "android_arm64_armv8-a",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
+ "foo.rs",
+ "src_lib1.rs",
+ "src_lib2.rs",
+ "src_lib3.rs",
+ "src_lib4.rs",
+ "src_filegroup1.rs",
+ "src_filegroup2.rs",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup1.rs",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/out/src_filegroup2.rs",
+
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
+ "out/soong/.intermediates/defaults/cc/common/crtbegin_dynamic/android_arm64_armv8-a/crtbegin_dynamic.o",
+ "out/soong/.intermediates/defaults/cc/common/crtend_android/android_arm64_armv8-a/crtend_android.o",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.clippy",
+ }),
+ expectedFlags: []string{
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/fizz_buzz",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/fizz_buzz.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_ffi static lib variant",
+ moduleName: "librust_ffi",
+ variant: "android_arm64_armv8-a_static",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, []string{
+ "foo.rs",
+ "src1.rs",
+ "static_only.rs",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a.clippy",
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_rlib/libstd.rlib",
+ }),
+ expectedFlags: []string{
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/librust_ffi.a",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.a.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_ffi shared lib variant",
+ moduleName: "librust_ffi",
+ variant: "android_arm64_armv8-a_shared",
+ rustcExpectedFilesToCopy: android.Concat(sboxCompilationFiles, sboxCompilationFilesWithCc, []string{
+ "foo.rs",
+ "src1.rs",
+ "shared_only.rs",
+
+ "out/soong/.intermediates/defaults/rust/libstd/android_arm64_armv8-a_dylib/unstripped/libstd.dylib.so",
+ "out/soong/.intermediates/defaults/cc/common/crtbegin_so/android_arm64_armv8-a/crtbegin_so.o",
+ "out/soong/.intermediates/defaults/cc/common/crtend_so/android_arm64_armv8-a/crtend_so.o",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.clippy",
+ }),
+ expectedFlags: []string{
+ "--emit link",
+ "-o __SBOX_SANDBOX_DIR__/out/librust_ffi.so",
+ "--emit dep-info=__SBOX_SANDBOX_DIR__/out/librust_ffi.so.d.raw",
+ "foo.rs", // this is the entry point
+ },
+ },
+ {
+ name: "rust_library with cc deps (dylib)",
+ moduleName: "libfizz_buzz_cc_deps",
+ variant: "android_arm64_armv8-a_dylib",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ {
+ name: "rust_library with cc deps (rlib rlib-std)",
+ moduleName: "libfizz_buzz_cc_deps",
+ variant: "android_arm64_armv8-a_rlib_rlib-std",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ {
+ name: "rust_library with cc deps (rlib dylib-std)",
+ moduleName: "libfizz_buzz_cc_deps",
+ variant: "android_arm64_armv8-a_rlib_dylib-std",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ {
+ name: "rust_library with transitive cc deps (dylib)",
+ moduleName: "libfizz_buzz_transitive_cc_deps",
+ variant: "android_arm64_armv8-a_dylib",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ {
+ name: "rust_library with transitive cc deps (rlib rlib-std)",
+ moduleName: "libfizz_buzz_transitive_cc_deps",
+ variant: "android_arm64_armv8-a_rlib_rlib-std",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ {
+ name: "rust_library with transitive cc deps (rlib dylib-std)",
+ moduleName: "libfizz_buzz_transitive_cc_deps",
+ variant: "android_arm64_armv8-a_rlib_dylib-std",
+ rustcExpectedFilesToCopy: []string{
+ "out/soong/.intermediates/cc_dep_static/android_arm64_armv8-a_static/cc_dep_static.a",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so",
+ "out/soong/.intermediates/cc_dep_shared/android_arm64_armv8-a_shared/cc_dep_shared.so.toc",
+ },
+ },
+ }
+
+ for _, tc := range testcases {
+ t.Run(tc.name, func(t *testing.T) {
+ writeFile := ctx.ModuleForTests(tc.moduleName, tc.variant).Rule("unescapedWriteFile")
+ contents := writeFile.BuildParams.Args["content"]
+ manifestProto := sbox_proto.Manifest{}
+ err := prototext.Unmarshal([]byte(contents), &manifestProto)
+ if err != nil {
+ t.Errorf("expected no errors unmarshaling manifest proto; got %v", err)
+ }
+
+ if len(manifestProto.Commands) != 1 {
+ t.Errorf("expected 1 command; got %v", len(manifestProto.Commands))
+ }
+
+ // check that sandbox contains correct files
+ rustc := manifestProto.Commands[0]
+ actualFilesToCopy := []string{}
+ for _, copy := range rustc.CopyBefore {
+ actualFilesToCopy = append(actualFilesToCopy, copy.GetFrom())
+ }
+ _, expectedFilesNotCopied, _ := android.ListSetDifference(tc.rustcExpectedFilesToCopy, actualFilesToCopy)
+ if len(expectedFilesNotCopied) > 0 {
+ t.Errorf("did not copy expected files to sbox: %v;\n files copied: %v", expectedFilesNotCopied, actualFilesToCopy)
+ }
+
+ rustcCmd := proptools.String(rustc.Command)
+ for _, flag := range tc.expectedFlags {
+ android.AssertStringDoesContain(
+ t,
+ fmt.Sprintf(
+ "missing flag in rustc invocation; expected to find substring %q; got %q",
+ flag,
+ rustcCmd,
+ ),
+ rustcCmd,
+ flag,
+ )
+ }
+ })
+ }
+}
diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go
index 43e95f4..d6a14b2 100644
--- a/rust/sanitize_test.go
+++ b/rust/sanitize_test.go
@@ -35,7 +35,7 @@
note_sync := "note_memtag_heap_sync"
found := None
- implicits := m.Rule("rustLink").Implicits
+ implicits := m.Rule("rustc").Implicits
for _, lib := range implicits {
if strings.Contains(lib.Rel(), note_async) {
found = Async
diff --git a/rust/testing.go b/rust/testing.go
index 3fe751e..9951937 100644
--- a/rust/testing.go
+++ b/rust/testing.go
@@ -52,6 +52,22 @@
func GatherRequiredDepsForTest() string {
bp := `
+ prebuilt_build_tool {
+ name: "rustc",
+ src: "linux-x86/1.69.0/bin/rustc",
+ deps: [
+ "linux-x86/1.69.0/lib/libstd.so",
+ "linux-x86/1.69.0/lib64/libc++.so.1",
+ ],
+ }
+ prebuilt_build_tool {
+ name: "clippy-driver",
+ src: "linux-x86/1.69.0/bin/clippy-driver",
+ }
+ prebuilt_build_tool {
+ name: "rustdoc",
+ src: "linux-x86/1.69.0/bin/rustdoc",
+ }
rust_prebuilt_library {
name: "libstd",
crate_name: "std",
@@ -63,6 +79,25 @@
},
host_supported: true,
sysroot: true,
+ rlibs: [
+ "libaddr2line",
+ "libadler",
+ "liballoc",
+ "libcfg_if",
+ "libcompiler_builtins",
+ "libcore",
+ "libgimli",
+ "libhashbrown",
+ "liblibc",
+ "libmemchr",
+ "libminiz_oxide",
+ "libobject",
+ "libpanic_unwind",
+ "librustc_demangle",
+ "librustc_std_workspace_alloc",
+ "librustc_std_workspace_core",
+ "libstd_detect",
+ ],
}
//////////////////////////////
// Device module requirements
@@ -99,6 +134,278 @@
nocrt: true,
system_shared_libs: [],
}
+ rust_library_rlib {
+ name: "libaddr2line",
+ crate_name: "addr2line",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libadler",
+ crate_name: "adler",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "liballoc",
+ crate_name: "alloc",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libcfg_if",
+ crate_name: "cfg_if",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libcompiler_builtins",
+ crate_name: "compiler_builtins",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libcore",
+ crate_name: "core",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libgimli",
+ crate_name: "gimli",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libhashbrown",
+ crate_name: "hashbrown",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "liblibc",
+ crate_name: "libc",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libmemchr",
+ crate_name: "memchr",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libminiz_oxide",
+ crate_name: "miniz_oxide",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libobject",
+ crate_name: "object",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libpanic_unwind",
+ crate_name: "panic_unwind",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "librustc_demangle",
+ crate_name: "rustc_demangle",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "librustc_std_workspace_alloc",
+ crate_name: "rustc_std_workspace_alloc",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "librustc_std_workspace_core",
+ crate_name: "rustc_std_workspace_core",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
+ rust_library_rlib {
+ name: "libstd_detect",
+ crate_name: "std_detect",
+ enabled:true,
+ srcs: ["foo.rs"],
+ no_stdlibs: true,
+ product_available: true,
+ host_supported: true,
+ vendor_available: true,
+ vendor_ramdisk_available: true,
+ recovery_available: true,
+ native_coverage: false,
+ sysroot: true,
+ apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
+ min_sdk_version: "29",
+ }
rust_library {
name: "libstd",
crate_name: "std",
@@ -113,6 +420,25 @@
sysroot: true,
apex_available: ["//apex_available:platform", "//apex_available:anyapex"],
min_sdk_version: "29",
+ rlibs: [
+ "libaddr2line",
+ "libadler",
+ "liballoc",
+ "libcfg_if",
+ "libcompiler_builtins",
+ "libcore",
+ "libgimli",
+ "libhashbrown",
+ "liblibc",
+ "libmemchr",
+ "libminiz_oxide",
+ "libobject",
+ "libpanic_unwind",
+ "librustc_demangle",
+ "librustc_std_workspace_alloc",
+ "librustc_std_workspace_core",
+ "libstd_detect",
+ ],
}
rust_library {
name: "libtest",
diff --git a/rust/toolchain_library.go b/rust/toolchain_library.go
index 326d529..cb345a4 100644
--- a/rust/toolchain_library.go
+++ b/rust/toolchain_library.go
@@ -18,9 +18,12 @@
import (
"path"
+ "path/filepath"
"android/soong/android"
"android/soong/rust/config"
+
+ "github.com/google/blueprint/proptools"
)
// This module is used to compile the rust toolchain libraries
@@ -33,11 +36,15 @@
rustToolchainLibraryRlibFactory)
android.RegisterModuleType("rust_toolchain_library_dylib",
rustToolchainLibraryDylibFactory)
+ android.RegisterModuleType("rust_toolchain_rustc_prebuilt",
+ rustToolchainRustcPrebuiltFactory)
}
type toolchainLibraryProperties struct {
- // path to the toolchain source, relative to the top of the toolchain source
- Toolchain_src *string `android:"arch_variant"`
+ // path to the toolchain crate root, relative to the top of the toolchain source
+ Toolchain_crate_root *string `android:"arch_variant"`
+ // path to the rest of the toolchain srcs, relative to the top of the toolchain source
+ Toolchain_srcs []string `android:"arch_variant"`
}
type toolchainLibraryDecorator struct {
@@ -82,16 +89,21 @@
func rustSetToolchainSource(ctx android.LoadHookContext) {
if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok {
- prefix := "linux-x86/" + GetRustPrebuiltVersion(ctx)
- newSrcs := []string{path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_src))}
+ prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), GetRustPrebuiltVersion(ctx))
+ versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root))
+ versionedSrcs := make([]string, len(toolchainLib.Properties.Toolchain_srcs))
+ for i, src := range toolchainLib.Properties.Toolchain_srcs {
+ versionedSrcs[i] = path.Join(prefix, src)
+ }
type props struct {
- Srcs []string
+ Crate_root *string
+ Srcs []string
}
p := &props{}
- p.Srcs = newSrcs
+ p.Crate_root = &versionedCrateRoot
+ p.Srcs = versionedSrcs
ctx.AppendProperties(p)
-
} else {
ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.")
}
@@ -101,3 +113,47 @@
func GetRustPrebuiltVersion(ctx android.LoadHookContext) string {
return ctx.AConfig().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion)
}
+
+type toolchainRustcPrebuiltProperties struct {
+ // path to rustc prebuilt, relative to the top of the toolchain source
+ Toolchain_prebuilt_src *string
+ // path to deps, relative to the top of the toolchain source
+ Toolchain_deps []string
+ // path to deps, relative to module directory
+ Deps []string
+}
+
+func rustToolchainRustcPrebuiltFactory() android.Module {
+ module := android.NewPrebuiltBuildTool()
+ module.AddProperties(&toolchainRustcPrebuiltProperties{})
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ var toolchainProps *toolchainRustcPrebuiltProperties
+ for _, p := range ctx.Module().GetProperties() {
+ toolchainProperties, ok := p.(*toolchainRustcPrebuiltProperties)
+ if ok {
+ toolchainProps = toolchainProperties
+ }
+ }
+
+ if toolchainProps.Toolchain_prebuilt_src == nil {
+ ctx.PropertyErrorf("toolchain_prebuilt_src", "must set path to rustc prebuilt")
+ }
+
+ prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), GetRustPrebuiltVersion(ctx))
+ deps := make([]string, 0, len(toolchainProps.Toolchain_deps)+len(toolchainProps.Deps))
+ for _, d := range toolchainProps.Toolchain_deps {
+ deps = append(deps, path.Join(prefix, d))
+ }
+ deps = append(deps, toolchainProps.Deps...)
+
+ props := struct {
+ Src *string
+ Deps []string
+ }{
+ Src: proptools.StringPtr(path.Join(prefix, *toolchainProps.Toolchain_prebuilt_src)),
+ Deps: deps,
+ }
+ ctx.AppendProperties(&props)
+ })
+ return module
+}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 1e7e7d3..621a724 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -1051,7 +1051,7 @@
ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
// libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
- libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"]
+ libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").RuleParams.Command
for _, input := range [][]string{
[]string{sharedVariant, "libvndk.vndk.30.arm64"},
[]string{staticVariant, "libvendor.vendor_static.30.arm64"},
@@ -1119,7 +1119,7 @@
t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName)
}
- binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"]
+ binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").RuleParams.Command
libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
diff --git a/scripts/check_prebuilt_presigned_apk.py b/scripts/check_prebuilt_presigned_apk.py
new file mode 100755
index 0000000..abedfb7
--- /dev/null
+++ b/scripts/check_prebuilt_presigned_apk.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python3
+
+import subprocess
+import argparse
+import re
+import sys
+import zipfile
+
+def check_target_sdk_less_than_30(args):
+ if not args.aapt2:
+ sys.exit('--aapt2 is required')
+ regex = re.compile(r"targetSdkVersion: *'([0-9]+)'")
+ output = subprocess.check_output([args.aapt2, "dump", "badging", args.apk], text=True)
+ targetSdkVersion = None
+ for line in output.splitlines():
+ match = regex.fullmatch(line.strip())
+ if match:
+ targetSdkVersion = int(match.group(1))
+ break
+
+ if targetSdkVersion is None or targetSdkVersion >= 30:
+ sys.exit(args.apk + ": Prebuilt, presigned apks with targetSdkVersion >= 30 (or a codename targetSdkVersion) must set preprocessed: true in the Android.bp definition (because they must be signed with signature v2, and the build system would wreck that signature otherwise)")
+
+def has_preprocessed_issues(args, *, fail=False):
+ if not args.zipalign:
+ sys.exit('--zipalign is required')
+ ret = subprocess.run([args.zipalign, '-c', '-p', '4', args.apk], stdout=subprocess.DEVNULL).returncode
+ if ret != 0:
+ if fail:
+ sys.exit(args.apk + ': Improper zip alignment')
+ return True
+
+ with zipfile.ZipFile(args.apk) as zf:
+ for info in zf.infolist():
+ if info.filename.startswith('lib/') and info.filename.endswith('.so') and info.compress_type != zipfile.ZIP_STORED:
+ if fail:
+ sys.exit(args.apk + ': Contains compressed JNI libraries')
+ return True
+ # It's ok for non-privileged apps to have compressed dex files, see go/gms-uncompressed-jni-slides
+ if args.privileged:
+ if info.filename.endswith('.dex') and info.compress_type != zipfile.ZIP_STORED:
+ if fail:
+ sys.exit(args.apk + ': Contains compressed dex files and is privileged')
+ return True
+ return False
+
+
+def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--aapt2', help = "the path to the aapt2 executable")
+ parser.add_argument('--zipalign', help = "the path to the zipalign executable")
+ parser.add_argument('--skip-preprocessed-apk-checks', action = 'store_true', help = "the value of the soong property with the same name")
+ parser.add_argument('--preprocessed', action = 'store_true', help = "the value of the soong property with the same name")
+ parser.add_argument('--privileged', action = 'store_true', help = "the value of the soong property with the same name")
+ parser.add_argument('apk', help = "the apk to check")
+ parser.add_argument('stampfile', help = "a file to touch if successful")
+ args = parser.parse_args()
+
+ if not args.preprocessed:
+ check_target_sdk_less_than_30(args)
+ elif args.skip_preprocessed_apk_checks:
+ if not has_preprocessed_issues(args):
+ sys.exit('This module sets `skip_preprocessed_apk_checks: true`, but does not actually have any issues. Please remove `skip_preprocessed_apk_checks`.')
+ else:
+ has_preprocessed_issues(args, fail=True)
+
+ subprocess.check_call(["touch", args.stampfile])
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index 3ac1b7e..c6aa3d0 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -120,6 +120,37 @@
f.write(pb.SerializeToString())
+def Validate(args):
+ if os.path.isdir(args.input):
+ config_file = os.path.join(args.input, 'etc/linker.config.pb')
+ if os.path.exists(config_file):
+ args.input = config_file
+ Validate(args)
+ # OK if there's no linker config file.
+ return
+
+ if not os.path.isfile(args.input):
+ sys.exit(f"{args.input} is not a file")
+
+ pb = linker_config_pb2.LinkerConfig()
+ with open(args.input, 'rb') as f:
+ pb.ParseFromString(f.read())
+
+ if args.type == 'apex':
+ # Shouldn't use provideLibs/requireLibs in APEX linker.config.pb
+ if getattr(pb, 'provideLibs'):
+ sys.exit(f'{args.input}: provideLibs is set. Use provideSharedLibs in apex_manifest')
+ if getattr(pb, 'requireLibs'):
+ sys.exit(f'{args.input}: requireLibs is set. Use requireSharedLibs in apex_manifest')
+ elif args.type == 'system':
+ if getattr(pb, 'visible'):
+ sys.exit(f'{args.input}: do not use visible, which is for APEX')
+ if getattr(pb, 'permittedPaths'):
+ sys.exit(f'{args.input}: do not use permittedPaths, which is for APEX')
+ else:
+ sys.exit(f'Unknown type: {args.type}')
+
+
def GetArgParser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
@@ -227,6 +258,18 @@
help='Linker configuration files to merge.')
append.set_defaults(func=Merge)
+ validate = subparsers.add_parser('validate', help='Validate configuration')
+ validate.add_argument(
+ '--type',
+ required=True,
+ choices=['apex', 'system'],
+ help='Type of linker configuration')
+ validate.add_argument(
+ 'input',
+ help='Input can be a directory which has etc/linker.config.pb or a path'
+ ' to the linker config file')
+ validate.set_defaults(func=Validate)
+
return parser
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/sh_binary.go b/sh/sh_binary.go
index 00794cd..79a885f 100644
--- a/sh/sh_binary.go
+++ b/sh/sh_binary.go
@@ -190,6 +190,15 @@
return s.outputFilePath
}
+func (s *ShBinary) OutputFiles(tag string) (android.Paths, error) {
+ switch tag {
+ case "":
+ return android.Paths{s.outputFilePath}, nil
+ default:
+ return nil, fmt.Errorf("unsupported module reference tag %q", tag)
+ }
+}
+
func (s *ShBinary) SubDir() string {
return proptools.String(s.properties.Sub_dir)
}
@@ -574,7 +583,7 @@
Auto_gen_config *bool
}
-func (m *ShBinary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *ShBinary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
srcs := bazel.MakeLabelListAttribute(
android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
@@ -602,7 +611,7 @@
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
-func (m *ShTest) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *ShTest) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
srcs := bazel.MakeLabelListAttribute(
android.BazelLabelForModuleSrc(ctx, []string{*m.properties.Src}))
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index a2c0fb7..d16bf32 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -591,7 +591,7 @@
}
// TODO(b/240463568): Additional properties will be added for API validation
-func (m *syspropLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+func (m *syspropLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
labels := cc.SyspropLibraryLabels{
SyspropLibraryLabel: m.BaseModuleName(),
SharedLibraryLabel: m.CcImplementationModuleName(),
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 9de9b97..73fbeab 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -47,13 +47,10 @@
}
function diff_files {
- file_list_file="$1"; shift
- files_in_spdx_file="$1"; shift
- partition_name="$1"; shift
- exclude=
- if [ -v 'diff_excludes[$partition_name]' ]; then
- exclude=${diff_excludes[$partition_name]}
- fi
+ local file_list_file="$1"; shift
+ local files_in_spdx_file="$1"; shift
+ local partition_name="$1"; shift
+ local exclude="$1"; shift
diff "$file_list_file" "$files_in_spdx_file" $exclude
if [ $? != "0" ]; then
@@ -84,9 +81,6 @@
dump_erofs=$out_dir/host/linux-x86/bin/dump.erofs
lz4=$out_dir/host/linux-x86/bin/lz4
- declare -A diff_excludes
- 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.
# Each line is captured in variable "entry", awk is used to get type and name.
@@ -158,7 +152,7 @@
sort -n -o "$files_in_spdx_file" "$files_in_spdx_file"
echo ============ Diffing files in $f and SBOM
- diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name"
+ diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" ""
done
RAMDISK_IMAGES="$product_out/ramdisk.img"
@@ -176,7 +170,7 @@
grep "FileName: /${partition_name}/" $product_out/sbom.spdx | sed 's/^FileName: //' | sort -n > "$files_in_spdx_file"
echo ============ Diffing files in $f and SBOM
- diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name"
+ diff_files "$file_list_file" "$files_in_spdx_file" "$partition_name" ""
done
verify_package_verification_code "$product_out/sbom.spdx"
diff --git a/tradefed/autogen_bazel.go b/tradefed/autogen_bazel.go
index 8283984..cc16176 100644
--- a/tradefed/autogen_bazel.go
+++ b/tradefed/autogen_bazel.go
@@ -49,7 +49,7 @@
}
func GetTestConfigAttributes(
- ctx android.TopDownMutatorContext,
+ ctx android.Bp2buildMutatorContext,
testConfig *string,
extraTestConfigs []string,
autoGenConfig *bool,
@@ -93,7 +93,7 @@
}
func GetTestConfig(
- ctx android.TopDownMutatorContext,
+ ctx android.Bp2buildMutatorContext,
testConfig *string,
) *bazel.Label {
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/ninja.go b/ui/build/ninja.go
index 61aaad8..b69e938 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -194,6 +194,10 @@
// LLVM compiler wrapper options
"TOOLCHAIN_RUSAGE_OUTPUT",
+
+ // We don't want this build broken flag to cause reanalysis, so allow it through to the
+ // actions.
+ "BUILD_BROKEN_INCORRECT_PARTITION_IMAGES",
}, config.BuildBrokenNinjaUsesEnvVars()...)...)
}
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/xml/xml.go b/xml/xml.go
index 8c0c072..65fe12a 100644
--- a/xml/xml.go
+++ b/xml/xml.go
@@ -145,8 +145,12 @@
Schema *string
}
-func (p *prebuiltEtcXml) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
- baseAttrs := p.PrebuiltEtc.Bp2buildHelper(ctx)
+func (p *prebuiltEtcXml) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ baseAttrs, convertible := p.PrebuiltEtc.Bp2buildHelper(ctx)
+
+ if !convertible {
+ return
+ }
var schema *string
if p.properties.Schema != nil {
diff --git a/zip/cmd/main.go b/zip/cmd/main.go
index 5231fae..37537ab 100644
--- a/zip/cmd/main.go
+++ b/zip/cmd/main.go
@@ -174,6 +174,7 @@
traceFile := flags.String("trace", "", "write trace to file")
sha256Checksum := flags.Bool("sha256", false, "add a zip header to each file containing its SHA256 digest")
doNotWrite := flags.Bool("n", false, "Nothing is written to disk -- all other work happens")
+ quiet := flags.Bool("quiet", false, "do not print warnings to console")
flags.Var(&rootPrefix{}, "P", "path prefix within the zip at which to place files")
flags.Var(&listFiles{}, "l", "file containing list of files to zip")
@@ -238,6 +239,7 @@
IgnoreMissingFiles: *ignoreMissingFiles,
Sha256Checksum: *sha256Checksum,
DoNotWrite: *doNotWrite,
+ Quiet: *quiet,
})
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err.Error())
diff --git a/zip/zip.go b/zip/zip.go
index 30a2ee7..f91a5f2 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -283,6 +283,7 @@
IgnoreMissingFiles bool
Sha256Checksum bool
DoNotWrite bool
+ Quiet bool
Stderr io.Writer
Filesystem pathtools.FileSystem
@@ -340,7 +341,9 @@
Err: os.ErrNotExist,
}
if args.IgnoreMissingFiles {
- fmt.Fprintln(z.stderr, "warning:", err)
+ if !args.Quiet {
+ fmt.Fprintln(z.stderr, "warning:", err)
+ }
} else {
return err
}
@@ -357,7 +360,9 @@
Err: os.ErrNotExist,
}
if args.IgnoreMissingFiles {
- fmt.Fprintln(z.stderr, "warning:", err)
+ if !args.Quiet {
+ fmt.Fprintln(z.stderr, "warning:", err)
+ }
} else {
return err
}
@@ -368,7 +373,9 @@
Err: syscall.ENOTDIR,
}
if args.IgnoreMissingFiles {
- fmt.Fprintln(z.stderr, "warning:", err)
+ if !args.Quiet {
+ fmt.Fprintln(z.stderr, "warning:", err)
+ }
} else {
return err
}