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

Commit 4aeaf37b authored by Alex Márquez Pérez Muñíz Díaz Púras Thaureaux's avatar Alex Márquez Pérez Muñíz Díaz Púras Thaureaux Committed by Gerrit Code Review
Browse files

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
parents 30204afc 62585e84
Loading
Loading
Loading
Loading
+18 −8
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ type CcInfo struct {
	// be a subset of OutputFiles. (or shared libraries, this will be equal to OutputFiles,
	// 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).
	// but general cc_library will also have dynamic libraries in output files).
	RootDynamicLibraries []string
	RootDynamicLibraries []string
	TocFile              string
}
}


type getOutputFilesRequestType struct{}
type getOutputFilesRequestType struct{}
@@ -100,14 +101,15 @@ func (g getCcInfoType) Name() string {
func (g getCcInfoType) StarlarkFunctionBody() string {
func (g getCcInfoType) StarlarkFunctionBody() string {
	return `
	return `
outputFiles = [f.path for f in target.files.to_list()]
outputFiles = [f.path for f in target.files.to_list()]
cc_info = providers(target)["CcInfo"]


includes = providers(target)["CcInfo"].compilation_context.includes.to_list()
includes = cc_info.compilation_context.includes.to_list()
system_includes = providers(target)["CcInfo"].compilation_context.system_includes.to_list()
system_includes = cc_info.compilation_context.system_includes.to_list()


ccObjectFiles = []
ccObjectFiles = []
staticLibraries = []
staticLibraries = []
rootStaticArchives = []
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 linker_input in linker_inputs:
  for library in linker_input.libraries:
  for library in linker_input.libraries:
@@ -120,11 +122,17 @@ for linker_input in linker_inputs:


rootDynamicLibraries = []
rootDynamicLibraries = []


if "@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo" in providers(target):
shared_info_tag = "@rules_cc//examples:experimental_cc_shared_library.bzl%CcSharedLibraryInfo"
  shared_info = providers(target)["@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:
  for lib in shared_info.linker_input.libraries:
    rootDynamicLibraries += [lib.dynamic_library.path]
    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 = [
returns = [
  outputFiles,
  outputFiles,
  staticLibraries,
  staticLibraries,
@@ -132,10 +140,10 @@ returns = [
  includes,
  includes,
  system_includes,
  system_includes,
  rootStaticArchives,
  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.
// 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
	var ccObjects []string


	splitString := strings.Split(rawString, "|")
	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)
		return CcInfo{}, fmt.Errorf("Expected %d items, got %q", expectedLen, splitString)
	}
	}
	outputFilesString := splitString[0]
	outputFilesString := splitString[0]
@@ -159,6 +167,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
	systemIncludes := splitOrEmpty(splitString[4], ", ")
	systemIncludes := splitOrEmpty(splitString[4], ", ")
	rootStaticArchives := splitOrEmpty(splitString[5], ", ")
	rootStaticArchives := splitOrEmpty(splitString[5], ", ")
	rootDynamicLibraries := splitOrEmpty(splitString[6], ", ")
	rootDynamicLibraries := splitOrEmpty(splitString[6], ", ")
	tocFile := splitString[7] // NOTE: Will be the empty string if there wasn't
	return CcInfo{
	return CcInfo{
		OutputFiles:          outputFiles,
		OutputFiles:          outputFiles,
		CcObjectFiles:        ccObjects,
		CcObjectFiles:        ccObjects,
@@ -167,6 +176,7 @@ func (g getCcInfoType) ParseResult(rawString string) (CcInfo, error) {
		SystemIncludes:       systemIncludes,
		SystemIncludes:       systemIncludes,
		RootStaticArchives:   rootStaticArchives,
		RootStaticArchives:   rootStaticArchives,
		RootDynamicLibraries: rootDynamicLibraries,
		RootDynamicLibraries: rootDynamicLibraries,
		TocFile:              tocFile,
	}, nil
	}, nil
}
}


+8 −5
Original line number Original line Diff line number Diff line
@@ -71,7 +71,7 @@ func TestGetCcInfoParseResults(t *testing.T) {
	}{
	}{
		{
		{
			description: "no result",
			description: "no result",
			input:       "||||||",
			input:       "|||||||",
			expectedOutput: CcInfo{
			expectedOutput: CcInfo{
				OutputFiles:          []string{},
				OutputFiles:          []string{},
				CcObjectFiles:        []string{},
				CcObjectFiles:        []string{},
@@ -80,11 +80,12 @@ func TestGetCcInfoParseResults(t *testing.T) {
				SystemIncludes:       []string{},
				SystemIncludes:       []string{},
				RootStaticArchives:   []string{},
				RootStaticArchives:   []string{},
				RootDynamicLibraries: []string{},
				RootDynamicLibraries: []string{},
				TocFile:              "",
			},
			},
		},
		},
		{
		{
			description: "only output",
			description: "only output",
			input:       "test||||||",
			input:       "test|||||||",
			expectedOutput: CcInfo{
			expectedOutput: CcInfo{
				OutputFiles:          []string{"test"},
				OutputFiles:          []string{"test"},
				CcObjectFiles:        []string{},
				CcObjectFiles:        []string{},
@@ -93,11 +94,12 @@ func TestGetCcInfoParseResults(t *testing.T) {
				SystemIncludes:       []string{},
				SystemIncludes:       []string{},
				RootStaticArchives:   []string{},
				RootStaticArchives:   []string{},
				RootDynamicLibraries: []string{},
				RootDynamicLibraries: []string{},
				TocFile:              "",
			},
			},
		},
		},
		{
		{
			description: "all items set",
			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{
			expectedOutput: CcInfo{
				OutputFiles:          []string{"out1", "out2"},
				OutputFiles:          []string{"out1", "out2"},
				CcObjectFiles:        []string{"object1", "object2"},
				CcObjectFiles:        []string{"object1", "object2"},
@@ -106,19 +108,20 @@ func TestGetCcInfoParseResults(t *testing.T) {
				SystemIncludes:       []string{"system/dir", "system/other/dir"},
				SystemIncludes:       []string{"system/dir", "system/other/dir"},
				RootStaticArchives:   []string{"rootstaticarchive1"},
				RootStaticArchives:   []string{"rootstaticarchive1"},
				RootDynamicLibraries: []string{"rootdynamiclibrary1"},
				RootDynamicLibraries: []string{"rootdynamiclibrary1"},
				TocFile:              "lib.so.toc",
			},
			},
		},
		},
		{
		{
			description:          "too few result splits",
			description:          "too few result splits",
			input:                "|",
			input:                "|",
			expectedOutput:       CcInfo{},
			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",
			description:          "too many result splits",
			input:                strings.Repeat("|", 8),
			input:                strings.Repeat("|", 8),
			expectedOutput:       CcInfo{},
			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 {
	for _, tc := range testCases {
+5 −20
Original line number Original line Diff line number Diff line
@@ -370,6 +370,7 @@ func LibrarySharedFactory() android.Module {
	module, library := NewLibrary(android.HostAndDeviceSupported)
	module, library := NewLibrary(android.HostAndDeviceSupported)
	library.BuildOnlyShared()
	library.BuildOnlyShared()
	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
	module.sdkMemberTypes = []android.SdkMemberType{sharedLibrarySdkMemberType}
	module.bazelHandler = &ccLibraryBazelHandler{module: module}
	return module.Init()
	return module.Init()
}
}


@@ -603,7 +604,10 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi


	handler.module.linker.(*libraryDecorator).unstrippedOutputFile = outputFilePath
	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
	handler.module.linker.(*libraryDecorator).tocFile = tocFile


	ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
	ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
@@ -616,25 +620,6 @@ func (handler *ccLibraryBazelHandler) generateSharedBazelBuildActions(ctx androi
	return true
	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 {
func (handler *ccLibraryBazelHandler) GenerateBazelBuildActions(ctx android.ModuleContext, label string) bool {
	bazelCtx := ctx.Config().BazelContext
	bazelCtx := ctx.Config().BazelContext
	ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
	ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType)
+45 −0
Original line number Original line Diff line number Diff line
@@ -320,3 +320,48 @@ func TestLibraryDynamicList(t *testing.T) {
		libfoo.Args["ldFlags"], "-Wl,--dynamic-list,foo.dynamic.txt")
		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)
}