diff --git a/bazel/aquery.go b/bazel/aquery.go index bda3a1ae6..d1119cb43 100644 --- a/bazel/aquery.go +++ b/bazel/aquery.go @@ -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 diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go index c30abeb87..92135c64a 100644 --- a/bazel/cquery/request_type.go +++ b/bazel/cquery/request_type.go @@ -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 } diff --git a/bazel/cquery/request_type_test.go b/bazel/cquery/request_type_test.go index 6369999fb..602849e7f 100644 --- a/bazel/cquery/request_type_test.go +++ b/bazel/cquery/request_type_test.go @@ -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 { diff --git a/cc/library.go b/cc/library.go index 873489db2..1c41fd850 100644 --- a/cc/library.go +++ b/cc/library.go @@ -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))