aboutsummaryrefslogtreecommitdiffhomepage
path: root/goenv/goenv.go
diff options
context:
space:
mode:
Diffstat (limited to 'goenv/goenv.go')
-rw-r--r--goenv/goenv.go90
1 files changed, 90 insertions, 0 deletions
diff --git a/goenv/goenv.go b/goenv/goenv.go
index 3f1352a78..0ef18ba50 100644
--- a/goenv/goenv.go
+++ b/goenv/goenv.go
@@ -3,12 +3,15 @@
package goenv
import (
+ "bytes"
+ "errors"
"fmt"
"os"
"os/exec"
"os/user"
"path/filepath"
"runtime"
+ "strings"
)
// Keys is a slice of all available environment variable keys.
@@ -67,11 +70,98 @@ func Get(name string) string {
return "1"
case "TINYGOROOT":
return sourceDir()
+ case "WASMOPT":
+ if path := os.Getenv("WASMOPT"); path != "" {
+ err := wasmOptCheckVersion(path)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "cannot use %q as wasm-opt (from WASMOPT environment variable): %s", path, err.Error())
+ os.Exit(1)
+ }
+
+ return path
+ }
+
+ return findWasmOpt()
default:
return ""
}
}
+// Find wasm-opt, or exit with an error.
+func findWasmOpt() string {
+ tinygoroot := sourceDir()
+ searchPaths := []string{
+ tinygoroot + "/bin/wasm-opt",
+ tinygoroot + "/build/wasm-opt",
+ }
+
+ var paths []string
+ for _, path := range searchPaths {
+ if runtime.GOOS == "windows" {
+ path += ".exe"
+ }
+
+ _, err := os.Stat(path)
+ if err != nil && os.IsNotExist(err) {
+ continue
+ }
+
+ paths = append(paths, path)
+ }
+
+ if path, err := exec.LookPath("wasm-opt"); err == nil {
+ paths = append(paths, path)
+ }
+
+ if len(paths) == 0 {
+ fmt.Fprintln(os.Stderr, "error: could not find wasm-opt, set the WASMOPT environment variable to override")
+ os.Exit(1)
+ }
+
+ errs := make([]error, len(paths))
+ for i, path := range paths {
+ err := wasmOptCheckVersion(path)
+ if err == nil {
+ return path
+ }
+
+ errs[i] = err
+ }
+ fmt.Fprintln(os.Stderr, "no usable wasm-opt found, update or run \"make binaryen\"")
+ for i, path := range paths {
+ fmt.Fprintf(os.Stderr, "\t%s: %s\n", path, errs[i].Error())
+ }
+ os.Exit(1)
+ panic("unreachable")
+}
+
+// wasmOptCheckVersion checks if a copy of wasm-opt is usable.
+func wasmOptCheckVersion(path string) error {
+ cmd := exec.Command(path, "--version")
+ var buf bytes.Buffer
+ cmd.Stdout = &buf
+ cmd.Stderr = os.Stderr
+ err := cmd.Run()
+ if err != nil {
+ return err
+ }
+
+ str := buf.String()
+ if strings.Contains(str, "(") {
+ // The git tag may be placed in parentheses after the main version string.
+ str = strings.Split(str, "(")[0]
+ }
+
+ str = strings.TrimSpace(str)
+ var ver uint
+ _, err = fmt.Sscanf(str, "wasm-opt version %d", &ver)
+ if err != nil || ver < 102 {
+ return errors.New("incompatible wasm-opt (need 102 or newer)")
+ }
+
+ return nil
+}
+
// Return the TINYGOROOT, or exit with an error.
func sourceDir() string {
// Use $TINYGOROOT as root, if available.