diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 0d6582294..bfe88f567 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -15,6 +15,7 @@ package bp2build import ( + "fmt" "testing" "android/soong/android" @@ -1141,6 +1142,81 @@ cc_library { } func TestCCLibraryNoCrtTrue(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library - nocrt: true emits attribute", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "foo-lib", + srcs: ["impl.cpp"], + nocrt: true, + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "foo-lib", + link_crt = False, + srcs = ["impl.cpp"], +)`}}) +} + +func TestCCLibraryNoCrtFalse(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library - nocrt: false - does not emit attribute", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "foo-lib", + srcs: ["impl.cpp"], + nocrt: false, + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_library( + name = "foo-lib", + srcs = ["impl.cpp"], +)`}}) +} + +func TestCCLibraryNoCrtArchVariant(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + description: "cc_library - nocrt in select", + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library { + name: "foo-lib", + srcs: ["impl.cpp"], + arch: { + arm: { + nocrt: true, + }, + x86: { + nocrt: false, + }, + }, + include_build_directory: false, +} +`, + expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo-lib\": nocrt is not supported for arch variants"), + }) +} + +func TestCCLibraryNoLibCrtTrue(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ description: "cc_library - simple example", moduleTypeUnderTest: "cc_library", @@ -1165,7 +1241,7 @@ cc_library { )`}}) } -func TestCCLibraryNoCrtFalse(t *testing.T) { +func TestCCLibraryNoLibCrtFalse(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ moduleTypeUnderTest: "cc_library", moduleTypeUnderTestFactory: cc.LibraryFactory, @@ -1189,7 +1265,7 @@ cc_library { )`}}) } -func TestCCLibraryNoCrtArchVariant(t *testing.T) { +func TestCCLibraryNoLibCrtArchVariant(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ moduleTypeUnderTest: "cc_library", moduleTypeUnderTestFactory: cc.LibraryFactory, @@ -1223,41 +1299,6 @@ cc_library { )`}}) } -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 { - name: "foo-lib", - srcs: ["impl.cpp"], - no_libcrt: false, - arch: { - arm: { - no_libcrt: true, - }, - x86: { - no_libcrt: true, - }, - }, - include_build_directory: false, -} -`, - expectedBazelTargets: []string{`cc_library( - name = "foo-lib", - srcs = ["impl.cpp"], - use_libcrt = select({ - "//build/bazel/platforms/arch:arm": False, - "//build/bazel/platforms/arch:x86": False, - "//conditions:default": True, - }), -)`}}) -} - func TestCcLibraryStrip(t *testing.T) { runCcLibraryTestCase(t, bp2buildTestCase{ description: "cc_library strip args", diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 3dcfbd7db..b27206747 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -15,6 +15,7 @@ package bp2build import ( + "fmt" "testing" "android/soong/android" @@ -364,3 +365,78 @@ cc_library_shared { )`}, }) } + +func TestCcLibrarySharedNoCrtTrue(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + description: "cc_library_shared - nocrt: true emits attribute", + moduleTypeUnderTest: "cc_library_shared", + moduleTypeUnderTestFactory: cc.LibrarySharedFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library_shared { + name: "foo_shared", + srcs: ["impl.cpp"], + nocrt: true, + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_library_shared( + name = "foo_shared", + link_crt = False, + srcs = ["impl.cpp"], +)`}}) +} + +func TestCcLibrarySharedNoCrtFalse(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + description: "cc_library_shared - nocrt: false doesn't emit attribute", + moduleTypeUnderTest: "cc_library_shared", + moduleTypeUnderTestFactory: cc.LibrarySharedFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library_shared { + name: "foo_shared", + srcs: ["impl.cpp"], + nocrt: false, + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_library_shared( + name = "foo_shared", + srcs = ["impl.cpp"], +)`}}) +} + +func TestCcLibrarySharedNoCrtArchVariant(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + description: "cc_library_shared - nocrt in select", + moduleTypeUnderTest: "cc_library_shared", + moduleTypeUnderTestFactory: cc.LibrarySharedFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibrarySharedBp2Build, + filesystem: map[string]string{ + "impl.cpp": "", + }, + blueprint: soongCcLibraryPreamble + ` +cc_library_shared { + name: "foo_shared", + srcs: ["impl.cpp"], + arch: { + arm: { + nocrt: true, + }, + x86: { + nocrt: false, + }, + }, + include_build_directory: false, +} +`, + expectedErr: fmt.Errorf("Android.bp:16:1: module \"foo_shared\": nocrt is not supported for arch variants"), + }) +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 22bd90bb0..ebba9d195 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -364,6 +364,7 @@ type linkerAttributes struct { wholeArchiveDeps bazel.LabelListAttribute systemDynamicDeps bazel.LabelListAttribute + linkCrt bazel.BoolAttribute useLibcrt bazel.BoolAttribute linkopts bazel.StringListAttribute versionScript bazel.LabelAttribute @@ -398,6 +399,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) var linkopts bazel.StringListAttribute var versionScript bazel.LabelAttribute + var linkCrt bazel.BoolAttribute var useLibcrt bazel.BoolAttribute var stripKeepSymbols bazel.BoolAttribute @@ -418,6 +420,9 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) } } + // Use a single variable to capture usage of nocrt in arch variants, so there's only 1 error message for this module + var disallowedArchVariantCrt bool + for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { for config, props := range configToProps { if baseLinkerProps, ok := props.(*BaseLinkerProperties); ok { @@ -457,10 +462,23 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) versionScript.SetSelectValue(axis, config, android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) } useLibcrt.SetSelectValue(axis, config, baseLinkerProps.libCrt()) + + // it's very unlikely for nocrt to be arch variant, so bp2build doesn't support it. + if baseLinkerProps.crt() != nil { + if axis == bazel.NoConfigAxis { + linkCrt.SetSelectValue(axis, config, baseLinkerProps.crt()) + } else if axis == bazel.ArchConfigurationAxis { + disallowedArchVariantCrt = true + } + } } } } + if disallowedArchVariantCrt { + ctx.ModuleErrorf("nocrt is not supported for arch variants") + } + type productVarDep struct { // the name of the corresponding excludes field, if one exists excludesField string @@ -530,6 +548,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) wholeArchiveDeps: wholeArchiveDeps, systemDynamicDeps: systemSharedDeps, + linkCrt: linkCrt, linkopts: linkopts, useLibcrt: useLibcrt, versionScript: versionScript, diff --git a/cc/library.go b/cc/library.go index 77eddbf13..58e0e2123 100644 --- a/cc/library.go +++ b/cc/library.go @@ -252,6 +252,7 @@ type bazelCcLibraryAttributes struct { // This is shared only. Version_script bazel.LabelAttribute + Link_crt bazel.BoolAttribute // Common properties shared between both shared and static variants. Shared staticOrSharedAttributes @@ -321,6 +322,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Local_includes: compilerAttrs.localIncludes, Absolute_includes: compilerAttrs.absoluteIncludes, Linkopts: linkerAttrs.linkopts, + Link_crt: linkerAttrs.linkCrt, Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, @@ -2415,6 +2417,7 @@ func ccSharedOrStaticBp2BuildMutatorInternal(ctx android.TopDownMutatorContext, Asflags: asFlags, Linkopts: linkerAttrs.linkopts, + Link_crt: linkerAttrs.linkCrt, Use_libcrt: linkerAttrs.useLibcrt, Rtti: compilerAttrs.rtti, Stl: compilerAttrs.stl, @@ -2472,6 +2475,7 @@ type bazelCcLibrarySharedAttributes struct { staticOrSharedAttributes Linkopts bazel.StringListAttribute + Link_crt bazel.BoolAttribute // Only for linking shared library (and cc_binary) Use_libcrt bazel.BoolAttribute Rtti bazel.BoolAttribute Stl *string diff --git a/cc/linker.go b/cc/linker.go index 0d612b583..20e377ceb 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -238,6 +238,19 @@ func invertBoolPtr(value *bool) *bool { return &ret } +func (blp *BaseLinkerProperties) crt() *bool { + val := invertBoolPtr(blp.Nocrt) + if val != nil && *val { + // == True + // + // Since crt is enabled for almost every module compiling against the Bionic runtime, + // use `nil` when it's enabled, and rely on the Starlark macro to set it to True by default. + // This keeps the BUILD files clean. + return nil + } + return val // can be False or nil +} + func (blp *BaseLinkerProperties) libCrt() *bool { return invertBoolPtr(blp.No_libcrt) }