aboutsummaryrefslogtreecommitdiff
path: root/compiler_wrapper/compiler_wrapper.go
diff options
context:
space:
mode:
Diffstat (limited to 'compiler_wrapper/compiler_wrapper.go')
-rw-r--r--compiler_wrapper/compiler_wrapper.go223
1 files changed, 46 insertions, 177 deletions
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go
index 986eabab..2b9459e4 100644
--- a/compiler_wrapper/compiler_wrapper.go
+++ b/compiler_wrapper/compiler_wrapper.go
@@ -6,14 +6,10 @@ package main
import (
"bytes"
- "context"
- "errors"
"fmt"
"io"
"path/filepath"
- "strconv"
"strings"
- "time"
)
func callCompiler(env env, cfg *config, inputCmd *command) int {
@@ -65,50 +61,6 @@ func calculateAndroidWrapperPath(mainBuilderPath string, absWrapperPath string)
return "." + string(filepath.Separator) + basePart
}
-func runAndroidClangTidy(env env, cmd *command) error {
- timeout, found := env.getenv("TIDY_TIMEOUT")
- if !found {
- return env.exec(cmd)
- }
- seconds, err := strconv.Atoi(timeout)
- if err != nil || seconds == 0 {
- return env.exec(cmd)
- }
- getSourceFile := func() string {
- // Note: This depends on Android build system's clang-tidy command line format.
- // Last non-flag before "--" in cmd.Args is used as the source file name.
- sourceFile := "unknown_file"
- for _, arg := range cmd.Args {
- if arg == "--" {
- break
- }
- if strings.HasPrefix(arg, "-") {
- continue
- }
- sourceFile = arg
- }
- return sourceFile
- }
- startTime := time.Now()
- err = env.runWithTimeout(cmd, time.Duration(seconds)*time.Second)
- if !errors.Is(err, context.DeadlineExceeded) {
- // When used time is over half of TIDY_TIMEOUT, give a warning.
- // These warnings allow users to fix slow jobs before they get worse.
- usedSeconds := int(time.Now().Sub(startTime) / time.Second)
- if usedSeconds > seconds/2 {
- warning := "%s:1:1: warning: clang-tidy used %d seconds.\n"
- fmt.Fprintf(env.stdout(), warning, getSourceFile(), usedSeconds)
- }
- return err
- }
- // When DeadllineExceeded, print warning messages.
- warning := "%s:1:1: warning: clang-tidy aborted after %d seconds.\n"
- fmt.Fprintf(env.stdout(), warning, getSourceFile(), seconds)
- fmt.Fprintf(env.stdout(), "TIMEOUT: %s %s\n", cmd.Path, strings.Join(cmd.Args, " "))
- // Do not stop Android build. Just give a warning and return no error.
- return nil
-}
-
func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
if err := checkUnsupportedFlags(inputCmd); err != nil {
return 0, err
@@ -122,15 +74,6 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
env = mainBuilder.env
var compilerCmd *command
clangSyntax := processClangSyntaxFlag(mainBuilder)
-
- rusageEnabled := isRusageEnabled(env)
-
- // Disable CCache for rusage logs
- // Note: Disabling Goma causes timeout related INFRA_FAILUREs in builders
- allowCCache := !rusageEnabled
- remoteBuildUsed := false
-
- workAroundKernelBugWithRetries := false
if cfg.isAndroidWrapper {
mainBuilder.path = calculateAndroidWrapperPath(mainBuilder.path, mainBuilder.absWrapperPath)
switch mainBuilder.target.compilerType {
@@ -138,9 +81,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
mainBuilder.addPreUserArgs(mainBuilder.cfg.clangFlags...)
mainBuilder.addPreUserArgs(mainBuilder.cfg.commonFlags...)
mainBuilder.addPostUserArgs(mainBuilder.cfg.clangPostFlags...)
- inheritGomaFromEnv := true
- // Android doesn't support rewrapper; don't try to use it.
- if remoteBuildUsed, err = processGomaCccFlags(mainBuilder, inheritGomaFromEnv); err != nil {
+ if _, err := processGomaCccFlags(mainBuilder); err != nil {
return 0, err
}
compilerCmd = mainBuilder.build()
@@ -156,18 +97,19 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
if err != nil {
return 0, err
}
+ allowCCache := true
if tidyMode != tidyModeNone {
allowCCache = false
- clangCmdWithoutRemoteBuildAndCCache := mainBuilder.build()
+ clangCmdWithoutGomaAndCCache := mainBuilder.build()
var err error
switch tidyMode {
case tidyModeTricium:
if cfg.triciumNitsDir == "" {
return 0, newErrorwithSourceLocf("tricium linting was requested, but no nits directory is configured")
}
- err = runClangTidyForTricium(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, cfg.triciumNitsDir, tidyFlags, cfg.crashArtifactsDir)
+ err = runClangTidyForTricium(env, clangCmdWithoutGomaAndCCache, cSrcFile, cfg.triciumNitsDir, tidyFlags, cfg.crashArtifactsDir)
case tidyModeAll:
- err = runClangTidy(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, tidyFlags)
+ err = runClangTidy(env, clangCmdWithoutGomaAndCCache, cSrcFile, tidyFlags)
default:
panic(fmt.Sprintf("Unknown tidy mode: %v", tidyMode))
}
@@ -176,135 +118,64 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
return 0, err
}
}
- if remoteBuildUsed, err = processRemoteBuildAndCCacheFlags(allowCCache, mainBuilder); err != nil {
+ if err := processGomaCCacheFlags(allowCCache, mainBuilder); err != nil {
return 0, err
}
compilerCmd = mainBuilder.build()
} else {
if clangSyntax {
- allowCCache = false
- _, clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
+ allowCCache := false
+ clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
if err != nil {
return 0, err
}
- _, gccCmd, err := calcGccCommand(rusageEnabled, mainBuilder)
+ gccCmd, err := calcGccCommand(mainBuilder)
if err != nil {
return 0, err
}
return checkClangSyntax(env, clangCmd, gccCmd)
}
- remoteBuildUsed, compilerCmd, err = calcGccCommand(rusageEnabled, mainBuilder)
+ compilerCmd, err = calcGccCommand(mainBuilder)
if err != nil {
return 0, err
}
- workAroundKernelBugWithRetries = true
}
}
-
+ rusageLogfileName := getRusageLogFilename(env)
bisectStage := getBisectStage(env)
-
- if rusageEnabled {
- compilerCmd = removeRusageFromCommand(compilerCmd)
- }
-
- if shouldForceDisableWerror(env, cfg, mainBuilder.target.compilerType) {
+ if shouldForceDisableWerror(env, cfg) {
+ if rusageLogfileName != "" {
+ return 0, newUserErrorf("GETRUSAGE is meaningless with FORCE_DISABLE_WERROR")
+ }
if bisectStage != "" {
return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
}
return doubleBuildWithWNoError(env, cfg, compilerCmd)
}
if shouldCompileWithFallback(env) {
- if rusageEnabled {
- return 0, newUserErrorf("TOOLCHAIN_RUSAGE_OUTPUT is meaningless with ANDROID_LLVM_PREBUILT_COMPILER_PATH")
+ if rusageLogfileName != "" {
+ return 0, newUserErrorf("GETRUSAGE is meaningless with FORCE_DISABLE_WERROR")
}
if bisectStage != "" {
- return 0, newUserErrorf("BISECT_STAGE is meaningless with ANDROID_LLVM_PREBUILT_COMPILER_PATH")
+ return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
}
return compileWithFallback(env, cfg, compilerCmd, mainBuilder.absWrapperPath)
}
- if bisectStage != "" {
- if rusageEnabled {
- return 0, newUserErrorf("TOOLCHAIN_RUSAGE_OUTPUT is meaningless with BISECT_STAGE")
+ if rusageLogfileName != "" {
+ if bisectStage != "" {
+ return 0, newUserErrorf("BISECT_STAGE is meaningless with GETRUSAGE")
}
+ return logRusage(env, rusageLogfileName, compilerCmd)
+ }
+ if bisectStage != "" {
compilerCmd, err = calcBisectCommand(env, cfg, bisectStage, compilerCmd)
if err != nil {
return 0, err
}
}
-
- errRetryCompilation := errors.New("compilation retry requested")
- var runCompiler func(willLogRusage bool) (int, error)
- if !workAroundKernelBugWithRetries {
- runCompiler = func(willLogRusage bool) (int, error) {
- var err error
- if willLogRusage {
- err = env.run(compilerCmd, env.stdin(), env.stdout(), env.stderr())
- } else if cfg.isAndroidWrapper && mainBuilder.target.compilerType == clangTidyType {
- // Only clang-tidy has timeout feature now.
- err = runAndroidClangTidy(env, compilerCmd)
- } else {
- // Note: We return from this in non-fatal circumstances only if the
- // underlying env is not really doing an exec, e.g. commandRecordingEnv.
- err = env.exec(compilerCmd)
- }
- return wrapSubprocessErrorWithSourceLoc(compilerCmd, err)
- }
- } else {
- getStdin, err := prebufferStdinIfNeeded(env, compilerCmd)
- if err != nil {
- return 0, wrapErrorwithSourceLocf(err, "prebuffering stdin: %v", err)
- }
-
- stdoutBuffer := &bytes.Buffer{}
- stderrBuffer := &bytes.Buffer{}
- retryAttempt := 0
- runCompiler = func(willLogRusage bool) (int, error) {
- retryAttempt++
- stdoutBuffer.Reset()
- stderrBuffer.Reset()
-
- exitCode, compilerErr := wrapSubprocessErrorWithSourceLoc(compilerCmd,
- env.run(compilerCmd, getStdin(), stdoutBuffer, stderrBuffer))
-
- if compilerErr != nil || exitCode != 0 {
- if retryAttempt < kernelBugRetryLimit && (errorContainsTracesOfKernelBug(compilerErr) || containsTracesOfKernelBug(stdoutBuffer.Bytes()) || containsTracesOfKernelBug(stderrBuffer.Bytes())) {
- return exitCode, errRetryCompilation
- }
- }
- _, stdoutErr := stdoutBuffer.WriteTo(env.stdout())
- _, stderrErr := stderrBuffer.WriteTo(env.stderr())
- if stdoutErr != nil {
- return exitCode, wrapErrorwithSourceLocf(err, "writing stdout: %v", stdoutErr)
- }
- if stderrErr != nil {
- return exitCode, wrapErrorwithSourceLocf(err, "writing stderr: %v", stderrErr)
- }
- return exitCode, compilerErr
- }
- }
-
- for {
- var exitCode int
- commitRusage, err := maybeCaptureRusage(env, compilerCmd, func(willLogRusage bool) error {
- var err error
- exitCode, err = runCompiler(willLogRusage)
- return err
- })
-
- switch {
- case err == errRetryCompilation:
- // Loop around again.
- case err != nil:
- return exitCode, err
- default:
- if !remoteBuildUsed {
- if err := commitRusage(exitCode); err != nil {
- return exitCode, fmt.Errorf("commiting rusage: %v", err)
- }
- }
- return exitCode, err
- }
- }
+ // Note: We return an exit code only if the underlying env is not
+ // really doing an exec, e.g. commandRecordingEnv.
+ return wrapSubprocessErrorWithSourceLoc(compilerCmd, env.exec(compilerCmd))
}
func prepareClangCommand(builder *commandBuilder) (err error) {
@@ -320,40 +191,38 @@ func prepareClangCommand(builder *commandBuilder) (err error) {
return processClangFlags(builder)
}
-func calcClangCommand(allowCCache bool, builder *commandBuilder) (bool, *command, error) {
+func calcClangCommand(allowCCache bool, builder *commandBuilder) (*command, error) {
err := prepareClangCommand(builder)
if err != nil {
- return false, nil, err
+ return nil, err
}
- remoteBuildUsed, err := processRemoteBuildAndCCacheFlags(allowCCache, builder)
- if err != nil {
- return remoteBuildUsed, nil, err
+ if err := processGomaCCacheFlags(allowCCache, builder); err != nil {
+ return nil, err
}
- return remoteBuildUsed, builder.build(), nil
+ return builder.build(), nil
}
-func calcGccCommand(enableRusage bool, builder *commandBuilder) (bool, *command, error) {
+func calcGccCommand(builder *commandBuilder) (*command, error) {
if !builder.cfg.isHostWrapper {
processSysrootFlag(builder)
}
builder.addPreUserArgs(builder.cfg.gccFlags...)
- calcCommonPreUserArgs(builder)
+ if !builder.cfg.isHostWrapper {
+ calcCommonPreUserArgs(builder)
+ }
processGccFlags(builder)
-
- remoteBuildUsed := false
if !builder.cfg.isHostWrapper {
- var err error
- if remoteBuildUsed, err = processRemoteBuildAndCCacheFlags(!enableRusage, builder); err != nil {
- return remoteBuildUsed, nil, err
+ allowCCache := true
+ if err := processGomaCCacheFlags(allowCCache, builder); err != nil {
+ return nil, err
}
}
- return remoteBuildUsed, builder.build(), nil
+ return builder.build(), nil
}
func calcCommonPreUserArgs(builder *commandBuilder) {
builder.addPreUserArgs(builder.cfg.commonFlags...)
if !builder.cfg.isHostWrapper {
- processLibGCCFlags(builder)
processPieFlags(builder)
processThumbCodeFlags(builder)
processStackProtectorFlags(builder)
@@ -362,18 +231,18 @@ func calcCommonPreUserArgs(builder *commandBuilder) {
processSanitizerFlags(builder)
}
-func processRemoteBuildAndCCacheFlags(allowCCache bool, builder *commandBuilder) (remoteBuildUsed bool, err error) {
- remoteBuildUsed = false
+func processGomaCCacheFlags(allowCCache bool, builder *commandBuilder) (err error) {
+ gomaccUsed := false
if !builder.cfg.isHostWrapper {
- remoteBuildUsed, err = processRemoteBuildFlags(builder)
+ gomaccUsed, err = processGomaCccFlags(builder)
if err != nil {
- return remoteBuildUsed, err
+ return err
}
}
- if !remoteBuildUsed && allowCCache {
+ if !gomaccUsed && allowCCache {
processCCacheFlag(builder)
}
- return remoteBuildUsed, nil
+ return nil
}
func getAbsWrapperPath(env env, wrapperCmd *command) (string, error) {