diff options
author | mobiletc-prebuild <mobiletc-prebuild@google.com> | 2024-01-25 08:00:21 -0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2024-01-25 17:41:21 +0000 |
commit | 73f2f02c8321957a368410d022f62b0e991ffa60 (patch) | |
tree | d8b8b247cd2d591c48c19b001a264e87af792651 | |
parent | 7868f472843914a6bae785cdcb3cbc24b301f7f8 (diff) | |
download | toolchain-utils-73f2f02c8321957a368410d022f62b0e991ffa60.tar.gz |
compiler_wrapper: automatic sync
This CL automatically brings toolchain-utils' compiler_wrapper/
directory in sync with chromiumos-overlay's. Please see
go/crostc-repo/+/main:sync_compiler_wrapper_within_cros.sh for more info
on this process.
BUG=None
TEST=None
Change-Id: I57353526b8f113892556bb4f4c07e10ecb42ce00
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/5237730
Commit-Queue: Bob Haarman <inglorion@chromium.org>
Reviewed-by: Bob Haarman <inglorion@chromium.org>
Tested-by: mobiletc-prebuild Role Account <mobiletc-prebuild@google.com>
Auto-Submit: mobiletc-prebuild Role Account <mobiletc-prebuild@google.com>
-rw-r--r-- | compiler_wrapper/compiler_wrapper.go | 5 | ||||
-rw-r--r-- | compiler_wrapper/disable_werror_flag.go | 76 | ||||
-rw-r--r-- | compiler_wrapper/disable_werror_flag_test.go | 93 |
3 files changed, 142 insertions, 32 deletions
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go index 472e6d83..d8741fd8 100644 --- a/compiler_wrapper/compiler_wrapper.go +++ b/compiler_wrapper/compiler_wrapper.go @@ -121,6 +121,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int processPrintCmdlineFlag(mainBuilder) env = mainBuilder.env var compilerCmd *command + disableWerrorConfig := processForceDisableWerrorFlag(env, cfg, mainBuilder) clangSyntax := processClangSyntaxFlag(mainBuilder) rusageEnabled := isRusageEnabled(env) @@ -231,11 +232,11 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int compilerCmd = removeRusageFromCommand(compilerCmd) } - if shouldForceDisableWerror(env, cfg, mainBuilder.target.compilerType) { + if disableWerrorConfig.enabled { if bisectStage != "" { return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR") } - return doubleBuildWithWNoError(env, cfg, compilerCmd) + return doubleBuildWithWNoError(env, cfg, compilerCmd, disableWerrorConfig) } if shouldCompileWithFallback(env) { if rusageEnabled { diff --git a/compiler_wrapper/disable_werror_flag.go b/compiler_wrapper/disable_werror_flag.go index 91bc5845..0546de9f 100644 --- a/compiler_wrapper/disable_werror_flag.go +++ b/compiler_wrapper/disable_werror_flag.go @@ -22,17 +22,63 @@ func getForceDisableWerrorDir(env env, cfg *config) string { return path.Join(getCompilerArtifactsDir(env), cfg.newWarningsDir) } -func shouldForceDisableWerror(env env, cfg *config, ty compilerType) bool { +type forceDisableWerrorConfig struct { + // If reportToStdout is true, we'll write -Werror reports to stdout. Otherwise, they'll be + // written to reportDir. If reportDir is empty, it will be determined via + // `getForceDisableWerrorDir`. + // + // Neither of these have specified values if `enabled == false`. + reportDir string + reportToStdout bool + + // If true, `-Werror` reporting should be used. + enabled bool +} + +func processForceDisableWerrorFlag(env env, cfg *config, builder *commandBuilder) forceDisableWerrorConfig { if cfg.isAndroidWrapper { - return cfg.useLlvmNext + return forceDisableWerrorConfig{ + reportToStdout: true, + enabled: cfg.useLlvmNext, + } } - // We only want this functionality for clang. - if ty != clangType { - return false + // CrOS only wants this functionality for clang. + if builder.target.compilerType != clangType { + return forceDisableWerrorConfig{enabled: false} } - value, _ := env.getenv("FORCE_DISABLE_WERROR") - return value != "" + + // CrOS supports two modes for enabling this flag: + // 1 (preferred). A CFLAG that specifies the directory to write reports to. e.g., + // `-D_CROSTC_FORCE_DISABLE_WERROR=/path/to/directory`. This flag will be removed from the + // command before the compiler is invoked. If multiple of these are passed, the last one + // wins, but all are removed from the build command. + // 2 (deprecated). An environment variable, FORCE_DISABLE_WERROR, set to any nonempty value. + // In this case, the wrapper will write to either somewhere under + // ${CROS_ARTIFACTS_TMP_DIR}, or to /tmp. + const cflagPrefix = "-D_CROSTC_FORCE_DISABLE_WERROR=" + + argDir := "" + sawArg := false + builder.transformArgs(func(arg builderArg) string { + value := arg.value + if !strings.HasPrefix(value, cflagPrefix) { + return value + } + argDir = value[len(cflagPrefix):] + sawArg = true + return "" + }) + + if sawArg { + return forceDisableWerrorConfig{ + reportDir: argDir, + enabled: true, + } + } + + envValue, _ := env.getenv("FORCE_DISABLE_WERROR") + return forceDisableWerrorConfig{enabled: envValue != ""} } func disableWerrorFlags(originalArgs []string) []string { @@ -64,7 +110,7 @@ func isLikelyAConfTest(cfg *config, cmd *command) bool { return false } -func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCode int, err error) { +func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command, werrorConfig forceDisableWerrorConfig) (exitCode int, err error) { originalStdoutBuffer := &bytes.Buffer{} originalStderrBuffer := &bytes.Buffer{} // TODO: This is a bug in the old wrapper that it drops the ccache path @@ -163,7 +209,7 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo // Write warning report to stdout for Android. On Android, // double-build can be requested on remote builds as well, where there // is no canonical place to write the warnings report. - if cfg.isAndroidWrapper { + if werrorConfig.reportToStdout { stdout := env.stdout() io.WriteString(stdout, "<LLVM_NEXT_ERROR_REPORT>") if err := json.NewEncoder(stdout).Encode(jsonData); err != nil { @@ -182,10 +228,14 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo oldMask := env.umask(0) defer env.umask(oldMask) - warningsDir := getForceDisableWerrorDir(env, cfg) + reportDir := werrorConfig.reportDir + if reportDir == "" { + reportDir = getForceDisableWerrorDir(env, cfg) + } + // Allow root and regular users to write to this without issue. - if err := os.MkdirAll(warningsDir, 0777); err != nil { - return 0, wrapErrorwithSourceLocf(err, "error creating warnings directory %s", warningsDir) + if err := os.MkdirAll(reportDir, 0777); err != nil { + return 0, wrapErrorwithSourceLocf(err, "error creating warnings directory %s", reportDir) } // Have some tag to show that files aren't fully written. It would be sad if @@ -196,7 +246,7 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo // Coming up with a consistent name for this is difficult (compiler command's // SHA can clash in the case of identically named files in different // directories, or similar); let's use a random one. - tmpFile, err := ioutil.TempFile(warningsDir, "warnings_report*.json"+incompleteSuffix) + tmpFile, err := ioutil.TempFile(reportDir, "warnings_report*.json"+incompleteSuffix) if err != nil { return 0, wrapErrorwithSourceLocf(err, "error creating warnings file") } diff --git a/compiler_wrapper/disable_werror_flag_test.go b/compiler_wrapper/disable_werror_flag_test.go index 9d3b4aba..74e915e0 100644 --- a/compiler_wrapper/disable_werror_flag_test.go +++ b/compiler_wrapper/disable_werror_flag_test.go @@ -13,6 +13,7 @@ import ( "os" "path" "path/filepath" + "reflect" "strings" "testing" ) @@ -415,27 +416,39 @@ func TestDoubleBuildWerrorChmodsThingsAppropriately(t *testing.T) { }) } +type commandBuilderOpts struct { + isGcc bool + cflags []string +} + +func newWerrorCommandBuilderOrDie(t *testing.T, ctx *testContext, opts commandBuilderOpts) *commandBuilder { + compiler := "clang" + if opts.isGcc { + compiler = "gcc" + } + cmd := ctx.newCommand(compiler, opts.cflags...) + b, err := newCommandBuilder(ctx, ctx.cfg, cmd) + if err != nil { + t.Fatalf("Constructing builder unexpectedly failed: %v", err) + } + return b +} + func TestAndroidDisableWerror(t *testing.T) { withTestContext(t, func(ctx *testContext) { ctx.cfg.isAndroidWrapper = true + builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{}) + // Disable werror ON ctx.cfg.useLlvmNext = true - if !shouldForceDisableWerror(ctx, ctx.cfg, gccType) { - t.Errorf("disable Werror not enabled for Android with useLlvmNext") - } - - if !shouldForceDisableWerror(ctx, ctx.cfg, clangType) { + if !processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled { t.Errorf("disable Werror not enabled for Android with useLlvmNext") } // Disable werror OFF ctx.cfg.useLlvmNext = false - if shouldForceDisableWerror(ctx, ctx.cfg, gccType) { - t.Errorf("disable-Werror enabled for Android without useLlvmNext") - } - - if shouldForceDisableWerror(ctx, ctx.cfg, clangType) { + if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled { t.Errorf("disable-Werror enabled for Android without useLlvmNext") } }) @@ -443,11 +456,8 @@ func TestAndroidDisableWerror(t *testing.T) { func TestChromeOSNoForceDisableWerror(t *testing.T) { withTestContext(t, func(ctx *testContext) { - if shouldForceDisableWerror(ctx, ctx.cfg, gccType) { - t.Errorf("disable Werror enabled for ChromeOS without FORCE_DISABLE_WERROR set") - } - - if shouldForceDisableWerror(ctx, ctx.cfg, clangType) { + builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{}) + if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled { t.Errorf("disable Werror enabled for ChromeOS without FORCE_DISABLE_WERROR set") } }) @@ -455,16 +465,65 @@ func TestChromeOSNoForceDisableWerror(t *testing.T) { func TestChromeOSForceDisableWerrorOnlyAppliesToClang(t *testing.T) { withForceDisableWErrorTestContext(t, func(ctx *testContext) { - if !shouldForceDisableWerror(ctx, ctx.cfg, clangType) { + ctx.env = append(ctx.env, "FORCE_DISABLE_WERROR=1") + builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{}) + if !processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled { t.Errorf("Disable -Werror should be enabled for clang.") } - if shouldForceDisableWerror(ctx, ctx.cfg, gccType) { + builder = newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{isGcc: true}) + if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled { t.Errorf("Disable -Werror should be disabled for gcc.") } }) } +func TestChromeOSForceDisableWerrorWorksAsFlag(t *testing.T) { + withForceDisableWErrorTestContext(t, func(ctx *testContext) { + builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{ + cflags: []string{"-D_CROSTC_FORCE_DISABLE_WERROR=/foo"}, + }) + werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder) + if !werrorConfig.enabled { + t.Fatalf("Disable -Werror should be enabled by flag.") + } + + if werrorConfig.reportToStdout { + t.Errorf("Stdout reporting should be disabled on ChromeOS") + } else if werrorConfig.reportDir != "/foo" { + t.Errorf("Got werror report dir %s; want /foo", werrorConfig.reportDir) + } + }) +} + +func TestChromeOSForceDisableWerrorRemovesFlags(t *testing.T) { + withForceDisableWErrorTestContext(t, func(ctx *testContext) { + builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{ + cflags: []string{ + "-D_CROSTC_FORCE_DISABLE_WERROR=/foo", + "-D_CROSTC_FORCE_DISABLE_WERROR=/bar", + "-Wfoo", + "-D_CROSTC_FORCE_DISABLE_WERROR=/baz", + }, + }) + werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder) + if !werrorConfig.enabled { + t.Fatalf("Disable -Werror should be enabled by flag.") + } + + if werrorConfig.reportToStdout { + t.Errorf("Stdout reporting should be disabled on ChromeOS") + } else if werrorConfig.reportDir != "/baz" { + t.Errorf("Got werror report dir %s; want /baz", werrorConfig.reportDir) + } + + args := builder.build().Args + if want := []string{"-Wfoo"}; !reflect.DeepEqual(args, want) { + t.Errorf("Got builder args %#v; want %#v", args, want) + } + }) +} + func TestClangTidyNoDoubleBuild(t *testing.T) { withTestContext(t, func(ctx *testContext) { ctx.cfg.isAndroidWrapper = true |