diff --git a/android/bazel.go b/android/bazel.go index 91ca969e1..5dda65537 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -253,6 +253,10 @@ var ( "cap_names.h", // http://b/198596102, depends on _makenames, a cc_binary "libminijail", // depends on unconverted modules: libcap + "getcap", // depends on unconverted modules: libcap + "setcap", // depends on unconverted modules: libcap + "minijail0", // depends on unconverted modules: libcap, libminijail + "drop_privs", // depends on unconverted modules: libminijail // Tests. Handle later. "libbionic_tests_headers_posix", // http://b/186024507, cc_library_static, sched.h, time.h not found @@ -279,6 +283,20 @@ var ( "libgtest_ndk_c++", // b/201816222: Requires sdk_version support. "libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support. + + "abb", // depends on unconverted modules: libadbd_core, libadbd_services, libcmd, libbinder, libutils, libselinux + "adb", // depends on unconverted modules: bin2c_fastdeployagent, libadb_crypto, libadb_host, libadb_pairing_connection, libadb_protos, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libmdnssd, libopenscreen-discovery, libopenscreen-platform-impl, libusb, libutils, libziparchive, libzstd, AdbWinApi + "adbd", // depends on unconverted modules: libadb_crypto, libadb_pairing_connection, libadb_protos, libadbd, libadbd_core, libapp_processes_protos_lite, libmdnssd, libzstd, libadbd_services, libcap, libminijail, libselinux + "bionic_tests_zipalign", // depends on unconverted modules: libziparchive, libutils + "linker", // depends on unconverted modules: liblinker_debuggerd_stub, libdebuggerd_handler_fallback, libziparchive, liblinker_main, liblinker_malloc + "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_* + "sefcontext_compile", // depends on unconverted modules: libsepol + "versioner", // depends on unconverted modules: libclang_cxx_host, libLLVM_host + + "linkerconfig", // http://b/202876379 has arch-variant static_executable + "mdnsd", // http://b/202876379 has arch-variant static_executable + + "acvp_modulewrapper", // disabled for android x86/x86_64 } // Per-module denylist of cc_library modules to only generate the static diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go new file mode 100644 index 000000000..3a07128ea --- /dev/null +++ b/bp2build/cc_binary_conversion_test.go @@ -0,0 +1,415 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package bp2build + +import ( + "android/soong/android" + "android/soong/cc" + "fmt" + "strings" + "testing" +) + +const ( + ccBinaryTypePlaceHolder = "{rule_name}" + compatibleWithPlaceHolder = "{target_compatible_with}" +) + +func registerCcBinaryModuleTypes(ctx android.RegistrationContext) { + cc.RegisterCCBuildComponents(ctx) + ctx.RegisterModuleType("filegroup", android.FileGroupFactory) + ctx.RegisterModuleType("cc_library_static", cc.LibraryStaticFactory) + ctx.RegisterModuleType("cc_library", cc.LibraryFactory) +} + +var binaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary", compatibleWithPlaceHolder, "") +var hostBinaryReplacer = strings.NewReplacer(ccBinaryTypePlaceHolder, "cc_binary_host", compatibleWithPlaceHolder, ` + target_compatible_with = select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + }),`) + +func runCcBinaryTests(t *testing.T, tc bp2buildTestCase) { + t.Helper() + runCcBinaryTestCase(t, tc) + runCcHostBinaryTestCase(t, tc) +} + +func runCcBinaryTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + testCase := tc + testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...) + testCase.moduleTypeUnderTest = "cc_binary" + testCase.moduleTypeUnderTestFactory = cc.BinaryFactory + testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryBp2build + testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description) + testCase.blueprint = binaryReplacer.Replace(testCase.blueprint) + for i, et := range testCase.expectedBazelTargets { + testCase.expectedBazelTargets[i] = binaryReplacer.Replace(et) + } + t.Run(testCase.description, func(t *testing.T) { + runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase) + }) +} + +func runCcHostBinaryTestCase(t *testing.T, tc bp2buildTestCase) { + t.Helper() + testCase := tc + testCase.expectedBazelTargets = append([]string{}, tc.expectedBazelTargets...) + testCase.moduleTypeUnderTest = "cc_binary_host" + testCase.moduleTypeUnderTestFactory = cc.BinaryHostFactory + testCase.moduleTypeUnderTestBp2BuildMutator = cc.BinaryHostBp2build + testCase.description = fmt.Sprintf("%s %s", testCase.moduleTypeUnderTest, testCase.description) + testCase.blueprint = hostBinaryReplacer.Replace(testCase.blueprint) + for i, et := range testCase.expectedBazelTargets { + testCase.expectedBazelTargets[i] = hostBinaryReplacer.Replace(et) + } + t.Run(testCase.description, func(t *testing.T) { + runBp2BuildTestCase(t, registerCcBinaryModuleTypes, testCase) + }) +} + +func TestBasicCcBinary(t *testing.T) { + runCcBinaryTests(t, bp2buildTestCase{ + description: "basic -- properties -> attrs with little/no transformation", + blueprint: ` +{rule_name} { + name: "foo", + srcs: ["a.cc"], + local_include_dirs: ["dir"], + include_dirs: ["absolute_dir"], + cflags: ["-Dcopt"], + cppflags: ["-Dcppflag"], + conlyflags: ["-Dconlyflag"], + asflags: ["-Dasflag"], + ldflags: ["ld-flag"], + rtti: true, + strip: { + all: true, + keep_symbols: true, + keep_symbols_and_debug_frame: true, + keep_symbols_list: ["symbol"], + none: true, + }, +} +`, + expectedBazelTargets: []string{`cc_binary( + name = "foo", + absolute_includes = ["absolute_dir"], + asflags = ["-Dasflag"], + conlyflags = ["-Dconlyflag"], + copts = ["-Dcopt"], + cppflags = ["-Dcppflag"], + linkopts = ["ld-flag"], + local_includes = [ + "dir", + ".", + ], + rtti = True, + srcs = ["a.cc"], + strip = { + "all": True, + "keep_symbols": True, + "keep_symbols_and_debug_frame": True, + "keep_symbols_list": ["symbol"], + "none": True, + },{target_compatible_with} +)`}, + }) +} + +func TestCcBinaryWithSharedLdflagDisableFeature(t *testing.T) { + runCcBinaryTests(t, bp2buildTestCase{ + description: `ldflag "-shared" disables static_flag feature`, + blueprint: ` +{rule_name} { + name: "foo", + ldflags: ["-shared"], + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_binary( + name = "foo", + features = ["-static_flag"], + linkopts = ["-shared"],{target_compatible_with} +)`}, + }) +} + +func TestCcBinaryWithLinkStatic(t *testing.T) { + runCcBinaryTests(t, bp2buildTestCase{ + description: "link static", + blueprint: ` +{rule_name} { + name: "foo", + static_executable: true, + include_build_directory: false, +} +`, + expectedBazelTargets: []string{`cc_binary( + name = "foo", + linkshared = False,{target_compatible_with} +)`}, + }) +} + +func TestCcBinaryVersionScript(t *testing.T) { + runCcBinaryTests(t, bp2buildTestCase{ + description: `version script`, + blueprint: ` +{rule_name} { + name: "foo", + include_build_directory: false, + version_script: "vs", +} +`, + expectedBazelTargets: []string{`cc_binary( + name = "foo", + additional_linker_inputs = ["vs"], + linkopts = ["-Wl,--version-script,$(location vs)"],{target_compatible_with} +)`}, + }) +} + +func TestCcBinarySplitSrcsByLang(t *testing.T) { + runCcHostBinaryTestCase(t, bp2buildTestCase{ + description: "split srcs by lang", + blueprint: ` +{rule_name} { + name: "foo", + srcs: [ + "asonly.S", + "conly.c", + "cpponly.cpp", + ":fg_foo", + ], + include_build_directory: false, +} +` + simpleModuleDoNotConvertBp2build("filegroup", "fg_foo"), + expectedBazelTargets: []string{`cc_binary( + name = "foo", + srcs = [ + "cpponly.cpp", + ":fg_foo_cpp_srcs", + ], + srcs_as = [ + "asonly.S", + ":fg_foo_as_srcs", + ], + srcs_c = [ + "conly.c", + ":fg_foo_c_srcs", + ],{target_compatible_with} +)`}, + }) +} + +func TestCcBinaryDoNotDistinguishBetweenDepsAndImplementationDeps(t *testing.T) { + runCcBinaryTestCase(t, bp2buildTestCase{ + description: "no implementation deps", + blueprint: ` +{rule_name} { + name: "foo", + shared_libs: ["implementation_shared_dep", "shared_dep"], + export_shared_lib_headers: ["shared_dep"], + static_libs: ["implementation_static_dep", "static_dep"], + export_static_lib_headers: ["static_dep", "whole_static_dep"], + whole_static_libs: ["not_explicitly_exported_whole_static_dep", "whole_static_dep"], + include_build_directory: false, +} +` + + simpleModuleDoNotConvertBp2build("cc_library_static", "static_dep") + + simpleModuleDoNotConvertBp2build("cc_library_static", "implementation_static_dep") + + simpleModuleDoNotConvertBp2build("cc_library_static", "whole_static_dep") + + simpleModuleDoNotConvertBp2build("cc_library_static", "not_explicitly_exported_whole_static_dep") + + simpleModuleDoNotConvertBp2build("cc_library", "shared_dep") + + simpleModuleDoNotConvertBp2build("cc_library", "implementation_shared_dep"), + expectedBazelTargets: []string{`cc_binary( + name = "foo", + deps = [ + ":implementation_static_dep", + ":static_dep", + ], + dynamic_deps = [ + ":implementation_shared_dep", + ":shared_dep", + ],{target_compatible_with} + whole_archive_deps = [ + ":not_explicitly_exported_whole_static_dep", + ":whole_static_dep", + ], +)`}, + }) +} + +func TestCcBinaryNocrtTests(t *testing.T) { + baseTestCases := []struct { + description string + soongProperty string + bazelAttr string + }{ + { + description: "nocrt: true", + soongProperty: `nocrt: true,`, + bazelAttr: ` link_crt = False,`, + }, + { + description: "nocrt: false", + soongProperty: `nocrt: false,`, + }, + { + description: "nocrt: not set", + }, + } + + baseBlueprint := `{rule_name} { + name: "foo",%s + include_build_directory: false, +} +` + + baseBazelTarget := `cc_binary( + name = "foo",%s{target_compatible_with} +)` + + for _, btc := range baseTestCases { + prop := btc.soongProperty + if len(prop) > 0 { + prop = "\n" + prop + } + attr := btc.bazelAttr + if len(attr) > 0 { + attr = "\n" + attr + } + runCcBinaryTests(t, bp2buildTestCase{ + description: btc.description, + blueprint: fmt.Sprintf(baseBlueprint, prop), + expectedBazelTargets: []string{ + fmt.Sprintf(baseBazelTarget, attr), + }, + }) + } +} + +func TestCcBinaryNo_libcrtTests(t *testing.T) { + baseTestCases := []struct { + description string + soongProperty string + bazelAttr string + }{ + { + description: "no_libcrt: true", + soongProperty: `no_libcrt: true,`, + bazelAttr: ` use_libcrt = False,`, + }, + { + description: "no_libcrt: false", + soongProperty: `no_libcrt: false,`, + bazelAttr: ` use_libcrt = True,`, + }, + { + description: "no_libcrt: not set", + }, + } + + baseBlueprint := `{rule_name} { + name: "foo",%s + include_build_directory: false, +} +` + + baseBazelTarget := `cc_binary( + name = "foo",{target_compatible_with}%s +)` + + for _, btc := range baseTestCases { + prop := btc.soongProperty + if len(prop) > 0 { + prop = "\n" + prop + } + attr := btc.bazelAttr + if len(attr) > 0 { + attr = "\n" + attr + } + runCcBinaryTests(t, bp2buildTestCase{ + description: btc.description, + blueprint: fmt.Sprintf(baseBlueprint, prop), + expectedBazelTargets: []string{ + fmt.Sprintf(baseBazelTarget, attr), + }, + }) + } +} + +func TestCcBinaryPropertiesToFeatures(t *testing.T) { + baseTestCases := []struct { + description string + soongProperty string + bazelAttr string + }{ + { + description: "pack_relocation: true", + soongProperty: `pack_relocations: true,`, + }, + { + description: "pack_relocations: false", + soongProperty: `pack_relocations: false,`, + bazelAttr: ` features = ["disable_pack_relocations"],`, + }, + { + description: "pack_relocations: not set", + }, + { + description: "pack_relocation: true", + soongProperty: `allow_undefined_symbols: true,`, + bazelAttr: ` features = ["-no_undefined_symbols"],`, + }, + { + description: "allow_undefined_symbols: false", + soongProperty: `allow_undefined_symbols: false,`, + }, + { + description: "allow_undefined_symbols: not set", + }, + } + + baseBlueprint := `{rule_name} { + name: "foo",%s + include_build_directory: false, +} +` + + baseBazelTarget := `cc_binary( + name = "foo",%s{target_compatible_with} +)` + + for _, btc := range baseTestCases { + prop := btc.soongProperty + if len(prop) > 0 { + prop = "\n" + prop + } + attr := btc.bazelAttr + if len(attr) > 0 { + attr = "\n" + attr + } + runCcBinaryTests(t, bp2buildTestCase{ + description: btc.description, + blueprint: fmt.Sprintf(baseBlueprint, prop), + expectedBazelTargets: []string{ + fmt.Sprintf(baseBazelTarget, attr), + }, + }) + } +} diff --git a/cc/binary.go b/cc/binary.go index b423c50ae..4d1301bb4 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -20,6 +20,7 @@ import ( "github.com/google/blueprint" "android/soong/android" + "android/soong/bazel" ) type BinaryLinkerProperties struct { @@ -62,7 +63,7 @@ func init() { func RegisterBinaryBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("cc_binary", BinaryFactory) - ctx.RegisterModuleType("cc_binary_host", binaryHostFactory) + ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory) } // cc_binary produces a binary that is runnable on a device. @@ -72,7 +73,7 @@ func BinaryFactory() android.Module { } // cc_binary_host produces a binary that is runnable on a host. -func binaryHostFactory() android.Module { +func BinaryHostFactory() android.Module { module, _ := NewBinary(android.HostSupported) return module.Init() } @@ -541,3 +542,125 @@ func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, lin }, }) } + +func init() { + android.RegisterBp2BuildMutator("cc_binary", BinaryBp2build) + android.RegisterBp2BuildMutator("cc_binary_host", BinaryHostBp2build) +} + +func BinaryBp2build(ctx android.TopDownMutatorContext) { + binaryBp2build(ctx, "cc_binary") +} + +func BinaryHostBp2build(ctx android.TopDownMutatorContext) { + binaryBp2build(ctx, "cc_binary_host") +} + +func binaryBp2build(ctx android.TopDownMutatorContext, typ string) { + m, ok := ctx.Module().(*Module) + if !ok { + // Not a cc module + return + } + if !m.ConvertWithBp2build(ctx) { + return + } + + if ctx.ModuleType() != typ { + return + } + + var compatibleWith bazel.StringListAttribute + if typ == "cc_binary_host" { + //incompatible with android OS + compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, android.Android.Name, []string{"@platforms//:incompatible"}) + compatibleWith.SetSelectValue(bazel.OsConfigurationAxis, bazel.ConditionsDefaultConfigKey, []string{}) + } + + compilerAttrs := bp2BuildParseCompilerProps(ctx, m) + linkerAttrs := bp2BuildParseLinkerProps(ctx, m) + + attrs := &binaryAttributes{ + binaryLinkerAttrs: bp2buildBinaryLinkerProps(ctx, m), + + Srcs: compilerAttrs.srcs, + Srcs_c: compilerAttrs.cSrcs, + Srcs_as: compilerAttrs.asSrcs, + + Copts: compilerAttrs.copts, + Cppflags: compilerAttrs.cppFlags, + Conlyflags: compilerAttrs.conlyFlags, + Asflags: compilerAttrs.asFlags, + + Deps: linkerAttrs.implementationDeps, + Dynamic_deps: linkerAttrs.implementationDynamicDeps, + Whole_archive_deps: linkerAttrs.wholeArchiveDeps, + System_deps: linkerAttrs.systemDynamicDeps, + + 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, + Cpp_std: compilerAttrs.cppStd, + + Additional_linker_inputs: linkerAttrs.additionalLinkerInputs, + + Strip: stripAttributes{ + Keep_symbols: linkerAttrs.stripKeepSymbols, + Keep_symbols_and_debug_frame: linkerAttrs.stripKeepSymbolsAndDebugFrame, + Keep_symbols_list: linkerAttrs.stripKeepSymbolsList, + All: linkerAttrs.stripAll, + None: linkerAttrs.stripNone, + }, + + Target_compatible_with: compatibleWith, + Features: linkerAttrs.features, + } + + ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{ + Rule_class: "cc_binary", + Bzl_load_location: "//build/bazel/rules:cc_binary.bzl", + }, + android.CommonAttributes{Name: m.Name()}, + attrs) +} + +// binaryAttributes contains Bazel attributes corresponding to a cc binary +type binaryAttributes struct { + binaryLinkerAttrs + Srcs bazel.LabelListAttribute + Srcs_c bazel.LabelListAttribute + Srcs_as bazel.LabelListAttribute + + Copts bazel.StringListAttribute + Cppflags bazel.StringListAttribute + Conlyflags bazel.StringListAttribute + Asflags bazel.StringListAttribute + + Deps bazel.LabelListAttribute + Dynamic_deps bazel.LabelListAttribute + Whole_archive_deps bazel.LabelListAttribute + System_deps bazel.LabelListAttribute + + Local_includes bazel.StringListAttribute + Absolute_includes bazel.StringListAttribute + + Linkopts bazel.StringListAttribute + Additional_linker_inputs bazel.LabelListAttribute + + Link_crt bazel.BoolAttribute + Use_libcrt bazel.BoolAttribute + + Rtti bazel.BoolAttribute + Stl *string + Cpp_std *string + + Strip stripAttributes + + Features bazel.StringListAttribute + + Target_compatible_with bazel.StringListAttribute +} diff --git a/cc/bp2build.go b/cc/bp2build.go index a7cabcc85..3c238b5d2 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -117,7 +117,13 @@ type depsPartition struct { type bazelLabelForDepsFn func(android.TopDownMutatorContext, []string) bazel.LabelList -func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition { +func maybePartitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition { + if !exportsDeps { + return depsPartition{ + implementation: fn(ctx, allDeps), + } + } + implementation, export := android.FilterList(allDeps, exportedDeps) return depsPartition{ @@ -128,7 +134,12 @@ func partitionExportedAndImplementationsDeps(ctx android.TopDownMutatorContext, type bazelLabelForDepsExcludesFn func(android.TopDownMutatorContext, []string, []string) bazel.LabelList -func partitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition { +func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.TopDownMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition { + if !exportsDeps { + return depsPartition{ + implementation: fn(ctx, allDeps, excludes), + } + } implementation, export := android.FilterList(allDeps, exportedDeps) return depsPartition{ @@ -145,11 +156,11 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs)) attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs)) - staticDeps := partitionExportedAndImplementationsDeps(ctx, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps) + staticDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Static_libs, props.Export_static_lib_headers, bazelLabelForStaticDeps) attrs.Deps.SetSelectValue(axis, config, staticDeps.export) attrs.Implementation_deps.SetSelectValue(axis, config, staticDeps.implementation) - sharedDeps := partitionExportedAndImplementationsDeps(ctx, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps) + sharedDeps := maybePartitionExportedAndImplementationsDeps(ctx, true, props.Shared_libs, props.Export_shared_lib_headers, bazelLabelForSharedDeps) attrs.Dynamic_deps.SetSelectValue(axis, config, sharedDeps.export) attrs.Implementation_dynamic_deps.SetSelectValue(axis, config, sharedDeps.implementation) @@ -465,6 +476,7 @@ 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 + isBinary := module.Binary() for axis, configToProps := range module.GetArchVariantProperties(ctx, &BaseLinkerProperties{}) { for config, props := range configToProps { @@ -474,7 +486,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) // Excludes to parallel Soong: // https://cs.android.com/android/platform/superproject/+/master:build/soong/cc/linker.go;l=247-249;drc=088b53577dde6e40085ffd737a1ae96ad82fc4b0 staticLibs := android.FirstUniqueStrings(baseLinkerProps.Static_libs) - staticDeps := partitionExportedAndImplementationsDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes) + staticDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, staticLibs, baseLinkerProps.Exclude_static_libs, baseLinkerProps.Export_static_lib_headers, bazelLabelForStaticDepsExcludes) deps.SetSelectValue(axis, config, staticDeps.export) implementationDeps.SetSelectValue(axis, config, staticDeps.implementation) @@ -491,12 +503,12 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) systemSharedDeps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, systemSharedLibs)) sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) - sharedDeps := partitionExportedAndImplementationsDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes) + sharedDeps := maybePartitionExportedAndImplementationsDepsExcludes(ctx, !isBinary, sharedLibs, baseLinkerProps.Exclude_shared_libs, baseLinkerProps.Export_shared_lib_headers, bazelLabelForSharedDepsExcludes) dynamicDeps.SetSelectValue(axis, config, sharedDeps.export) implementationDynamicDeps.SetSelectValue(axis, config, sharedDeps.implementation) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) - hDeps := partitionExportedAndImplementationsDeps(ctx, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps) + hDeps := maybePartitionExportedAndImplementationsDeps(ctx, !isBinary, headerLibs, baseLinkerProps.Export_header_lib_headers, bazelLabelForHeaderDeps) headerDeps.SetSelectValue(axis, config, hDeps.export) implementationHeaderDeps.SetSelectValue(axis, config, hDeps.implementation) @@ -512,6 +524,10 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) var linkerFlags []string if len(baseLinkerProps.Ldflags) > 0 { linkerFlags = append(linkerFlags, baseLinkerProps.Ldflags...) + // binaries remove static flag if -shared is in the linker flags + if module.Binary() && android.InList("-shared", linkerFlags) { + axisFeatures = append(axisFeatures, "-static_flag") + } } if baseLinkerProps.Version_script != nil { label := android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script) @@ -746,3 +762,29 @@ func bazelLabelForHeaderDeps(ctx android.TopDownMutatorContext, modules []string func bazelLabelForSharedDepsExcludes(ctx android.TopDownMutatorContext, modules, excludes []string) bazel.LabelList { return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule) } + +type binaryLinkerAttrs struct { + Linkshared *bool +} + +func bp2buildBinaryLinkerProps(ctx android.TopDownMutatorContext, m *Module) binaryLinkerAttrs { + attrs := binaryLinkerAttrs{} + archVariantProps := m.GetArchVariantProperties(ctx, &BinaryLinkerProperties{}) + for axis, configToProps := range archVariantProps { + for _, p := range configToProps { + props := p.(*BinaryLinkerProperties) + staticExecutable := props.Static_executable + if axis == bazel.NoConfigAxis { + if linkBinaryShared := !proptools.Bool(staticExecutable); !linkBinaryShared { + attrs.Linkshared = &linkBinaryShared + } + } else if staticExecutable != nil { + // TODO(b/202876379): Static_executable is arch-variant; however, linkshared is a + // nonconfigurable attribute. Only 4 AOSP modules use this feature, defer handling + ctx.ModuleErrorf("bp2build cannot migrate a module with arch/target-specific static_executable values") + } + } + } + + return attrs +}