Merge "Handle no_libcrt in bp2build."
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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,
|
||||||
|
}),
|
||||||
|
)`}})
|
||||||
|
}
|
||||||
|
@@ -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}
|
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)
|
||||||
|
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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,
|
||||||
|
12
cc/linker.go
12
cc/linker.go
@@ -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}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user