1 //===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This tool lets us build LLVM components within the tree by setting up a
11 // $GOPATH that resembles a tree fetched in the normal way with "go get".
13 //===----------------------------------------------------------------------===//
28 llvmpath, pkgpath string
32 {"bindings/go/llvm", "llvm.org/llvm/bindings/go/llvm"},
35 type compilerFlags struct {
39 var components = []string{
65 func llvmConfig(args ...string) string {
66 configpath := os.Getenv("LLVM_CONFIG")
68 // strip llvm-go, add llvm-config
69 configpath = os.Args[0][:len(os.Args[0])-7] + "llvm-config"
72 cmd := exec.Command(configpath, args...)
73 out, err := cmd.Output()
79 outstr = strings.TrimSuffix(outstr, "\n")
80 return strings.Replace(outstr, "\n", " ", -1)
83 func llvmFlags() compilerFlags {
84 ldflags := llvmConfig(append([]string{"--ldflags", "--libs", "--system-libs"}, components...)...)
85 if runtime.GOOS != "darwin" {
86 // OS X doesn't like -rpath with cgo. See:
87 // https://code.google.com/p/go/issues/detail?id=7293
88 ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags
91 cpp: llvmConfig("--cppflags"),
97 func addTag(args []string, tag string) []string {
98 args = append([]string{}, args...)
100 for i, a := range args {
101 if strings.HasPrefix(a, "-tags=") {
102 args[i] = a + " " + tag
104 } else if a == "-tags" && i+1 < len(args) {
105 args[i+1] = args[i+1] + " " + tag
110 args = append([]string{args[0], "-tags", tag}, args[1:]...)
115 func printComponents() {
116 fmt.Println(strings.Join(components, " "))
122 fmt.Printf(`// +build !byollvm
124 // This file is generated by llvm-go, do not edit.
135 type (run_build_sh int)
136 `, flags.cpp, flags.cxx, flags.ld)
139 func runGoWithLLVMEnv(args []string, cc, cxx, cppflags, cxxflags, ldflags string) {
140 args = addTag(args, "byollvm")
142 srcdir := llvmConfig("--src-root")
144 tmpgopath, err := ioutil.TempDir("", "gopath")
149 for _, p := range packages {
150 path := filepath.Join(tmpgopath, "src", p.pkgpath)
151 err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
156 err = os.Symlink(filepath.Join(srcdir, p.llvmpath), path)
162 newgopathlist := []string{tmpgopath}
163 newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
164 newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
171 "CGO_CPPFLAGS=" + flags.cpp + " " + cppflags,
172 "CGO_CXXFLAGS=" + flags.cxx + " " + cxxflags,
173 "CGO_LDFLAGS=" + flags.ld + " " + ldflags,
174 "GOPATH=" + newgopath,
176 for _, v := range os.Environ() {
177 if !strings.HasPrefix(v, "CC=") &&
178 !strings.HasPrefix(v, "CXX=") &&
179 !strings.HasPrefix(v, "CGO_CPPFLAGS=") &&
180 !strings.HasPrefix(v, "CGO_CXXFLAGS=") &&
181 !strings.HasPrefix(v, "CGO_LDFLAGS=") &&
182 !strings.HasPrefix(v, "GOPATH=") {
183 newenv = append(newenv, v)
187 gocmdpath, err := exec.LookPath("go")
192 proc, err := os.StartProcess(gocmdpath, append([]string{"go"}, args...),
195 Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
200 ps, err := proc.Wait()
205 os.RemoveAll(tmpgopath)
213 fmt.Println(`Usage: llvm-go subcommand [flags]
215 Available subcommands: build get install run test print-components print-config`)
220 cc := os.Getenv("CC")
221 cxx := os.Getenv("CXX")
222 cppflags := os.Getenv("CGO_CPPFLAGS")
223 cxxflags := os.Getenv("CGO_CXXFLAGS")
224 ldflags := os.Getenv("CGO_LDFLAGS")
231 case strings.HasPrefix(args[0], "cc="):
234 case strings.HasPrefix(args[0], "cxx="):
237 case strings.HasPrefix(args[0], "cppflags="):
238 cppflags = args[0][9:]
240 case strings.HasPrefix(args[0], "cxxflags="):
241 cxxflags = args[0][9:]
243 case strings.HasPrefix(args[0], "ldflags="):
244 ldflags = args[0][8:]
252 case "build", "get", "install", "run", "test":
253 runGoWithLLVMEnv(args, cc, cxx, cppflags, cxxflags, ldflags)
254 case "print-components":