xref: /aosp_15_r20/external/llvm/tools/llvm-go/llvm-go.go (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker//===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===//
2*9880d681SAndroid Build Coastguard Worker//
3*9880d681SAndroid Build Coastguard Worker//                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker//
5*9880d681SAndroid Build Coastguard Worker// This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker// License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker//
8*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker//
10*9880d681SAndroid Build Coastguard Worker// This tool lets us build LLVM components within the tree by setting up a
11*9880d681SAndroid Build Coastguard Worker// $GOPATH that resembles a tree fetched in the normal way with "go get".
12*9880d681SAndroid Build Coastguard Worker//
13*9880d681SAndroid Build Coastguard Worker//===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard Workerpackage main
16*9880d681SAndroid Build Coastguard Worker
17*9880d681SAndroid Build Coastguard Workerimport (
18*9880d681SAndroid Build Coastguard Worker	"fmt"
19*9880d681SAndroid Build Coastguard Worker	"io/ioutil"
20*9880d681SAndroid Build Coastguard Worker	"os"
21*9880d681SAndroid Build Coastguard Worker	"os/exec"
22*9880d681SAndroid Build Coastguard Worker	"path/filepath"
23*9880d681SAndroid Build Coastguard Worker	"runtime"
24*9880d681SAndroid Build Coastguard Worker	"strings"
25*9880d681SAndroid Build Coastguard Worker)
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Workerconst (
28*9880d681SAndroid Build Coastguard Worker	linkmodeComponentLibs = "component-libs"
29*9880d681SAndroid Build Coastguard Worker	linkmodeDylib         = "dylib"
30*9880d681SAndroid Build Coastguard Worker)
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Workertype pkg struct {
33*9880d681SAndroid Build Coastguard Worker	llvmpath, pkgpath string
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Workervar packages = []pkg{
37*9880d681SAndroid Build Coastguard Worker	{"bindings/go/llvm", "llvm.org/llvm/bindings/go/llvm"},
38*9880d681SAndroid Build Coastguard Worker	{"tools/llgo", "llvm.org/llgo"},
39*9880d681SAndroid Build Coastguard Worker}
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Workertype compilerFlags struct {
42*9880d681SAndroid Build Coastguard Worker	cpp, cxx, ld string
43*9880d681SAndroid Build Coastguard Worker}
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Workervar components = []string{
46*9880d681SAndroid Build Coastguard Worker	"all-targets",
47*9880d681SAndroid Build Coastguard Worker	"analysis",
48*9880d681SAndroid Build Coastguard Worker	"asmparser",
49*9880d681SAndroid Build Coastguard Worker	"asmprinter",
50*9880d681SAndroid Build Coastguard Worker	"bitreader",
51*9880d681SAndroid Build Coastguard Worker	"bitwriter",
52*9880d681SAndroid Build Coastguard Worker	"codegen",
53*9880d681SAndroid Build Coastguard Worker	"core",
54*9880d681SAndroid Build Coastguard Worker	"debuginfodwarf",
55*9880d681SAndroid Build Coastguard Worker	"executionengine",
56*9880d681SAndroid Build Coastguard Worker	"instrumentation",
57*9880d681SAndroid Build Coastguard Worker	"interpreter",
58*9880d681SAndroid Build Coastguard Worker	"ipo",
59*9880d681SAndroid Build Coastguard Worker	"irreader",
60*9880d681SAndroid Build Coastguard Worker	"linker",
61*9880d681SAndroid Build Coastguard Worker	"mc",
62*9880d681SAndroid Build Coastguard Worker	"mcjit",
63*9880d681SAndroid Build Coastguard Worker	"objcarcopts",
64*9880d681SAndroid Build Coastguard Worker	"option",
65*9880d681SAndroid Build Coastguard Worker	"profiledata",
66*9880d681SAndroid Build Coastguard Worker	"scalaropts",
67*9880d681SAndroid Build Coastguard Worker	"support",
68*9880d681SAndroid Build Coastguard Worker	"target",
69*9880d681SAndroid Build Coastguard Worker}
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Workerfunc llvmConfig(args ...string) string {
72*9880d681SAndroid Build Coastguard Worker	configpath := os.Getenv("LLVM_CONFIG")
73*9880d681SAndroid Build Coastguard Worker	if configpath == "" {
74*9880d681SAndroid Build Coastguard Worker		bin, _ := filepath.Split(os.Args[0])
75*9880d681SAndroid Build Coastguard Worker		configpath = filepath.Join(bin, "llvm-config")
76*9880d681SAndroid Build Coastguard Worker	}
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker	cmd := exec.Command(configpath, args...)
79*9880d681SAndroid Build Coastguard Worker	cmd.Stderr = os.Stderr
80*9880d681SAndroid Build Coastguard Worker	out, err := cmd.Output()
81*9880d681SAndroid Build Coastguard Worker	if err != nil {
82*9880d681SAndroid Build Coastguard Worker		panic(err.Error())
83*9880d681SAndroid Build Coastguard Worker	}
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker	outstr := string(out)
86*9880d681SAndroid Build Coastguard Worker	outstr = strings.TrimSuffix(outstr, "\n")
87*9880d681SAndroid Build Coastguard Worker	outstr = strings.Replace(outstr, "\n", " ", -1)
88*9880d681SAndroid Build Coastguard Worker	return outstr
89*9880d681SAndroid Build Coastguard Worker}
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Workerfunc llvmFlags() compilerFlags {
92*9880d681SAndroid Build Coastguard Worker	args := append([]string{"--ldflags", "--libs", "--system-libs"}, components...)
93*9880d681SAndroid Build Coastguard Worker	ldflags := llvmConfig(args...)
94*9880d681SAndroid Build Coastguard Worker	if runtime.GOOS != "darwin" {
95*9880d681SAndroid Build Coastguard Worker		// OS X doesn't like -rpath with cgo. See:
96*9880d681SAndroid Build Coastguard Worker		// https://code.google.com/p/go/issues/detail?id=7293
97*9880d681SAndroid Build Coastguard Worker		ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags
98*9880d681SAndroid Build Coastguard Worker	}
99*9880d681SAndroid Build Coastguard Worker	return compilerFlags{
100*9880d681SAndroid Build Coastguard Worker		cpp: llvmConfig("--cppflags"),
101*9880d681SAndroid Build Coastguard Worker		cxx: "-std=c++11",
102*9880d681SAndroid Build Coastguard Worker		ld:  ldflags,
103*9880d681SAndroid Build Coastguard Worker	}
104*9880d681SAndroid Build Coastguard Worker}
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Workerfunc addTag(args []string, tag string) []string {
107*9880d681SAndroid Build Coastguard Worker	args = append([]string{}, args...)
108*9880d681SAndroid Build Coastguard Worker	addedTag := false
109*9880d681SAndroid Build Coastguard Worker	for i, a := range args {
110*9880d681SAndroid Build Coastguard Worker		if strings.HasPrefix(a, "-tags=") {
111*9880d681SAndroid Build Coastguard Worker			args[i] = a + " " + tag
112*9880d681SAndroid Build Coastguard Worker			addedTag = true
113*9880d681SAndroid Build Coastguard Worker		} else if a == "-tags" && i+1 < len(args) {
114*9880d681SAndroid Build Coastguard Worker			args[i+1] = args[i+1] + " " + tag
115*9880d681SAndroid Build Coastguard Worker			addedTag = true
116*9880d681SAndroid Build Coastguard Worker		}
117*9880d681SAndroid Build Coastguard Worker	}
118*9880d681SAndroid Build Coastguard Worker	if !addedTag {
119*9880d681SAndroid Build Coastguard Worker		args = append([]string{args[0], "-tags", tag}, args[1:]...)
120*9880d681SAndroid Build Coastguard Worker	}
121*9880d681SAndroid Build Coastguard Worker	return args
122*9880d681SAndroid Build Coastguard Worker}
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Workerfunc printComponents() {
125*9880d681SAndroid Build Coastguard Worker	fmt.Println(strings.Join(components, " "))
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerfunc printConfig() {
129*9880d681SAndroid Build Coastguard Worker	flags := llvmFlags()
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker	fmt.Printf(`// +build !byollvm
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker// This file is generated by llvm-go, do not edit.
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Workerpackage llvm
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker/*
138*9880d681SAndroid Build Coastguard Worker#cgo CPPFLAGS: %s
139*9880d681SAndroid Build Coastguard Worker#cgo CXXFLAGS: %s
140*9880d681SAndroid Build Coastguard Worker#cgo LDFLAGS: %s
141*9880d681SAndroid Build Coastguard Worker*/
142*9880d681SAndroid Build Coastguard Workerimport "C"
143*9880d681SAndroid Build Coastguard Worker
144*9880d681SAndroid Build Coastguard Workertype (run_build_sh int)
145*9880d681SAndroid Build Coastguard Worker`, flags.cpp, flags.cxx, flags.ld)
146*9880d681SAndroid Build Coastguard Worker}
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Workerfunc runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string) {
149*9880d681SAndroid Build Coastguard Worker	args = addTag(args, "byollvm")
150*9880d681SAndroid Build Coastguard Worker
151*9880d681SAndroid Build Coastguard Worker	srcdir := llvmConfig("--src-root")
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker	tmpgopath, err := ioutil.TempDir("", "gopath")
154*9880d681SAndroid Build Coastguard Worker	if err != nil {
155*9880d681SAndroid Build Coastguard Worker		panic(err.Error())
156*9880d681SAndroid Build Coastguard Worker	}
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker	for _, p := range packages {
159*9880d681SAndroid Build Coastguard Worker		path := filepath.Join(tmpgopath, "src", p.pkgpath)
160*9880d681SAndroid Build Coastguard Worker		err := os.MkdirAll(filepath.Dir(path), os.ModePerm)
161*9880d681SAndroid Build Coastguard Worker		if err != nil {
162*9880d681SAndroid Build Coastguard Worker			panic(err.Error())
163*9880d681SAndroid Build Coastguard Worker		}
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker		err = os.Symlink(filepath.Join(srcdir, p.llvmpath), path)
166*9880d681SAndroid Build Coastguard Worker		if err != nil {
167*9880d681SAndroid Build Coastguard Worker			panic(err.Error())
168*9880d681SAndroid Build Coastguard Worker		}
169*9880d681SAndroid Build Coastguard Worker	}
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker	newpath := os.Getenv("PATH")
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker	newgopathlist := []string{tmpgopath}
174*9880d681SAndroid Build Coastguard Worker	newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...)
175*9880d681SAndroid Build Coastguard Worker	newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator))
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker	flags := llvmFlags()
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker	newenv := []string{
180*9880d681SAndroid Build Coastguard Worker		"CC=" + cc,
181*9880d681SAndroid Build Coastguard Worker		"CXX=" + cxx,
182*9880d681SAndroid Build Coastguard Worker		"CGO_CPPFLAGS=" + flags.cpp + " " + cppflags,
183*9880d681SAndroid Build Coastguard Worker		"CGO_CXXFLAGS=" + flags.cxx + " " + cxxflags,
184*9880d681SAndroid Build Coastguard Worker		"CGO_LDFLAGS=" + flags.ld + " " + ldflags,
185*9880d681SAndroid Build Coastguard Worker		"GOPATH=" + newgopath,
186*9880d681SAndroid Build Coastguard Worker		"PATH=" + newpath,
187*9880d681SAndroid Build Coastguard Worker	}
188*9880d681SAndroid Build Coastguard Worker	if llgo != "" {
189*9880d681SAndroid Build Coastguard Worker		newenv = append(newenv, "GCCGO="+llgo)
190*9880d681SAndroid Build Coastguard Worker	}
191*9880d681SAndroid Build Coastguard Worker
192*9880d681SAndroid Build Coastguard Worker	for _, v := range os.Environ() {
193*9880d681SAndroid Build Coastguard Worker		if !strings.HasPrefix(v, "CC=") &&
194*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "CXX=") &&
195*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "CGO_CPPFLAGS=") &&
196*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "CGO_CXXFLAGS=") &&
197*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "CGO_LDFLAGS=") &&
198*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "GCCGO=") &&
199*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "GOPATH=") &&
200*9880d681SAndroid Build Coastguard Worker			!strings.HasPrefix(v, "PATH=") {
201*9880d681SAndroid Build Coastguard Worker			newenv = append(newenv, v)
202*9880d681SAndroid Build Coastguard Worker		}
203*9880d681SAndroid Build Coastguard Worker	}
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker	gocmdpath, err := exec.LookPath(gocmd)
206*9880d681SAndroid Build Coastguard Worker	if err != nil {
207*9880d681SAndroid Build Coastguard Worker		panic(err.Error())
208*9880d681SAndroid Build Coastguard Worker	}
209*9880d681SAndroid Build Coastguard Worker
210*9880d681SAndroid Build Coastguard Worker	proc, err := os.StartProcess(gocmdpath, append([]string{gocmd}, args...),
211*9880d681SAndroid Build Coastguard Worker		&os.ProcAttr{
212*9880d681SAndroid Build Coastguard Worker			Env:   newenv,
213*9880d681SAndroid Build Coastguard Worker			Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
214*9880d681SAndroid Build Coastguard Worker		})
215*9880d681SAndroid Build Coastguard Worker	if err != nil {
216*9880d681SAndroid Build Coastguard Worker		panic(err.Error())
217*9880d681SAndroid Build Coastguard Worker	}
218*9880d681SAndroid Build Coastguard Worker	ps, err := proc.Wait()
219*9880d681SAndroid Build Coastguard Worker	if err != nil {
220*9880d681SAndroid Build Coastguard Worker		panic(err.Error())
221*9880d681SAndroid Build Coastguard Worker	}
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker	os.RemoveAll(tmpgopath)
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker	if !ps.Success() {
226*9880d681SAndroid Build Coastguard Worker		os.Exit(1)
227*9880d681SAndroid Build Coastguard Worker	}
228*9880d681SAndroid Build Coastguard Worker}
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Workerfunc usage() {
231*9880d681SAndroid Build Coastguard Worker	fmt.Println(`Usage: llvm-go subcommand [flags]
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard WorkerAvailable subcommands: build get install run test print-components print-config`)
234*9880d681SAndroid Build Coastguard Worker	os.Exit(0)
235*9880d681SAndroid Build Coastguard Worker}
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workerfunc main() {
238*9880d681SAndroid Build Coastguard Worker	cc := os.Getenv("CC")
239*9880d681SAndroid Build Coastguard Worker	cxx := os.Getenv("CXX")
240*9880d681SAndroid Build Coastguard Worker	cppflags := os.Getenv("CGO_CPPFLAGS")
241*9880d681SAndroid Build Coastguard Worker	cxxflags := os.Getenv("CGO_CXXFLAGS")
242*9880d681SAndroid Build Coastguard Worker	ldflags := os.Getenv("CGO_LDFLAGS")
243*9880d681SAndroid Build Coastguard Worker	gocmd := "go"
244*9880d681SAndroid Build Coastguard Worker	llgo := ""
245*9880d681SAndroid Build Coastguard Worker
246*9880d681SAndroid Build Coastguard Worker	flags := []struct {
247*9880d681SAndroid Build Coastguard Worker		name string
248*9880d681SAndroid Build Coastguard Worker		dest *string
249*9880d681SAndroid Build Coastguard Worker	}{
250*9880d681SAndroid Build Coastguard Worker		{"cc", &cc},
251*9880d681SAndroid Build Coastguard Worker		{"cxx", &cxx},
252*9880d681SAndroid Build Coastguard Worker		{"go", &gocmd},
253*9880d681SAndroid Build Coastguard Worker		{"llgo", &llgo},
254*9880d681SAndroid Build Coastguard Worker		{"cppflags", &cppflags},
255*9880d681SAndroid Build Coastguard Worker		{"ldflags", &ldflags},
256*9880d681SAndroid Build Coastguard Worker	}
257*9880d681SAndroid Build Coastguard Worker
258*9880d681SAndroid Build Coastguard Worker	args := os.Args[1:]
259*9880d681SAndroid Build Coastguard WorkerLOOP:
260*9880d681SAndroid Build Coastguard Worker	for {
261*9880d681SAndroid Build Coastguard Worker		if len(args) == 0 {
262*9880d681SAndroid Build Coastguard Worker			usage()
263*9880d681SAndroid Build Coastguard Worker		}
264*9880d681SAndroid Build Coastguard Worker		for _, flag := range flags {
265*9880d681SAndroid Build Coastguard Worker			if strings.HasPrefix(args[0], flag.name+"=") {
266*9880d681SAndroid Build Coastguard Worker				*flag.dest = args[0][len(flag.name)+1:]
267*9880d681SAndroid Build Coastguard Worker				args = args[1:]
268*9880d681SAndroid Build Coastguard Worker				continue LOOP
269*9880d681SAndroid Build Coastguard Worker			}
270*9880d681SAndroid Build Coastguard Worker		}
271*9880d681SAndroid Build Coastguard Worker		break
272*9880d681SAndroid Build Coastguard Worker	}
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker	switch args[0] {
275*9880d681SAndroid Build Coastguard Worker	case "build", "get", "install", "run", "test":
276*9880d681SAndroid Build Coastguard Worker		runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags)
277*9880d681SAndroid Build Coastguard Worker	case "print-components":
278*9880d681SAndroid Build Coastguard Worker		printComponents()
279*9880d681SAndroid Build Coastguard Worker	case "print-config":
280*9880d681SAndroid Build Coastguard Worker		printConfig()
281*9880d681SAndroid Build Coastguard Worker	default:
282*9880d681SAndroid Build Coastguard Worker		usage()
283*9880d681SAndroid Build Coastguard Worker	}
284*9880d681SAndroid Build Coastguard Worker}
285