From 290f99b4d19d4fb0240683615c0f830315e98f22 Mon Sep 17 00:00:00 2001 From: Li Jie Date: Sat, 4 Jan 2025 23:08:49 +0800 Subject: [PATCH] env: allow compiling code outside llgo directory --- internal/build/build.go | 8 +++--- internal/env/env.go | 58 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 internal/env/env.go diff --git a/internal/build/build.go b/internal/build/build.go index 7992066d..29ee14cf 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -37,10 +37,11 @@ import ( "golang.org/x/tools/go/ssa" "github.com/goplus/llgo/cl" + "github.com/goplus/llgo/internal/env" "github.com/goplus/llgo/internal/packages" "github.com/goplus/llgo/internal/typepatch" "github.com/goplus/llgo/ssa/abi" - "github.com/goplus/llgo/xtool/env" + xenv "github.com/goplus/llgo/xtool/env" "github.com/goplus/llgo/xtool/env/llvm" llssa "github.com/goplus/llgo/ssa" @@ -175,6 +176,7 @@ func Do(args []string, conf *Config) ([]Package, error) { } altPkgPaths := altPkgs(initial, llssa.PkgRuntime) + cfg.Dir = env.LLGoROOT() altPkgs, err := packages.LoadEx(dedup, sizes, cfg, altPkgPaths...) check(err) @@ -316,7 +318,7 @@ func buildAllPkgs(ctx *context, initial []*packages.Package, verbose bool) (pkgs for _, param := range altParts { param = strings.TrimSpace(param) if strings.ContainsRune(param, '$') { - expdArgs = append(expdArgs, env.ExpandEnvToArgs(param)...) + expdArgs = append(expdArgs, xenv.ExpandEnvToArgs(param)...) ctx.nLibdir++ } else { fields := strings.Fields(param) @@ -748,7 +750,7 @@ func clFiles(ctx *context, files string, pkg *packages.Package, procFile func(li args := make([]string, 0, 16) if strings.HasPrefix(files, "$") { // has cflags if pos := strings.IndexByte(files, ':'); pos > 0 { - cflags := env.ExpandEnvToArgs(files[:pos]) + cflags := xenv.ExpandEnvToArgs(files[:pos]) files = files[pos+1:] args = append(args, cflags...) } diff --git a/internal/env/env.go b/internal/env/env.go new file mode 100644 index 00000000..d40de6ad --- /dev/null +++ b/internal/env/env.go @@ -0,0 +1,58 @@ +package env + +import ( + "os" + "path/filepath" + "strings" +) + +const ( + LLGoCompilerPkg = "github.com/goplus/llgo" +) + +func LLGoROOT() string { + if root, ok := isLLGoRoot(os.Getenv("LLGO_ROOT")); ok { + return root + } + // Get executable path + exe, err := os.Executable() + if err != nil { + return "" + } + // Resolve any symlinks + exe, err = filepath.EvalSymlinks(exe) + if err != nil { + return "" + } + // Check if parent directory is bin + dir := filepath.Dir(exe) + if filepath.Base(dir) != "bin" { + return "" + } + // Get parent directory of bin + root := filepath.Dir(dir) + if root, ok := isLLGoRoot(root); ok { + return root + } + return "" +} + +func isLLGoRoot(root string) (string, bool) { + if root == "" { + return "", false + } + root, err := filepath.Abs(root) + if err != nil { + return "", false + } + // Check for go.mod + data, err := os.ReadFile(filepath.Join(root, "go.mod")) + if err != nil { + return "", false + } + // Check module name + if !strings.Contains(string(data), "module "+LLGoCompilerPkg+"\n") { + return "", false + } + return root, true +}