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.
Этот коммит содержится в:
родитель
9a54ee4241
коммит
9cad8bd0c8
7 изменённых файлов: 51 добавлений и 46 удалений
10
builtins.go
10
builtins.go
|
@ -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}
|
||||
}
|
||||
|
|
37
commands.go
37
commands.go
|
@ -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, " "))
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
28
main.go
28
main.go
|
@ -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}
|
||||
}
|
||||
|
|
|
@ -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"},
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче