diff --git a/compiler/compiler.go b/compiler/compiler.go index f7f9db2b..77300291 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -134,7 +134,7 @@ func (c *Compiler) Module() llvm.Module { return c.mod } -func (c *Compiler) Parse(mainPath string, buildTags []string) error { +func (c *Compiler) Parse(mainPath, sourceDir string, buildTags []string) error { tripleSplit := strings.Split(c.triple, "-") config := loader.Config{ @@ -148,7 +148,7 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error { Build: &build.Context{ GOARCH: tripleSplit[0], GOOS: tripleSplit[2], - GOROOT: ".", + GOROOT: sourceDir, GOPATH: runtime.GOROOT(), CgoEnabled: true, UseAllFiles: false, diff --git a/main.go b/main.go index 2f250208..635b4e57 100644 --- a/main.go +++ b/main.go @@ -32,7 +32,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, printIR, dumpSSA bool, p fmt.Println(c.IR()) }() } - return c.Parse(pkgName, spec.BuildTags) + return c.Parse(pkgName, sourceDir(), spec.BuildTags) }() if parseErr != nil { return parseErr @@ -93,6 +93,7 @@ func Compile(pkgName, outpath string, spec *TargetSpec, printIR, dumpSSA bool, p cmd := exec.Command(spec.Linker, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + cmd.Dir = sourceDir() err = cmd.Run() if err != nil { return err @@ -182,6 +183,7 @@ func Flash(pkgName, target, port string, printIR, dumpSSA bool, printSizes strin cmd := exec.Command("/bin/sh", "-c", flashCmd) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr + cmd.Dir = sourceDir() return cmd.Run() }) } @@ -192,7 +194,7 @@ func Run(pkgName string) error { if err != nil { return errors.New("compiler: " + err.Error()) } - err = c.Parse(pkgName, []string{runtime.GOOS, runtime.GOARCH}) + err = c.Parse(pkgName, sourceDir(), []string{runtime.GOOS, runtime.GOARCH}) if err != nil { return errors.New("compiler: " + err.Error()) } diff --git a/target.go b/target.go index 5f8a43b7..43a9700d 100644 --- a/target.go +++ b/target.go @@ -34,7 +34,7 @@ func LoadTarget(target string) (*TargetSpec, error) { // See whether there is a target specification for this target (e.g. // Arduino). - path := filepath.Join("targets", strings.ToLower(target)+".json") + path := filepath.Join(sourceDir(), "targets", strings.ToLower(target)+".json") if fp, err := os.Open(path); err == nil { defer fp.Close() err := json.NewDecoder(fp).Decode(spec) @@ -50,3 +50,11 @@ func LoadTarget(target string) (*TargetSpec, error) { return spec, nil } + +// Return the source directory of this package, or "." when it cannot be +// recovered. +func sourceDir() string { + // https://stackoverflow.com/a/32163888/559350 + _, path, _, _ := runtime.Caller(0) + return filepath.Dir(path) +}