move out c/cpp/py
This commit is contained in:
120
internal/env/env.go
vendored
Normal file
120
internal/env/env.go
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
LLGoCompilerPkg = "github.com/goplus/llgo"
|
||||
LLGoRuntimePkgName = "runtime"
|
||||
LLGoRuntimePkg = LLGoCompilerPkg + "/" + LLGoRuntimePkgName
|
||||
envFileName = "/internal/env/env.go"
|
||||
)
|
||||
|
||||
func GOROOT() string {
|
||||
root := os.Getenv("GOROOT")
|
||||
if root != "" {
|
||||
return root
|
||||
}
|
||||
cmd := exec.Command("go", "env", "GOROOT")
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err := cmd.Run()
|
||||
if err == nil {
|
||||
return strings.TrimSpace(out.String())
|
||||
}
|
||||
panic("cannot get GOROOT: " + err.Error())
|
||||
}
|
||||
|
||||
func LLGoRuntimeDir() string {
|
||||
root := LLGoROOT()
|
||||
if root != "" {
|
||||
return filepath.Join(root, LLGoRuntimePkgName)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func LLGoROOT() string {
|
||||
llgoRootEnv := os.Getenv("LLGO_ROOT")
|
||||
if llgoRootEnv != "" {
|
||||
if root, ok := isLLGoRoot(llgoRootEnv); ok {
|
||||
return root
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "WARNING: LLGO_ROOT is not a valid LLGO root: %s\n", llgoRootEnv)
|
||||
}
|
||||
// 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" {
|
||||
// Get parent directory of bin
|
||||
root := filepath.Dir(dir)
|
||||
if root, ok := isLLGoRoot(root); ok {
|
||||
return root
|
||||
}
|
||||
}
|
||||
if Devel() {
|
||||
root, err := getRuntimePkgDirByCaller()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if root, ok := isLLGoRoot(root); ok {
|
||||
fmt.Fprintln(os.Stderr, "WARNING: Using LLGO root for devel: "+root)
|
||||
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
|
||||
}
|
||||
|
||||
func getRuntimePkgDirByCaller() (string, error) {
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return "", fmt.Errorf("cannot get caller")
|
||||
}
|
||||
if !strings.HasSuffix(file, envFileName) {
|
||||
return "", fmt.Errorf("wrong caller")
|
||||
}
|
||||
// check file exists
|
||||
if _, err := os.Stat(file); os.IsNotExist(err) {
|
||||
return "", fmt.Errorf("file %s not exists", file)
|
||||
}
|
||||
modPath := strings.TrimSuffix(file, envFileName)
|
||||
if st, err := os.Stat(modPath); os.IsNotExist(err) || !st.IsDir() {
|
||||
return "", fmt.Errorf("not llgo compiler root: %s", modPath)
|
||||
}
|
||||
return modPath, nil
|
||||
}
|
||||
Reference in New Issue
Block a user