aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormobiletc-prebuild <mobiletc-prebuild@google.com>2024-01-25 08:00:21 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-01-25 17:41:21 +0000
commit73f2f02c8321957a368410d022f62b0e991ffa60 (patch)
treed8b8b247cd2d591c48c19b001a264e87af792651
parent7868f472843914a6bae785cdcb3cbc24b301f7f8 (diff)
downloadtoolchain-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.go5
-rw-r--r--compiler_wrapper/disable_werror_flag.go76
-rw-r--r--compiler_wrapper/disable_werror_flag_test.go93
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