Merge "Support mixedbuilds for static variant cc_library"

This commit is contained in:
Christopher Parsons 2021-06-04 15:09:21 +00:00 committed by Gerrit Code Review
commit fa4ab8a7f4
4 changed files with 32 additions and 19 deletions

View file

@ -247,7 +247,7 @@ func AqueryBuildStatements(aqueryJsonProto []byte) ([]BuildStatement, error) {
func shouldSkipAction(a action) bool {
// TODO(b/180945121): Handle symlink actions.
if a.Mnemonic == "Symlink" || a.Mnemonic == "SourceSymlinkManifest" || a.Mnemonic == "SymlinkTree" {
if a.Mnemonic == "Symlink" || a.Mnemonic == "SourceSymlinkManifest" || a.Mnemonic == "SymlinkTree" || a.Mnemonic == "SolibSymlink" {
return true
}
// Middleman actions are not handled like other actions; they are handled separately as a

View file

@ -16,6 +16,10 @@ type CcInfo struct {
CcStaticLibraryFiles []string
Includes []string
SystemIncludes []string
// Archives owned by the current target (not by its dependencies). These will
// be a subset of OutputFiles. (or static libraries, this will be equal to OutputFiles,
// but general cc_library will also have dynamic libraries in output files).
RootStaticArchives []string
}
type getOutputFilesRequestType struct{}
@ -70,6 +74,7 @@ system_includes = providers(target)["CcInfo"].compilation_context.system_include
ccObjectFiles = []
staticLibraries = []
rootStaticArchives = []
linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()
for linker_input in linker_inputs:
@ -78,6 +83,8 @@ for linker_input in linker_inputs:
ccObjectFiles += [object.path]
if library.static_library:
staticLibraries.append(library.static_library.path)
if linker_input.owner == target.label:
rootStaticArchives.append(library.static_library.path)
returns = [
outputFiles,
@ -85,6 +92,7 @@ returns = [
ccObjectFiles,
includes,
system_includes,
rootStaticArchives
]
return "|".join([", ".join(r) for r in returns])`
@ -98,7 +106,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
var ccObjects []string
splitString := strings.Split(rawString, "|")
if expectedLen := 5; len(splitString) != expectedLen {
if expectedLen := 6; len(splitString) != expectedLen {
return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
}
outputFilesString := splitString[0]
@ -109,12 +117,14 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
ccObjects = splitOrEmpty(ccObjectsString, ", ")
includes := splitOrEmpty(splitString[3], ", ")
systemIncludes := splitOrEmpty(splitString[4], ", ")
rootStaticArchives := splitOrEmpty(splitString[5], ", ")
return CcInfo{
OutputFiles: outputFiles,
CcObjectFiles: ccObjects,
CcStaticLibraryFiles: ccStaticLibraries,
Includes: includes,
SystemIncludes: systemIncludes,
RootStaticArchives: rootStaticArchives,
}, nil
}

View file

@ -46,48 +46,51 @@ func TestGetCcInfoParseResults(t *testing.T) {
}{
{
description: "no result",
input: "||||",
input: "|||||",
expectedOutput: CcInfo{
OutputFiles: []string{},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
RootStaticArchives: []string{},
},
},
{
description: "only output",
input: "test||||",
input: "test|||||",
expectedOutput: CcInfo{
OutputFiles: []string{"test"},
CcObjectFiles: []string{},
CcStaticLibraryFiles: []string{},
Includes: []string{},
SystemIncludes: []string{},
RootStaticArchives: []string{},
},
},
{
description: "all items set",
input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir",
input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|rootstaticarchive1",
expectedOutput: CcInfo{
OutputFiles: []string{"out1", "out2"},
CcObjectFiles: []string{"object1", "object2"},
CcStaticLibraryFiles: []string{"static_lib1", "static_lib2"},
Includes: []string{".", "dir/subdir"},
SystemIncludes: []string{"system/dir", "system/other/dir"},
RootStaticArchives: []string{"rootstaticarchive1"},
},
},
{
description: "too few result splits",
input: "|",
expectedOutput: CcInfo{},
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, []string{"", ""}),
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 6, []string{"", ""}),
},
{
description: "too many result splits",
input: strings.Repeat("|", 8),
expectedOutput: CcInfo{},
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 5, make([]string, 9)),
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 6, make([]string, 9)),
},
}
for _, tc := range testCases {

View file

@ -362,6 +362,7 @@ func LibraryFactory() android.Module {
staticLibrarySdkMemberType,
staticAndSharedLibrarySdkMemberType,
}
module.bazelHandler = &ccLibraryBazelHandler{module: module}
return module.Init()
}
@ -370,7 +371,7 @@ func LibraryStaticFactory() android.Module {
module, library := NewLibrary(android.HostAndDeviceSupported)
library.BuildOnlyStatic()
module.sdkMemberTypes = []android.SdkMemberType{staticLibrarySdkMemberType}
module.bazelHandler = &staticLibraryBazelHandler{module: module}
module.bazelHandler = &ccLibraryBazelHandler{module: module}
return module.Init()
}
@ -555,13 +556,17 @@ type libraryDecorator struct {
collectedSnapshotHeaders android.Paths
}
type staticLibraryBazelHandler struct {
type ccLibraryBazelHandler struct {
bazelHandler
module *Module
}
func (handler *staticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
func (handler *ccLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
if !handler.module.static() {
// TODO(cparsons): Support shared libraries.
return false
}
bazelCtx := ctx.Config().BazelContext
ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
if err != nil {
@ -571,18 +576,13 @@ func (handler *staticLibraryBazelHandler) generateBazelBuildActions(ctx android.
if !ok {
return ok
}
outputPaths := ccInfo.OutputFiles
rootStaticArchives := ccInfo.RootStaticArchives
objPaths := ccInfo.CcObjectFiles
if len(outputPaths) > 1 {
// TODO(cparsons): This is actually expected behavior for static libraries with no srcs.
// We should support this.
ctx.ModuleErrorf("expected at most one output file for '%s', but got %s", label, objPaths)
if len(rootStaticArchives) != 1 {
ctx.ModuleErrorf("expected exactly one root archive file for '%s', but got %s", label, rootStaticArchives)
return false
} else if len(outputPaths) == 0 {
handler.module.outputFile = android.OptionalPath{}
return true
}
outputFilePath := android.PathForBazelOut(ctx, outputPaths[0])
outputFilePath := android.PathForBazelOut(ctx, rootStaticArchives[0])
handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
objFiles := make(android.Paths, len(objPaths))