Merge changes from topic "mixed-build-cc-library-shared"
* changes: Expose TocFile via CcInfo Clean up StarlarkFunctionBody for getCcInfoType Incorporate cc_library_shared into mixed builds
This commit is contained in:
committed by
Gerrit Code Review
commit
4aeaf37bb7
@@ -25,6 +25,7 @@ type CcInfo struct {
|
||||
// be a subset of OutputFiles. (or shared libraries, this will be equal to OutputFiles,
|
||||
// but general cc_library will also have dynamic libraries in output files).
|
||||
RootDynamicLibraries []string
|
||||
TocFile string
|
||||
}
|
||||
|
||||
type getOutputFilesRequestType struct{}
|
||||
@@ -100,14 +101,15 @@ func (g getCcInfoType) Name() string {
|
||||
func (g getCcInfoType) StarlarkFunctionBody() string {
|
||||
return `
|
||||
outputFiles = [f.path for f in target.files.to_list()]
|
||||
cc_info = providers(target)["CcInfo"]
|
||||
|
||||
includes = providers(target)["CcInfo"].compilation_context.includes.to_list()
|
||||
system_includes = providers(target)["CcInfo"].compilation_context.system_includes.to_list()
|
||||
includes = cc_info.compilation_context.includes.to_list()
|
||||
system_includes = cc_info.compilation_context.system_includes.to_list()
|
||||
|
||||
ccObjectFiles = []
|
||||
staticLibraries = []
|
||||
rootStaticArchives = []
|
||||
linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()
|
||||
linker_inputs = cc_info.linking_context.linker_inputs.to_list()
|
||||
|
||||
for linker_input in linker_inputs:
|
||||
for library in linker_input.libraries:
|
||||
@@ -120,11 +122,17 @@ for linker_input in linker_inputs:
|
||||
|
||||
rootDynamicLibraries = []
|
||||
|
||||
if "@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo" in providers(target):
|
||||
shared_info = providers(target)["@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo"]
|
||||
shared_info_tag = "@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo"
|
||||
if shared_info_tag in providers(target):
|
||||
shared_info = providers(target)[shared_info_tag]
|
||||
for lib in shared_info.linker_input.libraries:
|
||||
rootDynamicLibraries += [lib.dynamic_library.path]
|
||||
|
||||
toc_file = ""
|
||||
toc_file_tag = "//build/bazel/rules:generate_toc.bzl%CcTocInfo"
|
||||
if toc_file_tag in providers(target):
|
||||
toc_file = providers(target)[toc_file_tag].toc.path
|
||||
|
||||
returns = [
|
||||
outputFiles,
|
||||
staticLibraries,
|
||||
@@ -132,10 +140,10 @@ returns = [
|
||||
includes,
|
||||
system_includes,
|
||||
rootStaticArchives,
|
||||
rootDynamicLibraries
|
||||
rootDynamicLibraries,
|
||||
]
|
||||
|
||||
return "|".join([", ".join(r) for r in returns])`
|
||||
return "|".join([", ".join(r) for r in returns] + [toc_file])`
|
||||
}
|
||||
|
||||
// ParseResult returns a value obtained by parsing the result of the request's Starlark function.
|
||||
@@ -146,7 +154,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
|
||||
var ccObjects []string
|
||||
|
||||
splitString := strings.Split(rawString, "|")
|
||||
if expectedLen := 7; len(splitString) != expectedLen {
|
||||
if expectedLen := 8; len(splitString) != expectedLen {
|
||||
return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
|
||||
}
|
||||
outputFilesString := splitString[0]
|
||||
@@ -159,6 +167,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
|
||||
systemIncludes := splitOrEmpty(splitString[4], ", ")
|
||||
rootStaticArchives := splitOrEmpty(splitString[5], ", ")
|
||||
rootDynamicLibraries := splitOrEmpty(splitString[6], ", ")
|
||||
tocFile := splitString[7] // NOTE: Will be the empty string if there wasn't
|
||||
return CcInfo{
|
||||
OutputFiles: outputFiles,
|
||||
CcObjectFiles: ccObjects,
|
||||
@@ -167,6 +176,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
|
||||
SystemIncludes: systemIncludes,
|
||||
RootStaticArchives: rootStaticArchives,
|
||||
RootDynamicLibraries: rootDynamicLibraries,
|
||||
TocFile: tocFile,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@@ -71,7 +71,7 @@ func TestGetCcInfoParseResults(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
description: "no result",
|
||||
input: "||||||",
|
||||
input: "|||||||",
|
||||
expectedOutput: CcInfo{
|
||||
OutputFiles: []string{},
|
||||
CcObjectFiles: []string{},
|
||||
@@ -80,11 +80,12 @@ func TestGetCcInfoParseResults(t *testing.T) {
|
||||
SystemIncludes: []string{},
|
||||
RootStaticArchives: []string{},
|
||||
RootDynamicLibraries: []string{},
|
||||
TocFile: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "only output",
|
||||
input: "test||||||",
|
||||
input: "test|||||||",
|
||||
expectedOutput: CcInfo{
|
||||
OutputFiles: []string{"test"},
|
||||
CcObjectFiles: []string{},
|
||||
@@ -93,11 +94,12 @@ func TestGetCcInfoParseResults(t *testing.T) {
|
||||
SystemIncludes: []string{},
|
||||
RootStaticArchives: []string{},
|
||||
RootDynamicLibraries: []string{},
|
||||
TocFile: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "all items set",
|
||||
input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|rootstaticarchive1|rootdynamiclibrary1",
|
||||
input: "out1, out2|static_lib1, static_lib2|object1, object2|., dir/subdir|system/dir, system/other/dir|rootstaticarchive1|rootdynamiclibrary1|lib.so.toc",
|
||||
expectedOutput: CcInfo{
|
||||
OutputFiles: []string{"out1", "out2"},
|
||||
CcObjectFiles: []string{"object1", "object2"},
|
||||
@@ -106,19 +108,20 @@ func TestGetCcInfoParseResults(t *testing.T) {
|
||||
SystemIncludes: []string{"system/dir", "system/other/dir"},
|
||||
RootStaticArchives: []string{"rootstaticarchive1"},
|
||||
RootDynamicLibraries: []string{"rootdynamiclibrary1"},
|
||||
TocFile: "lib.so.toc",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "too few result splits",
|
||||
input: "|",
|
||||
expectedOutput: CcInfo{},
|
||||
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 7, []string{"", ""}),
|
||||
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 8, []string{"", ""}),
|
||||
},
|
||||
{
|
||||
description: "too many result splits",
|
||||
input: strings.Repeat("|", 8),
|
||||
expectedOutput: CcInfo{},
|
||||
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 7, make([]string, 9)),
|
||||
expectedErrorMessage: fmt.Sprintf("Expected %d items, got %q", 8, make([]string, 9)),
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
|
@@ -370,6 +370,7 @@ func LibrarySharedFactory() android.Module {
|
||||
module, library := NewLibrary(android.HostAndDeviceSupported)
|
||||
library.BuildOnlyShared()
|
||||
module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
|
||||
module.bazelHandler = &ccLibraryBazelHandler{module: module}
|
||||
return module.Init()
|
||||
}
|
||||
|
||||
@@ -603,7 +604,10 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi
|
||||
|
||||
handler.module.linker.(*libraryDecorator).unstrippedOutputFile = outputFilePath
|
||||
|
||||
tocFile := getTocFile(ctx, label, ccInfo.OutputFiles)
|
||||
var tocFile android.OptionalPath
|
||||
if len(ccInfo.TocFile) > 0 {
|
||||
tocFile = android.OptionalPathForPath(android.PathForBazelOut(ctx, ccInfo.TocFile))
|
||||
}
|
||||
handler.module.linker.(*libraryDecorator).tocFile = tocFile
|
||||
|
||||
ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
|
||||
@@ -616,25 +620,6 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi
|
||||
return true
|
||||
}
|
||||
|
||||
// getTocFile looks for the .so.toc file in the target's output files, if any. The .so.toc file
|
||||
// contains the table of contents of all symbols of a shared object.
|
||||
func getTocFile(ctx android.ModuleContext, label string, outputFiles []string) android.OptionalPath {
|
||||
var tocFile string
|
||||
for _, file := range outputFiles {
|
||||
if strings.HasSuffix(file, ".so.toc") {
|
||||
if tocFile != "" {
|
||||
ctx.ModuleErrorf("The %s target cannot produce more than 1 .toc file.", label)
|
||||
}
|
||||
tocFile = file
|
||||
// Don't break to validate that there are no multiple .toc files per .so.
|
||||
}
|
||||
}
|
||||
if tocFile == "" {
|
||||
return android.OptionalPath{}
|
||||
}
|
||||
return android.OptionalPathForPath(android.PathForBazelOut(ctx, tocFile))
|
||||
}
|
||||
|
||||
func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
|
||||
bazelCtx := ctx.Config().BazelContext
|
||||
ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
|
||||
|
@@ -320,3 +320,48 @@ func TestLibraryDynamicList(t *testing.T) {
|
||||
libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt")
|
||||
|
||||
}
|
||||
|
||||
func TestCcLibrarySharedWithBazel(t *testing.T) {
|
||||
bp := `
|
||||
cc_library_shared {
|
||||
name: "foo",
|
||||
srcs: ["foo.cc"],
|
||||
bazel_module: { label: "//foo/bar:bar" },
|
||||
}`
|
||||
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
|
||||
config.BazelContext = android.MockBazelContext{
|
||||
OutputBaseDir: "outputbase",
|
||||
LabelToCcInfo: map[string]cquery.CcInfo{
|
||||
"//foo/bar:bar": cquery.CcInfo{
|
||||
CcObjectFiles: []string{"foo.o"},
|
||||
Includes: []string{"include"},
|
||||
SystemIncludes: []string{"system_include"},
|
||||
RootDynamicLibraries: []string{"foo.so"},
|
||||
TocFile: "foo.so.toc",
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := testCcWithConfig(t, config)
|
||||
|
||||
sharedFoo := ctx.ModuleForTests("foo", "android_arm_armv7-a-neon_shared").Module()
|
||||
producer := sharedFoo.(android.OutputFileProducer)
|
||||
outputFiles, err := producer.OutputFiles("")
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
|
||||
}
|
||||
expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
|
||||
android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
|
||||
|
||||
tocFilePath := sharedFoo.(*Module).Toc()
|
||||
if !tocFilePath.Valid() {
|
||||
t.Errorf("Invalid tocFilePath: %s", tocFilePath)
|
||||
}
|
||||
tocFile := tocFilePath.Path()
|
||||
expectedToc := "outputbase/execroot/__main__/foo.so.toc"
|
||||
android.AssertStringEquals(t, "toc file", expectedToc, tocFile.String())
|
||||
|
||||
entries := android.AndroidMkEntriesForTest(t, ctx, sharedFoo)[0]
|
||||
expectedFlags := []string{"-Ioutputbase/execroot/__main__/include", "-isystem outputbase/execroot/__main__/system_include"}
|
||||
gotFlags := entries.EntryMap["LOCAL_EXPORT_CFLAGS"]
|
||||
android.AssertDeepEquals(t, "androidmk exported cflags", expectedFlags, gotFlags)
|
||||
}
|
||||
|
Reference in New Issue
Block a user