Merge "Add overrides support for snapshots"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 9bba3c3..4ab94c3 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -180,8 +180,10 @@
"frameworks/base/tools/aapt2": Bp2BuildDefaultTrue,
"frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/libs/gui": Bp2BuildDefaultTrue,
"frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively,
"frameworks/native/libs/nativebase": Bp2BuildDefaultTrueRecursively,
+ "frameworks/native/libs/vr": Bp2BuildDefaultTrueRecursively,
"frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue,
"frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue,
"frameworks/native/opengl/tests/testLatency": Bp2BuildDefaultTrue,
@@ -397,14 +399,11 @@
"libbinder_headers_platform_shared",
"libbinderthreadstateutils",
"libbluetooth-types-header",
- "libbufferhub_headers",
"libcodec2",
"libcodec2_headers",
"libcodec2_internal",
"libdmabufheap",
- "libdvr_headers",
"libgsm",
- "libgui_bufferqueue_sources",
"libgrallocusage",
"libgralloctypes",
"libnativewindow",
@@ -417,7 +416,6 @@
"libneuralnetworks_headers",
"libneuralnetworks_packageinfo",
"libopus",
- "libpdx_headers",
"libprocpartition",
"libruy_static",
"libandroidio",
@@ -443,7 +441,6 @@
"libtextclassifier_hash_static",
"libtflite_kernel_utils",
"libtinyxml2",
- "libgui_aidl",
"libui",
"libui-types",
"libui_headers",
@@ -470,7 +467,6 @@
"statslog_neuralnetworks.h",
"tensorflow_headers",
- "libgui_headers",
"libstagefright_bufferpool@2.0",
"libstagefright_bufferpool@2.0.1",
"libSurfaceFlingerProp",
@@ -584,7 +580,6 @@
"libcodec2_hidl_plugin_stub",
"libcodec2_hidl_plugin",
"libstagefright_bufferqueue_helper_novndk",
- "libgui_bufferqueue_static",
"libGLESv2",
"libEGL",
"libcodec2_vndk",
@@ -634,13 +629,10 @@
Bp2buildModuleTypeAlwaysConvertList = []string{
"aidl_interface_headers",
- "api_domain",
"license",
"linker_config",
"java_import",
"java_import_host",
- "ndk_headers",
- "ndk_library",
"sysprop_library",
"bpf",
}
@@ -653,6 +645,23 @@
// the "prebuilt_" prefix to the name, so that it's differentiable from
// the source versions within Soong's module graph.
Bp2buildModuleDoNotConvertList = []string{
+ // TODO(b/250876486): Created cc_aidl_library doesn't have static libs from parent cc module
+ "libgui_window_info_static",
+ "libgui", // Depends on unconverted libgui_window_info_static
+ "libdisplay", // Depends on uncovnerted libgui
+ // Depends on unconverted libdisplay
+ "libdvr_static.google",
+ "libdvr.google",
+ "libvrsensor",
+ "dvr_api-test",
+ // Depends on unconverted libandroid, libgui
+ "dvr_buffer_queue-test",
+ "dvr_display-test",
+ // Depends on unconverted libchrome
+ "pdx_benchmarks",
+ "buffer_hub_queue-test",
+ "buffer_hub_queue_producer-test",
+
// cc bugs
"libactivitymanager_aidl", // TODO(b/207426160): Unsupported use of aidl sources (via Dactivity_manager_procstate_aidl) in a cc_library
@@ -935,6 +944,7 @@
"libdlext_test_norelro",
"libdlext_test_recursive",
"libdlext_test_zip",
+ "libdvrcommon_test",
"libfortify1-new-tests-clang",
"libfortify1-new-tests-clang",
"libfortify1-tests-clang",
diff --git a/android/android_test.go b/android/android_test.go
index fb82e37..64ceedc 100644
--- a/android/android_test.go
+++ b/android/android_test.go
@@ -15,10 +15,32 @@
package android
import (
+ "io/ioutil"
"os"
"testing"
)
+var buildDir string
+
+func setUp() {
+ var err error
+ buildDir, err = ioutil.TempDir("", "android_test")
+ if err != nil {
+ panic(err)
+ }
+}
+
+func tearDown() {
+ os.RemoveAll(buildDir)
+}
+
func TestMain(m *testing.M) {
- os.Exit(m.Run())
+ run := func() int {
+ setUp()
+ defer tearDown()
+
+ return m.Run()
+ }
+
+ os.Exit(run())
}
diff --git a/android/api_domain.go b/android/api_domain.go
index 8ff4752..7876654 100644
--- a/android/api_domain.go
+++ b/android/api_domain.go
@@ -67,7 +67,6 @@
m := &apiDomain{}
m.AddProperties(&m.properties)
InitAndroidArchModule(m, DeviceSupported, MultilibBoth)
- InitBazelModule(m)
return m
}
@@ -108,7 +107,9 @@
Cc_api_contributions bazel.LabelListAttribute
}
-func (a *apiDomain) ConvertWithBp2build(ctx TopDownMutatorContext) {
+var _ ApiProvider = (*apiDomain)(nil)
+
+func (a *apiDomain) ConvertWithApiBp2build(ctx TopDownMutatorContext) {
props := bazel.BazelTargetModuleProperties{
Rule_class: "api_domain",
Bzl_load_location: "//build/bazel/rules/apis:api_domain.bzl",
diff --git a/android/bazel.go b/android/bazel.go
index dd1de7b..7b227bd 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -134,6 +134,11 @@
SetBaseModuleType(baseModuleType string)
}
+// ApiProvider is implemented by modules that contribute to an API surface
+type ApiProvider interface {
+ ConvertWithApiBp2build(ctx TopDownMutatorContext)
+}
+
// MixedBuildBuildable is an interface that module types should implement in order
// to be "handled by Bazel" in a mixed build.
type MixedBuildBuildable interface {
@@ -415,6 +420,13 @@
return false
}
+ // 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 := ctx.OtherModuleDir(module)
@@ -510,6 +522,17 @@
bModule.ConvertWithBp2build(ctx)
}
+func registerApiBp2buildConversionMutator(ctx RegisterMutatorsContext) {
+ ctx.TopDown("apiBp2build_conversion", convertWithApiBp2build).Parallel()
+}
+
+// Generate API contribution targets if the Soong module provides APIs
+func convertWithApiBp2build(ctx TopDownMutatorContext) {
+ if m, ok := ctx.Module().(ApiProvider); ok {
+ m.ConvertWithApiBp2build(ctx)
+ }
+}
+
// GetMainClassInManifest scans the manifest file specified in filepath and returns
// the value of attribute Main-Class in the manifest file if it exists, or returns error.
// WARNING: this is for bp2build converters of java_* modules only.
diff --git a/android/config.go b/android/config.go
index ee432a2..e86fc27 100644
--- a/android/config.go
+++ b/android/config.go
@@ -83,6 +83,9 @@
// 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
diff --git a/android/module.go b/android/module.go
index a150e61..68d9f8e 100644
--- a/android/module.go
+++ b/android/module.go
@@ -3546,10 +3546,29 @@
reportPathError(ctx, err)
return nil
}
+ if len(paths) == 0 {
+ type addMissingDependenciesIntf interface {
+ AddMissingDependencies([]string)
+ OtherModuleName(blueprint.Module) string
+ }
+ if mctx, ok := ctx.(addMissingDependenciesIntf); ok && ctx.Config().AllowMissingDependencies() {
+ mctx.AddMissingDependencies([]string{mctx.OtherModuleName(module)})
+ } else {
+ ReportPathErrorf(ctx, "failed to get output files from module %q", pathContextName(ctx, module))
+ }
+ // Return a fake output file to avoid nil dereferences of Path objects later.
+ // This should never get used for an actual build as the error or missing
+ // dependency has already been reported.
+ p, err := pathForSource(ctx, filepath.Join("missing_output_file", pathContextName(ctx, module)))
+ if err != nil {
+ reportPathError(ctx, err)
+ return nil
+ }
+ return p
+ }
if len(paths) > 1 {
ReportPathErrorf(ctx, "got multiple output files from module %q, expected exactly one",
pathContextName(ctx, module))
- return nil
}
return paths[0]
}
@@ -3561,18 +3580,12 @@
return nil, fmt.Errorf("failed to get output file from module %q: %s",
pathContextName(ctx, module), err.Error())
}
- if len(paths) == 0 {
- return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
- }
return paths, nil
} else if sourceFileProducer, ok := module.(SourceFileProducer); ok {
if tag != "" {
return nil, fmt.Errorf("module %q is a SourceFileProducer, not an OutputFileProducer, and so does not support tag %q", pathContextName(ctx, module), tag)
}
paths := sourceFileProducer.Srcs()
- if len(paths) == 0 {
- return nil, fmt.Errorf("failed to get output files from module %q", pathContextName(ctx, module))
- }
return paths, nil
} else {
return nil, fmt.Errorf("module %q is not an OutputFileProducer", pathContextName(ctx, module))
diff --git a/android/module_test.go b/android/module_test.go
index 0580bef..1ca7422 100644
--- a/android/module_test.go
+++ b/android/module_test.go
@@ -15,6 +15,7 @@
package android
import (
+ "github.com/google/blueprint"
"path/filepath"
"runtime"
"testing"
@@ -978,3 +979,88 @@
})
}
}
+
+type fakeBlueprintModule struct{}
+
+func (fakeBlueprintModule) Name() string { return "foo" }
+
+func (fakeBlueprintModule) GenerateBuildActions(blueprint.ModuleContext) {}
+
+type sourceProducerTestModule struct {
+ fakeBlueprintModule
+ source Path
+}
+
+func (s sourceProducerTestModule) Srcs() Paths { return Paths{s.source} }
+
+type outputFileProducerTestModule struct {
+ fakeBlueprintModule
+ output map[string]Path
+ error map[string]error
+}
+
+func (o outputFileProducerTestModule) OutputFiles(tag string) (Paths, error) {
+ return PathsIfNonNil(o.output[tag]), o.error[tag]
+}
+
+type pathContextAddMissingDependenciesWrapper struct {
+ PathContext
+ missingDeps []string
+}
+
+func (p *pathContextAddMissingDependenciesWrapper) AddMissingDependencies(deps []string) {
+ p.missingDeps = append(p.missingDeps, deps...)
+}
+func (p *pathContextAddMissingDependenciesWrapper) OtherModuleName(module blueprint.Module) string {
+ return module.Name()
+}
+
+func TestOutputFileForModule(t *testing.T) {
+ testcases := []struct {
+ name string
+ module blueprint.Module
+ tag string
+ env map[string]string
+ config func(*config)
+ expected string
+ missingDeps []string
+ }{
+ {
+ name: "SourceFileProducer",
+ module: &sourceProducerTestModule{source: PathForTesting("foo.txt")},
+ expected: "foo.txt",
+ },
+ {
+ name: "OutputFileProducer",
+ module: &outputFileProducerTestModule{output: map[string]Path{"": PathForTesting("foo.txt")}},
+ expected: "foo.txt",
+ },
+ {
+ name: "OutputFileProducer_tag",
+ module: &outputFileProducerTestModule{output: map[string]Path{"foo": PathForTesting("foo.txt")}},
+ tag: "foo",
+ expected: "foo.txt",
+ },
+ {
+ name: "OutputFileProducer_AllowMissingDependencies",
+ config: func(config *config) {
+ config.TestProductVariables.Allow_missing_dependencies = boolPtr(true)
+ },
+ module: &outputFileProducerTestModule{},
+ missingDeps: []string{"foo"},
+ expected: "missing_output_file/foo",
+ },
+ }
+ for _, tt := range testcases {
+ config := TestConfig(buildDir, tt.env, "", nil)
+ if tt.config != nil {
+ tt.config(config.config)
+ }
+ ctx := &pathContextAddMissingDependenciesWrapper{
+ PathContext: PathContextForTesting(config),
+ }
+ got := OutputFileForModule(ctx, tt.module, tt.tag)
+ AssertPathRelativeToTopEquals(t, "expected source path", tt.expected, got)
+ AssertArrayString(t, "expected missing deps", tt.missingDeps, ctx.missingDeps)
+ }
+}
diff --git a/android/mutator.go b/android/mutator.go
index 9e4aa59..83d4e66 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -31,22 +31,33 @@
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
+ bp2buildMutators := append(preArchMutators, registerBp2buildConversionMutator)
+ registerMutatorsForBazelConversion(ctx, bp2buildMutators)
+}
+
+// RegisterMutatorsForApiBazelConversion is an alternate registration pipeline for api_bp2build
+// This pipeline restricts generation of Bazel targets to Soong modules that contribute APIs
+func RegisterMutatorsForApiBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
+ bp2buildMutators := append(preArchMutators, registerApiBp2buildConversionMutator)
+ registerMutatorsForBazelConversion(ctx, bp2buildMutators)
+}
+
+func registerMutatorsForBazelConversion(ctx *Context, bp2buildMutators []RegisterMutatorFunc) {
mctx := ®isterMutatorsContext{
bazelConversionMode: true,
}
- bp2buildMutators := append([]RegisterMutatorFunc{
+ allMutators := append([]RegisterMutatorFunc{
RegisterNamespaceMutator,
RegisterDefaultsPreArchMutators,
// TODO(b/165114590): this is required to resolve deps that are only prebuilts, but we should
// evaluate the impact on conversion.
RegisterPrebuiltsPreArchMutators,
},
- preArchMutators...)
- bp2buildMutators = append(bp2buildMutators, registerBp2buildConversionMutator)
+ bp2buildMutators...)
// Register bp2build mutators
- for _, f := range bp2buildMutators {
+ for _, f := range allMutators {
f(mctx)
}
diff --git a/android/paths.go b/android/paths.go
index 27f4bf5..dbcdb23 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1638,6 +1638,10 @@
}
}
+func (p InstallPath) Partition() string {
+ return p.partition
+}
+
// Join creates a new InstallPath with paths... joined with the current path. The
// provided paths... may not use '..' to escape from the current path.
func (p InstallPath) Join(ctx PathContext, paths ...string) InstallPath {
diff --git a/android/register.go b/android/register.go
index d4ce5f1..6c69cc5 100644
--- a/android/register.go
+++ b/android/register.go
@@ -180,6 +180,16 @@
RegisterMutatorsForBazelConversion(ctx, bp2buildPreArchMutators)
}
+// RegisterForApiBazelConversion is similar to RegisterForBazelConversion except that
+// it only generates API targets in the generated workspace
+func (ctx *Context) RegisterForApiBazelConversion() {
+ for _, t := range moduleTypes {
+ t.register(ctx)
+ }
+
+ RegisterMutatorsForApiBazelConversion(ctx, bp2buildPreArchMutators)
+}
+
// Register the pipeline of singletons, module types, and mutators for
// generating build.ninja and other files for Kati, from Android.bp files.
func (ctx *Context) Register() {
diff --git a/android/testing.go b/android/testing.go
index 7b74c89..4018659 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -461,6 +461,12 @@
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/apex/apex.go b/apex/apex.go
index 2e54e7e..4247db4 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -286,6 +286,9 @@
Arm64 struct {
ApexNativeDependencies
}
+ Riscv64 struct {
+ ApexNativeDependencies
+ }
X86 struct {
ApexNativeDependencies
}
@@ -787,6 +790,8 @@
depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
case android.Arm64:
depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
+ case android.Riscv64:
+ depsList = append(depsList, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
case android.X86:
depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
case android.X86_64:
@@ -1559,7 +1564,7 @@
dirInApex = filepath.Join(dirInApex, "bionic")
}
- fileToCopy := ccMod.OutputFile().Path()
+ fileToCopy := android.OutputFileForModule(ctx, ccMod, "")
androidMkModuleName := ccMod.BaseModuleName() + ccMod.Properties.SubName
return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, ccMod)
}
@@ -1570,7 +1575,7 @@
dirInApex = filepath.Join(dirInApex, cc.Target().NativeBridgeRelativePath)
}
dirInApex = filepath.Join(dirInApex, cc.RelativeInstallPath())
- fileToCopy := cc.OutputFile().Path()
+ fileToCopy := android.OutputFileForModule(ctx, cc, "")
androidMkModuleName := cc.BaseModuleName() + cc.Properties.SubName
af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, cc)
af.symlinks = cc.Symlinks()
@@ -1583,7 +1588,7 @@
if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
}
- fileToCopy := rustm.OutputFile().Path()
+ fileToCopy := android.OutputFileForModule(ctx, rustm, "")
androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
af := newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeExecutable, rustm)
return af
@@ -1602,7 +1607,7 @@
if rustm.Target().NativeBridge == android.NativeBridgeEnabled {
dirInApex = filepath.Join(dirInApex, rustm.Target().NativeBridgeRelativePath)
}
- fileToCopy := rustm.OutputFile().Path()
+ fileToCopy := android.OutputFileForModule(ctx, rustm, "")
androidMkModuleName := rustm.BaseModuleName() + rustm.Properties.SubName
return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm)
}
@@ -2659,9 +2664,13 @@
}
// Certificate
- if overridableProperties.Certificate != nil {
- attrs.Certificate = bazel.LabelAttribute{}
- attrs.Certificate.SetValue(android.BazelLabelForModuleDepSingle(ctx, *overridableProperties.Certificate))
+ if overridableProperties.Certificate == nil {
+ // delegated to the rule attr default
+ attrs.Certificate = nil
+ } else {
+ certificateName, certificate := java.ParseCertificateToAttribute(ctx, overridableProperties.Certificate)
+ attrs.Certificate_name = certificateName
+ attrs.Certificate = certificate
}
// Prebuilts
@@ -2726,16 +2735,23 @@
// 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.
- overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
- overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
- originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
- isMinSdkSet := a.properties.Min_sdk_version != nil
- isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0
- if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher {
- return overrideMinSdkValue
+ minApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
+ if minApiLevel.IsNone() {
+ return ""
}
- return proptools.String(a.properties.Min_sdk_version)
+ archMinApiLevel := cc.MinApiForArch(ctx, a.MultiTargets()[0].Arch.ArchType)
+ if !archMinApiLevel.IsNone() && archMinApiLevel.CompareTo(minApiLevel) > 0 {
+ minApiLevel = archMinApiLevel
+ }
+
+ overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
+ overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
+ if !overrideApiLevel.IsNone() && overrideApiLevel.CompareTo(minApiLevel) > 0 {
+ minApiLevel = overrideApiLevel
+ }
+
+ return minApiLevel.String()
}
// Returns apex's min_sdk_version SdkSpec, honoring overrides
@@ -3335,7 +3351,8 @@
Android_manifest bazel.LabelAttribute
File_contexts bazel.LabelAttribute
Key bazel.LabelAttribute
- Certificate bazel.LabelAttribute
+ Certificate *bazel.Label // used when the certificate prop is a module
+ Certificate_name *string // used when the certificate prop is a string
Min_sdk_version *string
Updatable bazel.BoolAttribute
Installable bazel.BoolAttribute
@@ -3397,10 +3414,7 @@
keyLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Key))
}
- var certificateLabelAttribute bazel.LabelAttribute
- if a.overridableProperties.Certificate != nil {
- certificateLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.overridableProperties.Certificate))
- }
+ certificateName, certificate := java.ParseCertificateToAttribute(ctx, a.overridableProperties.Certificate)
nativeSharedLibs := &convertedNativeSharedLibs{
Native_shared_libs_32: bazel.LabelListAttribute{},
@@ -3456,7 +3470,8 @@
File_contexts: fileContextsLabelAttribute,
Min_sdk_version: minSdkVersion,
Key: keyLabelAttribute,
- Certificate: certificateLabelAttribute,
+ Certificate: certificate,
+ Certificate_name: certificateName,
Updatable: updatableAttribute,
Installable: installableAttribute,
Native_shared_libs_32: nativeSharedLibs.Native_shared_libs_32,
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 25ae5bf..0f57911 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -537,7 +537,11 @@
}
if src == "" {
- ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String())
+ if ctx.Config().AllowMissingDependencies() {
+ ctx.AddMissingDependencies([]string{ctx.OtherModuleName(prebuilt)})
+ } else {
+ ctx.OtherModuleErrorf(prebuilt, "prebuilt_apex does not support %q", multiTargets[0].Arch.String())
+ }
// Drop through to return an empty string as the src (instead of nil) to avoid the prebuilt
// logic from reporting a more general, less useful message.
}
diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go
index b0a2966..233fce4 100644
--- a/bp2build/apex_conversion_test.go
+++ b/bp2build/apex_conversion_test.go
@@ -120,7 +120,7 @@
file_contexts: ":com.android.apogee-file_contexts",
min_sdk_version: "29",
key: "com.android.apogee.key",
- certificate: "com.android.apogee.certificate",
+ certificate: ":com.android.apogee.certificate",
updatable: false,
installable: false,
compressible: false,
@@ -582,7 +582,7 @@
file_contexts: ":com.android.apogee-file_contexts",
min_sdk_version: "29",
key: "com.android.apogee.key",
- certificate: "com.android.apogee.certificate",
+ certificate: ":com.android.apogee.certificate",
updatable: false,
installable: false,
compressible: false,
@@ -618,7 +618,7 @@
name: "com.google.android.apogee",
base: ":com.android.apogee",
key: "com.google.android.apogee.key",
- certificate: "com.google.android.apogee.certificate",
+ certificate: ":com.google.android.apogee.certificate",
prebuilts: [],
compressible: true,
}
@@ -1016,3 +1016,193 @@
}),
}})
}
+
+func TestBp2BuildOverrideApex_CertificateNil(t *testing.T) {
+ runOverrideApexTestCase(t, Bp2buildTestCase{
+ Description: "override_apex - don't set default certificate",
+ ModuleTypeUnderTest: "override_apex",
+ ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ Filesystem: map[string]string{},
+ Blueprint: `
+android_app_certificate {
+ name: "com.android.apogee.certificate",
+ certificate: "com.android.apogee",
+ bazel_module: { bp2build_available: false },
+}
+
+filegroup {
+ name: "com.android.apogee-file_contexts",
+ srcs: [
+ "com.android.apogee-file_contexts",
+ ],
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+ file_contexts: ":com.android.apogee-file_contexts",
+ certificate: ":com.android.apogee.certificate",
+ bazel_module: { bp2build_available: false },
+}
+
+override_apex {
+ name: "com.google.android.apogee",
+ base: ":com.android.apogee",
+ // certificate is deliberately omitted, and not converted to bazel,
+ // because the overridden apex shouldn't be using the base apex's cert.
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+ "file_contexts": `":com.android.apogee-file_contexts"`,
+ "manifest": `"apogee_manifest.json"`,
+ }),
+ }})
+}
+
+func TestApexCertificateIsModule(t *testing.T) {
+ runApexTestCase(t, Bp2buildTestCase{
+ Description: "apex - certificate is module",
+ ModuleTypeUnderTest: "apex",
+ ModuleTypeUnderTestFactory: apex.BundleFactory,
+ Filesystem: map[string]string{},
+ Blueprint: `
+android_app_certificate {
+ name: "com.android.apogee.certificate",
+ certificate: "com.android.apogee",
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+ file_contexts: ":com.android.apogee-file_contexts",
+ certificate: ":com.android.apogee.certificate",
+}
+` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"),
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+ "certificate": `":com.android.apogee.certificate"`,
+ "file_contexts": `":com.android.apogee-file_contexts"`,
+ "manifest": `"apogee_manifest.json"`,
+ }),
+ }})
+}
+
+func TestApexCertificateIsSrc(t *testing.T) {
+ runApexTestCase(t, Bp2buildTestCase{
+ Description: "apex - certificate is src",
+ ModuleTypeUnderTest: "apex",
+ ModuleTypeUnderTestFactory: apex.BundleFactory,
+ Filesystem: map[string]string{},
+ Blueprint: `
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+ file_contexts: ":com.android.apogee-file_contexts",
+ certificate: "com.android.apogee.certificate",
+}
+` + simpleModuleDoNotConvertBp2build("filegroup", "com.android.apogee-file_contexts"),
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("apex", "com.android.apogee", AttrNameToString{
+ "certificate_name": `"com.android.apogee.certificate"`,
+ "file_contexts": `":com.android.apogee-file_contexts"`,
+ "manifest": `"apogee_manifest.json"`,
+ }),
+ }})
+}
+
+func TestBp2BuildOverrideApex_CertificateIsModule(t *testing.T) {
+ runOverrideApexTestCase(t, Bp2buildTestCase{
+ Description: "override_apex - certificate is module",
+ ModuleTypeUnderTest: "override_apex",
+ ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ Filesystem: map[string]string{},
+ Blueprint: `
+android_app_certificate {
+ name: "com.android.apogee.certificate",
+ certificate: "com.android.apogee",
+ bazel_module: { bp2build_available: false },
+}
+
+filegroup {
+ name: "com.android.apogee-file_contexts",
+ srcs: [
+ "com.android.apogee-file_contexts",
+ ],
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ 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 {
+ name: "com.google.android.apogee",
+ base: ":com.android.apogee",
+ certificate: ":com.google.android.apogee.certificate",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+ "file_contexts": `":com.android.apogee-file_contexts"`,
+ "certificate": `":com.google.android.apogee.certificate"`,
+ "manifest": `"apogee_manifest.json"`,
+ }),
+ }})
+}
+
+func TestBp2BuildOverrideApex_CertificateIsSrc(t *testing.T) {
+ runOverrideApexTestCase(t, Bp2buildTestCase{
+ Description: "override_apex - certificate is src",
+ ModuleTypeUnderTest: "override_apex",
+ ModuleTypeUnderTestFactory: apex.OverrideApexFactory,
+ Filesystem: map[string]string{},
+ Blueprint: `
+android_app_certificate {
+ name: "com.android.apogee.certificate",
+ certificate: "com.android.apogee",
+ bazel_module: { bp2build_available: false },
+}
+
+filegroup {
+ name: "com.android.apogee-file_contexts",
+ srcs: [
+ "com.android.apogee-file_contexts",
+ ],
+ bazel_module: { bp2build_available: false },
+}
+
+apex {
+ name: "com.android.apogee",
+ manifest: "apogee_manifest.json",
+ file_contexts: ":com.android.apogee-file_contexts",
+ certificate: ":com.android.apogee.certificate",
+ bazel_module: { bp2build_available: false },
+}
+
+override_apex {
+ name: "com.google.android.apogee",
+ base: ":com.android.apogee",
+ certificate: "com.google.android.apogee.certificate",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("apex", "com.google.android.apogee", AttrNameToString{
+ "file_contexts": `":com.android.apogee-file_contexts"`,
+ "certificate_name": `"com.google.android.apogee.certificate"`,
+ "manifest": `"apogee_manifest.json"`,
+ }),
+ }})
+}
diff --git a/bp2build/api_domain_conversion_test.go b/bp2build/api_domain_conversion_test.go
index fc9d1d5..224008f 100644
--- a/bp2build/api_domain_conversion_test.go
+++ b/bp2build/api_domain_conversion_test.go
@@ -60,7 +60,7 @@
"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
},
)
- RunBp2BuildTestCase(t, registerApiDomainModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, registerApiDomainModuleTypes, Bp2buildTestCase{
Blueprint: bp,
ExpectedBazelTargets: []string{expectedBazelTarget},
Filesystem: fs,
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 36c3a48..82ce115 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -163,6 +163,9 @@
// 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
@@ -181,6 +184,8 @@
return "Bp2Build"
case QueryView:
return "QueryView"
+ case ApiBp2build:
+ return "ApiBp2build"
default:
return fmt.Sprintf("%d", mode)
}
@@ -327,6 +332,10 @@
errs = append(errs, err)
}
targets = append(targets, t)
+ case ApiBp2build:
+ if aModule, ok := m.(android.Module); ok && aModule.IsConvertedByBp2build() {
+ targets, errs = generateBazelTargets(bpCtx, aModule)
+ }
default:
errs = append(errs, fmt.Errorf("Unknown code-generation mode: %s", ctx.Mode()))
return
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index c1fb800..7c24a94 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -1853,3 +1853,27 @@
},
})
}
+
+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",
+ })
+}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 28d2c75..a8e557d 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -85,6 +85,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "api": attr.string(),
"arch_paths": attr.string_list(),
"arch_paths_exclude": attr.string_list(),
# bazel_module start
@@ -119,6 +120,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "api": attr.string(),
"arch_paths": attr.string_list(),
"arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
@@ -149,6 +151,7 @@
"soong_module_name": attr.string(mandatory = True),
"soong_module_variant": attr.string(),
"soong_module_deps": attr.label_list(providers = [SoongModuleInfo]),
+ "api": attr.string(),
"arch_paths": attr.string_list(),
"arch_paths_exclude": attr.string_list(),
"bool_prop": attr.bool(),
diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go
index c23779e..72d3940 100644
--- a/bp2build/cc_binary_conversion_test.go
+++ b/bp2build/cc_binary_conversion_test.go
@@ -201,20 +201,27 @@
})
}
-func TestCcBinaryVersionScript(t *testing.T) {
+func TestCcBinaryVersionScriptAndDynamicList(t *testing.T) {
runCcBinaryTests(t, ccBinaryBp2buildTestCase{
- description: `version script`,
+ description: `version script and dynamic list`,
blueprint: `
{rule_name} {
name: "foo",
include_build_directory: false,
version_script: "vs",
+ dynamic_list: "dynamic.list",
}
`,
targets: []testBazelTarget{
{"cc_binary", "foo", AttrNameToString{
- "additional_linker_inputs": `["vs"]`,
- "linkopts": `["-Wl,--version-script,$(location vs)"]`,
+ "additional_linker_inputs": `[
+ "vs",
+ "dynamic.list",
+ ]`,
+ "linkopts": `[
+ "-Wl,--version-script,$(location vs)",
+ "-Wl,--dynamic-list,$(location dynamic.list)",
+ ]`,
},
},
},
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 1b8e9b4..728a4dc 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -870,9 +870,9 @@
})}})
}
-func TestCcLibraryNonConfiguredVersionScript(t *testing.T) {
+func TestCcLibraryNonConfiguredVersionScriptAndDynamicList(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
- Description: "cc_library non-configured version script",
+ Description: "cc_library non-configured version script and dynamic list",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
@@ -882,6 +882,7 @@
name: "a",
srcs: ["a.cpp"],
version_script: "v.map",
+ dynamic_list: "dynamic.list",
bazel_module: { bp2build_available: true },
include_build_directory: false,
}
@@ -889,17 +890,23 @@
},
Blueprint: soongCcLibraryPreamble,
ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
- "additional_linker_inputs": `["v.map"]`,
- "linkopts": `["-Wl,--version-script,$(location v.map)"]`,
- "srcs": `["a.cpp"]`,
+ "additional_linker_inputs": `[
+ "v.map",
+ "dynamic.list",
+ ]`,
+ "linkopts": `[
+ "-Wl,--version-script,$(location v.map)",
+ "-Wl,--dynamic-list,$(location dynamic.list)",
+ ]`,
+ "srcs": `["a.cpp"]`,
}),
},
)
}
-func TestCcLibraryConfiguredVersionScript(t *testing.T) {
+func TestCcLibraryConfiguredVersionScriptAndDynamicList(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
- Description: "cc_library configured version script",
+ Description: "cc_library configured version script and dynamic list",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
@@ -911,9 +918,11 @@
arch: {
arm: {
version_script: "arm.map",
+ dynamic_list: "dynamic_arm.list",
},
arm64: {
version_script: "arm64.map",
+ dynamic_list: "dynamic_arm64.list",
},
},
@@ -925,13 +934,25 @@
Blueprint: soongCcLibraryPreamble,
ExpectedBazelTargets: makeCcLibraryTargets("a", AttrNameToString{
"additional_linker_inputs": `select({
- "//build/bazel/platforms/arch:arm": ["arm.map"],
- "//build/bazel/platforms/arch:arm64": ["arm64.map"],
+ "//build/bazel/platforms/arch:arm": [
+ "arm.map",
+ "dynamic_arm.list",
+ ],
+ "//build/bazel/platforms/arch:arm64": [
+ "arm64.map",
+ "dynamic_arm64.list",
+ ],
"//conditions:default": [],
})`,
"linkopts": `select({
- "//build/bazel/platforms/arch:arm": ["-Wl,--version-script,$(location arm.map)"],
- "//build/bazel/platforms/arch:arm64": ["-Wl,--version-script,$(location arm64.map)"],
+ "//build/bazel/platforms/arch:arm": [
+ "-Wl,--version-script,$(location arm.map)",
+ "-Wl,--dynamic-list,$(location dynamic_arm.list)",
+ ],
+ "//build/bazel/platforms/arch:arm64": [
+ "-Wl,--version-script,$(location arm64.map)",
+ "-Wl,--dynamic-list,$(location dynamic_arm64.list)",
+ ],
"//conditions:default": [],
})`,
"srcs": `["a.cpp"]`,
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 522c10e..4d8b8a4 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -97,7 +97,7 @@
targets.sort()
var content string
- if mode == Bp2Build {
+ if mode == Bp2Build || mode == ApiBp2build {
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/ndk_headers_conversion_test.go b/bp2build/ndk_headers_conversion_test.go
index c7cc6b2..9d0f1f2 100644
--- a/bp2build/ndk_headers_conversion_test.go
+++ b/bp2build/ndk_headers_conversion_test.go
@@ -79,7 +79,7 @@
"hdrs": testCase.expectedHdrs,
},
)
- RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
Description: testCase.desc,
Blueprint: fmt.Sprintf(bpTemplate, testCase.srcs, testCase.excludeSrcs),
ExpectedBazelTargets: []string{expectedBazelTarget},
@@ -121,7 +121,7 @@
"include_dir": testCase.expectedIncludeDir,
},
)
- RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
Description: testCase.desc,
Blueprint: fmt.Sprintf(bpTemplate, testCase.from),
ExpectedBazelTargets: []string{expectedBazelTarget},
@@ -156,7 +156,7 @@
]`,
},
)
- RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
Blueprint: bp,
Filesystem: fs,
ExpectedBazelTargets: []string{expectedBazelTarget},
diff --git a/bp2build/ndk_library_conversion_test.go b/bp2build/ndk_library_conversion_test.go
index 244ce20..819ab25 100644
--- a/bp2build/ndk_library_conversion_test.go
+++ b/bp2build/ndk_library_conversion_test.go
@@ -37,7 +37,7 @@
"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
},
)
- RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
Blueprint: bp,
ExpectedBazelTargets: []string{expectedBazelTarget},
})
@@ -69,7 +69,7 @@
"target_compatible_with": `["//build/bazel/platforms/os:android"]`,
},
)
- RunBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
+ RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{
Blueprint: bp,
Filesystem: fs,
ExpectedBazelTargets: []string{expectedBazelTarget},
diff --git a/bp2build/testing.go b/bp2build/testing.go
index c2c1b19..31aa830 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -24,6 +24,8 @@
"strings"
"testing"
+ "github.com/google/blueprint/proptools"
+
"android/soong/android"
"android/soong/android/allowlists"
"android/soong/bazel"
@@ -88,6 +90,22 @@
}
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
+ bp2buildSetup := func(ctx *android.TestContext) {
+ registerModuleTypes(ctx)
+ ctx.RegisterForBazelConversion()
+ }
+ runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
+}
+
+func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
+ apiBp2BuildSetup := func(ctx *android.TestContext) {
+ registerModuleTypes(ctx)
+ ctx.RegisterForApiBazelConversion()
+ }
+ runBp2BuildTestCaseWithSetup(t, apiBp2BuildSetup, tc)
+}
+
+func runBp2BuildTestCaseWithSetup(t *testing.T, setup func(ctx *android.TestContext), tc Bp2buildTestCase) {
t.Helper()
dir := "."
filesystem := make(map[string][]byte)
@@ -103,7 +121,7 @@
config := android.TestConfig(buildDir, nil, tc.Blueprint, filesystem)
ctx := android.NewTestContext(config)
- registerModuleTypes(ctx)
+ setup(ctx)
ctx.RegisterModuleType(tc.ModuleTypeUnderTest, tc.ModuleTypeUnderTestFactory)
// A default configuration for tests to not have to specify bp2build_available on top level targets.
@@ -118,7 +136,6 @@
})
}
ctx.RegisterBp2BuildConfig(bp2buildConfig)
- ctx.RegisterForBazelConversion()
_, parseErrs := ctx.ParseFileList(dir, toParse)
if errored(t, tc, parseErrs) {
@@ -198,6 +215,8 @@
// Prop used to indicate this conversion should be 1 module -> multiple targets
One_to_many_prop *bool
+
+ Api *string // File describing the APIs of this module
}
type customModule struct {
@@ -320,6 +339,7 @@
String_ptr_prop *string
String_list_prop []string
Arch_paths bazel.LabelListAttribute
+ Api bazel.LabelAttribute
}
func (m *customModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
@@ -364,6 +384,23 @@
ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs)
}
+var _ android.ApiProvider = (*customModule)(nil)
+
+func (c *customModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "custom_api_contribution",
+ }
+ apiAttribute := bazel.MakeLabelAttribute(
+ android.BazelLabelForModuleSrcSingle(ctx, proptools.String(c.props.Api)).Label,
+ )
+ attrs := &customBazelModuleAttributes{
+ Api: *apiAttribute,
+ }
+ ctx.CreateBazelTargetModule(props,
+ android.CommonAttributes{Name: c.Name()},
+ attrs)
+}
+
// A bp2build mutator that uses load statements and creates a 1:M mapping from
// module to target.
func customBp2buildOneToMany(ctx android.TopDownMutatorContext, m *customModule) {
diff --git a/build_test.bash b/build_test.bash
index 8b91e2c..6f0fba7 100755
--- a/build_test.bash
+++ b/build_test.bash
@@ -59,7 +59,7 @@
echo
echo "Running Bazel smoke test..."
-STANDALONE_BAZEL=true "${TOP}/tools/bazel" --batch --max_idle_secs=1 info
+STANDALONE_BAZEL=true "${TOP}/tools/bazel" --batch --max_idle_secs=1 help
echo
echo "Running Soong test..."
diff --git a/cc/api_level.go b/cc/api_level.go
index fd145a9..8f9e1f6 100644
--- a/cc/api_level.go
+++ b/cc/api_level.go
@@ -20,7 +20,7 @@
"android/soong/android"
)
-func minApiForArch(ctx android.BaseModuleContext,
+func MinApiForArch(ctx android.EarlyModuleContext,
arch android.ArchType) android.ApiLevel {
switch arch {
@@ -28,6 +28,8 @@
return ctx.Config().MinSupportedSdkVersion()
case android.Arm64, android.X86_64:
return android.FirstLp64Version
+ case android.Riscv64:
+ return android.FutureApiLevel
default:
panic(fmt.Errorf("Unknown arch %q", arch))
}
@@ -36,7 +38,7 @@
func nativeApiLevelFromUser(ctx android.BaseModuleContext,
raw string) (android.ApiLevel, error) {
- min := minApiForArch(ctx, ctx.Arch().ArchType)
+ min := MinApiForArch(ctx, ctx.Arch().ArchType)
if raw == "minimum" {
return min, nil
}
diff --git a/cc/builder.go b/cc/builder.go
index 0bea9da..39f7dc3 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -672,11 +672,16 @@
tidyCmd := "${config.ClangBin}/clang-tidy"
rule := clangTidy
+ reducedCFlags := moduleFlags
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_CLANG_TIDY") {
rule = clangTidyRE
+ // b/248371171, work around RBE input processor problem
+ // some cflags rejected by input processor, but usually
+ // do not affect included files or clang-tidy
+ reducedCFlags = config.TidyReduceCFlags(reducedCFlags)
}
- sharedCFlags := shareFlags("cFlags", moduleFlags)
+ sharedCFlags := shareFlags("cFlags", reducedCFlags)
srcRelPath := srcFile.Rel()
// Add the .tidy rule
diff --git a/cc/cc.go b/cc/cc.go
index 598f6be..d4eaa53 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -3334,6 +3334,11 @@
return android.Paths{c.outputFile.Path()}, nil
}
return android.Paths{}, nil
+ case "unstripped":
+ if c.linker != nil {
+ return android.PathsIfNonNil(c.linker.unstrippedOutputFilePath()), nil
+ }
+ return nil, nil
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -3740,6 +3745,13 @@
} else {
sharedOrStaticLibraryBp2Build(ctx, c, false)
}
+ }
+}
+
+var _ android.ApiProvider = (*Module)(nil)
+
+func (c *Module) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) {
+ switch c.typ() {
case ndkLibrary:
ndkLibraryBp2build(ctx, c)
}
@@ -3832,6 +3844,15 @@
}
}
+func (c *Module) Partition() string {
+ if p, ok := c.installer.(interface {
+ getPartition() string
+ }); ok {
+ return p.getPartition()
+ }
+ return ""
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var BoolPtr = proptools.BoolPtr
diff --git a/cc/config/tidy.go b/cc/config/tidy.go
index 23bda66..af49e88 100644
--- a/cc/config/tidy.go
+++ b/cc/config/tidy.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "regexp"
"strings"
)
@@ -237,3 +238,11 @@
}
return flags
}
+
+var (
+ removedCFlags = regexp.MustCompile(" -fsanitize=[^ ]*memtag-[^ ]* ")
+)
+
+func TidyReduceCFlags(flags string) string {
+ return removedCFlags.ReplaceAllString(flags, " ")
+}
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 8a8c107..13c94ad 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -103,6 +103,7 @@
*baseCompiler
fuzzPackagedModule fuzz.FuzzPackagedModule
installedSharedDeps []string
+ sharedLibraries android.Paths
}
func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -142,13 +143,6 @@
return flags
}
-func UnstrippedOutputFile(module android.Module) android.Path {
- if mod, ok := module.(LinkableInterface); ok {
- return mod.UnstrippedOutputFile()
- }
- panic("UnstrippedOutputFile called on non-LinkableInterface module: " + module.Name())
-}
-
// IsValidSharedDependency takes a module and determines if it is a unique shared library
// that should be installed in the fuzz target output directories. This function
// returns true, unless:
@@ -270,22 +264,9 @@
}
// Grab the list of required shared libraries.
- seen := make(map[string]bool)
- var sharedLibraries android.Paths
- ctx.WalkDeps(func(child, parent android.Module) bool {
- if seen[child.Name()] {
- return false
- }
- seen[child.Name()] = true
+ fuzzBin.sharedLibraries = CollectAllSharedDependencies(ctx)
- if IsValidSharedDependency(child) {
- sharedLibraries = append(sharedLibraries, child.(*Module).UnstrippedOutputFile())
- return true
- }
- return false
- })
-
- for _, lib := range sharedLibraries {
+ for _, lib := range fuzzBin.sharedLibraries {
fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
sharedLibraryInstallLocation(
lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))
@@ -412,9 +393,6 @@
archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
- // Grab the list of required shared libraries.
- sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, UnstrippedOutputFile, IsValidSharedDependency)
-
var files []fuzz.FileToZip
builder := android.NewRuleBuilder(pctx, ctx)
@@ -422,10 +400,10 @@
files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)
// Package shared libraries
- files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
+ files = append(files, GetSharedLibsToZip(fuzzModule.sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
// The executable.
- files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
+ files = append(files, fuzz.FileToZip{android.OutputFileForModule(ctx, ccModule, "unstripped"), ""})
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
@@ -494,3 +472,46 @@
}
return files
}
+
+// CollectAllSharedDependencies search over the provided module's dependencies using
+// VisitDirectDeps and WalkDeps to enumerate all shared library dependencies.
+// VisitDirectDeps is used first to avoid incorrectly using the core libraries (sanitizer
+// runtimes, libc, libdl, etc.) from a dependency. This may cause issues when dependencies
+// have explicit sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
+func CollectAllSharedDependencies(ctx android.ModuleContext) android.Paths {
+ seen := make(map[string]bool)
+ recursed := make(map[string]bool)
+
+ var sharedLibraries android.Paths
+
+ // Enumerate the first level of dependencies, as we discard all non-library
+ // modules in the BFS loop below.
+ ctx.VisitDirectDeps(func(dep android.Module) {
+ if !IsValidSharedDependency(dep) {
+ return
+ }
+ if seen[ctx.OtherModuleName(dep)] {
+ return
+ }
+ seen[ctx.OtherModuleName(dep)] = true
+ sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, dep, "unstripped"))
+ })
+
+ ctx.WalkDeps(func(child, parent android.Module) bool {
+ if !IsValidSharedDependency(child) {
+ return false
+ }
+ if !seen[ctx.OtherModuleName(child)] {
+ seen[ctx.OtherModuleName(child)] = true
+ sharedLibraries = append(sharedLibraries, android.OutputFileForModule(ctx, child, "unstripped"))
+ }
+
+ if recursed[ctx.OtherModuleName(child)] {
+ return false
+ }
+ recursed[ctx.OtherModuleName(child)] = true
+ return true
+ })
+
+ return sharedLibraries
+}
diff --git a/cc/library.go b/cc/library.go
index 6594808..13a7a3e 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1089,6 +1089,12 @@
} else {
flag = "--systemapi"
}
+ // b/184712170, unless the lib is an NDK library, exclude all public symbols from
+ // the stub so that it is mandated that all symbols are explicitly marked with
+ // either apex or systemapi.
+ if !ctx.Module().(*Module).IsNdk(ctx.Config()) {
+ flag = flag + " --no-ndk"
+ }
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
@@ -2227,6 +2233,10 @@
mod.ModuleBase.MakeUninstallable()
}
+func (library *libraryDecorator) getPartition() string {
+ return library.path.Partition()
+}
+
func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPath {
return library.apiListCoverageXmlPath
}
diff --git a/cc/linkable.go b/cc/linkable.go
index 2316d86..0522fc6 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -253,6 +253,9 @@
// VndkVersion returns the VNDK version string for this module.
VndkVersion() string
+
+ // Partition returns the partition string for this module.
+ Partition() string
}
var (
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 08e2a39..7354be9 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -173,7 +173,9 @@
}, attrs)
}
-func (h *headerModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+var _ android.ApiProvider = (*headerModule)(nil)
+
+func (h *headerModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) {
// Generate `cc_api_headers` target for Multi-tree API export
createCcApiHeadersTarget(ctx, h.properties.Srcs, h.properties.Exclude_srcs, h.properties.From)
}
@@ -192,7 +194,6 @@
module := &headerModule{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
- android.InitBazelModule(module)
return module
}
@@ -263,7 +264,9 @@
processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths)
}
-func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
+var _ android.ApiProvider = (*versionedHeaderModule)(nil)
+
+func (h *versionedHeaderModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) {
// Glob all .h files under `From`
includePattern := headerGlobPattern(proptools.String(h.properties.From))
// Generate `cc_api_headers` target for Multi-tree API export
@@ -319,7 +322,6 @@
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
- android.InitBazelModule(module)
return module
}
diff --git a/cc/ndkstubgen/__init__.py b/cc/ndkstubgen/__init__.py
index f893d41..efad70a 100755
--- a/cc/ndkstubgen/__init__.py
+++ b/cc/ndkstubgen/__init__.py
@@ -111,6 +111,11 @@
action='store_true',
dest='systemapi',
help='Use the SystemAPI variant.')
+ parser.add_argument(
+ '--no-ndk',
+ action='store_false',
+ dest='ndk',
+ help='Do not include NDK APIs.')
parser.add_argument('--api-map',
type=resolved_path,
@@ -147,7 +152,7 @@
verbosity = 2
logging.basicConfig(level=verbose_map[verbosity])
- filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi)
+ filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi, args.ndk)
with args.symbol_file.open() as symbol_file:
try:
versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
diff --git a/cc/ndkstubgen/test_ndkstubgen.py b/cc/ndkstubgen/test_ndkstubgen.py
index 450719b..1e0bdf3 100755
--- a/cc/ndkstubgen/test_ndkstubgen.py
+++ b/cc/ndkstubgen/test_ndkstubgen.py
@@ -424,6 +424,45 @@
""")
self.assertEqual(expected_version, version_file.getvalue())
+ def test_integration_with_nondk(self) -> None:
+ input_file = io.StringIO(textwrap.dedent("""\
+ VERSION_1 {
+ global:
+ foo;
+ bar; # apex
+ local:
+ *;
+ };
+ """))
+ f = copy(self.filter)
+ f.apex = True
+ f.ndk = False # ndk symbols should be excluded
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
+ versions = parser.parse()
+
+ src_file = io.StringIO()
+ version_file = io.StringIO()
+ symbol_list_file = io.StringIO()
+ f = copy(self.filter)
+ f.apex = True
+ f.ndk = False # ndk symbols should be excluded
+ generator = ndkstubgen.Generator(src_file,
+ version_file, symbol_list_file, f)
+ generator.write(versions)
+
+ expected_src = textwrap.dedent("""\
+ void bar() {}
+ """)
+ self.assertEqual(expected_src, src_file.getvalue())
+
+ expected_version = textwrap.dedent("""\
+ VERSION_1 {
+ global:
+ bar;
+ };
+ """)
+ self.assertEqual(expected_version, version_file.getvalue())
+
def test_empty_stub(self) -> None:
"""Tests that empty stubs can be generated.
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index 471a12f..9bf07f2 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -208,12 +208,14 @@
symbol should be omitted or not
"""
- def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi: bool = False):
+ def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi:
+ bool = False, ndk: bool = True):
self.arch = arch
self.api = api
self.llndk = llndk
self.apex = apex
self.systemapi = systemapi
+ self.ndk = ndk
def _should_omit_tags(self, tags: Tags) -> bool:
"""Returns True if the tagged object should be omitted.
@@ -253,8 +255,13 @@
def should_omit_symbol(self, symbol: Symbol) -> bool:
"""Returns True if the symbol should be omitted."""
- return self._should_omit_tags(symbol.tags)
+ if not symbol.tags.has_mode_tags and not self.ndk:
+ # Symbols that don't have mode tags are NDK. They are usually
+ # included, but have to be omitted if NDK symbols are explicitly
+ # filtered-out
+ return True
+ return self._should_omit_tags(symbol.tags)
def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
"""Returns true if the symbol is present for the given architecture."""
diff --git a/cc/symbolfile/test_symbolfile.py b/cc/symbolfile/test_symbolfile.py
index e17a8d0..856b9d7 100644
--- a/cc/symbolfile/test_symbolfile.py
+++ b/cc/symbolfile/test_symbolfile.py
@@ -308,6 +308,20 @@
def assertInclude(self, f: Filter, s: Symbol) -> None:
self.assertFalse(f.should_omit_symbol(s))
+ def test_omit_ndk(self) -> None:
+ f_ndk = self.filter
+ f_nondk = copy(f_ndk)
+ f_nondk.ndk = False
+ f_nondk.apex = True
+
+ s_ndk = Symbol('foo', Tags())
+ s_nonndk = Symbol('foo', Tags.from_strs(['apex']))
+
+ self.assertInclude(f_ndk, s_ndk)
+ self.assertOmit(f_ndk, s_nonndk)
+ self.assertOmit(f_nondk, s_ndk)
+ self.assertInclude(f_nondk, s_nonndk)
+
def test_omit_llndk(self) -> None:
f_none = self.filter
f_llndk = copy(f_none)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 0b8cc88..770ad0c 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -24,6 +24,7 @@
"time"
"android/soong/android"
+ "android/soong/bazel"
"android/soong/bp2build"
"android/soong/shared"
"android/soong/ui/metrics/bp2build_metrics_proto"
@@ -48,11 +49,12 @@
delveListen string
delvePath string
- moduleGraphFile string
- moduleActionsFile string
- docFile string
- bazelQueryViewDir string
- bp2buildMarker string
+ moduleGraphFile string
+ moduleActionsFile string
+ docFile string
+ bazelQueryViewDir string
+ bazelApiBp2buildDir string
+ bp2buildMarker string
cmdlineArgs bootstrap.Args
)
@@ -81,6 +83,7 @@
flag.StringVar(&moduleActionsFile, "module_actions_file", "", "JSON file to output inputs/outputs of actions of modules")
flag.StringVar(&docFile, "soong_docs", "", "build documentation file to output")
flag.StringVar(&bazelQueryViewDir, "bazel_queryview_dir", "", "path to the bazel queryview directory relative to --top")
+ flag.StringVar(&bazelApiBp2buildDir, "bazel_api_bp2build_dir", "", "path to the bazel api_bp2build directory relative to --top")
flag.StringVar(&bp2buildMarker, "bp2build_marker", "", "If set, run bp2build, touch the specified marker file then exit")
flag.StringVar(&cmdlineArgs.OutFile, "o", "build.ninja", "the Ninja file to output")
flag.BoolVar(&cmdlineArgs.EmptyNinjaFile, "empty-ninja-file", false, "write out a 0-byte ninja file")
@@ -129,6 +132,8 @@
buildMode = android.Bp2build
} else if bazelQueryViewDir != "" {
buildMode = android.GenerateQueryView
+ } else if bazelApiBp2buildDir != "" {
+ buildMode = android.ApiBp2build
} else if moduleGraphFile != "" {
buildMode = android.GenerateModuleGraph
} else if docFile != "" {
@@ -178,7 +183,7 @@
defer ctx.EventHandler.End("queryview")
codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.QueryView)
absoluteQueryViewDir := shared.JoinPath(topDir, queryviewDir)
- if err := createBazelQueryView(codegenContext, absoluteQueryViewDir); err != nil {
+ if err := createBazelWorkspace(codegenContext, absoluteQueryViewDir); err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
}
@@ -186,6 +191,96 @@
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(configuration android.Config, extraNinjaDeps []string) string {
+ // Create a new context and register mutators that are only meaningful to API export
+ ctx := android.NewContext(configuration)
+ ctx.EventHandler.Begin("api_bp2build")
+ defer ctx.EventHandler.End("api_bp2build")
+ ctx.SetNameInterface(newNameResolver(configuration))
+ 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 := bootstrap.RunBlueprint(cmdlineArgs,
+ bootstrap.StopBeforePrepareBuildActions,
+ ctx.Context,
+ configuration)
+ ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
+
+ // Add the globbed dependencies
+ globs := writeBuildGlobsNinjaFile(ctx, configuration.SoongOutDir(), configuration)
+ ninjaDeps = append(ninjaDeps, globs...)
+
+ // Run codegen to generate BUILD files
+ codegenContext := bp2build.NewCodegenContext(configuration, *ctx, bp2build.ApiBp2build)
+ absoluteApiBp2buildDir := shared.JoinPath(topDir, bazelApiBp2buildDir)
+ if err := createBazelWorkspace(codegenContext, absoluteApiBp2buildDir); err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err)
+ os.Exit(1)
+ }
+ ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
+
+ // Create soong_injection repository
+ soongInjectionFiles := bp2build.CreateSoongInjectionFiles(configuration, bp2build.CodegenMetrics{})
+ absoluteSoongInjectionDir := shared.JoinPath(topDir, configuration.SoongOutDir(), bazel.SoongInjectionDirName)
+ for _, file := range soongInjectionFiles {
+ writeReadOnlyFile(absoluteSoongInjectionDir, file)
+ }
+
+ workspace := shared.JoinPath(configuration.SoongOutDir(), "api_bp2build")
+
+ excludes := bazelArtifacts()
+ // Exclude all src BUILD files
+ excludes = append(excludes, apiBuildFileExcludes()...)
+
+ // Create the symlink forest
+ symlinkDeps := bp2build.PlantSymlinkForest(
+ configuration,
+ topDir,
+ workspace,
+ bazelApiBp2buildDir,
+ ".",
+ excludes)
+ 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() []string {
+ ret := make([]string, 0)
+
+ srcs, err := getExistingBazelRelatedFiles(topDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
+ os.Exit(1)
+ }
+ for _, src := range srcs {
+ if src != "WORKSPACE" &&
+ src != "BUILD" &&
+ src != "BUILD.bazel" &&
+ !strings.HasPrefix(src, "build/bazel") &&
+ !strings.HasPrefix(src, "prebuilts/clang") {
+ ret = append(ret, src)
+ }
+ }
+ return ret
+}
+
func writeMetrics(configuration android.Config, eventHandler metrics.EventHandler, metricsDir string) {
if len(metricsDir) < 1 {
fmt.Fprintf(os.Stderr, "\nMissing required env var for generating soong metrics: LOG_DIR\n")
@@ -248,6 +343,8 @@
return bp2buildMarker
} else if configuration.IsMixedBuildsEnabled() {
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
+ } else if configuration.BuildMode == android.ApiBp2build {
+ return runApiBp2build(configuration, extraNinjaDeps)
} else {
var stopBefore bootstrap.StopBefore
if configuration.BuildMode == android.GenerateModuleGraph {
@@ -476,6 +573,16 @@
return files, nil
}
+func bazelArtifacts() []string {
+ return []string{
+ "bazel-bin",
+ "bazel-genfiles",
+ "bazel-out",
+ "bazel-testlogs",
+ "bazel-" + filepath.Base(topDir),
+ }
+}
+
// 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.
@@ -524,13 +631,7 @@
generatedRoot := shared.JoinPath(configuration.SoongOutDir(), "bp2build")
workspaceRoot := shared.JoinPath(configuration.SoongOutDir(), "workspace")
- excludes := []string{
- "bazel-bin",
- "bazel-genfiles",
- "bazel-out",
- "bazel-testlogs",
- "bazel-" + filepath.Base(topDir),
- }
+ excludes := bazelArtifacts()
if outDir[0] != '/' {
excludes = append(excludes, outDir)
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index 983dbf0..cd1d6fb 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -23,8 +23,9 @@
"android/soong/bp2build"
)
-func createBazelQueryView(ctx *bp2build.CodegenContext, bazelQueryViewDir string) error {
- os.RemoveAll(bazelQueryViewDir)
+// A helper function to generate a Read-only Bazel workspace in outDir
+func createBazelWorkspace(ctx *bp2build.CodegenContext, outDir string) error {
+ os.RemoveAll(outDir)
ruleShims := bp2build.CreateRuleShims(android.ModuleTypeFactories())
res, err := bp2build.GenerateBazelTargets(ctx, true)
@@ -33,9 +34,9 @@
}
filesToWrite := bp2build.CreateBazelFiles(ctx.Config(), ruleShims, res.BuildDirToTargets(),
- bp2build.QueryView)
+ ctx.Mode())
for _, f := range filesToWrite {
- if err := writeReadOnlyFile(bazelQueryViewDir, f); err != nil {
+ if err := writeReadOnlyFile(outDir, f); err != nil {
return err
}
}
diff --git a/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
index 362a8ef..baad58e 100644
--- a/etc/prebuilt_etc.go
+++ b/etc/prebuilt_etc.go
@@ -296,27 +296,37 @@
}
func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- if p.properties.Src == nil {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- return
- }
- p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
-
- // Determine the output file basename.
- // If Filename is set, use the name specified by the property.
- // If Filename_from_src is set, use the source file name.
- // Otherwise use the module name.
filename := proptools.String(p.properties.Filename)
filenameFromSrc := proptools.Bool(p.properties.Filename_from_src)
- if filename != "" {
- if filenameFromSrc {
- ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
- return
+ if p.properties.Src != nil {
+ p.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(p.properties.Src))
+
+ // Determine the output file basename.
+ // If Filename is set, use the name specified by the property.
+ // If Filename_from_src is set, use the source file name.
+ // Otherwise use the module name.
+ if filename != "" {
+ if filenameFromSrc {
+ ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+ return
+ }
+ } else if filenameFromSrc {
+ filename = p.sourceFilePath.Base()
+ } else {
+ filename = ctx.ModuleName()
}
- } else if filenameFromSrc {
- filename = p.sourceFilePath.Base()
+ } else if ctx.Config().AllowMissingDependencies() {
+ // If no srcs was set and AllowMissingDependencies is enabled then
+ // mark the module as missing dependencies and set a fake source path
+ // and file name.
+ ctx.AddMissingDependencies([]string{"MISSING_PREBUILT_SRC_FILE"})
+ p.sourceFilePath = android.PathForModuleSrc(ctx)
+ if filename == "" {
+ filename = ctx.ModuleName()
+ }
} else {
- filename = ctx.ModuleName()
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ return
}
p.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
diff --git a/etc/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go
index cf1f6d7..a6477dd 100644
--- a/etc/prebuilt_etc_test.go
+++ b/etc/prebuilt_etc_test.go
@@ -195,6 +195,30 @@
}
}
+func TestPrebuiltEtcAllowMissingDependencies(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForPrebuiltEtcTest,
+ android.PrepareForTestDisallowNonExistentPaths,
+ android.FixtureModifyConfig(
+ func(config android.Config) {
+ config.TestProductVariables.Allow_missing_dependencies = proptools.BoolPtr(true)
+ }),
+ ).RunTestWithBp(t, `
+ prebuilt_etc {
+ name: "foo.conf",
+ filename_from_src: true,
+ arch: {
+ x86: {
+ src: "x86.conf",
+ },
+ },
+ }
+ `)
+
+ android.AssertStringEquals(t, "expected error rule", "android/soong/android.Error",
+ result.ModuleForTests("foo.conf", "android_arm64_armv8-a").Output("foo.conf").Rule.String())
+}
+
func TestPrebuiltRootInstallDirPath(t *testing.T) {
result := prepareForPrebuiltEtcTest.RunTestWithBp(t, `
prebuilt_root {
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index c8cd21b..eb248bb 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -379,42 +379,3 @@
sort.Strings(fuzzTargets)
ctx.Strict(targets, strings.Join(fuzzTargets, " "))
}
-
-// CollectAllSharedDependencies performs a breadth-first search over the provided module's
-// dependencies using `visitDirectDeps` to enumerate all shared library
-// dependencies. We require breadth-first expansion, as otherwise we may
-// incorrectly use the core libraries (sanitizer runtimes, libc, libdl, etc.)
-// from a dependency. This may cause issues when dependencies have explicit
-// sanitizer tags, as we may get a dependency on an unsanitized libc, etc.
-func CollectAllSharedDependencies(ctx android.SingletonContext, module android.Module, unstrippedOutputFile func(module android.Module) android.Path, isValidSharedDependency func(dependency android.Module) bool) android.Paths {
- var fringe []android.Module
-
- seen := make(map[string]bool)
-
- // Enumerate the first level of dependencies, as we discard all non-library
- // modules in the BFS loop below.
- ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep) {
- fringe = append(fringe, dep)
- }
- })
-
- var sharedLibraries android.Paths
-
- for i := 0; i < len(fringe); i++ {
- module := fringe[i]
- if seen[module.Name()] {
- continue
- }
- seen[module.Name()] = true
-
- sharedLibraries = append(sharedLibraries, unstrippedOutputFile(module))
- ctx.VisitDirectDeps(module, func(dep android.Module) {
- if isValidSharedDependency(dep) && !seen[dep.Name()] {
- fringe = append(fringe, dep)
- }
- })
- }
-
- return sharedLibraries
-}
diff --git a/java/androidmk.go b/java/androidmk.go
index 75ac0e7..cd86880 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -17,6 +17,7 @@
import (
"fmt"
"io"
+ "strings"
"android/soong/android"
)
@@ -398,6 +399,19 @@
} else {
for _, jniLib := range app.jniLibs {
entries.AddStrings("LOCAL_SOONG_JNI_LIBS_"+jniLib.target.Arch.ArchType.String(), jniLib.name)
+ var partitionTag string
+
+ // Mimic the creation of partition_tag in build/make,
+ // which defaults to an empty string when the partition is system.
+ // Otherwise, capitalize with a leading _
+ if jniLib.partition == "system" {
+ partitionTag = ""
+ } else {
+ split := strings.Split(jniLib.partition, "/")
+ partitionTag = "_" + strings.ToUpper(split[len(split)-1])
+ }
+ entries.AddStrings("LOCAL_SOONG_JNI_LIBS_PARTITION_"+jniLib.target.Arch.ArchType.String(),
+ jniLib.name+":"+partitionTag)
}
}
diff --git a/java/androidmk_test.go b/java/androidmk_test.go
index 197da4f..1232cd1 100644
--- a/java/androidmk_test.go
+++ b/java/androidmk_test.go
@@ -19,6 +19,9 @@
"testing"
"android/soong/android"
+ "android/soong/cc"
+
+ "github.com/google/blueprint/proptools"
)
func TestRequired(t *testing.T) {
@@ -252,3 +255,149 @@
android.AssertDeepEquals(t, "overrides property", expected.overrides, actual)
}
}
+
+func TestJniPartition(t *testing.T) {
+ bp := `
+ cc_library {
+ name: "libjni_system",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ }
+
+ cc_library {
+ name: "libjni_system_ext",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ system_ext_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_odm",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ device_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_product",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ product_specific: true,
+ }
+
+ cc_library {
+ name: "libjni_vendor",
+ system_shared_libs: [],
+ sdk_version: "current",
+ stl: "none",
+ soc_specific: true,
+ }
+
+ android_app {
+ name: "test_app_system_jni_system",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system"],
+ }
+
+ android_app {
+ name: "test_app_system_jni_system_ext",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system_ext"],
+ }
+
+ android_app {
+ name: "test_app_system_ext_jni_system",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system"],
+ system_ext_specific: true
+ }
+
+ android_app {
+ name: "test_app_system_ext_jni_system_ext",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_system_ext"],
+ system_ext_specific: true
+ }
+
+ android_app {
+ name: "test_app_product_jni_product",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_product"],
+ product_specific: true
+ }
+
+ android_app {
+ name: "test_app_vendor_jni_odm",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_odm"],
+ soc_specific: true
+ }
+
+ android_app {
+ name: "test_app_odm_jni_vendor",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_vendor"],
+ device_specific: true
+ }
+ android_app {
+ name: "test_app_system_jni_multiple",
+ privileged: true,
+ platform_apis: true,
+ certificate: "platform",
+ jni_libs: ["libjni_system", "libjni_system_ext"],
+ }
+ android_app {
+ name: "test_app_vendor_jni_multiple",
+ sdk_version: "core_platform",
+ jni_libs: ["libjni_odm", "libjni_vendor"],
+ soc_specific: true
+ }
+ `
+ arch := "arm64"
+ ctx := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ cc.PrepareForTestWithCcDefaultModules,
+ android.PrepareForTestWithAndroidMk,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.TestProductVariables.DeviceArch = proptools.StringPtr(arch)
+ }),
+ ).
+ RunTestWithBp(t, bp)
+ testCases := []struct {
+ name string
+ partitionNames []string
+ partitionTags []string
+ }{
+ {"test_app_system_jni_system", []string{"libjni_system"}, []string{""}},
+ {"test_app_system_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
+ {"test_app_system_ext_jni_system", []string{"libjni_system"}, []string{""}},
+ {"test_app_system_ext_jni_system_ext", []string{"libjni_system_ext"}, []string{"_SYSTEM_EXT"}},
+ {"test_app_product_jni_product", []string{"libjni_product"}, []string{"_PRODUCT"}},
+ {"test_app_vendor_jni_odm", []string{"libjni_odm"}, []string{"_ODM"}},
+ {"test_app_odm_jni_vendor", []string{"libjni_vendor"}, []string{"_VENDOR"}},
+ {"test_app_system_jni_multiple", []string{"libjni_system", "libjni_system_ext"}, []string{"", "_SYSTEM_EXT"}},
+ {"test_app_vendor_jni_multiple", []string{"libjni_odm", "libjni_vendor"}, []string{"_ODM", "_VENDOR"}},
+ }
+
+ for _, test := range testCases {
+ t.Run(test.name, func(t *testing.T) {
+ mod := ctx.ModuleForTests(test.name, "android_common").Module()
+ entry := android.AndroidMkEntriesForTest(t, ctx.TestContext, mod)[0]
+ for i := range test.partitionNames {
+ actual := entry.EntryMap["LOCAL_SOONG_JNI_LIBS_PARTITION_"+arch][i]
+ expected := test.partitionNames[i] + ":" + test.partitionTags[i]
+ android.AssertStringEquals(t, "Expected and actual differ", expected, actual)
+ }
+ })
+ }
+}
diff --git a/java/app.go b/java/app.go
index 1955e2a..bbd9d2d 100755
--- a/java/app.go
+++ b/java/app.go
@@ -798,6 +798,7 @@
target: module.Target(),
coverageFile: dep.CoverageOutputFile(),
unstrippedFile: dep.UnstrippedOutputFile(),
+ partition: dep.Partition(),
})
} else {
ctx.ModuleErrorf("dependency %q missing output file", otherName)
@@ -1489,6 +1490,20 @@
Certificate_name *string
}
+// ParseCertificateToAttribute splits the certificate prop into a certificate
+// label attribute or a certificate_name string attribute.
+func ParseCertificateToAttribute(ctx android.TopDownMutatorContext, certificate *string) (*string, *bazel.Label) {
+ var certificateLabel *bazel.Label
+ certificateName := proptools.StringDefault(certificate, "")
+ certModule := android.SrcIsModule(certificateName)
+ if certModule != "" {
+ c := android.BazelLabelForModuleDepSingle(ctx, certificateName)
+ certificateLabel = &c
+ certificate = nil
+ }
+ return certificate, certificateLabel
+}
+
// ConvertWithBp2build is used to convert android_app to Bazel.
func (a *AndroidApp) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
commonAttrs, depLabels := a.convertLibraryAttrsBp2Build(ctx)
@@ -1498,15 +1513,7 @@
aapt := a.convertAaptAttrsWithBp2Build(ctx)
- var certificate *bazel.Label
- certificateNamePtr := a.overridableAppProperties.Certificate
- certificateName := proptools.StringDefault(certificateNamePtr, "")
- certModule := android.SrcIsModule(certificateName)
- if certModule != "" {
- c := android.BazelLabelForModuleDepSingle(ctx, certificateName)
- certificate = &c
- certificateNamePtr = nil
- }
+ certificateName, certificate := ParseCertificateToAttribute(ctx, a.overridableAppProperties.Certificate)
attrs := &bazelAndroidAppAttributes{
commonAttrs,
aapt,
@@ -1514,7 +1521,7 @@
// TODO(b/209576404): handle package name override by product variable PRODUCT_MANIFEST_PACKAGE_NAME_OVERRIDES
a.overridableAppProperties.Package_name,
certificate,
- certificateNamePtr,
+ certificateName,
}
props := bazel.BazelTargetModuleProperties{
diff --git a/java/app_set.go b/java/app_set.go
index 694b167..d99fadb 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -90,10 +90,11 @@
}
var TargetCpuAbi = map[string]string{
- "arm": "ARMEABI_V7A",
- "arm64": "ARM64_V8A",
- "x86": "X86",
- "x86_64": "X86_64",
+ "arm": "ARMEABI_V7A",
+ "arm64": "ARM64_V8A",
+ "riscv64": "RISCV64",
+ "x86": "X86",
+ "x86_64": "X86_64",
}
func SupportedAbis(ctx android.ModuleContext) []string {
diff --git a/java/java.go b/java/java.go
index fc2af3b..5091d26 100644
--- a/java/java.go
+++ b/java/java.go
@@ -421,6 +421,7 @@
target android.Target
coverageFile android.OptionalPath
unstrippedFile android.Path
+ partition string
}
func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) {
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 59ffff5..fad1df7 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -65,8 +65,27 @@
name string
// The api scope that this scope extends.
+ //
+ // This organizes the scopes into an extension hierarchy.
+ //
+ // If set this means that the API provided by this scope includes the API provided by the scope
+ // set in this field.
extends *apiScope
+ // The next api scope that a library that uses this scope can access.
+ //
+ // This organizes the scopes into an access hierarchy.
+ //
+ // If set this means that a library that can access this API can also access the API provided by
+ // the scope set in this field.
+ //
+ // A module that sets sdk_version: "<scope>_current" should have access to the <scope> API of
+ // every java_sdk_library that it depends on. If the library does not provide an API for <scope>
+ // then it will traverse up this access hierarchy to find an API that it does provide.
+ //
+ // If this is not set then it defaults to the scope set in extends.
+ canAccess *apiScope
+
// The legacy enabled status for a specific scope can be dependent on other
// properties that have been specified on the library so it is provided by
// a function that can determine the status by examining those properties.
@@ -107,7 +126,7 @@
// The scope specific prefix to add to the api file base of "current.txt" or "removed.txt".
apiFilePrefix string
- // The scope specific prefix to add to the sdk library module name to construct a scope specific
+ // The scope specific suffix to add to the sdk library module name to construct a scope specific
// module name.
moduleSuffix string
@@ -193,6 +212,11 @@
}
}
+ // By default, a library that can access a scope can also access the scope it extends.
+ if scope.canAccess == nil {
+ scope.canAccess = scope.extends
+ }
+
// Escape any special characters in the arguments. This is needed because droidstubs
// passes these directly to the shell command.
scope.droidstubsArgs = proptools.ShellEscapeList(scopeSpecificArgs)
@@ -310,6 +334,14 @@
apiScopeSystemServer = initApiScope(&apiScope{
name: "system-server",
extends: apiScopePublic,
+
+ // The system-server scope can access the module-lib scope.
+ //
+ // A module that provides a system-server API is appended to the standard bootclasspath that is
+ // used by the system server. So, it should be able to access module-lib APIs provided by
+ // libraries on the bootclasspath.
+ canAccess: apiScopeModuleLib,
+
// The system-server scope is disabled by default in legacy mode.
//
// Enabling this would break existing usages.
@@ -926,7 +958,7 @@
// If this does not support the requested api scope then find the closest available
// scope it does support. Returns nil if no such scope is available.
func (c *commonToSdkLibraryAndImport) findClosestScopePath(scope *apiScope) *scopePaths {
- for s := scope; s != nil; s = s.extends {
+ for s := scope; s != nil; s = s.canAccess {
if paths := c.findScopePaths(s); paths != nil {
return paths
}
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index ea7b2f7..096bca8 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"regexp"
+ "strings"
"testing"
"android/soong/android"
@@ -699,6 +700,80 @@
`)
}
+func TestJavaSdkLibrary_SystemServer_AccessToStubScopeLibs(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo-public", "foo-system", "foo-module-lib", "foo-system-server"),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "foo-public",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ public: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-system",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-module-lib",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system: {
+ enabled: true,
+ },
+ module_lib: {
+ enabled: true,
+ },
+ }
+
+ java_sdk_library {
+ name: "foo-system-server",
+ srcs: ["a.java"],
+ api_packages: ["foo"],
+ system_server: {
+ enabled: true,
+ },
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["a.java"],
+ libs: ["foo-public", "foo-system", "foo-module-lib", "foo-system-server"],
+ sdk_version: "system_server_current",
+ }
+ `)
+
+ stubsPath := func(name string, scope *apiScope) string {
+ name = scope.stubsLibraryModuleName(name)
+ return fmt.Sprintf("out/soong/.intermediates/%[1]s/android_common/turbine-combined/%[1]s.jar", name)
+ }
+
+ // The bar library should depend on the highest (where system server is highest and public is
+ // lowest) API scopes provided by each of the foo-* modules. The highest API scope provided by the
+ // foo-<x> module is <x>.
+ barLibrary := result.ModuleForTests("bar", "android_common").Rule("javac")
+ stubLibraries := []string{
+ stubsPath("foo-public", apiScopePublic),
+ stubsPath("foo-system", apiScopeSystem),
+ stubsPath("foo-module-lib", apiScopeModuleLib),
+ stubsPath("foo-system-server", apiScopeSystemServer),
+ }
+ expectedPattern := fmt.Sprintf(`^-classpath .*:\Q%s\E$`, strings.Join(stubLibraries, ":"))
+ if expected, actual := expectedPattern, barLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected pattern %q to match %#q", expected, actual)
+ }
+}
+
func TestJavaSdkLibrary_MissingScope(t *testing.T) {
prepareForJavaTest.
ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(`requires api scope module-lib from foo but it only has \[\] available`)).
diff --git a/rust/compiler.go b/rust/compiler.go
index bf6a488..6055158 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -161,7 +161,7 @@
// This is primarily meant for rust_binary and rust_ffi modules where the default
// linkage of libstd might need to be overridden in some use cases. This should
// generally be avoided with other module types since it may cause collisions at
- // linkage if all dependencies of the root binary module do not link against libstd\
+ // linkage if all dependencies of the root binary module do not link against libstd
// the same way.
Prefer_rlib *bool `android:"arch_variant"`
diff --git a/rust/config/riscv64_device.go b/rust/config/riscv64_device.go
index 3b41a10..d014dbf 100644
--- a/rust/config/riscv64_device.go
+++ b/rust/config/riscv64_device.go
@@ -25,7 +25,7 @@
Riscv64ArchFeatureRustFlags = map[string][]string{"": {}}
Riscv64LinkFlags = []string{}
- Riscv64ArchVariantRustFlags = map[string][]string{}
+ Riscv64ArchVariantRustFlags = map[string][]string{"": {}}
)
func init() {
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 586095c..76cf21a 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -34,6 +34,7 @@
*binaryDecorator
fuzzPackagedModule fuzz.FuzzPackagedModule
+ sharedLibraries android.Paths
}
var _ compiler = (*fuzzDecorator)(nil)
@@ -86,6 +87,15 @@
&fuzzer.fuzzPackagedModule.FuzzProperties)
}
+func (fuzzer *fuzzDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
+ out := fuzzer.binaryDecorator.compile(ctx, flags, deps)
+
+ // Grab the list of required shared libraries.
+ fuzzer.sharedLibraries = cc.CollectAllSharedDependencies(ctx)
+
+ return out
+}
+
func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage {
return RlibLinkage
}
@@ -149,11 +159,8 @@
// The executable.
files = append(files, fuzz.FileToZip{rustModule.UnstrippedOutputFile(), ""})
- // Grab the list of required shared libraries.
- sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)
-
// Package shared libraries
- files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
+ files = append(files, cc.GetSharedLibsToZip(fuzzModule.sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
diff --git a/rust/rust.go b/rust/rust.go
index 7342a14..28a300b 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1664,6 +1664,10 @@
}
}
+func (c *Module) Partition() string {
+ return ""
+}
+
var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh
index 6bc0165..61d131b 100755
--- a/tests/apex_comparison_tests.sh
+++ b/tests/apex_comparison_tests.sh
@@ -58,7 +58,7 @@
######################
build/soong/soong_ui.bash --make-mode BP2BUILD_VERBOSE=1 --skip-soong-tests bp2build
-BAZEL_OUT="$(call_bazel info output_path)"
+BAZEL_OUT="$(call_bazel info --config=bp2build output_path)"
export TARGET_PRODUCT="module_arm"
call_bazel build --config=bp2build --config=ci --config=android \
diff --git a/tests/mixed_mode_test.sh b/tests/mixed_mode_test.sh
index b408fd3..f6fffad 100755
--- a/tests/mixed_mode_test.sh
+++ b/tests/mixed_mode_test.sh
@@ -14,7 +14,9 @@
setup
create_mock_bazel
- STANDALONE_BAZEL=true run_bazel info
+ run_soong bp2build
+
+ run_bazel info --config=bp2build
}
test_bazel_smoke
diff --git a/ui/build/build.go b/ui/build/build.go
index ab8cd56..2022e50 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -112,10 +112,6 @@
// checkBazelMode fails the build if there are conflicting arguments for which bazel
// build mode to use.
func checkBazelMode(ctx Context, config Config) {
- if config.Environment().IsEnvTrue("USE_BAZEL_ANALYSIS") {
- ctx.Fatalln("USE_BAZEL_ANALYSIS is deprecated. Unset USE_BAZEL_ANALYSIS.\n" +
- "Use --bazel-mode-dev instead. For example: `m --bazel-mode-dev nothing`")
- }
if config.bazelProdMode && config.bazelDevMode {
ctx.Fatalln("Conflicting bazel mode.\n" +
"Do not specify both --bazel-mode and --bazel-mode-dev")
diff --git a/ui/build/config.go b/ui/build/config.go
index 14a99d0..2060660 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -71,6 +71,7 @@
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.
@@ -756,6 +757,8 @@
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" {
@@ -833,7 +836,7 @@
return true
}
- if !c.JsonModuleGraph() && !c.Bp2Build() && !c.Queryview() && !c.SoongDocs() {
+ if !c.JsonModuleGraph() && !c.Bp2Build() && !c.Queryview() && !c.SoongDocs() && !c.ApiBp2build() {
// Command line was empty, the default Ninja target is built
return true
}
@@ -916,6 +919,10 @@
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")
}
@@ -957,6 +964,10 @@
return c.bp2build
}
+func (c *configImpl) ApiBp2build() bool {
+ return c.apiBp2build
+}
+
func (c *configImpl) Queryview() bool {
return c.queryview
}
diff --git a/ui/build/soong.go b/ui/build/soong.go
index ac00fe6..e0d67cc 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -45,6 +45,7 @@
bp2buildTag = "bp2build"
jsonModuleGraphTag = "modulegraph"
queryviewTag = "queryview"
+ apiBp2buildTag = "api_bp2build"
soongDocsTag = "soong_docs"
// bootstrapEpoch is used to determine if an incremental build is incompatible with the current
@@ -237,6 +238,7 @@
config.NamedGlobFile(bp2buildTag),
config.NamedGlobFile(jsonModuleGraphTag),
config.NamedGlobFile(queryviewTag),
+ config.NamedGlobFile(apiBp2buildTag),
config.NamedGlobFile(soongDocsTag),
}
}
@@ -307,6 +309,19 @@
fmt.Sprintf("generating the Soong module graph as a Bazel workspace at %s", queryviewDir),
)
+ // 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")
+ apiBp2buildInvocation := primaryBuilderInvocation(
+ config,
+ apiBp2buildTag,
+ config.ApiBp2buildMarkerFile(),
+ []string{
+ "--bazel_api_bp2build_dir", apiBp2buildDir,
+ },
+ fmt.Sprintf("generating BUILD files for API contributions at %s", apiBp2buildDir),
+ )
+
soongDocsInvocation := primaryBuilderInvocation(
config,
soongDocsTag,
@@ -345,6 +360,7 @@
bp2buildInvocation,
jsonModuleGraphInvocation,
queryviewInvocation,
+ apiBp2buildInvocation,
soongDocsInvocation},
}
@@ -417,6 +433,10 @@
checkEnvironmentFile(soongBuildEnv, config.UsedEnvFile(queryviewTag))
}
+ if config.ApiBp2build() {
+ checkEnvironmentFile(soongBuildEnv, config.UsedEnvFile(apiBp2buildTag))
+ }
+
if config.SoongDocs() {
checkEnvironmentFile(soongBuildEnv, config.UsedEnvFile(soongDocsTag))
}
@@ -480,6 +500,10 @@
targets = append(targets, config.QueryviewMarkerFile())
}
+ if config.ApiBp2build() {
+ targets = append(targets, config.ApiBp2buildMarkerFile())
+ }
+
if config.SoongDocs() {
targets = append(targets, config.SoongDocsHtml())
}