Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3f9e155f authored by Liz Kammer's avatar Liz Kammer
Browse files

Handle simple prebuilt static libraries from bazel

Test: generate & sync BUILD files via bp2build && mixed build droid
Bug: 184192619
Change-Id: I27f0d76c88cbff25f3c7a805f3dfbb1eeaf8e771
parent f29df7cc
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -69,6 +69,10 @@ type BazelContext interface {
	// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
	GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool)

	// GetPrebuiltCcStaticLibraryFiles returns paths to prebuilt cc static libraries, and whether the
	// results were available
	GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool)

	// ** End cquery methods

	// Issues commands to Bazel to receive results for all cquery requests
@@ -126,6 +130,11 @@ func (m MockBazelContext) GetOutputFilesAndCcObjectFiles(label string, archType
	return result, result, ok
}

func (m MockBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
	result, ok := m.AllFiles[label]
	return result, ok
}

func (m MockBazelContext) InvokeBazel() error {
	panic("unimplemented")
}
@@ -169,6 +178,19 @@ func (bazelCtx *bazelContext) GetOutputFilesAndCcObjectFiles(label string, archT
	return outputFiles, ccObjects, ok
}

// GetPrebuiltCcStaticLibraryFiles returns a slice of prebuilt static libraries for the given
// label/archType if there are query results; otherwise, it enqueues the query and returns false.
func (bazelCtx *bazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
	result, ok := bazelCtx.cquery(label, cquery.GetPrebuiltCcStaticLibraryFiles, archType)
	if !ok {
		return nil, false
	}

	bazelOutput := strings.TrimSpace(result)
	ret := cquery.GetPrebuiltCcStaticLibraryFiles.ParseResult(bazelOutput)
	return ret, ok
}

func (n noopBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
	panic("unimplemented")
}
@@ -177,6 +199,10 @@ func (n noopBazelContext) GetOutputFilesAndCcObjectFiles(label string, archType
	panic("unimplemented")
}

func (n noopBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
	panic("unimplemented")
}

func (n noopBazelContext) InvokeBazel() error {
	panic("unimplemented")
}
+31 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ import (
var (
	GetOutputFiles                  = &getOutputFilesRequestType{}
	GetOutputFilesAndCcObjectFiles  = &getOutputFilesAndCcObjectFilesType{}
	GetPrebuiltCcStaticLibraryFiles = &getPrebuiltCcStaticLibraryFiles{}
)

type GetOutputFilesAndCcObjectFiles_Result struct {
@@ -86,6 +87,34 @@ func (g getOutputFilesAndCcObjectFilesType) ParseResult(rawString string) GetOut
	return GetOutputFilesAndCcObjectFiles_Result{outputFiles, ccObjects}
}

type getPrebuiltCcStaticLibraryFiles struct{}

// Name returns the name of the starlark function to get prebuilt cc static library files
func (g getPrebuiltCcStaticLibraryFiles) Name() string {
	return "getPrebuiltCcStaticLibraryFiles"
}

// StarlarkFunctionBody returns the unindented body of a starlark function for extracting the static
// library paths from a cc_import module.
func (g getPrebuiltCcStaticLibraryFiles) StarlarkFunctionBody() string {
	return `
linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()

static_libraries = []
for linker_input in linker_inputs:
  for library in linker_input.libraries:
    static_libraries.append(library.static_library.path)

return ', '.join(static_libraries)`
}

// ParseResult returns a slice of bazel output paths to static libraries if any exist for the given
// rawString corresponding to the string output which was created by evaluating the
// StarlarkFunctionBody.
func (g getPrebuiltCcStaticLibraryFiles) ParseResult(rawString string) []string {
	return strings.Split(rawString, ", ")
}

// splitOrEmpty is a modification of strings.Split() that returns an empty list
// if the given string is empty.
func splitOrEmpty(s string, sep string) []string {
+47 −0
Original line number Diff line number Diff line
@@ -305,6 +305,7 @@ func PrebuiltStaticLibraryFactory() android.Module {
func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
	module, library := NewPrebuiltLibrary(hod)
	library.BuildOnlyStatic()
	module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library}
	return module, library
}

@@ -319,6 +320,52 @@ type prebuiltObjectLinker struct {
	properties prebuiltObjectProperties
}

type prebuiltStaticLibraryBazelHandler struct {
	bazelHandler

	module  *Module
	library *libraryDecorator
}

func (h *prebuiltStaticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
	bazelCtx := ctx.Config().BazelContext
	staticLibs, ok := bazelCtx.GetPrebuiltCcStaticLibraryFiles(label, ctx.Arch().ArchType)
	if !ok {
		return false
	}
	if len(staticLibs) > 1 {
		ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
		return false
	}

	// TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags

	// 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(staticLibs) == 0 {
		h.module.outputFile = android.OptionalPath{}
		return true
	}

	out := android.PathForBazelOut(ctx, staticLibs[0])
	h.module.outputFile = android.OptionalPathForPath(out)

	depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(out).Build()
	ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
		StaticLibrary: out,

		TransitiveStaticLibrariesForOrdering: depSet,
	})

	return true
}

func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
	return &p.Prebuilt
}