diff options
| author | 2021-10-08 10:41:31 +0000 | |
|---|---|---|
| committer | 2021-10-08 11:16:20 +0000 | |
| commit | 97b8531492fce820a61d11c2ca5ad2d5abe21eaa (patch) | |
| tree | b3348e1c20a2823a6ea2956468f5e8e9103dfe96 | |
| parent | 800112b97f45535f2380ad3948d72fcf1fa74166 (diff) | |
Add bp2build support for cpp_std.
This converts cpp_std and gnu_extensions into a -std copt, if cpp_std is
specified or gnu_extensions is false if cpp_std is not specified.
I chose to go with this copts approach because the tradeoff is a much
simpler setting than adding a new attr(s) everywhere that uses features
to set the flag.
This approach limits the number of user-configurable knobs (since users
would then be able to set std in _both_ copts and the new attr). But it
does rely on the user copt overriding the toolchain's default gnu++17
version, which can mean a `-std` flag showing up twice in the action.
Fixes: b/202462232
Test: b build //system/libziparchive:libziparchive
Change-Id: I81dad029059461739b91f318d662e089edb46b84
| -rw-r--r-- | bp2build/cc_library_conversion_test.go | 84 | ||||
| -rw-r--r-- | cc/bp2build.go | 19 | ||||
| -rw-r--r-- | cc/compiler.go | 32 |
3 files changed, 123 insertions, 12 deletions
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index bfe88f567..3ca2dd943 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -1677,4 +1677,88 @@ cc_library { "//conditions:default": [], }), )`}}) + +} + +func TestCcLibraryCppStdWithGnuExtensions_ConvertstoCopt(t *testing.T) { + type testCase struct { + cpp_std string + gnu_extensions string + bazel_cpp_std string + } + + testCases := []testCase{ + // Existing usages of cpp_std in AOSP are: + // experimental, c++11, c++17, c++2a, c++98, gnu++11, gnu++17 + // + // not set, only emit if gnu_extensions is disabled. the default (gnu+17 + // is set in the toolchain.) + {cpp_std: "", gnu_extensions: "", bazel_cpp_std: ""}, + {cpp_std: "", gnu_extensions: "false", bazel_cpp_std: "c++17"}, + {cpp_std: "", gnu_extensions: "true", bazel_cpp_std: ""}, + // experimental defaults to gnu++2a + {cpp_std: "experimental", gnu_extensions: "", bazel_cpp_std: "gnu++2a"}, + {cpp_std: "experimental", gnu_extensions: "false", bazel_cpp_std: "c++2a"}, + {cpp_std: "experimental", gnu_extensions: "true", bazel_cpp_std: "gnu++2a"}, + // Explicitly setting a c++ std does not use replace gnu++ std even if + // gnu_extensions is true. + // "c++11", + {cpp_std: "c++11", gnu_extensions: "", bazel_cpp_std: "c++11"}, + {cpp_std: "c++11", gnu_extensions: "false", bazel_cpp_std: "c++11"}, + {cpp_std: "c++11", gnu_extensions: "true", bazel_cpp_std: "c++11"}, + // "c++17", + {cpp_std: "c++17", gnu_extensions: "", bazel_cpp_std: "c++17"}, + {cpp_std: "c++17", gnu_extensions: "false", bazel_cpp_std: "c++17"}, + {cpp_std: "c++17", gnu_extensions: "true", bazel_cpp_std: "c++17"}, + // "c++2a", + {cpp_std: "c++2a", gnu_extensions: "", bazel_cpp_std: "c++2a"}, + {cpp_std: "c++2a", gnu_extensions: "false", bazel_cpp_std: "c++2a"}, + {cpp_std: "c++2a", gnu_extensions: "true", bazel_cpp_std: "c++2a"}, + // "c++98", + {cpp_std: "c++98", gnu_extensions: "", bazel_cpp_std: "c++98"}, + {cpp_std: "c++98", gnu_extensions: "false", bazel_cpp_std: "c++98"}, + {cpp_std: "c++98", gnu_extensions: "true", bazel_cpp_std: "c++98"}, + // gnu++ is replaced with c++ if gnu_extensions is explicitly false. + // "gnu++11", + {cpp_std: "gnu++11", gnu_extensions: "", bazel_cpp_std: "gnu++11"}, + {cpp_std: "gnu++11", gnu_extensions: "false", bazel_cpp_std: "c++11"}, + {cpp_std: "gnu++11", gnu_extensions: "true", bazel_cpp_std: "gnu++11"}, + // "gnu++17", + {cpp_std: "gnu++17", gnu_extensions: "", bazel_cpp_std: "gnu++17"}, + {cpp_std: "gnu++17", gnu_extensions: "false", bazel_cpp_std: "c++17"}, + {cpp_std: "gnu++17", gnu_extensions: "true", bazel_cpp_std: "gnu++17"}, + } + for _, tc := range testCases { + cppStdAttr := "" + if tc.cpp_std != "" { + cppStdAttr = fmt.Sprintf(" cpp_std: \"%s\",", tc.cpp_std) + } + gnuExtensionsAttr := "" + if tc.gnu_extensions != "" { + gnuExtensionsAttr = fmt.Sprintf(" gnu_extensions: %s,", tc.gnu_extensions) + } + bazelCppStdAttr := "" + if tc.bazel_cpp_std != "" { + bazelCppStdAttr = fmt.Sprintf("\n copts = [\"-std=%s\"],", tc.bazel_cpp_std) + } + + runCcLibraryTestCase(t, bp2buildTestCase{ + description: fmt.Sprintf( + "cc_library with cpp_std: %s and gnu_extensions: %s", tc.cpp_std, tc.gnu_extensions), + moduleTypeUnderTest: "cc_library", + moduleTypeUnderTestFactory: cc.LibraryFactory, + moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, + blueprint: soongCcLibraryPreamble + fmt.Sprintf(` +cc_library { + name: "a", +%s // cpp_std: *string +%s // gnu_extensions: *bool + include_build_directory: false, +} +`, cppStdAttr, gnuExtensionsAttr), + expectedBazelTargets: []string{fmt.Sprintf(`cc_library( + name = "a",%s +)`, bazelCppStdAttr)}, + }) + } } diff --git a/cc/bp2build.go b/cc/bp2build.go index ebba9d195..ec15b26db 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -277,7 +277,24 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul srcs.SetSelectValue(axis, config, srcsList) } - archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags) + var archVariantCopts []string + if axis == bazel.NoConfigAxis { + // If cpp_std is not specified, don't generate it in the + // BUILD file. For readability purposes, cpp_std and gnu_extensions are + // combined into a single -std=<version> copt, except in the + // default case where cpp_std is nil and gnu_extensions is true or unspecified, + // then the toolchain's default "gnu++17" will be used. + if baseCompilerProps.Cpp_std != nil { + // TODO(b/202491296): Handle C_std. + // These transformations are shared with compiler.go. + cppStdVal := parseCppStd(baseCompilerProps.Cpp_std) + _, cppStdVal = maybeReplaceGnuToC(baseCompilerProps.Gnu_extensions, "", cppStdVal) + archVariantCopts = append(archVariantCopts, "-std="+cppStdVal) + } else if baseCompilerProps.Gnu_extensions != nil && !*baseCompilerProps.Gnu_extensions { + archVariantCopts = append(archVariantCopts, "-std=c++17") + } + } + archVariantCopts = append(archVariantCopts, parseCommandLineFlags(baseCompilerProps.Cflags)...) archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags) localIncludeDirs := baseCompilerProps.Local_include_dirs diff --git a/cc/compiler.go b/cc/compiler.go index b535e7ff6..4f96712e6 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -305,6 +305,25 @@ func addToModuleList(ctx ModuleContext, key android.OnceKey, module string) { getNamedMapForConfig(ctx.Config(), key).Store(module, true) } +func maybeReplaceGnuToC(gnuExtensions *bool, cStd string, cppStd string) (string, string) { + if gnuExtensions != nil && *gnuExtensions == false { + cStd = gnuToCReplacer.Replace(cStd) + cppStd = gnuToCReplacer.Replace(cppStd) + } + return cStd, cppStd +} + +func parseCppStd(cppStdPtr *string) string { + cppStd := String(cppStdPtr) + switch cppStd { + case "": + cppStd = config.CppStdVersion + case "experimental": + cppStd = config.ExperimentalCppStdVersion + } + return cppStd +} + // Create a Flags struct that collects the compile flags from global values, // per-target values, module type values, and per-module Blueprints properties func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { @@ -484,18 +503,9 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps cStd = String(compiler.Properties.C_std) } - cppStd := String(compiler.Properties.Cpp_std) - switch String(compiler.Properties.Cpp_std) { - case "": - cppStd = config.CppStdVersion - case "experimental": - cppStd = config.ExperimentalCppStdVersion - } + cppStd := parseCppStd(compiler.Properties.Cpp_std) - if compiler.Properties.Gnu_extensions != nil && *compiler.Properties.Gnu_extensions == false { - cStd = gnuToCReplacer.Replace(cStd) - cppStd = gnuToCReplacer.Replace(cppStd) - } + cStd, cppStd = maybeReplaceGnuToC(compiler.Properties.Gnu_extensions, cStd, cppStd) flags.Local.ConlyFlags = append([]string{"-std=" + cStd}, flags.Local.ConlyFlags...) flags.Local.CppFlags = append([]string{"-std=" + cppStd}, flags.Local.CppFlags...) |