main: add fallback mechanism for LLVM commands

On Debian, all LLVM commands have a version suffix (clang-8, ld.lld-8,
wasm-ld-8, etc.). However. Most other distributions only provide a
version prefix for Clang and not for all the other commands.

This commit fixes the issue by trying the command with the version
suffix first and falling back to one without if needed.
This commit is contained in:
Ayke van Laethem
2019-05-03 19:30:54 +02:00
committed by Ron Evans
parent 9a54ee4241
commit 9cad8bd0c8
7 changed files with 51 additions and 46 deletions
+3 -7
View File
@@ -5,7 +5,6 @@ import (
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
@@ -192,13 +191,13 @@ func loadBuiltins(target string) (path string, err error) {
srcs[i] = filepath.Join(builtinsDir, name)
}
if path, err := cacheLoad(outfile, commands["clang"], srcs); path != "" || err != nil {
if path, err := cacheLoad(outfile, commands["clang"][0], srcs); path != "" || err != nil {
return path, err
}
var cachepath string
err = compileBuiltins(target, func(path string) error {
path, err := cacheStore(path, outfile, commands["clang"], srcs)
path, err := cacheStore(path, outfile, commands["clang"][0], srcs)
cachepath = path
return err
})
@@ -240,10 +239,7 @@ func compileBuiltins(target string, callback func(path string) error) error {
// Note: -fdebug-prefix-map is necessary to make the output archive
// reproducible. Otherwise the temporary directory is stored in the
// archive itself, which varies each run.
cmd := exec.Command(commands["clang"], "-c", "-Oz", "-g", "-Werror", "-Wall", "-std=c11", "-fshort-enums", "-nostdlibinc", "-ffunction-sections", "-fdata-sections", "--target="+target, "-fdebug-prefix-map="+dir+"="+remapDir, "-o", objpath, srcpath)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
err := execCommand(commands["clang"], "-c", "-Oz", "-g", "-Werror", "-Wall", "-std=c11", "-fshort-enums", "-nostdlibinc", "-ffunction-sections", "-fdata-sections", "--target="+target, "-fdebug-prefix-map="+dir+"="+remapDir, "-o", objpath, srcpath)
if err != nil {
return &commandError{"failed to build", srcpath, err}
}
+30 -7
View File
@@ -1,10 +1,33 @@
// +build !darwin
package main
// commands used by the compilation process might have different file names on Linux than those used on macOS.
var commands = map[string]string{
"clang": "clang-8",
"ld.lld": "ld.lld-8",
"wasm-ld": "wasm-ld-8",
import (
"errors"
"os"
"os/exec"
"strings"
)
// Commands used by the compilation process might have different file names
// across operating systems and distributions.
var commands = map[string][]string{
"clang": {"clang-8"},
"ld.lld": {"ld.lld-8", "ld.lld"},
"wasm-ld": {"wasm-ld-8", "wasm-ld"},
}
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 {
// this command was not found, try the next
continue
}
}
return nil
}
return errors.New("none of these commands were found in your $PATH: " + strings.Join(cmdNames, " "))
}
-10
View File
@@ -1,10 +0,0 @@
// +build darwin
package main
// commands used by the compilation process might have different file names on macOS than those used on Linux.
var commands = map[string]string{
"clang": "clang-8",
"ld.lld": "ld.lld",
"wasm-ld": "wasm-ld",
}
+5 -2
View File
@@ -24,7 +24,7 @@ import "C"
// This version uses the built-in linker when trying to use lld.
func Link(linker string, flags ...string) error {
switch linker {
case "ld.lld", commands["ld.lld"]:
case "ld.lld":
flags = append([]string{"tinygo:" + linker}, flags...)
var cflag *C.char
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
@@ -39,7 +39,7 @@ func Link(linker string, flags ...string) error {
return errors.New("failed to link using built-in ld.lld")
}
return nil
case "wasm-ld", commands["wasm-ld"]:
case "wasm-ld":
flags = append([]string{"tinygo:" + linker}, flags...)
var cflag *C.char
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
@@ -57,6 +57,9 @@ func Link(linker string, flags ...string) error {
return nil
default:
// 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
+3
View File
@@ -14,6 +14,9 @@ import (
//
// This version always runs the linker as an external command.
func Link(linker string, flags ...string) error {
if cmdNames, ok := commands[linker]; ok {
return execCommand(cmdNames, flags...)
}
cmd := exec.Command(linker, flags...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
+9 -19
View File
@@ -222,14 +222,11 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
for i, path := range spec.ExtraFiles {
abspath := filepath.Join(root, path)
outpath := filepath.Join(dir, "extra-"+strconv.Itoa(i)+"-"+filepath.Base(path)+".o")
cmdName := spec.Compiler
if name, ok := commands[cmdName]; ok {
cmdName = name
cmdNames := []string{spec.Compiler}
if names, ok := commands[spec.Compiler]; ok {
cmdNames = names
}
cmd := exec.Command(cmdName, append(cflags, "-c", "-o", outpath, abspath)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
err := execCommand(cmdNames, append(cflags, "-c", "-o", outpath, abspath)...)
if err != nil {
return &commandError{"failed to build", path, err}
}
@@ -241,14 +238,11 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
for _, file := range pkg.CFiles {
path := filepath.Join(pkg.Package.Dir, file)
outpath := filepath.Join(dir, "pkg"+strconv.Itoa(i)+"-"+file+".o")
cmdName := spec.Compiler
if name, ok := commands[cmdName]; ok {
cmdName = name
cmdNames := []string{spec.Compiler}
if names, ok := commands[spec.Compiler]; ok {
cmdNames = names
}
cmd := exec.Command(cmdName, append(cflags, "-c", "-o", outpath, path)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
err := execCommand(cmdNames, append(cflags, "-c", "-o", outpath, path)...)
if err != nil {
return &commandError{"failed to build", path, err}
}
@@ -257,11 +251,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
}
// Link the object files together.
if linker, ok := commands[spec.Linker]; ok {
err = Link(linker, ldflags...)
} else {
err = Link(spec.Linker, ldflags...)
}
err = Link(spec.Linker, ldflags...)
if err != nil {
return &commandError{"failed to link", executable, err}
}
+1 -1
View File
@@ -211,7 +211,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
GOOS: goos,
GOARCH: goarch,
BuildTags: []string{goos, goarch},
Compiler: commands["clang"],
Compiler: "clang",
Linker: "cc",
GDB: "gdb",
GDBCmds: []string{"run"},