Support second execution of the compiler with -Wno-error
BUG=chromium:773875
TEST=unit test
Change-Id: Ib77fd7c166a13acb733a1dbdfd88129141c4227a
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1692969
Reviewed-by: Tobias Bosch <tbosch@google.com>
Tested-by: Tobias Bosch <tbosch@google.com>
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go
index 1eacb57..3f94e18 100644
--- a/compiler_wrapper/compiler_wrapper.go
+++ b/compiler_wrapper/compiler_wrapper.go
@@ -18,7 +18,7 @@
} else if cfg.oldWrapperPath != "" {
exitCode, compilerErr = callCompilerWithRunAndCompareToOldWrapper(env, cfg, inputCmd)
} else {
- exitCode, compilerErr = callCompilerWithExec(env, cfg, inputCmd)
+ exitCode, compilerErr = callCompilerInternal(env, cfg, inputCmd)
}
if compilerErr != nil {
printCompilerError(env.stderr(), compilerErr)
@@ -31,62 +31,35 @@
recordingEnv := &commandRecordingEnv{
env: env,
}
- compilerCmd, exitCode, err := calcCompilerCommand(recordingEnv, cfg, inputCmd)
- if err != nil || exitCode != 0 {
- return exitCode, err
+ // Note: this won't do a real exec as recordingEnv redirects exec to run.
+ if exitCode, err = callCompilerInternal(recordingEnv, cfg, inputCmd); err != nil {
+ return 0, err
}
- exitCode = 0
- // Note: we are not using env.exec here so that we can compare the exit code
- // against the old wrapper too.
- if err := recordingEnv.run(compilerCmd, env.stdout(), env.stderr()); err != nil {
- if userErr, ok := getCCacheError(compilerCmd, err); ok {
- return exitCode, userErr
- }
- var ok bool
- if exitCode, ok = getExitCode(err); !ok {
- return exitCode, wrapErrorwithSourceLocf(err, "failed to execute %#v", compilerCmd)
- }
- }
- if err := compareToOldWrapper(env, cfg, inputCmd, recordingEnv.cmdResults); err != nil {
+ if err = compareToOldWrapper(env, cfg, inputCmd, recordingEnv.cmdResults, exitCode); err != nil {
return exitCode, err
}
return exitCode, nil
}
-func callCompilerWithExec(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
- compilerCmd, exitCode, err := calcCompilerCommand(env, cfg, inputCmd)
- if err != nil || exitCode != 0 {
- return exitCode, err
- }
- if err := env.exec(compilerCmd); err != nil {
- // Note: No need to check for exit code error as exec will
- // stop this control flow once the command started executing.
- if userErr, ok := getCCacheError(compilerCmd, err); ok {
- return exitCode, userErr
- }
- return exitCode, wrapErrorwithSourceLocf(err, "failed to execute %#v", compilerCmd)
- }
- return exitCode, nil
-}
-
-func calcCompilerCommand(env env, cfg *config, inputCmd *command) (compilerCmd *command, exitCode int, err error) {
+func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
if err := checkUnsupportedFlags(inputCmd); err != nil {
- return nil, exitCode, err
+ return 0, err
}
mainBuilder, err := newCommandBuilder(env, cfg, inputCmd)
if err != nil {
- return nil, exitCode, err
+ return 0, err
}
+ var compilerCmd *command
clangSyntax := processClangSyntaxFlag(mainBuilder)
if mainBuilder.target.compilerType == clangType {
cSrcFile, useClangTidy := processClangTidyFlags(mainBuilder)
compilerCmd, err = calcClangCommand(useClangTidy, mainBuilder)
if err != nil {
- return nil, exitCode, err
+ return 0, err
}
if useClangTidy {
if err := runClangTidy(env, compilerCmd, cSrcFile); err != nil {
- return nil, exitCode, err
+ return 0, err
}
}
} else {
@@ -94,17 +67,30 @@
forceLocal := false
clangCmd, err := calcClangCommand(forceLocal, mainBuilder.clone())
if err != nil {
- return nil, 0, err
+ return 0, err
}
exitCode, err = checkClangSyntax(env, clangCmd)
if err != nil || exitCode != 0 {
- return nil, exitCode, err
+ return exitCode, err
}
}
compilerCmd = calcGccCommand(mainBuilder)
}
-
- return compilerCmd, exitCode, nil
+ if shouldForceDisableWError(env) {
+ return doubleBuildWithWNoError(env, cfg, compilerCmd)
+ }
+ if err := env.exec(compilerCmd); err != nil {
+ if userErr, ok := getCCacheError(compilerCmd, err); ok {
+ return 0, userErr
+ }
+ // Note: This case only happens when the underlying env is not
+ // really doing an exec, e.g. commandRecordingEnv.
+ if exitCode, ok := getExitCode(err); ok {
+ return exitCode, nil
+ }
+ return exitCode, wrapErrorwithSourceLocf(err, "failed to execute %#v", compilerCmd)
+ }
+ return 0, err
}
func calcClangCommand(forceLocal bool, builder *commandBuilder) (*command, error) {