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

Commit d366c909 authored by Liz Kammer's avatar Liz Kammer
Browse files

Handle no_libcrt in bp2build.

Test: ci/bp2build.sh
Bug: 187928307
Change-Id: Ib80c4318169652b322e5d878c8784679e42f87dd
parent 2f265950
Loading
Loading
Loading
Loading
+77 −0
Original line number Diff line number Diff line
@@ -350,6 +350,83 @@ func (la *LabelAttribute) SortedConfigurationAxes() []ConfigurationAxis {
	return keys
}

type configToBools map[string]bool

func (ctb configToBools) setValue(config string, value *bool) {
	if value == nil {
		if _, ok := ctb[config]; ok {
			delete(ctb, config)
		}
		return
	}
	ctb[config] = *value
}

type configurableBools map[ConfigurationAxis]configToBools

func (cb configurableBools) setValueForAxis(axis ConfigurationAxis, config string, value *bool) {
	if cb[axis] == nil {
		cb[axis] = make(configToBools)
	}
	cb[axis].setValue(config, value)
}

// BoolAttribute represents an attribute whose value is a single bool but may be configurable..
type BoolAttribute struct {
	Value *bool

	ConfigurableValues configurableBools
}

// HasConfigurableValues returns whether there are configurable values for this attribute.
func (ba BoolAttribute) HasConfigurableValues() bool {
	return len(ba.ConfigurableValues) > 0
}

// SetSelectValue sets value for the given axis/config.
func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, value *bool) {
	axis.validateConfig(config)
	switch axis.configurationType {
	case noConfig:
		ba.Value = value
	case arch, os, osArch, productVariables:
		if ba.ConfigurableValues == nil {
			ba.ConfigurableValues = make(configurableBools)
		}
		ba.ConfigurableValues.setValueForAxis(axis, config, value)
	default:
		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
	}
}

// SelectValue gets the value for the given axis/config.
func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool {
	axis.validateConfig(config)
	switch axis.configurationType {
	case noConfig:
		return ba.Value
	case arch, os, osArch, productVariables:
		if v, ok := ba.ConfigurableValues[axis][config]; ok {
			return &v
		} else {
			return nil
		}
	default:
		panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis))
	}
}

// SortedConfigurationAxes returns all the used ConfigurationAxis in sorted order.
func (ba *BoolAttribute) SortedConfigurationAxes() []ConfigurationAxis {
	keys := make([]ConfigurationAxis, 0, len(ba.ConfigurableValues))
	for k := range ba.ConfigurableValues {
		keys = append(keys, k)
	}

	sort.Slice(keys, func(i, j int) bool { return keys[i].less(keys[j]) })
	return keys
}

// labelListSelectValues supports config-specific label_list typed Bazel attribute values.
type labelListSelectValues map[string]LabelList

+4 −0
Original line number Diff line number Diff line
@@ -567,6 +567,10 @@ func isZero(value reflect.Value) bool {
		} else {
			return true
		}
	// Always print bools, if you want a bool attribute to be able to take the default value, use a
	// bool pointer instead
	case reflect.Bool:
		return false
	default:
		if !value.IsValid() {
			return true
+73 −58
Original line number Diff line number Diff line
@@ -23,10 +23,12 @@ import (

func TestGenerateSoongModuleTargets(t *testing.T) {
	testCases := []struct {
		description         string
		bp                  string
		expectedBazelTarget string
	}{
		{
			description: "only name",
			bp: `custom { name: "foo" }
    `,
			expectedBazelTarget: `soong_module(
@@ -36,12 +38,14 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = False,
)`,
		},
		{
			description: "handles bool",
			bp: `custom {
  name: "foo",
	ramdisk: true,
  bool_prop: true,
}
    `,
			expectedBazelTarget: `soong_module(
@@ -51,10 +55,11 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    ramdisk = True,
    bool_prop = True,
)`,
		},
		{
			description: "string escaping",
			bp: `custom {
  name: "foo",
  owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
@@ -67,10 +72,12 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = False,
    owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
)`,
		},
		{
			description: "single item string list",
			bp: `custom {
  name: "foo",
  required: ["bar"],
@@ -83,10 +90,12 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = False,
    required = ["bar"],
)`,
		},
		{
			description: "list of strings",
			bp: `custom {
  name: "foo",
  target_required: ["qux", "bazqux"],
@@ -99,6 +108,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = False,
    target_required = [
        "qux",
        "bazqux",
@@ -106,6 +116,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
)`,
		},
		{
			description: "dist/dists",
			bp: `custom {
  name: "foo",
  dist: {
@@ -125,6 +136,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = False,
    dist = {
        "tag": ".foo",
        "targets": ["goal_foo"],
@@ -136,11 +148,12 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
)`,
		},
		{
			description: "put it together",
			bp: `custom {
  name: "foo",
  required: ["bar"],
  target_required: ["qux", "bazqux"],
	ramdisk: true,
  bool_prop: true,
  owner: "custom_owner",
  dists: [
    {
@@ -157,12 +170,12 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
    soong_module_variant = "",
    soong_module_deps = [
    ],
    bool_prop = True,
    dists = [{
        "tag": ".tag",
        "targets": ["my_goal"],
    }],
    owner = "custom_owner",
    ramdisk = True,
    required = ["bar"],
    target_required = [
        "qux",
@@ -174,6 +187,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {

	dir := "."
	for _, testCase := range testCases {
		t.Run(testCase.description, func(t *testing.T) {
			config := android.TestConfig(buildDir, nil, testCase.bp, nil)
			ctx := android.NewTestContext(config)

@@ -199,6 +213,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
					actualBazelTarget.content,
				)
			}
		})
	}
}

+205 −73
Original line number Diff line number Diff line
@@ -1099,3 +1099,135 @@ cc_library {
		},
	})
}

func TestCCLibraryNoCrtTrue(t *testing.T) {
	runCcLibraryTestCase(t, bp2buildTestCase{
		description:                        "cc_library - simple example",
		moduleTypeUnderTest:                "cc_library",
		moduleTypeUnderTestFactory:         cc.LibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
		filesystem: map[string]string{
			"impl.cpp": "",
		},
		blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "some-headers" }
cc_library {
    name: "foo-lib",
    srcs: ["impl.cpp"],
    no_libcrt: true,
}
`,
		expectedBazelTargets: []string{`cc_library(
    name = "foo-lib",
    copts = [
        "-I.",
        "-I$(BINDIR)/.",
    ],
    srcs = ["impl.cpp"],
    use_libcrt = False,
)`}})
}

func TestCCLibraryNoCrtFalse(t *testing.T) {
	runCcLibraryTestCase(t, bp2buildTestCase{
		moduleTypeUnderTest:                "cc_library",
		moduleTypeUnderTestFactory:         cc.LibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
		filesystem: map[string]string{
			"impl.cpp": "",
		},
		blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "some-headers" }
cc_library {
    name: "foo-lib",
    srcs: ["impl.cpp"],
    no_libcrt: false,
}
`,
		expectedBazelTargets: []string{`cc_library(
    name = "foo-lib",
    copts = [
        "-I.",
        "-I$(BINDIR)/.",
    ],
    srcs = ["impl.cpp"],
    use_libcrt = True,
)`}})
}

func TestCCLibraryNoCrtArchVariant(t *testing.T) {
	runCcLibraryTestCase(t, bp2buildTestCase{
		moduleTypeUnderTest:                "cc_library",
		moduleTypeUnderTestFactory:         cc.LibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
		filesystem: map[string]string{
			"impl.cpp": "",
		},
		blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "some-headers" }
cc_library {
    name: "foo-lib",
    srcs: ["impl.cpp"],
    arch: {
        arm: {
            no_libcrt: true,
        },
        x86: {
            no_libcrt: true,
        },
    },
}
`,
		expectedBazelTargets: []string{`cc_library(
    name = "foo-lib",
    copts = [
        "-I.",
        "-I$(BINDIR)/.",
    ],
    srcs = ["impl.cpp"],
    use_libcrt = select({
        "//build/bazel/platforms/arch:arm": False,
        "//build/bazel/platforms/arch:x86": False,
        "//conditions:default": None,
    }),
)`}})
}

func TestCCLibraryNoCrtArchVariantWithDefault(t *testing.T) {
	runCcLibraryTestCase(t, bp2buildTestCase{
		moduleTypeUnderTest:                "cc_library",
		moduleTypeUnderTestFactory:         cc.LibraryFactory,
		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build,
		filesystem: map[string]string{
			"impl.cpp": "",
		},
		blueprint: soongCcLibraryPreamble + `
cc_library_headers { name: "some-headers" }
cc_library {
    name: "foo-lib",
    srcs: ["impl.cpp"],
    no_libcrt: false,
    arch: {
        arm: {
            no_libcrt: true,
        },
        x86: {
            no_libcrt: true,
        },
    },
}
`,
		expectedBazelTargets: []string{`cc_library(
    name = "foo-lib",
    copts = [
        "-I.",
        "-I$(BINDIR)/.",
    ],
    srcs = ["impl.cpp"],
    use_libcrt = select({
        "//build/bazel/platforms/arch:arm": False,
        "//build/bazel/platforms/arch:x86": False,
        "//conditions:default": True,
    }),
)`}})
}
+36 −0
Original line number Diff line number Diff line
@@ -374,3 +374,39 @@ func TestCcLibraryHeadersArchAndTargetExportSystemIncludes(t *testing.T) {
)`},
	})
}

func TestCcLibraryHeadersNoCrtIgnored(t *testing.T) {
	runCcLibraryHeadersTestCase(t, bp2buildTestCase{
		description:                        "cc_library_headers test",
		moduleTypeUnderTest:                "cc_library_headers",
		moduleTypeUnderTestFactory:         cc.LibraryHeaderFactory,
		moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryHeadersBp2Build,
		filesystem: map[string]string{
			"lib-1/lib1a.h":                        "",
			"lib-1/lib1b.h":                        "",
			"lib-2/lib2a.h":                        "",
			"lib-2/lib2b.h":                        "",
			"dir-1/dir1a.h":                        "",
			"dir-1/dir1b.h":                        "",
			"dir-2/dir2a.h":                        "",
			"dir-2/dir2b.h":                        "",
			"arch_arm64_exported_include_dir/a.h":  "",
			"arch_x86_exported_include_dir/b.h":    "",
			"arch_x86_64_exported_include_dir/c.h": "",
		},
		blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
    name: "lib-1",
    export_include_dirs: ["lib-1"],
    no_libcrt: true,
}`,
		expectedBazelTargets: []string{`cc_library_headers(
    name = "lib-1",
    copts = [
        "-I.",
        "-I$(BINDIR)/.",
    ],
    includes = ["lib-1"],
)`},
	})
}
Loading