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