Merge "Handle no_libcrt in bp2build."

This commit is contained in:
Treehugger Robot
2021-06-09 00:48:06 +00:00
committed by Gerrit Code Review
9 changed files with 457 additions and 144 deletions

View File

@@ -350,6 +350,83 @@ func (la *LabelAttribute) SortedConfigurationAxes() []ConfigurationAxis {
return keys 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. // labelListSelectValues supports config-specific label_list typed Bazel attribute values.
type labelListSelectValues map[string]LabelList type labelListSelectValues map[string]LabelList

View File

@@ -567,6 +567,10 @@ func isZero(value reflect.Value) bool {
} else { } else {
return true 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: default:
if !value.IsValid() { if !value.IsValid() {
return true return true

View File

@@ -23,12 +23,14 @@ import (
func TestGenerateSoongModuleTargets(t *testing.T) { func TestGenerateSoongModuleTargets(t *testing.T) {
testCases := []struct { testCases := []struct {
description string
bp string bp string
expectedBazelTarget string expectedBazelTarget string
}{ }{
{ {
description: "only name",
bp: `custom { name: "foo" } bp: `custom { name: "foo" }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -36,14 +38,16 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = False,
)`, )`,
}, },
{ {
description: "handles bool",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
ramdisk: true, bool_prop: true,
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -51,15 +55,16 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
ramdisk = True, bool_prop = True,
)`, )`,
}, },
{ {
description: "string escaping",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
owner: "a_string_with\"quotes\"_and_\\backslashes\\\\", owner: "a_string_with\"quotes\"_and_\\backslashes\\\\",
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -67,15 +72,17 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = False,
owner = "a_string_with\"quotes\"_and_\\backslashes\\\\", owner = "a_string_with\"quotes\"_and_\\backslashes\\\\",
)`, )`,
}, },
{ {
description: "single item string list",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
required: ["bar"], required: ["bar"],
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -83,15 +90,17 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = False,
required = ["bar"], required = ["bar"],
)`, )`,
}, },
{ {
description: "list of strings",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
target_required: ["qux", "bazqux"], target_required: ["qux", "bazqux"],
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -99,6 +108,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = False,
target_required = [ target_required = [
"qux", "qux",
"bazqux", "bazqux",
@@ -106,18 +116,19 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
)`, )`,
}, },
{ {
description: "dist/dists",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
dist: { dist: {
targets: ["goal_foo"], targets: ["goal_foo"],
tag: ".foo", tag: ".foo",
}, },
dists: [{ dists: [{
targets: ["goal_bar"], targets: ["goal_bar"],
tag: ".bar", tag: ".bar",
}], }],
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -125,6 +136,7 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = False,
dist = { dist = {
"tag": ".foo", "tag": ".foo",
"targets": ["goal_foo"], "targets": ["goal_foo"],
@@ -136,20 +148,21 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
)`, )`,
}, },
{ {
description: "put it together",
bp: `custom { bp: `custom {
name: "foo", name: "foo",
required: ["bar"], required: ["bar"],
target_required: ["qux", "bazqux"], target_required: ["qux", "bazqux"],
ramdisk: true, bool_prop: true,
owner: "custom_owner", owner: "custom_owner",
dists: [ dists: [
{ {
tag: ".tag", tag: ".tag",
targets: ["my_goal"], targets: ["my_goal"],
}, },
], ],
} }
`, `,
expectedBazelTarget: `soong_module( expectedBazelTarget: `soong_module(
name = "foo", name = "foo",
soong_module_name = "foo", soong_module_name = "foo",
@@ -157,12 +170,12 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
soong_module_variant = "", soong_module_variant = "",
soong_module_deps = [ soong_module_deps = [
], ],
bool_prop = True,
dists = [{ dists = [{
"tag": ".tag", "tag": ".tag",
"targets": ["my_goal"], "targets": ["my_goal"],
}], }],
owner = "custom_owner", owner = "custom_owner",
ramdisk = True,
required = ["bar"], required = ["bar"],
target_required = [ target_required = [
"qux", "qux",
@@ -174,31 +187,33 @@ func TestGenerateSoongModuleTargets(t *testing.T) {
dir := "." dir := "."
for _, testCase := range testCases { for _, testCase := range testCases {
config := android.TestConfig(buildDir, nil, testCase.bp, nil) t.Run(testCase.description, func(t *testing.T) {
ctx := android.NewTestContext(config) config := android.TestConfig(buildDir, nil, testCase.bp, nil)
ctx := android.NewTestContext(config)
ctx.RegisterModuleType("custom", customModuleFactory) ctx.RegisterModuleType("custom", customModuleFactory)
ctx.Register() ctx.Register()
_, errs := ctx.ParseFileList(dir, []string{"Android.bp"}) _, errs := ctx.ParseFileList(dir, []string{"Android.bp"})
android.FailIfErrored(t, errs) android.FailIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config) _, errs = ctx.PrepareBuildActions(config)
android.FailIfErrored(t, errs) android.FailIfErrored(t, errs)
codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView) codegenCtx := NewCodegenContext(config, *ctx.Context, QueryView)
bazelTargets := generateBazelTargetsForDir(codegenCtx, dir) bazelTargets := generateBazelTargetsForDir(codegenCtx, dir)
if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount { if actualCount, expectedCount := len(bazelTargets), 1; actualCount != expectedCount {
t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount) t.Fatalf("Expected %d bazel target, got %d", expectedCount, actualCount)
} }
actualBazelTarget := bazelTargets[0] actualBazelTarget := bazelTargets[0]
if actualBazelTarget.content != testCase.expectedBazelTarget { if actualBazelTarget.content != testCase.expectedBazelTarget {
t.Errorf( t.Errorf(
"Expected generated Bazel target to be '%s', got '%s'", "Expected generated Bazel target to be '%s', got '%s'",
testCase.expectedBazelTarget, testCase.expectedBazelTarget,
actualBazelTarget.content, actualBazelTarget.content,
) )
} }
})
} }
} }

View File

@@ -25,18 +25,18 @@ const (
// See cc/testing.go for more context // See cc/testing.go for more context
soongCcLibraryPreamble = ` soongCcLibraryPreamble = `
cc_defaults { cc_defaults {
name: "linux_bionic_supported", name: "linux_bionic_supported",
} }
toolchain_library { toolchain_library {
name: "libclang_rt.builtins-x86_64-android", name: "libclang_rt.builtins-x86_64-android",
defaults: ["linux_bionic_supported"], defaults: ["linux_bionic_supported"],
vendor_available: true, vendor_available: true,
vendor_ramdisk_available: true, vendor_ramdisk_available: true,
product_available: true, product_available: true,
recovery_available: true, recovery_available: true,
native_bridge_supported: true, native_bridge_supported: true,
src: "", src: "",
}` }`
) )
@@ -564,32 +564,32 @@ func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
cc_library { cc_library {
name: "a", name: "a",
srcs: [ srcs: [
"both_source.cpp", "both_source.cpp",
"both_source.cc", "both_source.cc",
"both_source.c", "both_source.c",
"both_source.s", "both_source.s",
"both_source.S", "both_source.S",
":both_filegroup", ":both_filegroup",
], ],
static: { static: {
srcs: [ srcs: [
"static_source.cpp", "static_source.cpp",
"static_source.cc", "static_source.cc",
"static_source.c", "static_source.c",
"static_source.s", "static_source.s",
"static_source.S", "static_source.S",
":static_filegroup", ":static_filegroup",
], ],
}, },
shared: { shared: {
srcs: [ srcs: [
"shared_source.cpp", "shared_source.cpp",
"shared_source.cc", "shared_source.cc",
"shared_source.c", "shared_source.c",
"shared_source.s", "shared_source.s",
"shared_source.S", "shared_source.S",
":shared_filegroup", ":shared_filegroup",
], ],
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
} }
@@ -598,21 +598,21 @@ filegroup {
name: "both_filegroup", name: "both_filegroup",
srcs: [ srcs: [
// Not relevant, handled by filegroup macro // Not relevant, handled by filegroup macro
], ],
} }
filegroup { filegroup {
name: "shared_filegroup", name: "shared_filegroup",
srcs: [ srcs: [
// Not relevant, handled by filegroup macro // Not relevant, handled by filegroup macro
], ],
} }
filegroup { filegroup {
name: "static_filegroup", name: "static_filegroup",
srcs: [ srcs: [
// Not relevant, handled by filegroup macro // Not relevant, handled by filegroup macro
], ],
} }
`, `,
}, },
@@ -710,21 +710,21 @@ func TestCcLibraryConfiguredVersionScript(t *testing.T) {
dir: "foo/bar", dir: "foo/bar",
filesystem: map[string]string{ filesystem: map[string]string{
"foo/bar/Android.bp": ` "foo/bar/Android.bp": `
cc_library { cc_library {
name: "a", name: "a",
srcs: ["a.cpp"], srcs: ["a.cpp"],
arch: { arch: {
arm: { arm: {
version_script: "arm.map", version_script: "arm.map",
}, },
arm64: { arm64: {
version_script: "arm64.map", version_script: "arm64.map",
}, },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
} }
`, `,
}, },
blueprint: soongCcLibraryPreamble, blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library( expectedBazelTargets: []string{`cc_library(
@@ -805,8 +805,8 @@ cc_library {
srcs: ["b.cpp"], srcs: ["b.cpp"],
arch: { arch: {
x86_64: { x86_64: {
pack_relocations: false, pack_relocations: false,
}, },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
} }
@@ -816,8 +816,8 @@ cc_library {
srcs: ["c.cpp"], srcs: ["c.cpp"],
target: { target: {
darwin: { darwin: {
pack_relocations: false, pack_relocations: false,
}, },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
}`, }`,
@@ -900,22 +900,22 @@ func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
name: "a", name: "a",
srcs: ["a.cpp"], srcs: ["a.cpp"],
cflags: [ cflags: [
"-Wall", "-Wall",
], ],
cppflags: [ cppflags: [
"-fsigned-char", "-fsigned-char",
"-pedantic", "-pedantic",
], ],
arch: { arch: {
arm64: { arm64: {
cppflags: ["-DARM64=1"], cppflags: ["-DARM64=1"],
}, },
}, },
target: { target: {
android: { android: {
cppflags: ["-DANDROID=1"], cppflags: ["-DANDROID=1"],
}, },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
} }
`, `,
@@ -953,21 +953,21 @@ func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
dir: "foo/bar", dir: "foo/bar",
filesystem: map[string]string{ filesystem: map[string]string{
"foo/bar/Android.bp": ` "foo/bar/Android.bp": `
cc_library { cc_library {
name: "a", name: "a",
srcs: ["a.cpp"], srcs: ["a.cpp"],
target: { target: {
android_arm: { android_arm: {
version_script: "android_arm.map", version_script: "android_arm.map",
}, },
linux_bionic_arm64: { linux_bionic_arm64: {
version_script: "linux_bionic_arm64.map", version_script: "linux_bionic_arm64.map",
}, },
}, },
bazel_module: { bp2build_available: true }, bazel_module: { bp2build_available: true },
} }
`, `,
}, },
blueprint: soongCcLibraryPreamble, blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library( expectedBazelTargets: []string{`cc_library(
@@ -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,
}),
)`}})
}

View File

@@ -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"],
)`},
})
}

View File

@@ -51,6 +51,28 @@ func getLabelValue(label bazel.LabelAttribute) (reflect.Value, []selects) {
return value, []selects{ret} return value, []selects{ret}
} }
func getBoolValue(boolAttr bazel.BoolAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(boolAttr.Value)
if !boolAttr.HasConfigurableValues() {
return value, []selects{}
}
ret := selects{}
for _, axis := range boolAttr.SortedConfigurationAxes() {
configToBools := boolAttr.ConfigurableValues[axis]
for config, bools := range configToBools {
selectKey := axis.SelectKey(config)
ret[selectKey] = reflect.ValueOf(bools)
}
}
// if there is a select, use the base value as the conditions default value
if len(ret) > 0 {
ret[bazel.ConditionsDefaultSelectKey] = value
value = reflect.Zero(value.Type())
}
return value, []selects{ret}
}
func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) { func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, []selects) {
value := reflect.ValueOf(list.Value.Includes) value := reflect.ValueOf(list.Value.Includes)
var ret []selects var ret []selects
@@ -85,22 +107,30 @@ func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect
return false, reflect.Zero(reflect.TypeOf([]string{})) return false, reflect.Zero(reflect.TypeOf([]string{}))
} }
var (
emptyBazelList = "[]"
bazelNone = "None"
)
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain // prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
// select statements. // select statements.
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value var value reflect.Value
var configurableAttrs []selects var configurableAttrs []selects
var defaultSelectValue string var defaultSelectValue *string
switch list := v.(type) { switch list := v.(type) {
case bazel.StringListAttribute: case bazel.StringListAttribute:
value, configurableAttrs = getStringListValues(list) value, configurableAttrs = getStringListValues(list)
defaultSelectValue = "[]" defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute: case bazel.LabelListAttribute:
value, configurableAttrs = getLabelListValues(list) value, configurableAttrs = getLabelListValues(list)
defaultSelectValue = "[]" defaultSelectValue = &emptyBazelList
case bazel.LabelAttribute: case bazel.LabelAttribute:
value, configurableAttrs = getLabelValue(list) value, configurableAttrs = getLabelValue(list)
defaultSelectValue = "None" defaultSelectValue = &bazelNone
case bazel.BoolAttribute:
value, configurableAttrs = getBoolValue(list)
defaultSelectValue = &bazelNone
default: default:
return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v) return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v)
} }
@@ -116,7 +146,7 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
ret += s ret += s
} }
// Convenience function to append selects components to an attribute value. // Convenience function to append selects components to an attribute value.
appendSelects := func(selectsData selects, defaultValue, s string) (string, error) { appendSelects := func(selectsData selects, defaultValue *string, s string) (string, error) {
selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent) selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent)
if err != nil { if err != nil {
return "", err return "", err
@@ -141,13 +171,11 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
// prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way // prettyPrintSelectMap converts a map of select keys to reflected Values as a generic way
// to construct a select map for any kind of attribute type. // to construct a select map for any kind of attribute type.
func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue string, indent int) (string, error) { func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue *string, indent int) (string, error) {
if selectMap == nil { if selectMap == nil {
return "", nil return "", nil
} }
// addConditionsDefault := false
var selects string var selects string
for _, selectKey := range android.SortedStringKeys(selectMap) { for _, selectKey := range android.SortedStringKeys(selectMap) {
if selectKey == bazel.ConditionsDefaultSelectKey { if selectKey == bazel.ConditionsDefaultSelectKey {
@@ -184,14 +212,14 @@ func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue strin
if err != nil { if err != nil {
return "", err return "", err
} }
if s == "" { if s != "" {
// Print an explicit empty list (the default value) even if the value is
// empty, to avoid errors about not finding a configuration that matches.
ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, defaultValue)
} else {
// Print the custom default value. // Print the custom default value.
ret += s ret += s
ret += ",\n" ret += ",\n"
} else if defaultValue != nil {
// Print an explicit empty list (the default value) even if the value is
// empty, to avoid errors about not finding a configuration that matches.
ret += fmt.Sprintf("%s\"%s\": %s,\n", makeIndent(indent+1), bazel.ConditionsDefaultSelectKey, *defaultValue)
} }
ret += makeIndent(indent) ret += makeIndent(indent)

View File

@@ -489,6 +489,7 @@ type linkerAttributes struct {
dynamicDeps bazel.LabelListAttribute dynamicDeps bazel.LabelListAttribute
wholeArchiveDeps bazel.LabelListAttribute wholeArchiveDeps bazel.LabelListAttribute
exportedDeps bazel.LabelListAttribute exportedDeps bazel.LabelListAttribute
useLibcrt bazel.BoolAttribute
linkopts bazel.StringListAttribute linkopts bazel.StringListAttribute
versionScript bazel.LabelAttribute versionScript bazel.LabelAttribute
} }
@@ -512,6 +513,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
var wholeArchiveDeps bazel.LabelListAttribute var wholeArchiveDeps bazel.LabelListAttribute
var linkopts bazel.StringListAttribute var linkopts bazel.StringListAttribute
var versionScript bazel.LabelAttribute var versionScript bazel.LabelAttribute
var useLibcrt bazel.BoolAttribute
for _, linkerProps := range module.linker.linkerProps() { for _, linkerProps := range module.linker.linkerProps() {
if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok { if baseLinkerProps, ok := linkerProps.(*BaseLinkerProperties); ok {
@@ -535,6 +537,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
if baseLinkerProps.Version_script != nil { if baseLinkerProps.Version_script != nil {
versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) versionScript.SetValue(android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
} }
useLibcrt.Value = baseLinkerProps.libCrt()
break break
} }
@@ -559,6 +562,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
if baseLinkerProps.Version_script != nil { if baseLinkerProps.Version_script != nil {
versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script))
} }
useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt())
} }
} }
} }
@@ -624,6 +628,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module)
dynamicDeps: dynamicDeps, dynamicDeps: dynamicDeps,
wholeArchiveDeps: wholeArchiveDeps, wholeArchiveDeps: wholeArchiveDeps,
linkopts: linkopts, linkopts: linkopts,
useLibcrt: useLibcrt,
versionScript: versionScript, versionScript: versionScript,
} }
} }

View File

@@ -234,6 +234,7 @@ type bazelCcLibraryAttributes struct {
Whole_archive_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute
Includes bazel.StringListAttribute Includes bazel.StringListAttribute
Linkopts bazel.StringListAttribute Linkopts bazel.StringListAttribute
Use_libcrt bazel.BoolAttribute
// Attributes pertaining to shared variant. // Attributes pertaining to shared variant.
Shared_srcs bazel.LabelListAttribute Shared_srcs bazel.LabelListAttribute
@@ -320,6 +321,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) {
Whole_archive_deps: linkerAttrs.wholeArchiveDeps, Whole_archive_deps: linkerAttrs.wholeArchiveDeps,
Includes: exportedIncludes, Includes: exportedIncludes,
Linkopts: linkerAttrs.linkopts, Linkopts: linkerAttrs.linkopts,
Use_libcrt: linkerAttrs.useLibcrt,
Shared_srcs: sharedAttrs.srcs, Shared_srcs: sharedAttrs.srcs,
Shared_srcs_c: sharedAttrs.srcs_c, Shared_srcs_c: sharedAttrs.srcs_c,
@@ -2262,6 +2264,7 @@ type bazelCcLibraryStaticAttributes struct {
Whole_archive_deps bazel.LabelListAttribute Whole_archive_deps bazel.LabelListAttribute
Linkopts bazel.StringListAttribute Linkopts bazel.StringListAttribute
Linkstatic bool Linkstatic bool
Use_libcrt bazel.BoolAttribute
Includes bazel.StringListAttribute Includes bazel.StringListAttribute
Hdrs bazel.LabelListAttribute Hdrs bazel.LabelListAttribute
@@ -2298,6 +2301,7 @@ func ccLibraryStaticBp2BuildInternal(ctx android.TopDownMutatorContext, module *
Linkopts: linkerAttrs.linkopts, Linkopts: linkerAttrs.linkopts,
Linkstatic: true, Linkstatic: true,
Use_libcrt: linkerAttrs.useLibcrt,
Includes: exportedIncludes, Includes: exportedIncludes,
Cppflags: compilerAttrs.cppFlags, Cppflags: compilerAttrs.cppFlags,

View File

@@ -200,6 +200,18 @@ type BaseLinkerProperties struct {
Exclude_shared_libs []string `android:"arch_variant"` Exclude_shared_libs []string `android:"arch_variant"`
} }
func invertBoolPtr(value *bool) *bool {
if value == nil {
return nil
}
ret := !(*value)
return &ret
}
func (blp *BaseLinkerProperties) libCrt() *bool {
return invertBoolPtr(blp.No_libcrt)
}
func NewBaseLinker(sanitize *sanitize) *baseLinker { func NewBaseLinker(sanitize *sanitize) *baseLinker {
return &baseLinker{sanitize: sanitize} return &baseLinker{sanitize: sanitize}
} }