Merge "Enable Mixed Builds for Prebuilt Library"
This commit is contained in:
commit
74e8df0741
5 changed files with 219 additions and 47 deletions
|
@ -37,14 +37,15 @@ const (
|
|||
|
||||
var (
|
||||
Bp2buildDefaultConfig = Bp2BuildConfig{
|
||||
"art/libartpalette": Bp2BuildDefaultTrueRecursively,
|
||||
"art/libdexfile": Bp2BuildDefaultTrueRecursively,
|
||||
"art/libnativebridge": Bp2BuildDefaultTrueRecursively,
|
||||
"art/runtime": Bp2BuildDefaultTrueRecursively,
|
||||
"art/tools": Bp2BuildDefaultTrue,
|
||||
"bionic": Bp2BuildDefaultTrueRecursively,
|
||||
"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
|
||||
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
|
||||
"prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively,
|
||||
"art/libartpalette": Bp2BuildDefaultTrueRecursively,
|
||||
"art/libdexfile": Bp2BuildDefaultTrueRecursively,
|
||||
"art/libnativebridge": Bp2BuildDefaultTrueRecursively,
|
||||
"art/runtime": Bp2BuildDefaultTrueRecursively,
|
||||
"art/tools": Bp2BuildDefaultTrue,
|
||||
"bionic": Bp2BuildDefaultTrueRecursively,
|
||||
"bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue,
|
||||
"build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively,
|
||||
"build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively,
|
||||
"build/bazel/examples/python": Bp2BuildDefaultTrueRecursively,
|
||||
"build/bazel/examples/gensrcs": Bp2BuildDefaultTrueRecursively,
|
||||
|
|
|
@ -110,6 +110,18 @@ func RemoveOptionalPrebuiltPrefix(name string) string {
|
|||
return strings.TrimPrefix(name, "prebuilt_")
|
||||
}
|
||||
|
||||
// RemoveOptionalPrebuiltPrefixFromBazelLabel removes the "prebuilt_" prefix from the *target name* of a Bazel label.
|
||||
// This differs from RemoveOptionalPrebuiltPrefix in that it does not remove it from the start of the string, but
|
||||
// instead removes it from the target name itself.
|
||||
func RemoveOptionalPrebuiltPrefixFromBazelLabel(label string) string {
|
||||
splitLabel := strings.Split(label, ":")
|
||||
bazelModuleNameNoPrebuilt := RemoveOptionalPrebuiltPrefix(splitLabel[1])
|
||||
return strings.Join([]string{
|
||||
splitLabel[0],
|
||||
bazelModuleNameNoPrebuilt,
|
||||
}, ":")
|
||||
}
|
||||
|
||||
func (p *Prebuilt) Name(name string) string {
|
||||
return PrebuiltNameFromSource(name)
|
||||
}
|
||||
|
|
11
cc/cc.go
11
cc/cc.go
|
@ -1789,13 +1789,20 @@ func GetSubnameProperty(actx android.ModuleContext, c LinkableInterface) string
|
|||
var _ android.MixedBuildBuildable = (*Module)(nil)
|
||||
|
||||
func (c *Module) getBazelModuleLabel(ctx android.BaseModuleContext) string {
|
||||
var bazelModuleLabel string
|
||||
if c.typ() == fullLibrary && c.static() {
|
||||
// cc_library is a special case in bp2build; two targets are generated -- one for each
|
||||
// of the shared and static variants. The shared variant keeps the module name, but the
|
||||
// static variant uses a different suffixed name.
|
||||
return bazelLabelForStaticModule(ctx, c)
|
||||
bazelModuleLabel = bazelLabelForStaticModule(ctx, c)
|
||||
} else {
|
||||
bazelModuleLabel = c.GetBazelLabel(ctx, c)
|
||||
}
|
||||
return c.GetBazelLabel(ctx, c)
|
||||
labelNoPrebuilt := bazelModuleLabel
|
||||
if c.IsPrebuilt() {
|
||||
labelNoPrebuilt = android.RemoveOptionalPrebuiltPrefixFromBazelLabel(bazelModuleLabel)
|
||||
}
|
||||
return labelNoPrebuilt
|
||||
}
|
||||
|
||||
func (c *Module) QueueBazelCall(ctx android.BaseModuleContext) {
|
||||
|
|
|
@ -55,6 +55,13 @@ type prebuiltLinkerProperties struct {
|
|||
// This is needed only if this library is linked by other modules in build time.
|
||||
// Only makes sense for the Windows target.
|
||||
Windows_import_lib *string `android:"path,arch_variant"`
|
||||
|
||||
// MixedBuildsDisabled is true if and only if building this prebuilt is explicitly disabled in mixed builds for either
|
||||
// its static or shared version on the current build variant. This is to prevent Bazel targets for build variants with
|
||||
// which either the static or shared version is incompatible from participating in mixed buiods. Please note that this
|
||||
// is an override and does not fully determine whether Bazel or Soong will be used. For the full determination, see
|
||||
// cc.ProcessBazelQueryResponse, cc.QueueBazelCall, and cc.MixedBuildsDisabled.
|
||||
MixedBuildsDisabled bool `blueprint:"mutated"`
|
||||
}
|
||||
|
||||
type prebuiltLinker struct {
|
||||
|
@ -244,6 +251,7 @@ func (p *prebuiltLibraryLinker) nativeCoverage() bool {
|
|||
|
||||
func (p *prebuiltLibraryLinker) disablePrebuilt() {
|
||||
p.properties.Srcs = nil
|
||||
p.properties.MixedBuildsDisabled = true
|
||||
}
|
||||
|
||||
// Implements versionedInterface
|
||||
|
@ -255,6 +263,7 @@ func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string)
|
|||
module, library := NewLibrary(hod)
|
||||
module.compiler = nil
|
||||
module.bazelable = true
|
||||
module.bazelHandler = &prebuiltLibraryBazelHandler{module: module, library: library}
|
||||
|
||||
prebuilt := &prebuiltLibraryLinker{
|
||||
libraryDecorator: library,
|
||||
|
@ -310,8 +319,6 @@ func PrebuiltSharedTestLibraryFactory() android.Module {
|
|||
func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
|
||||
module, library := NewPrebuiltLibrary(hod, "srcs")
|
||||
library.BuildOnlyShared()
|
||||
module.bazelable = true
|
||||
module.bazelHandler = &prebuiltSharedLibraryBazelHandler{module: module, library: library}
|
||||
|
||||
// Prebuilt shared libraries can be included in APEXes
|
||||
android.InitApexModule(module)
|
||||
|
@ -329,8 +336,7 @@ func PrebuiltStaticLibraryFactory() android.Module {
|
|||
func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
|
||||
module, library := NewPrebuiltLibrary(hod, "srcs")
|
||||
library.BuildOnlyStatic()
|
||||
module.bazelable = true
|
||||
module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library}
|
||||
|
||||
return module, library
|
||||
}
|
||||
|
||||
|
@ -406,29 +412,52 @@ type prebuiltObjectLinker struct {
|
|||
properties prebuiltObjectProperties
|
||||
}
|
||||
|
||||
type prebuiltStaticLibraryBazelHandler struct {
|
||||
type prebuiltLibraryBazelHandler struct {
|
||||
module *Module
|
||||
library *libraryDecorator
|
||||
}
|
||||
|
||||
var _ BazelHandler = (*prebuiltStaticLibraryBazelHandler)(nil)
|
||||
var _ BazelHandler = (*prebuiltLibraryBazelHandler)(nil)
|
||||
|
||||
func (h *prebuiltStaticLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
|
||||
func (h *prebuiltLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
|
||||
if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
|
||||
return
|
||||
}
|
||||
bazelCtx := ctx.Config().BazelContext
|
||||
bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
|
||||
}
|
||||
|
||||
func (h *prebuiltStaticLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
|
||||
func (h *prebuiltLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
|
||||
if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
|
||||
return
|
||||
}
|
||||
bazelCtx := ctx.Config().BazelContext
|
||||
ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if h.module.static() {
|
||||
if ok := h.processStaticBazelQueryResponse(ctx, label, ccInfo); !ok {
|
||||
return
|
||||
}
|
||||
} else if h.module.Shared() {
|
||||
if ok := h.processSharedBazelQueryResponse(ctx, label, ccInfo); !ok {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
h.module.maybeUnhideFromMake()
|
||||
}
|
||||
|
||||
func (h *prebuiltLibraryBazelHandler) processStaticBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
|
||||
staticLibs := ccInfo.CcStaticLibraryFiles
|
||||
if len(staticLibs) > 1 {
|
||||
ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags
|
||||
|
@ -443,7 +472,7 @@ func (h *prebuiltStaticLibraryBazelHandler) ProcessBazelQueryResponse(ctx androi
|
|||
|
||||
if len(staticLibs) == 0 {
|
||||
h.module.outputFile = android.OptionalPath{}
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
out := android.PathForBazelOut(ctx, staticLibs[0])
|
||||
|
@ -455,31 +484,15 @@ func (h *prebuiltStaticLibraryBazelHandler) ProcessBazelQueryResponse(ctx androi
|
|||
|
||||
TransitiveStaticLibrariesForOrdering: depSet,
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type prebuiltSharedLibraryBazelHandler struct {
|
||||
module *Module
|
||||
library *libraryDecorator
|
||||
}
|
||||
|
||||
var _ BazelHandler = (*prebuiltSharedLibraryBazelHandler)(nil)
|
||||
|
||||
func (h *prebuiltSharedLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
|
||||
bazelCtx := ctx.Config().BazelContext
|
||||
bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
|
||||
}
|
||||
|
||||
func (h *prebuiltSharedLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
|
||||
bazelCtx := ctx.Config().BazelContext
|
||||
ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
|
||||
if err != nil {
|
||||
ctx.ModuleErrorf(err.Error())
|
||||
return
|
||||
}
|
||||
func (h *prebuiltLibraryBazelHandler) processSharedBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
|
||||
sharedLibs := ccInfo.CcSharedLibraryFiles
|
||||
if len(sharedLibs) != 1 {
|
||||
if len(sharedLibs) > 1 {
|
||||
ctx.ModuleErrorf("expected 1 shared library from bazel target %s, got %q", label, sharedLibs)
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO(b/184543518): cc_prebuilt_library_shared may have properties for re-exporting flags
|
||||
|
@ -487,14 +500,9 @@ func (h *prebuiltSharedLibraryBazelHandler) ProcessBazelQueryResponse(ctx androi
|
|||
// TODO(eakammer):Add stub-related flags if this library is a stub library.
|
||||
// h.library.exportVersioningMacroIfNeeded(ctx)
|
||||
|
||||
// Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
|
||||
// validation will fail. For now, set this to an empty list.
|
||||
// TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
|
||||
h.library.collectedSnapshotHeaders = android.Paths{}
|
||||
|
||||
if len(sharedLibs) == 0 {
|
||||
h.module.outputFile = android.OptionalPath{}
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
out := android.PathForBazelOut(ctx, sharedLibs[0])
|
||||
|
@ -519,6 +527,7 @@ func (h *prebuiltSharedLibraryBazelHandler) ProcessBazelQueryResponse(ctx androi
|
|||
|
||||
h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
|
||||
h.module.maybeUnhideFromMake()
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
|
||||
|
|
|
@ -381,6 +381,149 @@ func TestPrebuiltLibrarySanitized(t *testing.T) {
|
|||
assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a")
|
||||
}
|
||||
|
||||
func TestPrebuiltLibraryWithBazel(t *testing.T) {
|
||||
const bp = `
|
||||
cc_prebuilt_library {
|
||||
name: "foo",
|
||||
shared: {
|
||||
srcs: ["foo.so"],
|
||||
},
|
||||
static: {
|
||||
srcs: ["foo.a"],
|
||||
},
|
||||
bazel_module: { label: "//foo/bar:bar" },
|
||||
}`
|
||||
outBaseDir := "outputbase"
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForPrebuiltTest,
|
||||
android.FixtureModifyConfig(func(config android.Config) {
|
||||
config.BazelContext = android.MockBazelContext{
|
||||
OutputBaseDir: outBaseDir,
|
||||
LabelToCcInfo: map[string]cquery.CcInfo{
|
||||
"//foo/bar:bar": cquery.CcInfo{
|
||||
CcSharedLibraryFiles: []string{"foo.so"},
|
||||
},
|
||||
"//foo/bar:bar_bp2build_cc_library_static": cquery.CcInfo{
|
||||
CcStaticLibraryFiles: []string{"foo.a"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
).RunTestWithBp(t, bp)
|
||||
sharedFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
|
||||
pathPrefix := outBaseDir + "/execroot/__main__/"
|
||||
|
||||
sharedInfo := result.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
||||
android.AssertPathRelativeToTopEquals(t,
|
||||
"prebuilt library shared target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
|
||||
pathPrefix+"foo.so", sharedInfo.SharedLibrary)
|
||||
|
||||
outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
|
||||
}
|
||||
expectedOutputFiles := []string{pathPrefix + "foo.so"}
|
||||
android.AssertDeepEquals(t,
|
||||
"prebuilt library shared target output files did not match expected.",
|
||||
expectedOutputFiles, outputFiles.Strings())
|
||||
|
||||
staticFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
|
||||
staticInfo := result.ModuleProvider(staticFoo, StaticLibraryInfoProvider).(StaticLibraryInfo)
|
||||
android.AssertPathRelativeToTopEquals(t,
|
||||
"prebuilt library static target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
|
||||
pathPrefix+"foo.a", staticInfo.StaticLibrary)
|
||||
|
||||
staticOutputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error getting cc_object staticOutputFiles %s", err)
|
||||
}
|
||||
expectedStaticOutputFiles := []string{pathPrefix + "foo.a"}
|
||||
android.AssertDeepEquals(t,
|
||||
"prebuilt library static target output files did not match expected.",
|
||||
expectedStaticOutputFiles, staticOutputFiles.Strings())
|
||||
}
|
||||
|
||||
func TestPrebuiltLibraryWithBazelStaticDisabled(t *testing.T) {
|
||||
const bp = `
|
||||
cc_prebuilt_library {
|
||||
name: "foo",
|
||||
shared: {
|
||||
srcs: ["foo.so"],
|
||||
},
|
||||
static: {
|
||||
enabled: false
|
||||
},
|
||||
bazel_module: { label: "//foo/bar:bar" },
|
||||
}`
|
||||
outBaseDir := "outputbase"
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForPrebuiltTest,
|
||||
android.FixtureModifyConfig(func(config android.Config) {
|
||||
config.BazelContext = android.MockBazelContext{
|
||||
OutputBaseDir: outBaseDir,
|
||||
LabelToCcInfo: map[string]cquery.CcInfo{
|
||||
"//foo/bar:bar": cquery.CcInfo{
|
||||
CcSharedLibraryFiles: []string{"foo.so"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
).RunTestWithBp(t, bp)
|
||||
sharedFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
|
||||
pathPrefix := outBaseDir + "/execroot/__main__/"
|
||||
|
||||
sharedInfo := result.ModuleProvider(sharedFoo, SharedLibraryInfoProvider).(SharedLibraryInfo)
|
||||
android.AssertPathRelativeToTopEquals(t,
|
||||
"prebuilt library shared target path did not exist or did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
|
||||
pathPrefix+"foo.so", sharedInfo.SharedLibrary)
|
||||
|
||||
outputFiles, err := sharedFoo.(android.OutputFileProducer).OutputFiles("")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
|
||||
}
|
||||
expectedOutputFiles := []string{pathPrefix + "foo.so"}
|
||||
android.AssertDeepEquals(t,
|
||||
"prebuilt library shared target output files did not match expected.",
|
||||
expectedOutputFiles, outputFiles.Strings())
|
||||
}
|
||||
|
||||
func TestPrebuiltLibraryStaticWithBazel(t *testing.T) {
|
||||
const bp = `
|
||||
cc_prebuilt_library_static {
|
||||
name: "foo",
|
||||
srcs: ["foo.so"],
|
||||
bazel_module: { label: "//foo/bar:bar" },
|
||||
}`
|
||||
outBaseDir := "outputbase"
|
||||
result := android.GroupFixturePreparers(
|
||||
prepareForPrebuiltTest,
|
||||
android.FixtureModifyConfig(func(config android.Config) {
|
||||
config.BazelContext = android.MockBazelContext{
|
||||
OutputBaseDir: outBaseDir,
|
||||
LabelToCcInfo: map[string]cquery.CcInfo{
|
||||
"//foo/bar:bar": cquery.CcInfo{
|
||||
CcStaticLibraryFiles: []string{"foo.so"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
).RunTestWithBp(t, bp)
|
||||
staticFoo := result.ModuleForTests("foo", "android_arm_armv7-a-neon_static").Module()
|
||||
pathPrefix := outBaseDir + "/execroot/__main__/"
|
||||
|
||||
info := result.ModuleProvider(staticFoo, StaticLibraryInfoProvider).(StaticLibraryInfo)
|
||||
android.AssertPathRelativeToTopEquals(t,
|
||||
"prebuilt library static path did not match expected. If the base path is what does not match, it is likely that Soong built this module instead of Bazel.",
|
||||
pathPrefix+"foo.so", info.StaticLibrary)
|
||||
|
||||
outputFiles, err := staticFoo.(android.OutputFileProducer).OutputFiles("")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
|
||||
}
|
||||
expectedOutputFiles := []string{pathPrefix + "foo.so"}
|
||||
android.AssertDeepEquals(t, "prebuilt library static output files did not match expected.", expectedOutputFiles, outputFiles.Strings())
|
||||
}
|
||||
|
||||
func TestPrebuiltLibrarySharedWithBazelWithoutToc(t *testing.T) {
|
||||
const bp = `
|
||||
cc_prebuilt_library_shared {
|
||||
|
|
Loading…
Reference in a new issue