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"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -192,13 +191,13 @@ func loadBuiltins(target string) (path string, err error) {
|
||||||
srcs[i] = filepath.Join(builtinsDir, name)
|
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
|
return path, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var cachepath string
|
var cachepath string
|
||||||
err = compileBuiltins(target, func(path string) error {
|
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
|
cachepath = path
|
||||||
return err
|
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
|
// Note: -fdebug-prefix-map is necessary to make the output archive
|
||||||
// reproducible. Otherwise the temporary directory is stored in the
|
// reproducible. Otherwise the temporary directory is stored in the
|
||||||
// archive itself, which varies each run.
|
// 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)
|
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)
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to build", srcpath, err}
|
return &commandError{"failed to build", srcpath, err}
|
||||||
}
|
}
|
||||||
|
|
37
commands.go
37
commands.go
|
@ -1,10 +1,33 @@
|
||||||
// +build !darwin
|
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
// commands used by the compilation process might have different file names on Linux than those used on macOS.
|
import (
|
||||||
var commands = map[string]string{
|
"errors"
|
||||||
"clang": "clang-8",
|
"os"
|
||||||
"ld.lld": "ld.lld-8",
|
"os/exec"
|
||||||
"wasm-ld": "wasm-ld-8",
|
"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.
|
// This version uses the built-in linker when trying to use lld.
|
||||||
func Link(linker string, flags ...string) error {
|
func Link(linker string, flags ...string) error {
|
||||||
switch linker {
|
switch linker {
|
||||||
case "ld.lld", commands["ld.lld"]:
|
case "ld.lld":
|
||||||
flags = append([]string{"tinygo:" + linker}, flags...)
|
flags = append([]string{"tinygo:" + linker}, flags...)
|
||||||
var cflag *C.char
|
var cflag *C.char
|
||||||
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
|
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 errors.New("failed to link using built-in ld.lld")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case "wasm-ld", commands["wasm-ld"]:
|
case "wasm-ld":
|
||||||
flags = append([]string{"tinygo:" + linker}, flags...)
|
flags = append([]string{"tinygo:" + linker}, flags...)
|
||||||
var cflag *C.char
|
var cflag *C.char
|
||||||
buf := C.calloc(C.size_t(len(flags)), C.size_t(unsafe.Sizeof(cflag)))
|
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
|
return nil
|
||||||
default:
|
default:
|
||||||
// Fall back to external command.
|
// Fall back to external command.
|
||||||
|
if cmdNames, ok := commands[linker]; ok {
|
||||||
|
return execCommand(cmdNames, flags...)
|
||||||
|
}
|
||||||
cmd := exec.Command(linker, flags...)
|
cmd := exec.Command(linker, flags...)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
|
|
|
@ -14,6 +14,9 @@ import (
|
||||||
//
|
//
|
||||||
// This version always runs the linker as an external command.
|
// This version always runs the linker as an external command.
|
||||||
func Link(linker string, flags ...string) error {
|
func Link(linker string, flags ...string) error {
|
||||||
|
if cmdNames, ok := commands[linker]; ok {
|
||||||
|
return execCommand(cmdNames, flags...)
|
||||||
|
}
|
||||||
cmd := exec.Command(linker, flags...)
|
cmd := exec.Command(linker, flags...)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
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 {
|
for i, path := range spec.ExtraFiles {
|
||||||
abspath := filepath.Join(root, path)
|
abspath := filepath.Join(root, path)
|
||||||
outpath := filepath.Join(dir, "extra-"+strconv.Itoa(i)+"-"+filepath.Base(path)+".o")
|
outpath := filepath.Join(dir, "extra-"+strconv.Itoa(i)+"-"+filepath.Base(path)+".o")
|
||||||
cmdName := spec.Compiler
|
cmdNames := []string{spec.Compiler}
|
||||||
if name, ok := commands[cmdName]; ok {
|
if names, ok := commands[spec.Compiler]; ok {
|
||||||
cmdName = name
|
cmdNames = names
|
||||||
}
|
}
|
||||||
cmd := exec.Command(cmdName, append(cflags, "-c", "-o", outpath, abspath)...)
|
err := execCommand(cmdNames, append(cflags, "-c", "-o", outpath, abspath)...)
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to build", path, err}
|
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 {
|
for _, file := range pkg.CFiles {
|
||||||
path := filepath.Join(pkg.Package.Dir, file)
|
path := filepath.Join(pkg.Package.Dir, file)
|
||||||
outpath := filepath.Join(dir, "pkg"+strconv.Itoa(i)+"-"+file+".o")
|
outpath := filepath.Join(dir, "pkg"+strconv.Itoa(i)+"-"+file+".o")
|
||||||
cmdName := spec.Compiler
|
cmdNames := []string{spec.Compiler}
|
||||||
if name, ok := commands[cmdName]; ok {
|
if names, ok := commands[spec.Compiler]; ok {
|
||||||
cmdName = name
|
cmdNames = names
|
||||||
}
|
}
|
||||||
cmd := exec.Command(cmdName, append(cflags, "-c", "-o", outpath, path)...)
|
err := execCommand(cmdNames, append(cflags, "-c", "-o", outpath, path)...)
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to build", path, err}
|
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.
|
// Link the object files together.
|
||||||
if linker, ok := commands[spec.Linker]; ok {
|
err = Link(spec.Linker, ldflags...)
|
||||||
err = Link(linker, ldflags...)
|
|
||||||
} else {
|
|
||||||
err = Link(spec.Linker, ldflags...)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &commandError{"failed to link", executable, err}
|
return &commandError{"failed to link", executable, err}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,7 +211,7 @@ func defaultTarget(goos, goarch, triple string) (*TargetSpec, error) {
|
||||||
GOOS: goos,
|
GOOS: goos,
|
||||||
GOARCH: goarch,
|
GOARCH: goarch,
|
||||||
BuildTags: []string{goos, goarch},
|
BuildTags: []string{goos, goarch},
|
||||||
Compiler: commands["clang"],
|
Compiler: "clang",
|
||||||
Linker: "cc",
|
Linker: "cc",
|
||||||
GDB: "gdb",
|
GDB: "gdb",
|
||||||
GDBCmds: []string{"run"},
|
GDBCmds: []string{"run"},
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче