Handle no_libcrt in bp2build.

Test: ci/bp2build.sh
Bug: 187928307
Change-Id: Ib80c4318169652b322e5d878c8784679e42f87dd
This commit is contained in:
Liz Kammer
2021-06-03 13:43:01 -04:00
parent 2f26595072
commit d366c909ca
9 changed files with 457 additions and 144 deletions

View File

@@ -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

View File

@@ -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

View File

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

View File

@@ -25,18 +25,18 @@ const (
// See cc/testing.go for more context
soongCcLibraryPreamble = `
cc_defaults {
name: "linux_bionic_supported",
name: "linux_bionic_supported",
}
toolchain_library {
name: "libclang_rt.builtins-x86_64-android",
defaults: ["linux_bionic_supported"],
vendor_available: true,
vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
src: "",
name: "libclang_rt.builtins-x86_64-android",
defaults: ["linux_bionic_supported"],
vendor_available: true,
vendor_ramdisk_available: true,
product_available: true,
recovery_available: true,
native_bridge_supported: true,
src: "",
}`
)
@@ -564,32 +564,32 @@ func TestCcLibrarySharedStaticPropsWithMixedSources(t *testing.T) {
cc_library {
name: "a",
srcs: [
"both_source.cpp",
"both_source.cc",
"both_source.c",
"both_source.s",
"both_source.S",
"both_source.cpp",
"both_source.cc",
"both_source.c",
"both_source.s",
"both_source.S",
":both_filegroup",
],
],
static: {
srcs: [
"static_source.cpp",
"static_source.cc",
"static_source.c",
"static_source.s",
"static_source.S",
":static_filegroup",
],
srcs: [
"static_source.cpp",
"static_source.cc",
"static_source.c",
"static_source.s",
"static_source.S",
":static_filegroup",
],
},
shared: {
srcs: [
"shared_source.cpp",
"shared_source.cc",
"shared_source.c",
"shared_source.s",
"shared_source.S",
":shared_filegroup",
],
srcs: [
"shared_source.cpp",
"shared_source.cc",
"shared_source.c",
"shared_source.s",
"shared_source.S",
":shared_filegroup",
],
},
bazel_module: { bp2build_available: true },
}
@@ -598,21 +598,21 @@ filegroup {
name: "both_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
],
],
}
filegroup {
name: "shared_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
],
],
}
filegroup {
name: "static_filegroup",
srcs: [
// Not relevant, handled by filegroup macro
],
],
}
`,
},
@@ -710,21 +710,21 @@ func TestCcLibraryConfiguredVersionScript(t *testing.T) {
dir: "foo/bar",
filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["a.cpp"],
arch: {
arm: {
version_script: "arm.map",
},
arm64: {
version_script: "arm64.map",
},
},
cc_library {
name: "a",
srcs: ["a.cpp"],
arch: {
arm: {
version_script: "arm.map",
},
arm64: {
version_script: "arm64.map",
},
},
bazel_module: { bp2build_available: true },
}
`,
bazel_module: { bp2build_available: true },
}
`,
},
blueprint: soongCcLibraryPreamble,
expectedBazelTargets: []string{`cc_library(
@@ -805,8 +805,8 @@ cc_library {
srcs: ["b.cpp"],
arch: {
x86_64: {
pack_relocations: false,
},
pack_relocations: false,
},
},
bazel_module: { bp2build_available: true },
}
@@ -816,8 +816,8 @@ cc_library {
srcs: ["c.cpp"],
target: {
darwin: {
pack_relocations: false,
},
pack_relocations: false,
},
},
bazel_module: { bp2build_available: true },
}`,
@@ -900,22 +900,22 @@ func TestCcLibraryCppFlagsGoesIntoCopts(t *testing.T) {
name: "a",
srcs: ["a.cpp"],
cflags: [
"-Wall",
],
"-Wall",
],
cppflags: [
"-fsigned-char",
"-pedantic",
],
],
arch: {
arm64: {
cppflags: ["-DARM64=1"],
},
},
},
},
target: {
android: {
cppflags: ["-DANDROID=1"],
},
},
},
},
bazel_module: { bp2build_available: true },
}
`,
@@ -953,21 +953,21 @@ func TestCcLibraryLabelAttributeGetTargetProperties(t *testing.T) {
dir: "foo/bar",
filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
name: "a",
srcs: ["a.cpp"],
target: {
android_arm: {
version_script: "android_arm.map",
},
linux_bionic_arm64: {
version_script: "linux_bionic_arm64.map",
},
},
cc_library {
name: "a",
srcs: ["a.cpp"],
target: {
android_arm: {
version_script: "android_arm.map",
},
linux_bionic_arm64: {
version_script: "linux_bionic_arm64.map",
},
},
bazel_module: { bp2build_available: true },
}
`,
bazel_module: { bp2build_available: true },
}
`,
},
blueprint: soongCcLibraryPreamble,
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}
}
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) {
value := reflect.ValueOf(list.Value.Includes)
var ret []selects
@@ -85,22 +107,30 @@ func labelListSelectValue(selectKey string, list bazel.LabelList) (bool, reflect
return false, reflect.Zero(reflect.TypeOf([]string{}))
}
var (
emptyBazelList = "[]"
bazelNone = "None"
)
// prettyPrintAttribute converts an Attribute to its Bazel syntax. May contain
// select statements.
func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) {
var value reflect.Value
var configurableAttrs []selects
var defaultSelectValue string
var defaultSelectValue *string
switch list := v.(type) {
case bazel.StringListAttribute:
value, configurableAttrs = getStringListValues(list)
defaultSelectValue = "[]"
defaultSelectValue = &emptyBazelList
case bazel.LabelListAttribute:
value, configurableAttrs = getLabelListValues(list)
defaultSelectValue = "[]"
defaultSelectValue = &emptyBazelList
case bazel.LabelAttribute:
value, configurableAttrs = getLabelValue(list)
defaultSelectValue = "None"
defaultSelectValue = &bazelNone
case bazel.BoolAttribute:
value, configurableAttrs = getBoolValue(list)
defaultSelectValue = &bazelNone
default:
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
}
// 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)
if err != nil {
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
// 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 {
return "", nil
}
// addConditionsDefault := false
var selects string
for _, selectKey := range android.SortedStringKeys(selectMap) {
if selectKey == bazel.ConditionsDefaultSelectKey {
@@ -184,14 +212,14 @@ func prettyPrintSelectMap(selectMap map[string]reflect.Value, defaultValue strin
if err != nil {
return "", err
}
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 {
if s != "" {
// Print the custom default value.
ret += s
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)

View File

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

View File

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

View File

@@ -200,6 +200,18 @@ type BaseLinkerProperties struct {
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 {
return &baseLinker{sanitize: sanitize}
}