From ef9c900ec3d5bc720fb61f6a360fdd8614ebfff2 Mon Sep 17 00:00:00 2001 From: Trevor Radcliffe Date: Fri, 13 May 2022 20:55:35 +0000 Subject: [PATCH] Generate genlex rules from bp2build for cc targets This change will cause bp2build to generate genlex targets any time a .l or .ll file is present in the srcs for a cc target and add those genlex targets to the srcs attribute of the original target. Bug: 207408632 Test: unit tests Change-Id: I1bce82c9d3c3d458eae1cef547ffae3d6e975134 --- android/allowlists/allowlists.go | 18 +++---- bazel/aquery.go | 2 +- bp2build/cc_binary_conversion_test.go | 48 +++++++++++++++++- bp2build/cc_library_conversion_test.go | 48 ++++++++++++++++++ bp2build/cc_library_shared_conversion_test.go | 49 +++++++++++++++++++ bp2build/cc_prebuilt_library_static_test.go | 49 +++++++++++++++++++ cc/bp2build.go | 23 ++++++++- cc/gen.go | 36 ++++++++++++++ 8 files changed, 260 insertions(+), 13 deletions(-) diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 0cb69467e..69703d1c3 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -310,7 +310,6 @@ var ( Bp2buildModuleDoNotConvertList = []string{ // cc bugs - "libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules "libactivitymanager_aidl", // TODO(b/207426160): Unsupported use of aidl sources (via Dactivity_manager_procstate_aidl) in a cc_library "gen-kotlin-build-file.py", // TODO(b/198619163) module has same name as source "libgtest_ndk_c++", "libgtest_main_ndk_c++", // TODO(b/201816222): Requires sdk_version support. @@ -363,15 +362,14 @@ var ( "libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported // unconverted deps - "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib - "abb", // depends on unconverted modules: libcmd, libbinder - "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi - "android_icu4j_srcgen", // depends on unconverted modules: currysrc - "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc - "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full - "art-script", // depends on unconverted modules: dalvikvm, dex2oat - "bin2c_fastdeployagent", // depends on unconverted modules: deployagent - "chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol + "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib + "abb", // depends on unconverted modules: libcmd, libbinder + "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi + "android_icu4j_srcgen", // depends on unconverted modules: currysrc + "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc + "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full + "art-script", // depends on unconverted modules: dalvikvm, dex2oat + "bin2c_fastdeployagent", // depends on unconverted modules: deployagent "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig "conv_linker_config", // depends on unconverted modules: linker_config_proto "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9 diff --git a/bazel/aquery.go b/bazel/aquery.go index ee09d0b13..b09bc098c 100644 --- a/bazel/aquery.go +++ b/bazel/aquery.go @@ -628,7 +628,7 @@ func addCommandForPyBinaryRunfilesDir(oldCommand string, zipperCommandPath, zipF } func isSymlinkAction(a action) bool { - return a.Mnemonic == "Symlink" || a.Mnemonic == "SolibSymlink" + return a.Mnemonic == "Symlink" || a.Mnemonic == "SolibSymlink" || a.Mnemonic == "ExecutableSymlink" } func isTemplateExpandAction(a action) bool { diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 037564bb1..30be9979e 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -86,7 +86,7 @@ func runCcHostBinaryTestCase(t *testing.T, tc ccBinaryBp2buildTestCase) { testCase := tc for i, tar := range testCase.targets { switch tar.typ { - case "cc_binary", "proto_library", "cc_lite_proto_library": + case "cc_binary", "proto_library", "cc_lite_proto_library", "genlex": tar.attrs["target_compatible_with"] = `select({ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], "//conditions:default": [], @@ -505,3 +505,49 @@ func TestCcBinaryStaticProto(t *testing.T) { }, }) } + +func TestCcBinaryConvertLex(t *testing.T) { + runCcBinaryTests(t, ccBinaryBp2buildTestCase{ + description: `.l and .ll sources converted to .c and .cc`, + blueprint: ` +{rule_name} { + name: "foo", + srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"], + lex: { flags: ["--foo_opt", "--bar_opt"] }, + include_build_directory: false, +} +`, + targets: []testBazelTarget{ + {"genlex", "foo_genlex_l", attrNameToString{ + "srcs": `[ + "foo1.l", + "foo2.l", + ]`, + "lexopts": `[ + "--foo_opt", + "--bar_opt", + ]`, + }}, + {"genlex", "foo_genlex_ll", attrNameToString{ + "srcs": `[ + "bar1.ll", + "bar2.ll", + ]`, + "lexopts": `[ + "--foo_opt", + "--bar_opt", + ]`, + }}, + {"cc_binary", "foo", attrNameToString{ + "srcs": `[ + "bar.cc", + ":foo_genlex_ll", + ]`, + "srcs_c": `[ + "foo.c", + ":foo_genlex_l", + ]`, + }}, + }, + }) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index ab9298116..a0bc9e7b4 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -2457,3 +2457,51 @@ func TestCcLibraryEscapeLdflags(t *testing.T) { }), }) } + +func TestCcLibraryConvertLex(t *testing.T) { + runCcLibraryTestCase(t, bp2buildTestCase{ + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + filesystem: map[string]string{ + "foo.c": "", + "bar.cc": "", + "foo1.l": "", + "bar1.ll": "", + "foo2.l": "", + "bar2.ll": "", + }, + blueprint: `cc_library { + name: "foo_lib", + srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"], + lex: { flags: ["--foo_flags"] }, + include_build_directory: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: append([]string{ + makeBazelTarget("genlex", "foo_lib_genlex_l", attrNameToString{ + "srcs": `[ + "foo1.l", + "foo2.l", + ]`, + "lexopts": `["--foo_flags"]`, + }), + makeBazelTarget("genlex", "foo_lib_genlex_ll", attrNameToString{ + "srcs": `[ + "bar1.ll", + "bar2.ll", + ]`, + "lexopts": `["--foo_flags"]`, + }), + }, + makeCcLibraryTargets("foo_lib", attrNameToString{ + "srcs": `[ + "bar.cc", + ":foo_lib_genlex_ll", + ]`, + "srcs_c": `[ + "foo.c", + ":foo_lib_genlex_l", + ]`, + })...), + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 7c2c10077..be096168c 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -520,3 +520,52 @@ cc_library_shared { })}, }) } + +func TestCcLibrarySharedConvertLex(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + description: "cc_library_shared with lex files", + moduleTypeUnderTest: "cc_library_shared", + moduleTypeUnderTestFactory: cc.LibrarySharedFactory, + filesystem: map[string]string{ + "foo.c": "", + "bar.cc": "", + "foo1.l": "", + "bar1.ll": "", + "foo2.l": "", + "bar2.ll": "", + }, + blueprint: `cc_library_shared { + name: "foo_lib", + srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"], + lex: { flags: ["--foo_flags"] }, + include_build_directory: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("genlex", "foo_lib_genlex_l", attrNameToString{ + "srcs": `[ + "foo1.l", + "foo2.l", + ]`, + "lexopts": `["--foo_flags"]`, + }), + makeBazelTarget("genlex", "foo_lib_genlex_ll", attrNameToString{ + "srcs": `[ + "bar1.ll", + "bar2.ll", + ]`, + "lexopts": `["--foo_flags"]`, + }), + makeBazelTarget("cc_library_shared", "foo_lib", attrNameToString{ + "srcs": `[ + "bar.cc", + ":foo_lib_genlex_ll", + ]`, + "srcs_c": `[ + "foo.c", + ":foo_lib_genlex_l", + ]`, + }), + }, + }) +} diff --git a/bp2build/cc_prebuilt_library_static_test.go b/bp2build/cc_prebuilt_library_static_test.go index 3feb1f155..59839c884 100644 --- a/bp2build/cc_prebuilt_library_static_test.go +++ b/bp2build/cc_prebuilt_library_static_test.go @@ -96,3 +96,52 @@ cc_prebuilt_library_static { expectedErr: fmt.Errorf("Expected at most one source file"), }) } + +func TestCcLibraryStaticConvertLex(t *testing.T) { + runCcLibrarySharedTestCase(t, bp2buildTestCase{ + description: "cc_library_static with lex files", + moduleTypeUnderTest: "cc_library_static", + moduleTypeUnderTestFactory: cc.LibraryStaticFactory, + filesystem: map[string]string{ + "foo.c": "", + "bar.cc": "", + "foo1.l": "", + "bar1.ll": "", + "foo2.l": "", + "bar2.ll": "", + }, + blueprint: `cc_library_static { + name: "foo_lib", + srcs: ["foo.c", "bar.cc", "foo1.l", "foo2.l", "bar1.ll", "bar2.ll"], + lex: { flags: ["--foo_flags"] }, + include_build_directory: false, + bazel_module: { bp2build_available: true }, +}`, + expectedBazelTargets: []string{ + makeBazelTarget("genlex", "foo_lib_genlex_l", attrNameToString{ + "srcs": `[ + "foo1.l", + "foo2.l", + ]`, + "lexopts": `["--foo_flags"]`, + }), + makeBazelTarget("genlex", "foo_lib_genlex_ll", attrNameToString{ + "srcs": `[ + "bar1.ll", + "bar2.ll", + ]`, + "lexopts": `["--foo_flags"]`, + }), + makeBazelTarget("cc_library_static", "foo_lib", attrNameToString{ + "srcs": `[ + "bar.cc", + ":foo_lib_genlex_ll", + ]`, + "srcs_c": `[ + "foo.c", + ":foo_lib_genlex_l", + ]`, + }), + }, + }) +} diff --git a/cc/bp2build.go b/cc/bp2build.go index 4155aa326..ba02b7ef8 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -29,6 +29,8 @@ import ( const ( cSrcPartition = "c" asSrcPartition = "as" + lSrcPartition = "l" + llSrcPartition = "ll" cppSrcPartition = "cpp" protoSrcPartition = "proto" ) @@ -76,6 +78,12 @@ func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.Lab protoSrcPartition: android.ProtoSrcLabelPartition, cSrcPartition: bazel.LabelPartition{Extensions: []string{".c"}, LabelMapper: addSuffixForFilegroup("_c_srcs")}, asSrcPartition: bazel.LabelPartition{Extensions: []string{".s", ".S"}, LabelMapper: addSuffixForFilegroup("_as_srcs")}, + // TODO(http://b/231968910): If there is ever a filegroup target that + // contains .l or .ll files we will need to find a way to add a + // LabelMapper for these that identifies these filegroups and + // converts them appropriately + lSrcPartition: bazel.LabelPartition{Extensions: []string{".l"}}, + llSrcPartition: bazel.LabelPartition{Extensions: []string{".ll"}}, // C++ is the "catch-all" group, and comprises generated sources because we don't // know the language of these sources until the genrule is executed. cppSrcPartition: bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true}, @@ -285,6 +293,11 @@ type compilerAttributes struct { cppFlags bazel.StringListAttribute srcs bazel.LabelListAttribute + // Lex sources and options + lSrcs bazel.LabelListAttribute + llSrcs bazel.LabelListAttribute + lexopts bazel.StringListAttribute + hdrs bazel.LabelListAttribute rtti bazel.BoolAttribute @@ -407,6 +420,8 @@ func (ca *compilerAttributes) finalize(ctx android.BazelConversionPathContext, i ca.srcs = partitionedSrcs[cppSrcPartition] ca.cSrcs = partitionedSrcs[cSrcPartition] ca.asSrcs = partitionedSrcs[asSrcPartition] + ca.lSrcs = partitionedSrcs[lSrcPartition] + ca.llSrcs = partitionedSrcs[llSrcPartition] ca.absoluteIncludes.DeduplicateAxesFromBase() ca.localIncludes.DeduplicateAxesFromBase() @@ -515,7 +530,9 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) var allHdrs []string if baseCompilerProps, ok := archVariantCompilerProps[axis][config].(*BaseCompilerProperties); ok { allHdrs = baseCompilerProps.Generated_headers - + if baseCompilerProps.Lex != nil { + compilerAttrs.lexopts.SetSelectValue(axis, config, baseCompilerProps.Lex.Flags) + } (&compilerAttrs).bp2buildForAxisAndConfig(ctx, axis, config, baseCompilerProps) } @@ -570,6 +587,10 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) (&linkerAttrs).wholeArchiveDeps.Add(protoDep.wholeStaticLib) (&linkerAttrs).implementationWholeArchiveDeps.Add(protoDep.implementationWholeStaticLib) + convertedLSrcs := bp2BuildLex(ctx, module.Name(), compilerAttrs) + (&compilerAttrs).srcs.Add(&convertedLSrcs.srcName) + (&compilerAttrs).cSrcs.Add(&convertedLSrcs.cSrcName) + return baseAttributes{ compilerAttrs, linkerAttrs, diff --git a/cc/gen.go b/cc/gen.go index 8f6236349..08b49c97d 100644 --- a/cc/gen.go +++ b/cc/gen.go @@ -18,6 +18,7 @@ import ( "path/filepath" "strings" + "android/soong/bazel" "github.com/google/blueprint" "android/soong/android" @@ -169,6 +170,41 @@ func genLex(ctx android.ModuleContext, lexFile android.Path, outFile android.Mod }) } +type LexAttrs struct { + Srcs bazel.LabelListAttribute + Lexopts bazel.StringListAttribute +} + +type LexNames struct { + cSrcName bazel.LabelAttribute + srcName bazel.LabelAttribute +} + +func bp2BuildLex(ctx android.Bp2buildMutatorContext, moduleName string, ca compilerAttributes) LexNames { + names := LexNames{} + if !ca.lSrcs.IsEmpty() { + names.cSrcName = createLexTargetModule(ctx, moduleName+"_genlex_l", ca.lSrcs, ca.lexopts) + } + if !ca.llSrcs.IsEmpty() { + names.srcName = createLexTargetModule(ctx, moduleName+"_genlex_ll", ca.llSrcs, ca.lexopts) + } + return names +} + +func createLexTargetModule(ctx android.Bp2buildMutatorContext, name string, srcs bazel.LabelListAttribute, opts bazel.StringListAttribute) bazel.LabelAttribute { + ctx.CreateBazelTargetModule( + bazel.BazelTargetModuleProperties{ + Rule_class: "genlex", + Bzl_load_location: "//build/bazel/rules/cc:flex.bzl", + }, + android.CommonAttributes{Name: name}, + &LexAttrs{ + Srcs: srcs, + Lexopts: opts, + }) + return bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + name}} +} + func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Paths) { headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h") publicHeaderFile := android.PathForModuleGen(ctx, "sysprop/public", "include", syspropFile.Rel()+".h")