blob: 314a8a711199cbfb157a0b5781e58395d6504829 [file] [log] [blame]
Tobias Boschef8f9692019-06-10 15:50:33 -07001package main
2
3import (
Tobias Bosch900dbc92019-06-24 09:31:39 -07004 "fmt"
5 "io"
Tobias Boschef8f9692019-06-10 15:50:33 -07006 "path/filepath"
Tobias Boschef8f9692019-06-10 15:50:33 -07007)
8
Tobias Bosch900dbc92019-06-24 09:31:39 -07009func callCompiler(env env, cfg *config, inputCmd *command) int {
10 exitCode := 0
11 var compilerErr error
Tobias Bosch9780ea92019-07-11 01:19:42 -070012 if cfg.oldWrapperPath != "" {
Tobias Bosch900dbc92019-06-24 09:31:39 -070013 exitCode, compilerErr = callCompilerWithRunAndCompareToOldWrapper(env, cfg, inputCmd)
14 } else {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070015 exitCode, compilerErr = callCompilerInternal(env, cfg, inputCmd)
Tobias Bosch900dbc92019-06-24 09:31:39 -070016 }
17 if compilerErr != nil {
18 printCompilerError(env.stderr(), compilerErr)
19 exitCode = 1
20 }
21 return exitCode
22}
23
24func callCompilerWithRunAndCompareToOldWrapper(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
25 recordingEnv := &commandRecordingEnv{
26 env: env,
27 }
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070028 // Note: this won't do a real exec as recordingEnv redirects exec to run.
29 if exitCode, err = callCompilerInternal(recordingEnv, cfg, inputCmd); err != nil {
30 return 0, err
Tobias Bosch900dbc92019-06-24 09:31:39 -070031 }
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070032 if err = compareToOldWrapper(env, cfg, inputCmd, recordingEnv.cmdResults, exitCode); err != nil {
Tobias Bosch900dbc92019-06-24 09:31:39 -070033 return exitCode, err
34 }
35 return exitCode, nil
36}
37
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070038func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
Tobias Bosch900dbc92019-06-24 09:31:39 -070039 if err := checkUnsupportedFlags(inputCmd); err != nil {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070040 return 0, err
Tobias Bosch900dbc92019-06-24 09:31:39 -070041 }
Tobias Boschd8684172019-07-08 10:59:14 -070042 mainBuilder, err := newCommandBuilder(env, cfg, inputCmd)
Tobias Boschef8f9692019-06-10 15:50:33 -070043 if err != nil {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070044 return 0, err
Tobias Boschef8f9692019-06-10 15:50:33 -070045 }
Tobias Bosch58472812019-07-11 04:24:52 -070046 processPrintConfigFlag(mainBuilder)
47 processPrintCmdlineFlag(mainBuilder)
48 env = mainBuilder.env
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070049 var compilerCmd *command
Tobias Boschd8684172019-07-08 10:59:14 -070050 clangSyntax := processClangSyntaxFlag(mainBuilder)
51 if mainBuilder.target.compilerType == clangType {
Tobias Bosch38f3c422019-07-08 11:03:26 -070052 cSrcFile, useClangTidy := processClangTidyFlags(mainBuilder)
53 compilerCmd, err = calcClangCommand(useClangTidy, mainBuilder)
Tobias Boschd8684172019-07-08 10:59:14 -070054 if err != nil {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070055 return 0, err
Tobias Boschd8684172019-07-08 10:59:14 -070056 }
Tobias Bosch38f3c422019-07-08 11:03:26 -070057 if useClangTidy {
58 if err := runClangTidy(env, compilerCmd, cSrcFile); err != nil {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070059 return 0, err
Tobias Bosch38f3c422019-07-08 11:03:26 -070060 }
61 }
Tobias Boschef8f9692019-06-10 15:50:33 -070062 } else {
Tobias Boschd8684172019-07-08 10:59:14 -070063 if clangSyntax {
Tobias Bosch38f3c422019-07-08 11:03:26 -070064 forceLocal := false
65 clangCmd, err := calcClangCommand(forceLocal, mainBuilder.clone())
Tobias Boschd8684172019-07-08 10:59:14 -070066 if err != nil {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070067 return 0, err
Tobias Boschd8684172019-07-08 10:59:14 -070068 }
69 exitCode, err = checkClangSyntax(env, clangCmd)
70 if err != nil || exitCode != 0 {
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070071 return exitCode, err
Tobias Boschd8684172019-07-08 10:59:14 -070072 }
73 }
74 compilerCmd = calcGccCommand(mainBuilder)
Tobias Boschef8f9692019-06-10 15:50:33 -070075 }
Tobias Bosch9d609302019-07-10 06:16:04 -070076 rusageLogfileName := getRusageLogFilename(env)
Tobias Bosch9780ea92019-07-11 01:19:42 -070077 bisectStage := getBisectStage(env)
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070078 if shouldForceDisableWError(env) {
Tobias Bosch9d609302019-07-10 06:16:04 -070079 if rusageLogfileName != "" {
80 return 0, newUserErrorf("GETRUSAGE is meaningless with FORCE_DISABLE_WERROR")
81 }
Tobias Bosch9780ea92019-07-11 01:19:42 -070082 if bisectStage != "" {
83 return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
84 }
Tobias Boschf6d9f4f2019-07-09 08:09:01 -070085 return doubleBuildWithWNoError(env, cfg, compilerCmd)
86 }
Tobias Bosch9d609302019-07-10 06:16:04 -070087 if rusageLogfileName != "" {
Tobias Bosch9780ea92019-07-11 01:19:42 -070088 if bisectStage != "" {
89 return 0, newUserErrorf("BISECT_STAGE is meaningless with GETRUSAGE")
90 }
Tobias Bosch9d609302019-07-10 06:16:04 -070091 return logRusage(env, rusageLogfileName, compilerCmd)
92 }
Tobias Bosch9780ea92019-07-11 01:19:42 -070093 if bisectStage != "" {
94 compilerCmd = calcBisectCommand(env, bisectStage, compilerCmd)
95 }
Tobias Bosch9332d212019-07-10 06:23:57 -070096 // Note: We return an exit code only if the underlying env is not
97 // really doing an exec, e.g. commandRecordingEnv.
98 return wrapSubprocessErrorWithSourceLoc(compilerCmd, env.exec(compilerCmd))
Tobias Boschd8684172019-07-08 10:59:14 -070099}
100
Tobias Bosch38f3c422019-07-08 11:03:26 -0700101func calcClangCommand(forceLocal bool, builder *commandBuilder) (*command, error) {
Tobias Boschd8684172019-07-08 10:59:14 -0700102 sysroot := processSysrootFlag(builder)
103 builder.addPreUserArgs(builder.cfg.clangFlags...)
104 calcCommonPreUserArgs(builder)
105 if err := processClangFlags(builder); err != nil {
106 return nil, err
107 }
Tobias Bosch38f3c422019-07-08 11:03:26 -0700108 if !forceLocal {
109 processGomaCCacheFlags(sysroot, builder)
110 }
Tobias Boschd8684172019-07-08 10:59:14 -0700111 return builder.build(), nil
112}
113
114func calcGccCommand(builder *commandBuilder) *command {
115 sysroot := processSysrootFlag(builder)
116 builder.addPreUserArgs(builder.cfg.gccFlags...)
117 calcCommonPreUserArgs(builder)
118 processGccFlags(builder)
119 processGomaCCacheFlags(sysroot, builder)
120 return builder.build()
121}
122
123func calcCommonPreUserArgs(builder *commandBuilder) {
124 builder.addPreUserArgs(builder.cfg.commonFlags...)
Tobias Boschef8f9692019-06-10 15:50:33 -0700125 processPieFlags(builder)
126 processStackProtectorFlags(builder)
127 processThumbCodeFlags(builder)
128 processX86Flags(builder)
129 processSanitizerFlags(builder)
Tobias Boschd8684172019-07-08 10:59:14 -0700130}
131
132func processGomaCCacheFlags(sysroot string, builder *commandBuilder) {
Tobias Boschef8f9692019-06-10 15:50:33 -0700133 gomaccUsed := processGomaCccFlags(builder)
134 if !gomaccUsed {
135 processCCacheFlag(sysroot, builder)
136 }
Tobias Boschef8f9692019-06-10 15:50:33 -0700137}
138
Tobias Bosch58472812019-07-11 04:24:52 -0700139func getAbsWrapperDir(env env, wrapperCmd *command) (string, error) {
140 wrapperPath := getAbsCmdPath(env, wrapperCmd)
Tobias Boschef8f9692019-06-10 15:50:33 -0700141 evaledCmdPath, err := filepath.EvalSymlinks(wrapperPath)
142 if err != nil {
Tobias Bosch900dbc92019-06-24 09:31:39 -0700143 return "", wrapErrorwithSourceLocf(err, "failed to evaluate symlinks for %s", wrapperPath)
Tobias Boschef8f9692019-06-10 15:50:33 -0700144 }
145 return filepath.Dir(evaledCmdPath), nil
146}
147
Tobias Bosch900dbc92019-06-24 09:31:39 -0700148func printCompilerError(writer io.Writer, compilerErr error) {
149 if _, ok := compilerErr.(userError); ok {
150 fmt.Fprintf(writer, "%s\n", compilerErr)
151 } else {
152 fmt.Fprintf(writer,
153 "Internal error. Please report to chromeos-toolchain@google.com.\n%s\n",
154 compilerErr)
Tobias Boschef8f9692019-06-10 15:50:33 -0700155 }
Tobias Boschef8f9692019-06-10 15:50:33 -0700156}