Handle no_libcrt in bp2build.
Test: ci/bp2build.sh Bug: 187928307 Change-Id: Ib80c4318169652b322e5d878c8784679e42f87dd
This commit is contained in:
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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,
|
||||
}),
|
||||
)`}})
|
||||
}
|
||||
|
@@ -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"],
|
||||
)`},
|
||||
})
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
|
@@ -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,
|
||||
|
12
cc/linker.go
12
cc/linker.go
@@ -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}
|
||||
}
|
||||
|
Reference in New Issue
Block a user