Quellcode durchsuchen

Add bp2build support for cc_prebuilt_object

Add bp2build support for cc_prebuilt_object to allow buiiding
musl crt objects that use prebuilt clang_rt.crtbegin and
clang_rt.crtend.

Bug: 259266326
Test: //extenral/musl:libc_musl builds
Change-Id: Ic2b0375bc6e7336d31c9e2cf51bdc2ea894185aa
Colin Cross vor 1 Jahr
Ursprung
Commit
c5075e917e
5 geänderte Dateien mit 170 neuen und 3 gelöschten Zeilen
  1. 1 0
      bp2build/Android.bp
  2. 101 0
      bp2build/cc_prebuilt_object_conversion_test.go
  3. 13 0
      cc/bp2build.go
  4. 3 1
      cc/cc.go
  5. 52 2
      cc/prebuilt.go

+ 1 - 0
bp2build/Android.bp

@@ -51,6 +51,7 @@ bootstrap_go_package {
         "cc_prebuilt_library_conversion_test.go",
         "cc_prebuilt_library_shared_test.go",
         "cc_prebuilt_library_static_test.go",
+        "cc_prebuilt_object_conversion_test.go",
         "cc_test_conversion_test.go",
         "cc_yasm_conversion_test.go",
         "conversion_test.go",

+ 101 - 0
bp2build/cc_prebuilt_object_conversion_test.go

@@ -0,0 +1,101 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package bp2build
+
+import (
+	"fmt"
+	"testing"
+
+	"android/soong/cc"
+)
+
+func runCcPrebuiltObjectTestCase(t *testing.T, testCase Bp2buildTestCase) {
+	t.Helper()
+	description := fmt.Sprintf("cc_prebuilt_object: %s", testCase.Description)
+	testCase.ModuleTypeUnderTest = "cc_prebuilt_object"
+	testCase.ModuleTypeUnderTestFactory = cc.PrebuiltObjectFactory
+	testCase.Description = description
+	t.Run(description, func(t *testing.T) {
+		t.Helper()
+		RunBp2BuildTestCaseSimple(t, testCase)
+	})
+}
+
+func TestPrebuiltObject(t *testing.T) {
+	runCcPrebuiltObjectTestCase(t,
+		Bp2buildTestCase{
+			Description: "simple",
+			Filesystem: map[string]string{
+				"obj.o": "",
+			},
+			Blueprint: `
+cc_prebuilt_object {
+	name: "objtest",
+	srcs: ["obj.o"],
+	bazel_module: { bp2build_available: true },
+}`,
+			ExpectedBazelTargets: []string{
+				MakeBazelTarget("cc_prebuilt_object", "objtest", AttrNameToString{
+					"src": `"obj.o"`,
+				})},
+		})
+}
+
+func TestPrebuiltObjectWithArchVariance(t *testing.T) {
+	runCcPrebuiltObjectTestCase(t,
+		Bp2buildTestCase{
+			Description: "with arch variance",
+			Filesystem: map[string]string{
+				"obja.o": "",
+				"objb.o": "",
+			},
+			Blueprint: `
+cc_prebuilt_object {
+	name: "objtest",
+	arch: {
+		arm64: { srcs: ["obja.o"], },
+		arm: { srcs: ["objb.o"], },
+	},
+	bazel_module: { bp2build_available: true },
+}`, ExpectedBazelTargets: []string{
+				MakeBazelTarget("cc_prebuilt_object", "objtest", AttrNameToString{
+					"src": `select({
+        "//build/bazel/platforms/arch:arm": "objb.o",
+        "//build/bazel/platforms/arch:arm64": "obja.o",
+        "//conditions:default": None,
+    })`,
+				}),
+			},
+		})
+}
+
+func TestPrebuiltObjectMultipleSrcsFails(t *testing.T) {
+	runCcPrebuiltObjectTestCase(t,
+		Bp2buildTestCase{
+			Description: "fails because multiple sources",
+			Filesystem: map[string]string{
+				"obja": "",
+				"objb": "",
+			},
+			Blueprint: `
+cc_prebuilt_object {
+	name: "objtest",
+	srcs: ["obja.o", "objb.o"],
+	bazel_module: { bp2build_available: true },
+}`,
+			ExpectedErr: fmt.Errorf("Expected at most one source file"),
+		})
+}
+
+// TODO: nosrcs test

+ 13 - 0
cc/bp2build.go

@@ -337,6 +337,19 @@ func bp2BuildParsePrebuiltBinaryProps(ctx android.BazelConversionPathContext, mo
 	}
 }
 
+func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+	var srcLabelAttribute bazel.LabelAttribute
+	bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
+		if props, ok := props.(*prebuiltObjectProperties); ok {
+			parseSrc(ctx, &srcLabelAttribute, axis, config, props.Srcs)
+		}
+	})
+
+	return prebuiltAttributes{
+		Src: srcLabelAttribute,
+	}
+}
+
 type baseAttributes struct {
 	compilerAttributes
 	linkerAttributes

+ 3 - 1
cc/cc.go

@@ -3775,7 +3775,9 @@ func (c *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
 			testBinaryBp2build(ctx, c)
 		}
 	case object:
-		if !prebuilt {
+		if prebuilt {
+			prebuiltObjectBp2Build(ctx, c)
+		} else {
 			objectBp2Build(ctx, c)
 		}
 	case fullLibrary:

+ 52 - 2
cc/prebuilt.go

@@ -32,7 +32,7 @@ func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) {
 	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
 	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
 	ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
-	ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
+	ctx.RegisterModuleType("cc_prebuilt_object", PrebuiltObjectFactory)
 	ctx.RegisterModuleType("cc_prebuilt_binary", PrebuiltBinaryFactory)
 }
 
@@ -572,6 +572,8 @@ func (p *prebuiltObjectLinker) object() bool {
 
 func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module {
 	module := newObject(hod)
+	module.bazelHandler = &prebuiltObjectBazelHandler{module: module}
+	module.bazelable = true
 	prebuilt := &prebuiltObjectLinker{
 		objectLinker: objectLinker{
 			baseLinker: NewBaseLinker(nil),
@@ -584,7 +586,55 @@ func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module {
 	return module
 }
 
-func prebuiltObjectFactory() android.Module {
+type prebuiltObjectBazelHandler struct {
+	module *Module
+}
+
+var _ BazelHandler = (*prebuiltObjectBazelHandler)(nil)
+
+func (h *prebuiltObjectBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
+	bazelCtx := ctx.Config().BazelContext
+	bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
+}
+
+func (h *prebuiltObjectBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
+	bazelCtx := ctx.Config().BazelContext
+	outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
+	if err != nil {
+		ctx.ModuleErrorf(err.Error())
+		return
+	}
+	if len(outputs) != 1 {
+		ctx.ModuleErrorf("Expected a single output for `%s`, but got:\n%v", label, outputs)
+		return
+	}
+	out := android.PathForBazelOut(ctx, outputs[0])
+	h.module.outputFile = android.OptionalPathForPath(out)
+	h.module.maybeUnhideFromMake()
+}
+
+type bazelPrebuiltObjectAttributes struct {
+	Src bazel.LabelAttribute
+}
+
+func prebuiltObjectBp2Build(ctx android.TopDownMutatorContext, module *Module) {
+	prebuiltAttrs := bp2BuildParsePrebuiltObjectProps(ctx, module)
+
+	attrs := &bazelPrebuiltObjectAttributes{
+		Src: prebuiltAttrs.Src,
+	}
+
+	props := bazel.BazelTargetModuleProperties{
+		Rule_class:        "cc_prebuilt_object",
+		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_object.bzl",
+	}
+
+	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
+	tags := android.ApexAvailableTags(module)
+	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name, Tags: tags}, attrs)
+}
+
+func PrebuiltObjectFactory() android.Module {
 	module := NewPrebuiltObject(android.HostAndDeviceSupported)
 	return module.Init()
 }