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

Commit c34d9143 authored by Alexander Smundak's avatar Alexander Smundak Committed by Gerrit Code Review
Browse files

Merge "Add CcUnstrippedInfo provider and use it in mixed builds"

parents 21c71a35 edd16668
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -144,6 +144,9 @@ type BazelContext interface {
	// Returns the results of the GetApexInfo query (including output files)
	GetApexInfo(label string, cfgkey configKey) (cquery.ApexCqueryInfo, error)

	// Returns the results of the GetCcUnstrippedInfo query
	GetCcUnstrippedInfo(label string, cfgkey configKey) (cquery.CcUnstrippedInfo, error)

	// ** end Cquery Results Retrieval Functions

	// Issues commands to Bazel to receive results for all cquery requests
@@ -224,6 +227,7 @@ type MockBazelContext struct {
	LabelToCcInfo       map[string]cquery.CcInfo
	LabelToPythonBinary map[string]string
	LabelToApexInfo     map[string]cquery.ApexCqueryInfo
	LabelToCcBinary     map[string]cquery.CcUnstrippedInfo
}

func (m MockBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
@@ -249,6 +253,11 @@ func (n MockBazelContext) GetApexInfo(_ string, _ configKey) (cquery.ApexCqueryI
	panic("unimplemented")
}

func (m MockBazelContext) GetCcUnstrippedInfo(label string, _ configKey) (cquery.CcUnstrippedInfo, error) {
	result, _ := m.LabelToCcBinary[label]
	return result, nil
}

func (m MockBazelContext) InvokeBazel(_ Config) error {
	panic("unimplemented")
}
@@ -312,6 +321,14 @@ func (bazelCtx *bazelContext) GetApexInfo(label string, cfgKey configKey) (cquer
	return cquery.ApexCqueryInfo{}, fmt.Errorf("no bazel response found for %v", key)
}

func (bazelCtx *bazelContext) GetCcUnstrippedInfo(label string, cfgKey configKey) (cquery.CcUnstrippedInfo, error) {
	key := makeCqueryKey(label, cquery.GetCcUnstrippedInfo, cfgKey)
	if rawString, ok := bazelCtx.results[key]; ok {
		return cquery.GetCcUnstrippedInfo.ParseResult(strings.TrimSpace(rawString)), nil
	}
	return cquery.CcUnstrippedInfo{}, fmt.Errorf("no bazel response for %s", key)
}

func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
	panic("unimplemented")
}
@@ -332,6 +349,11 @@ func (n noopBazelContext) GetApexInfo(_ string, _ configKey) (cquery.ApexCqueryI
	panic("unimplemented")
}

func (n noopBazelContext) GetCcUnstrippedInfo(_ string, _ configKey) (cquery.CcUnstrippedInfo, error) {
	//TODO implement me
	panic("implement me")
}

func (n noopBazelContext) InvokeBazel(_ Config) error {
	panic("unimplemented")
}
+54 −5
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ var (
	GetPythonBinary     = &getPythonBinaryRequestType{}
	GetCcInfo           = &getCcInfoType{}
	GetApexInfo         = &getApexInfoType{}
	GetCcUnstrippedInfo = &getCcUnstippedInfoType{}
)

type CcInfo struct {
@@ -30,6 +31,7 @@ type CcInfo struct {
	// but general cc_library will also have dynamic libraries in output files).
	RootDynamicLibraries []string
	TocFile              string
	UnstrippedOutput     string
}

type getOutputFilesRequestType struct{}
@@ -135,12 +137,17 @@ sharedLibraries = []
rootSharedLibraries = []

shared_info_tag = "//build/bazel/rules/cc:cc_library_shared.bzl%CcSharedLibraryOutputInfo"
unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
unstripped = ""

if shared_info_tag in providers(target):
  shared_info = providers(target)[shared_info_tag]
  path = shared_info.output_file.path
  sharedLibraries.append(path)
  rootSharedLibraries += [path]
  unstripped = path
  if unstripped_tag in providers(target):
    unstripped = providers(target)[unstripped_tag].unstripped.path
else:
  for linker_input in linker_inputs:
    for library in linker_input.libraries:
@@ -168,7 +175,8 @@ return json_encode({
	"Headers": headers,
	"RootStaticArchives": rootStaticArchives,
	"RootDynamicLibraries": rootSharedLibraries,
	"TocFile": toc_file
	"TocFile": toc_file,
	"UnstrippedOutput": unstripped,
})`

}
@@ -237,6 +245,47 @@ func (g getApexInfoType) ParseResult(rawString string) ApexCqueryInfo {
	return info
}

// getCcUnstrippedInfoType implements cqueryRequest interface. It handles the
// interaction with `bazel cquery` to retrieve CcUnstrippedInfo provided
// by the` cc_binary` and `cc_shared_library` rules.
type getCcUnstippedInfoType struct{}

func (g getCcUnstippedInfoType) Name() string {
	return "getCcUnstrippedInfo"
}

func (g getCcUnstippedInfoType) StarlarkFunctionBody() string {
	return `unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
p = providers(target)
output_path = target.files.to_list()[0].path
unstripped = output_path
if unstripped_tag in p:
    unstripped = p[unstripped_tag].unstripped.files.to_list()[0].path
return json_encode({
    "OutputFile":  output_path,
    "UnstrippedOutput": unstripped,
})
`
}

// ParseResult returns a value obtained by parsing the result of the request's Starlark function.
// The given rawString must correspond to the string output which was created by evaluating the
// Starlark given in StarlarkFunctionBody.
func (g getCcUnstippedInfoType) ParseResult(rawString string) CcUnstrippedInfo {
	var info CcUnstrippedInfo
	decoder := json.NewDecoder(strings.NewReader(rawString))
	decoder.DisallowUnknownFields() //useful to detect typos, e.g. in unit tests
	if err := decoder.Decode(&info); err != nil {
		panic(fmt.Errorf("cannot parse cquery result '%s': %s", rawString, err))
	}
	return info
}

type CcUnstrippedInfo struct {
	OutputFile       string
	UnstrippedOutput string
}

// 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 {
+28 −0
Original line number Diff line number Diff line
@@ -165,3 +165,31 @@ func TestGetApexInfoParseResults(t *testing.T) {
		}
	}
}

func TestGetCcUnstrippedParseResults(t *testing.T) {
	testCases := []struct {
		description    string
		input          string
		expectedOutput CcUnstrippedInfo
	}{
		{
			description:    "no result",
			input:          "{}",
			expectedOutput: CcUnstrippedInfo{},
		},
		{
			description: "one result",
			input:       `{"OutputFile":"myapp", "UnstrippedOutput":"myapp_unstripped"}`,
			expectedOutput: CcUnstrippedInfo{
				OutputFile:       "myapp",
				UnstrippedOutput: "myapp_unstripped",
			},
		},
	}
	for _, tc := range testCases {
		actualOutput := GetCcUnstrippedInfo.ParseResult(tc.input)
		if !reflect.DeepEqual(tc.expectedOutput, actualOutput) {
			t.Errorf("%q: expected %#v != actual %#v", tc.description, tc.expectedOutput, actualOutput)
		}
	}
}
+4 −9
Original line number Diff line number Diff line
@@ -577,25 +577,20 @@ var _ BazelHandler = (*ccBinaryBazelHandler)(nil)

func (handler *ccBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
	bazelCtx := ctx.Config().BazelContext
	bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
	bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKey(ctx))
}

func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
	bazelCtx := ctx.Config().BazelContext
	filePaths, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
	info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKey(ctx))
	if err != nil {
		ctx.ModuleErrorf(err.Error())
		return
	}

	if len(filePaths) != 1 {
		ctx.ModuleErrorf("expected exactly one output file for '%s', but got %s", label, filePaths)
		return
	}
	outputFilePath := android.PathForBazelOut(ctx, filePaths[0])
	outputFilePath := android.PathForBazelOut(ctx, info.OutputFile)
	handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
	// TODO(b/220164721): We need to decide if we should return the stripped as the unstripped.
	handler.module.linker.(*binaryDecorator).unstrippedOutputFile = outputFilePath
	handler.module.linker.(*binaryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)
}

func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes {
+7 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
package cc

import (
	"android/soong/bazel/cquery"
	"testing"

	"android/soong/android"
@@ -30,8 +31,11 @@ cc_binary {
	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
	config.BazelContext = android.MockBazelContext{
		OutputBaseDir: "outputbase",
		LabelToOutputFiles: map[string][]string{
			"//foo/bar:bar": []string{"foo"},
		LabelToCcBinary: map[string]cquery.CcUnstrippedInfo{
			"//foo/bar:bar": cquery.CcUnstrippedInfo{
				OutputFile:       "foo",
				UnstrippedOutput: "foo.unstripped",
			},
		},
	}
	ctx := testCcWithConfig(t, config)
@@ -46,7 +50,7 @@ cc_binary {
	android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())

	unStrippedFilePath := binMod.(*Module).UnstrippedOutputFile()
	expectedUnStrippedFile := "outputbase/execroot/__main__/foo"
	expectedUnStrippedFile := "outputbase/execroot/__main__/foo.unstripped"
	android.AssertStringEquals(t, "Unstripped output file", expectedUnStrippedFile, unStrippedFilePath.String())
}

Loading