Index: llvm/tools/llvm-go/CMakeLists.txt =================================================================== --- llvm/tools/llvm-go/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -if(LLVM_BINDINGS MATCHES "go") - set(binpath ${CMAKE_BINARY_DIR}/bin/llvm-go${CMAKE_EXECUTABLE_SUFFIX}) - add_custom_command(OUTPUT ${binpath} - COMMAND ${GO_EXECUTABLE} build -o ${binpath} llvm-go.go - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/llvm-go.go - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - COMMENT "Building Go executable llvm-go") - add_custom_target(llvm-go ALL DEPENDS ${binpath}) -endif() Index: llvm/tools/llvm-go/llvm-go.go =================================================================== --- llvm/tools/llvm-go/llvm-go.go +++ /dev/null @@ -1,315 +0,0 @@ -//===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This tool lets us build LLVM components within the tree by setting up a -// $GOPATH that resembles a tree fetched in the normal way with "go get". -// -//===----------------------------------------------------------------------===// - -package main - -import ( - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" -) - -const ( - linkmodeComponentLibs = "component-libs" - linkmodeDylib = "dylib" -) - -type pkg struct { - llvmpath, pkgpath string -} - -var packages = []pkg{ - {"bindings/go/llvm", "llvm.org/llvm/bindings/go/llvm"}, -} - -type compilerFlags struct { - cpp, cxx, ld string -} - -var components = []string{ - "all-targets", - "analysis", - "asmparser", - "asmprinter", - "bitreader", - "bitwriter", - "codegen", - "core", - "coroutines", - "debuginfodwarf", - "executionengine", - "instrumentation", - "interpreter", - "ipo", - "irreader", - "linker", - "mc", - "mcjit", - "objcarcopts", - "option", - "profiledata", - "scalaropts", - "support", - "target", -} - -func llvmConfig(args ...string) string { - configpath := os.Getenv("LLVM_CONFIG") - if configpath == "" { - bin, _ := filepath.Split(os.Args[0]) - configpath = filepath.Join(bin, "llvm-config") - } - - cmd := exec.Command(configpath, args...) - cmd.Stderr = os.Stderr - out, err := cmd.Output() - if err != nil { - panic(err.Error()) - } - - outstr := string(out) - outstr = strings.TrimSuffix(outstr, "\n") - outstr = strings.Replace(outstr, "\n", " ", -1) - return outstr -} - -func llvmFlags() compilerFlags { - args := append([]string{"--ldflags", "--libs", "--system-libs"}, components...) - ldflags := llvmConfig(args...) - stdLibOption := "" - if strings.Contains(llvmConfig("--cxxflags"), "-stdlib=libc++") { - // If libc++ is used to build LLVM libraries, -stdlib=libc++ is - // needed to resolve dependent symbols - stdLibOption = "-stdlib=libc++" - } - if runtime.GOOS == "aix" { - // AIX linker does not honour `-rpath`, the closest substitution - // is `-blibpath` - ldflags = "-Wl,-blibpath:" + llvmConfig("--libdir") + " " + ldflags - } else if runtime.GOOS != "darwin" { - // OS X doesn't like -rpath with cgo. See: - // https://github.com/golang/go/issues/7293 - ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags - } - return compilerFlags{ - cpp: llvmConfig("--cppflags"), - cxx: "-std=c++14" + " " + stdLibOption, - ld: ldflags, - } -} - -func addTag(args []string, tag string) []string { - args = append([]string{}, args...) - addedTag := false - for i, a := range args { - if strings.HasPrefix(a, "-tags=") { - args[i] = a + " " + tag - addedTag = true - } else if a == "-tags" && i+1 < len(args) { - args[i+1] = args[i+1] + " " + tag - addedTag = true - } - } - if !addedTag { - args = append([]string{args[0], "-tags", tag}, args[1:]...) - } - return args -} - -func printComponents() { - fmt.Println(strings.Join(components, " ")) -} - -func printConfig() { - flags := llvmFlags() - - fmt.Printf(`// +build !byollvm - -// This file is generated by llvm-go, do not edit. - -package llvm - -/* -#cgo CPPFLAGS: %s -#cgo CXXFLAGS: %s -#cgo LDFLAGS: %s -*/ -import "C" - -type (run_build_sh int) -`, flags.cpp, flags.cxx, flags.ld) -} - -func runGoWithLLVMEnv(args []string, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags string, packages []pkg) { - args = addTag(args, "byollvm") - - srcdir := llvmConfig("--src-root") - - tmpgopath, err := ioutil.TempDir("", "gopath") - if err != nil { - panic(err.Error()) - } - - for _, p := range packages { - path := filepath.Join(tmpgopath, "src", p.pkgpath) - err := os.MkdirAll(filepath.Dir(path), os.ModePerm) - if err != nil { - panic(err.Error()) - } - - abspath := p.llvmpath - if !filepath.IsAbs(abspath) { - abspath = filepath.Join(srcdir, abspath) - } - - err = os.Symlink(abspath, path) - if err != nil { - panic(err.Error()) - } - } - - newpath := os.Getenv("PATH") - - newgopathlist := []string{tmpgopath} - newgopathlist = append(newgopathlist, filepath.SplitList(os.Getenv("GOPATH"))...) - newgopath := strings.Join(newgopathlist, string(filepath.ListSeparator)) - - flags := llvmFlags() - - newenv := []string{ - "CC=" + cc, - "CXX=" + cxx, - "CGO_CPPFLAGS=" + flags.cpp + " " + cppflags, - "CGO_CXXFLAGS=" + flags.cxx + " " + cxxflags, - "CGO_LDFLAGS=" + flags.ld + " " + ldflags, - "GOPATH=" + newgopath, - "PATH=" + newpath, - } - if llgo != "" { - newenv = append(newenv, "GCCGO="+llgo) - } - - for _, v := range os.Environ() { - if !strings.HasPrefix(v, "CC=") && - !strings.HasPrefix(v, "CXX=") && - !strings.HasPrefix(v, "CGO_CPPFLAGS=") && - !strings.HasPrefix(v, "CGO_CXXFLAGS=") && - !strings.HasPrefix(v, "CGO_LDFLAGS=") && - !strings.HasPrefix(v, "GCCGO=") && - !strings.HasPrefix(v, "GOPATH=") && - !strings.HasPrefix(v, "PATH=") { - newenv = append(newenv, v) - } - } - - gocmdpath, err := exec.LookPath(gocmd) - if err != nil { - panic(err.Error()) - } - - proc, err := os.StartProcess(gocmdpath, append([]string{gocmd}, args...), - &os.ProcAttr{ - Env: newenv, - Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, - }) - if err != nil { - panic(err.Error()) - } - ps, err := proc.Wait() - if err != nil { - panic(err.Error()) - } - - os.RemoveAll(tmpgopath) - - if !ps.Success() { - os.Exit(1) - } -} - -func usage() { - fmt.Println(`Usage: llvm-go subcommand [flags] - -Available subcommands: build get install run test print-components print-config`) - os.Exit(0) -} - -func main() { - cc := os.Getenv("CC") - cxx := os.Getenv("CXX") - cppflags := os.Getenv("CGO_CPPFLAGS") - cxxflags := os.Getenv("CGO_CXXFLAGS") - ldflags := os.Getenv("CGO_LDFLAGS") - gocmd := "go" - llgo := "" - packagesString := "" - - flags := []struct { - name string - dest *string - }{ - {"cc", &cc}, - {"cxx", &cxx}, - {"go", &gocmd}, - {"llgo", &llgo}, - {"cppflags", &cppflags}, - {"ldflags", &ldflags}, - {"packages", &packagesString}, - } - - args := os.Args[1:] -LOOP: - for { - if len(args) == 0 { - usage() - } - for _, flag := range flags { - if strings.HasPrefix(args[0], flag.name+"=") { - *flag.dest = args[0][len(flag.name)+1:] - args = args[1:] - continue LOOP - } - } - break - } - - packages := packages - if packagesString != "" { - for _, field := range strings.Fields(packagesString) { - pos := strings.IndexRune(field, '=') - if pos == -1 { - fmt.Fprintf(os.Stderr, "invalid packages value %q, expected 'pkgpath=llvmpath [pkgpath=llvmpath ...]'\n", packagesString) - os.Exit(1) - } - packages = append(packages, pkg{ - pkgpath: field[:pos], - llvmpath: field[pos+1:], - }) - } - } - - switch args[0] { - case "build", "get", "install", "run", "test": - runGoWithLLVMEnv(args, cc, cxx, gocmd, llgo, cppflags, cxxflags, ldflags, packages) - case "print-components": - printComponents() - case "print-config": - printConfig() - default: - usage() - } -}