mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
8e6cb89ceb
This is a large commit that moves all code directly related to
compiling/linking into a new builder package. This has a number of
advantages:
* It cleanly separates the API between the command line and the full
compilation (with a very small API surface).
* When the compiler finally compiles one package at a time (instead of
everything at once as it does now), something will have to invoke it
once per package. This builder package will be the natural place to
do that, and also be the place where the whole process can be
parallelized.
* It allows the TinyGo compiler to be used as a package. A client can
simply import the builder package and compile code using it.
As part of this refactor, the following additional things changed:
* Exported symbols have been made unexported when they weren't needed.
* The compilation target has been moved into the compileopts.Options
struct. This is done because the target really is just another
compiler option, and the API is simplified by moving it in there.
* The moveFile function has been duplicated. It does not really belong
in the builder API but is used both by the builder and the command
line. Moving it into a separate package didn't seem useful either
for what is essentially an utility function.
* Some doc strings have been improved.
Some future changes/refactors I'd like to make after this commit:
* Clean up the API between the builder and the compiler package.
* Perhaps move the test files (in testdata/) into the builder package.
* Perhaps move the loader package into the builder package.
56 lines
1.9 KiB
Go
56 lines
1.9 KiB
Go
package builder
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"os/exec"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
// Commands lists command alternatives for various operating systems. These
|
|
// commands may have a slightly different name across operating systems and
|
|
// distributions or may not even exist in $PATH, in which case absolute paths
|
|
// may be used.
|
|
var commands = map[string][]string{
|
|
"clang": {"clang-8"},
|
|
"ld.lld": {"ld.lld-8", "ld.lld"},
|
|
"wasm-ld": {"wasm-ld-8", "wasm-ld"},
|
|
}
|
|
|
|
func init() {
|
|
// Add the path to a Homebrew-installed LLVM 8 for ease of use (no need to
|
|
// manually set $PATH).
|
|
if runtime.GOOS == "darwin" {
|
|
commands["clang"] = append(commands["clang"], "/usr/local/opt/llvm@8/bin/clang-8")
|
|
commands["ld.lld"] = append(commands["ld.lld"], "/usr/local/opt/llvm@8/bin/ld.lld")
|
|
commands["wasm-ld"] = append(commands["wasm-ld"], "/usr/local/opt/llvm@8/bin/wasm-ld")
|
|
}
|
|
// Add the path for when LLVM was installed with the installer from
|
|
// llvm.org, which by default doesn't add LLVM to the $PATH environment
|
|
// variable.
|
|
if runtime.GOOS == "windows" {
|
|
commands["clang"] = append(commands["clang"], "clang", "C:\\Program Files\\LLVM\\bin\\clang.exe")
|
|
commands["ld.lld"] = append(commands["ld.lld"], "lld", "C:\\Program Files\\LLVM\\bin\\lld.exe")
|
|
commands["wasm-ld"] = append(commands["wasm-ld"], "C:\\Program Files\\LLVM\\bin\\wasm-ld.exe")
|
|
}
|
|
}
|
|
|
|
func execCommand(cmdNames []string, args ...string) error {
|
|
for _, cmdName := range cmdNames {
|
|
cmd := exec.Command(cmdName, args...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
err := cmd.Run()
|
|
if err != nil {
|
|
if err, ok := err.(*exec.Error); ok && (err.Err == exec.ErrNotFound || err.Err.Error() == "file does not exist") {
|
|
// this command was not found, try the next
|
|
continue
|
|
}
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
return errors.New("none of these commands were found in your $PATH: " + strings.Join(cmdNames, " "))
|
|
}
|