aboutsummaryrefslogtreecommitdiffhomepage
path: root/builder/tools.go
diff options
context:
space:
mode:
authorAyke van Laethem <[email protected]>2020-04-02 21:14:07 +0200
committerRon Evans <[email protected]>2020-04-03 12:41:44 +0200
commitf06d7d1bd6cf5d5231dde4de8ef4ae5ecd908074 (patch)
tree75a607804bb0323a9d782e662bf3c96a3a962dcf /builder/tools.go
parent407149e323d8235cf8bce153201195ddbe2eaa65 (diff)
downloadtinygo-f06d7d1bd6cf5d5231dde4de8ef4ae5ecd908074.tar.gz
tinygo-f06d7d1bd6cf5d5231dde4de8ef4ae5ecd908074.zip
builder: run tools (clang, ...) as separate processes
This is necessary because LLVM defines many options in global variables that are modified when invoking Clang. In particular, LLVM 10 seems to have a bug in which it always sets the -pgo-warn-misexpect flag. Setting it multiple times (over various cc1 invocations) results in an error: clang (LLVM option parsing): for the --pgo-warn-misexpect option: may only occur zero or one times! This is fixed by running the Clang invocation in a new `tinygo` invocation. Because we've had issues with lld in the past, also run lld in a separate process so similar issues won't happen with lld in the future.
Diffstat (limited to 'builder/tools.go')
-rw-r--r--builder/tools.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/builder/tools.go b/builder/tools.go
new file mode 100644
index 000000000..bc0f97824
--- /dev/null
+++ b/builder/tools.go
@@ -0,0 +1,59 @@
+package builder
+
+import (
+ "errors"
+ "os"
+ "os/exec"
+
+ "github.com/tinygo-org/tinygo/goenv"
+)
+
+// runCCompiler invokes a C compiler with the given arguments.
+func runCCompiler(command string, flags ...string) error {
+ if hasBuiltinTools && command == "clang" {
+ // Compile this with the internal Clang compiler.
+ headerPath := getClangHeaderPath(goenv.Get("TINYGOROOT"))
+ if headerPath == "" {
+ return errors.New("could not locate Clang headers")
+ }
+ flags = append(flags, "-I"+headerPath)
+ cmd := exec.Command(os.Args[0], append([]string{"clang"}, flags...)...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+ }
+
+ // Running some other compiler. Maybe it has been defined in the
+ // commands map (unlikely).
+ if cmdNames, ok := commands[command]; ok {
+ return execCommand(cmdNames, flags...)
+ }
+
+ // Alternatively, run the compiler directly.
+ cmd := exec.Command(command, flags...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+}
+
+// link invokes a linker with the given name and flags.
+func link(linker string, flags ...string) error {
+ if hasBuiltinTools && (linker == "ld.lld" || linker == "wasm-ld") {
+ // Run command with internal linker.
+ cmd := exec.Command(os.Args[0], append([]string{linker}, flags...)...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ return cmd.Run()
+ }
+
+ // Fall back to external command.
+ if cmdNames, ok := commands[linker]; ok {
+ return execCommand(cmdNames, flags...)
+ }
+
+ cmd := exec.Command(linker, flags...)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ cmd.Dir = goenv.Get("TINYGOROOT")
+ return cmd.Run()
+}