mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-14 16:03:41 +00:00
loader: merge roots from both Go and TinyGo in a cached directory
This commit changes the way that packages are looked up. Instead of working around the loader package by modifying the GOROOT variable for specific packages, create a new GOROOT using symlinks. This GOROOT is cached for the specified configuration (Go version, underlying GOROOT path, TinyGo path, whether to override the syscall package). This will also enable go module support in the future. Windows is a bit harder to support, because it only allows the creation of symlinks when developer mode is enabled. This is worked around by using symlinks and if that fails, using directory junctions or hardlinks instead. This should work in the vast majority of cases. The only case it doesn't work, is if developer mode is disabled and TinyGo, the Go toolchain, and the cache directory are not all on the same filesystem. If this is a problem, it is still possible to improve the code by using file copies instead. As a side effect, this also makes diagnostics use a relative file path only when the file is not in GOROOT or in TINYGOROOT.
This commit is contained in:
committed by
Ron Evans
parent
bde73fc214
commit
35015a7918
+5
-44
@@ -137,64 +137,25 @@ func Compile(pkgName string, machine llvm.TargetMachine, config *compileopts.Con
|
||||
c.funcPtrAddrSpace = dummyFunc.Type().PointerAddressSpace()
|
||||
dummyFunc.EraseFromParentAsFunction()
|
||||
|
||||
// Prefix the GOPATH with the system GOROOT, as GOROOT is already set to
|
||||
// the TinyGo root.
|
||||
overlayGopath := goenv.Get("GOPATH")
|
||||
if overlayGopath == "" {
|
||||
overlayGopath = goenv.Get("GOROOT")
|
||||
} else {
|
||||
overlayGopath = goenv.Get("GOROOT") + string(filepath.ListSeparator) + overlayGopath
|
||||
}
|
||||
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return c.mod, nil, nil, []error{err}
|
||||
}
|
||||
goroot, err := loader.GetCachedGoroot(c.Config)
|
||||
if err != nil {
|
||||
return c.mod, nil, []error{err}
|
||||
}
|
||||
lprogram := &loader.Program{
|
||||
Build: &build.Context{
|
||||
GOARCH: c.GOARCH(),
|
||||
GOOS: c.GOOS(),
|
||||
GOROOT: goenv.Get("GOROOT"),
|
||||
GOROOT: goroot,
|
||||
GOPATH: goenv.Get("GOPATH"),
|
||||
CgoEnabled: c.CgoEnabled(),
|
||||
UseAllFiles: false,
|
||||
Compiler: "gc", // must be one of the recognized compilers
|
||||
BuildTags: c.BuildTags(),
|
||||
},
|
||||
OverlayBuild: &build.Context{
|
||||
GOARCH: c.GOARCH(),
|
||||
GOOS: c.GOOS(),
|
||||
GOROOT: goenv.Get("TINYGOROOT"),
|
||||
GOPATH: overlayGopath,
|
||||
CgoEnabled: c.CgoEnabled(),
|
||||
UseAllFiles: false,
|
||||
Compiler: "gc", // must be one of the recognized compilers
|
||||
BuildTags: c.BuildTags(),
|
||||
},
|
||||
OverlayPath: func(path string) string {
|
||||
// Return the (overlay) import path when it should be overlaid, and
|
||||
// "" if it should not.
|
||||
if strings.HasPrefix(path, tinygoPath+"/src/") {
|
||||
// Avoid issues with packages that are imported twice, one from
|
||||
// GOPATH and one from TINYGOPATH.
|
||||
path = path[len(tinygoPath+"/src/"):]
|
||||
}
|
||||
switch path {
|
||||
case "machine", "os", "reflect", "runtime", "runtime/interrupt", "runtime/volatile", "sync", "testing", "internal/reflectlite", "internal/bytealg", "internal/task":
|
||||
return path
|
||||
default:
|
||||
if strings.HasPrefix(path, "device/") || strings.HasPrefix(path, "examples/") {
|
||||
return path
|
||||
} else if path == "syscall" {
|
||||
for _, tag := range c.BuildTags() {
|
||||
if tag == "baremetal" || tag == "darwin" {
|
||||
return path
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
},
|
||||
TypeChecker: types.Config{
|
||||
Sizes: &stdSizes{
|
||||
IntSize: int64(c.targetData.TypeAllocSize(c.intType)),
|
||||
|
||||
Reference in New Issue
Block a user