env: allow compiling code outside llgo directory

This commit is contained in:
Li Jie
2025-01-04 23:08:49 +08:00
parent 7f10bc2a1b
commit 290f99b4d1
2 changed files with 63 additions and 3 deletions

View File

@@ -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...)
}

58
internal/env/env.go vendored Normal file
View File

@@ -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
}