main: move target specification into a separate package
Этот коммит содержится в:
родитель
dff6e6566d
коммит
e7cf75030c
7 изменённых файлов: 129 добавлений и 114 удалений
|
@ -65,7 +65,7 @@ commands:
|
||||||
- go-cache-v2-{{ checksum "go.mod" }}
|
- go-cache-v2-{{ checksum "go.mod" }}
|
||||||
- llvm-source-linux
|
- llvm-source-linux
|
||||||
- run: go install .
|
- run: go install .
|
||||||
- run: go test -v ./cgo ./interp ./transform .
|
- run: go test -v ./cgo ./compileopts ./interp ./transform .
|
||||||
- run: make gen-device -j4
|
- run: make gen-device -j4
|
||||||
- run: make smoketest RISCV=0
|
- run: make smoketest RISCV=0
|
||||||
- save_cache:
|
- save_cache:
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -139,7 +139,7 @@ tinygo:
|
||||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o build/tinygo$(EXE) -tags byollvm .
|
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) build -o build/tinygo$(EXE) -tags byollvm .
|
||||||
|
|
||||||
test:
|
test:
|
||||||
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -tags byollvm ./cgo ./interp ./transform .
|
CGO_CPPFLAGS="$(CGO_CPPFLAGS)" CGO_CXXFLAGS="$(CGO_CXXFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GO) test -v -tags byollvm ./cgo ./compileopts ./interp ./transform .
|
||||||
|
|
||||||
tinygo-test:
|
tinygo-test:
|
||||||
cd tests/tinygotest && tinygo test
|
cd tests/tinygotest && tinygo test
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package main
|
package compileopts
|
||||||
|
|
||||||
|
// This file loads a target specification from a JSON file.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
@ -300,104 +300,3 @@ func (spec *TargetSpec) OpenOCDConfiguration() (args []string, err error) {
|
||||||
args = append(args, "-f", "target/"+spec.OpenOCDTarget+".cfg")
|
args = append(args, "-f", "target/"+spec.OpenOCDTarget+".cfg")
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getGorootVersion returns the major and minor version for a given GOROOT path.
|
|
||||||
// If the goroot cannot be determined, (0, 0) is returned.
|
|
||||||
func getGorootVersion(goroot string) (major, minor int, err error) {
|
|
||||||
s, err := getGorootVersionString(goroot)
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if s == "" || s[:2] != "go" {
|
|
||||||
return 0, 0, errors.New("could not parse Go version: version does not start with 'go' prefix")
|
|
||||||
}
|
|
||||||
|
|
||||||
parts := strings.Split(s[2:], ".")
|
|
||||||
if len(parts) < 2 {
|
|
||||||
return 0, 0, errors.New("could not parse Go version: version has less than two parts")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ignore the errors, we don't really handle errors here anyway.
|
|
||||||
var trailing string
|
|
||||||
n, err := fmt.Sscanf(s, "go%d.%d%s", &major, &minor, &trailing)
|
|
||||||
if n == 2 && err == io.EOF {
|
|
||||||
// Means there were no trailing characters (i.e., not an alpha/beta)
|
|
||||||
err = nil
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return 0, 0, fmt.Errorf("failed to parse version: %s", err)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// getGorootVersionString returns the version string as reported by the Go
|
|
||||||
// toolchain for the given GOROOT path. It is usually of the form `go1.x.y` but
|
|
||||||
// can have some variations (for beta releases, for example).
|
|
||||||
func getGorootVersionString(goroot string) (string, error) {
|
|
||||||
if data, err := ioutil.ReadFile(filepath.Join(
|
|
||||||
goroot, "src", "runtime", "internal", "sys", "zversion.go")); err == nil {
|
|
||||||
|
|
||||||
r := regexp.MustCompile("const TheVersion = `(.*)`")
|
|
||||||
matches := r.FindSubmatch(data)
|
|
||||||
if len(matches) != 2 {
|
|
||||||
return "", errors.New("Invalid go version output:\n" + string(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(matches[1]), nil
|
|
||||||
|
|
||||||
} else if data, err := ioutil.ReadFile(filepath.Join(goroot, "VERSION")); err == nil {
|
|
||||||
return string(data), nil
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// getClangHeaderPath returns the path to the built-in Clang headers. It tries
|
|
||||||
// multiple locations, which should make it find the directory when installed in
|
|
||||||
// various ways.
|
|
||||||
func getClangHeaderPath(TINYGOROOT string) string {
|
|
||||||
// Check whether we're running from the source directory.
|
|
||||||
path := filepath.Join(TINYGOROOT, "llvm", "tools", "clang", "lib", "Headers")
|
|
||||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether we're running from the installation directory.
|
|
||||||
path = filepath.Join(TINYGOROOT, "lib", "clang", "include")
|
|
||||||
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
|
||||||
return path
|
|
||||||
}
|
|
||||||
|
|
||||||
// It looks like we are built with a system-installed LLVM. Do a last
|
|
||||||
// attempt: try to use Clang headers relative to the clang binary.
|
|
||||||
for _, cmdName := range commands["clang"] {
|
|
||||||
binpath, err := exec.LookPath(cmdName)
|
|
||||||
if err == nil {
|
|
||||||
// This should be the command that will also be used by
|
|
||||||
// execCommand. To avoid inconsistencies, make sure we use the
|
|
||||||
// headers relative to this command.
|
|
||||||
binpath, err = filepath.EvalSymlinks(binpath)
|
|
||||||
if err != nil {
|
|
||||||
// Unexpected.
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
// Example executable:
|
|
||||||
// /usr/lib/llvm-8/bin/clang
|
|
||||||
// Example include path:
|
|
||||||
// /usr/lib/llvm-8/lib/clang/8.0.1/include/
|
|
||||||
llvmRoot := filepath.Dir(filepath.Dir(binpath))
|
|
||||||
clangVersionRoot := filepath.Join(llvmRoot, "lib", "clang")
|
|
||||||
dirnames, err := ioutil.ReadDir(clangVersionRoot)
|
|
||||||
if err != nil || len(dirnames) != 1 {
|
|
||||||
// Unexpected.
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return filepath.Join(clangVersionRoot, dirnames[0].Name(), "include")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Could not find it.
|
|
||||||
return ""
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package compileopts
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
13
main.go
13
main.go
|
@ -17,6 +17,7 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tinygo-org/tinygo/compileopts"
|
||||||
"github.com/tinygo-org/tinygo/compiler"
|
"github.com/tinygo-org/tinygo/compiler"
|
||||||
"github.com/tinygo-org/tinygo/goenv"
|
"github.com/tinygo-org/tinygo/goenv"
|
||||||
"github.com/tinygo-org/tinygo/interp"
|
"github.com/tinygo-org/tinygo/interp"
|
||||||
|
@ -66,7 +67,7 @@ type BuildConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function for Compiler object.
|
// Helper function for Compiler object.
|
||||||
func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, action func(string) error) error {
|
func Compile(pkgName, outpath string, spec *compileopts.TargetSpec, config *BuildConfig, action func(string) error) error {
|
||||||
if config.gc == "" && spec.GC != "" {
|
if config.gc == "" && spec.GC != "" {
|
||||||
config.gc = spec.GC
|
config.gc = spec.GC
|
||||||
}
|
}
|
||||||
|
@ -335,7 +336,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, config *BuildConfig, act
|
||||||
}
|
}
|
||||||
|
|
||||||
func Build(pkgName, outpath, target string, config *BuildConfig) error {
|
func Build(pkgName, outpath, target string, config *BuildConfig) error {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -369,7 +370,7 @@ func Build(pkgName, outpath, target string, config *BuildConfig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Test(pkgName, target string, config *BuildConfig) error {
|
func Test(pkgName, target string, config *BuildConfig) error {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -396,7 +397,7 @@ func Test(pkgName, target string, config *BuildConfig) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Flash(pkgName, target, port string, config *BuildConfig) error {
|
func Flash(pkgName, target, port string, config *BuildConfig) error {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -503,7 +504,7 @@ func Flash(pkgName, target, port string, config *BuildConfig) error {
|
||||||
// Note: this command is expected to execute just before exiting, as it
|
// Note: this command is expected to execute just before exiting, as it
|
||||||
// modifies global state.
|
// modifies global state.
|
||||||
func FlashGDB(pkgName, target, port string, ocdOutput bool, config *BuildConfig) error {
|
func FlashGDB(pkgName, target, port string, ocdOutput bool, config *BuildConfig) error {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -594,7 +595,7 @@ func FlashGDB(pkgName, target, port string, ocdOutput bool, config *BuildConfig)
|
||||||
|
|
||||||
// Compile and run the given program, directly or in an emulator.
|
// Compile and run the given program, directly or in an emulator.
|
||||||
func Run(pkgName, target string, config *BuildConfig) error {
|
func Run(pkgName, target string, config *BuildConfig) error {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/tinygo-org/tinygo/compileopts"
|
||||||
"github.com/tinygo-org/tinygo/loader"
|
"github.com/tinygo-org/tinygo/loader"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -142,7 +143,7 @@ func runTest(path, tmpdir string, target string, t *testing.T) {
|
||||||
if target == "" {
|
if target == "" {
|
||||||
cmd = exec.Command(binary)
|
cmd = exec.Command(binary)
|
||||||
} else {
|
} else {
|
||||||
spec, err := LoadTarget(target)
|
spec, err := compileopts.LoadTarget(target)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("failed to load target spec:", err)
|
t.Fatal("failed to load target spec:", err)
|
||||||
}
|
}
|
||||||
|
|
114
paths.go
Обычный файл
114
paths.go
Обычный файл
|
@ -0,0 +1,114 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getGorootVersion returns the major and minor version for a given GOROOT path.
|
||||||
|
// If the goroot cannot be determined, (0, 0) is returned.
|
||||||
|
func getGorootVersion(goroot string) (major, minor int, err error) {
|
||||||
|
s, err := getGorootVersionString(goroot)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == "" || s[:2] != "go" {
|
||||||
|
return 0, 0, errors.New("could not parse Go version: version does not start with 'go' prefix")
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(s[2:], ".")
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return 0, 0, errors.New("could not parse Go version: version has less than two parts")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore the errors, we don't really handle errors here anyway.
|
||||||
|
var trailing string
|
||||||
|
n, err := fmt.Sscanf(s, "go%d.%d%s", &major, &minor, &trailing)
|
||||||
|
if n == 2 && err == io.EOF {
|
||||||
|
// Means there were no trailing characters (i.e., not an alpha/beta)
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, fmt.Errorf("failed to parse version: %s", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getGorootVersionString returns the version string as reported by the Go
|
||||||
|
// toolchain for the given GOROOT path. It is usually of the form `go1.x.y` but
|
||||||
|
// can have some variations (for beta releases, for example).
|
||||||
|
func getGorootVersionString(goroot string) (string, error) {
|
||||||
|
if data, err := ioutil.ReadFile(filepath.Join(
|
||||||
|
goroot, "src", "runtime", "internal", "sys", "zversion.go")); err == nil {
|
||||||
|
|
||||||
|
r := regexp.MustCompile("const TheVersion = `(.*)`")
|
||||||
|
matches := r.FindSubmatch(data)
|
||||||
|
if len(matches) != 2 {
|
||||||
|
return "", errors.New("Invalid go version output:\n" + string(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(matches[1]), nil
|
||||||
|
|
||||||
|
} else if data, err := ioutil.ReadFile(filepath.Join(goroot, "VERSION")); err == nil {
|
||||||
|
return string(data), nil
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// getClangHeaderPath returns the path to the built-in Clang headers. It tries
|
||||||
|
// multiple locations, which should make it find the directory when installed in
|
||||||
|
// various ways.
|
||||||
|
func getClangHeaderPath(TINYGOROOT string) string {
|
||||||
|
// Check whether we're running from the source directory.
|
||||||
|
path := filepath.Join(TINYGOROOT, "llvm", "tools", "clang", "lib", "Headers")
|
||||||
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether we're running from the installation directory.
|
||||||
|
path = filepath.Join(TINYGOROOT, "lib", "clang", "include")
|
||||||
|
if _, err := os.Stat(path); !os.IsNotExist(err) {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// It looks like we are built with a system-installed LLVM. Do a last
|
||||||
|
// attempt: try to use Clang headers relative to the clang binary.
|
||||||
|
for _, cmdName := range commands["clang"] {
|
||||||
|
binpath, err := exec.LookPath(cmdName)
|
||||||
|
if err == nil {
|
||||||
|
// This should be the command that will also be used by
|
||||||
|
// execCommand. To avoid inconsistencies, make sure we use the
|
||||||
|
// headers relative to this command.
|
||||||
|
binpath, err = filepath.EvalSymlinks(binpath)
|
||||||
|
if err != nil {
|
||||||
|
// Unexpected.
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// Example executable:
|
||||||
|
// /usr/lib/llvm-8/bin/clang
|
||||||
|
// Example include path:
|
||||||
|
// /usr/lib/llvm-8/lib/clang/8.0.1/include/
|
||||||
|
llvmRoot := filepath.Dir(filepath.Dir(binpath))
|
||||||
|
clangVersionRoot := filepath.Join(llvmRoot, "lib", "clang")
|
||||||
|
dirnames, err := ioutil.ReadDir(clangVersionRoot)
|
||||||
|
if err != nil || len(dirnames) != 1 {
|
||||||
|
// Unexpected.
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return filepath.Join(clangVersionRoot, dirnames[0].Name(), "include")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Could not find it.
|
||||||
|
return ""
|
||||||
|
}
|
Загрузка…
Создание таблицы
Сослаться в новой задаче