purego_init.go raw

   1  //go:build purego
   2  
   3  package llvm
   4  
   5  import (
   6  	"fmt"
   7  	"os"
   8  	"path/filepath"
   9  	"unsafe"
  10  
  11  	"github.com/ebitengine/purego"
  12  )
  13  
  14  func init() {
  15  	llvmPath := os.Getenv("LLVM_LIB_PATH")
  16  	if llvmPath == "" {
  17  		llvmPath = findLLVM()
  18  	}
  19  	if llvmPath == "" {
  20  		fmt.Fprintf(os.Stderr, "purego LLVM: cannot find libLLVM-22; set LLVM_LIB_PATH\n")
  21  		os.Exit(1)
  22  	}
  23  
  24  	gluePath := os.Getenv("LLVM_GLUE_PATH")
  25  	if gluePath == "" {
  26  		gluePath = findGlue()
  27  	}
  28  
  29  	if err := Init(llvmPath, gluePath); err != nil {
  30  		fmt.Fprintf(os.Stderr, "purego LLVM init: %v\n", err)
  31  		os.Exit(1)
  32  	}
  33  
  34  	sym := trySym(libLLVM, "LLVMGetVersion")
  35  	if sym != 0 {
  36  		var major, minor, patch uint32
  37  		purego.SyscallN(sym,
  38  			uintptr(unsafe.Pointer(&major)),
  39  			uintptr(unsafe.Pointer(&minor)),
  40  			uintptr(unsafe.Pointer(&patch)))
  41  		Version = fmt.Sprintf("%d.%d.%d", major, minor, patch)
  42  	} else {
  43  		Version = "19.0.0"
  44  	}
  45  }
  46  
  47  func findLLVM() string {
  48  	candidates := []string{
  49  		"/usr/lib/libLLVM-22.so",
  50  		"/usr/lib64/libLLVM-22.so",
  51  		"/usr/lib/llvm-22/lib/libLLVM-22.so",
  52  		"/usr/lib/llvm22/lib/libLLVM-22.so",
  53  		"/usr/local/lib/libLLVM-22.so",
  54  	}
  55  	for _, p := range candidates {
  56  		if _, err := os.Stat(p); err == nil {
  57  			return p
  58  		}
  59  	}
  60  	return ""
  61  }
  62  
  63  func findGlue() string {
  64  	exe, err := os.Executable()
  65  	if err != nil {
  66  		return ""
  67  	}
  68  	dir := filepath.Dir(exe)
  69  	candidates := []string{
  70  		filepath.Join(dir, "libmoxie-llvm-glue.so"),
  71  		filepath.Join(dir, "..", "lib", "libmoxie-llvm-glue.so"),
  72  		filepath.Join(dir, "..", "llvm-glue", "libmoxie-llvm-glue.so"),
  73  	}
  74  	moxieRoot := os.Getenv("MOXIEROOT")
  75  	if moxieRoot != "" {
  76  		candidates = append(candidates, filepath.Join(moxieRoot, "llvm-glue", "libmoxie-llvm-glue.so"))
  77  	}
  78  	for _, p := range candidates {
  79  		if _, err := os.Stat(p); err == nil {
  80  			return p
  81  		}
  82  	}
  83  	return ""
  84  }
  85