forked from OSchip/llvm-project
Add llvm-go tool.
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". It is intended that components such as the Go frontend will be built in-tree using this tool. Differential Revision: http://reviews.llvm.org/D5902 llvm-svn: 220462
This commit is contained in:
parent
30428bc844
commit
244ecf55bd
|
@ -1,36 +1,5 @@
|
||||||
#!/bin/sh -xe
|
#!/bin/sh -xe
|
||||||
|
|
||||||
llvm_components="\
|
|
||||||
all-targets \
|
|
||||||
analysis \
|
|
||||||
asmparser \
|
|
||||||
asmprinter \
|
|
||||||
bitreader \
|
|
||||||
bitwriter \
|
|
||||||
codegen \
|
|
||||||
core \
|
|
||||||
debuginfo \
|
|
||||||
executionengine \
|
|
||||||
instrumentation \
|
|
||||||
interpreter \
|
|
||||||
ipo \
|
|
||||||
irreader \
|
|
||||||
linker \
|
|
||||||
mc \
|
|
||||||
mcjit \
|
|
||||||
objcarcopts \
|
|
||||||
option \
|
|
||||||
profiledata \
|
|
||||||
scalaropts \
|
|
||||||
support \
|
|
||||||
target \
|
|
||||||
"
|
|
||||||
|
|
||||||
if [ "$1" = "--print-components" ] ; then
|
|
||||||
echo $llvm_components
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
gollvmdir=$(dirname "$0")/llvm
|
gollvmdir=$(dirname "$0")/llvm
|
||||||
|
|
||||||
workdir=$gollvmdir/workdir
|
workdir=$gollvmdir/workdir
|
||||||
|
@ -41,12 +10,14 @@ mkdir -p $llvm_builddir
|
||||||
|
|
||||||
cmake_flags="../../../../.. $@"
|
cmake_flags="../../../../.. $@"
|
||||||
llvm_config="$llvm_builddir/bin/llvm-config"
|
llvm_config="$llvm_builddir/bin/llvm-config"
|
||||||
|
llvm_go="$llvm_builddir/bin/llvm-go"
|
||||||
|
|
||||||
if test -n "`which ninja`" ; then
|
if test -n "`which ninja`" ; then
|
||||||
# If Ninja is available, we can speed up the build by building only the
|
# If Ninja is available, we can speed up the build by building only the
|
||||||
# required subset of LLVM.
|
# required subset of LLVM.
|
||||||
(cd $llvm_builddir && cmake -G Ninja $cmake_flags)
|
(cd $llvm_builddir && cmake -G Ninja $cmake_flags)
|
||||||
ninja -C $llvm_builddir llvm-config
|
ninja -C $llvm_builddir llvm-config llvm-go
|
||||||
|
llvm_components="$($llvm_go print-components)"
|
||||||
llvm_buildtargets="$($llvm_config --libs $llvm_components | sed -e 's/-l//g')"
|
llvm_buildtargets="$($llvm_config --libs $llvm_components | sed -e 's/-l//g')"
|
||||||
ninja -C $llvm_builddir $llvm_buildtargets FileCheck
|
ninja -C $llvm_builddir $llvm_buildtargets FileCheck
|
||||||
else
|
else
|
||||||
|
@ -54,14 +25,7 @@ else
|
||||||
make -C $llvm_builddir -j4
|
make -C $llvm_builddir -j4
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
$llvm_go print-config > $gollvmdir/llvm_config.go
|
||||||
|
|
||||||
llvm_version="$($llvm_config --version)"
|
llvm_version="$($llvm_config --version)"
|
||||||
llvm_cflags="$($llvm_config --cppflags)"
|
|
||||||
llvm_ldflags="$($llvm_config --ldflags) $($llvm_config --libs $llvm_components) $($llvm_config --system-libs)"
|
|
||||||
if [ $(uname) != "Darwin" ]; then
|
|
||||||
# OS X doesn't like -rpath with cgo. See:
|
|
||||||
# https://code.google.com/p/go/issues/detail?id=7293
|
|
||||||
llvm_ldflags="-Wl,-rpath,$($llvm_config --libdir) $llvm_ldflags"
|
|
||||||
fi
|
|
||||||
sed -e "s#@LLVM_CFLAGS@#$llvm_cflags#g; s#@LLVM_LDFLAGS@#$llvm_ldflags#g" $gollvmdir/llvm_config.go.in > \
|
|
||||||
$gollvmdir/llvm_config.go
|
|
||||||
printf "package llvm\n\nconst Version = \"%s\"\n" "$llvm_version" > $gollvmdir/version.go
|
printf "package llvm\n\nconst Version = \"%s\"\n" "$llvm_version" > $gollvmdir/version.go
|
||||||
|
|
|
@ -493,16 +493,20 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LLVM_BINDINGS "")
|
set(LLVM_BINDINGS "")
|
||||||
find_program(GO_EXECUTABLE NAMES go DOC "go executable")
|
if(WIN32)
|
||||||
if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
|
|
||||||
message(STATUS "Go bindings disabled.")
|
message(STATUS "Go bindings disabled.")
|
||||||
else()
|
else()
|
||||||
execute_process(COMMAND ${GO_EXECUTABLE} run ${CMAKE_SOURCE_DIR}/bindings/go/conftest.go
|
find_program(GO_EXECUTABLE NAMES go DOC "go executable")
|
||||||
RESULT_VARIABLE GO_CONFTEST)
|
if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
|
||||||
if(GO_CONFTEST STREQUAL "0")
|
message(STATUS "Go bindings disabled.")
|
||||||
set(LLVM_BINDINGS "${LLVM_BINDINGS} go")
|
|
||||||
message(STATUS "Go bindings enabled.")
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Go bindings disabled, need at least Go 1.2.")
|
execute_process(COMMAND ${GO_EXECUTABLE} run ${CMAKE_SOURCE_DIR}/bindings/go/conftest.go
|
||||||
|
RESULT_VARIABLE GO_CONFTEST)
|
||||||
|
if(GO_CONFTEST STREQUAL "0")
|
||||||
|
set(LLVM_BINDINGS "${LLVM_BINDINGS} go")
|
||||||
|
message(STATUS "Go bindings enabled.")
|
||||||
|
else()
|
||||||
|
message(STATUS "Go bindings disabled, need at least Go 1.2.")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,8 +1,3 @@
|
||||||
; RUN: cd %S/../../../bindings/go/llvm && \
|
; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
|
||||||
; RUN: env CGO_CPPFLAGS="$(llvm-config --cppflags)" \
|
|
||||||
; RUN: CGO_CXXFLAGS=-std=c++11 \
|
|
||||||
; RUN: CGO_LDFLAGS="$(llvm-config --ldflags --libs --system-libs \
|
|
||||||
; RUN: $(../build.sh --print-components)) $CGO_LDFLAGS" \
|
|
||||||
; RUN: %go test -tags byollvm .
|
|
||||||
|
|
||||||
; REQUIRES: shell
|
; REQUIRES: shell
|
||||||
|
|
|
@ -30,8 +30,9 @@ set(LLVM_TEST_DEPENDS
|
||||||
llvm-cov
|
llvm-cov
|
||||||
llvm-diff
|
llvm-diff
|
||||||
llvm-dis
|
llvm-dis
|
||||||
llvm-extract
|
|
||||||
llvm-dwarfdump
|
llvm-dwarfdump
|
||||||
|
llvm-extract
|
||||||
|
llvm-go
|
||||||
llvm-link
|
llvm-link
|
||||||
llvm-lto
|
llvm-lto
|
||||||
llvm-mc
|
llvm-mc
|
||||||
|
|
|
@ -200,6 +200,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
|
||||||
r"\bllvm-dis\b",
|
r"\bllvm-dis\b",
|
||||||
r"\bllvm-dwarfdump\b",
|
r"\bllvm-dwarfdump\b",
|
||||||
r"\bllvm-extract\b",
|
r"\bllvm-extract\b",
|
||||||
|
r"\bllvm-go\b",
|
||||||
r"\bllvm-link\b",
|
r"\bllvm-link\b",
|
||||||
r"\bllvm-lto\b",
|
r"\bllvm-lto\b",
|
||||||
r"\bllvm-mc\b",
|
r"\bllvm-mc\b",
|
||||||
|
|
|
@ -52,6 +52,8 @@ add_llvm_tool_subdirectory(llvm-c-test)
|
||||||
add_llvm_tool_subdirectory(obj2yaml)
|
add_llvm_tool_subdirectory(obj2yaml)
|
||||||
add_llvm_tool_subdirectory(yaml2obj)
|
add_llvm_tool_subdirectory(yaml2obj)
|
||||||
|
|
||||||
|
add_llvm_tool_subdirectory(llvm-go)
|
||||||
|
|
||||||
if(NOT CYGWIN AND LLVM_ENABLE_PIC)
|
if(NOT CYGWIN AND LLVM_ENABLE_PIC)
|
||||||
add_llvm_tool_subdirectory(lto)
|
add_llvm_tool_subdirectory(lto)
|
||||||
add_llvm_tool_subdirectory(llvm-lto)
|
add_llvm_tool_subdirectory(llvm-lto)
|
||||||
|
|
|
@ -74,4 +74,8 @@ ifneq ($(ENABLE_SHARED),1)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter go,$(BINDINGS_TO_BUILD)))
|
||||||
|
PARALLEL_DIRS += llvm-go
|
||||||
|
endif
|
||||||
|
|
||||||
include $(LEVEL)/Makefile.common
|
include $(LEVEL)/Makefile.common
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
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()
|
|
@ -0,0 +1,16 @@
|
||||||
|
##===- tools/llvm-go/Makefile ------------------------------*- Makefile -*-===##
|
||||||
|
#
|
||||||
|
# The LLVM Compiler Infrastructure
|
||||||
|
#
|
||||||
|
# This file is distributed under the University of Illinois Open Source
|
||||||
|
# License. See LICENSE.TXT for details.
|
||||||
|
#
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
|
LEVEL := ../..
|
||||||
|
include $(LEVEL)/Makefile.common
|
||||||
|
|
||||||
|
all:: $(ToolDir)/llvm-go$(EXEEXT)
|
||||||
|
|
||||||
|
$(ToolDir)/llvm-go$(EXEEXT): $(PROJ_SRC_DIR)/llvm-go.go
|
||||||
|
$(GO) build -o $@ $<
|
|
@ -0,0 +1,261 @@
|
||||||
|
//===-- llvm-go.go - go tool wrapper for LLVM -----------------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
)
|
||||||
|
|
||||||
|
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",
|
||||||
|
"debuginfo",
|
||||||
|
"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 == "" {
|
||||||
|
// strip llvm-go, add llvm-config
|
||||||
|
configpath = os.Args[0][:len(os.Args[0])-7] + "llvm-config"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(configpath, args...)
|
||||||
|
out, err := cmd.Output()
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
outstr := string(out)
|
||||||
|
outstr = strings.TrimSuffix(outstr, "\n")
|
||||||
|
return strings.Replace(outstr, "\n", " ", -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func llvmFlags() compilerFlags {
|
||||||
|
ldflags := llvmConfig(append([]string{"--ldflags", "--libs", "--system-libs"}, components...)...)
|
||||||
|
if runtime.GOOS != "darwin" {
|
||||||
|
// OS X doesn't like -rpath with cgo. See:
|
||||||
|
// https://code.google.com/p/go/issues/detail?id=7293
|
||||||
|
ldflags = "-Wl,-rpath," + llvmConfig("--libdir") + " " + ldflags
|
||||||
|
}
|
||||||
|
return compilerFlags{
|
||||||
|
cpp: llvmConfig("--cppflags"),
|
||||||
|
cxx: "-std=c++11",
|
||||||
|
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, cppflags, cxxflags, ldflags string) {
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.Symlink(filepath.Join(srcdir, p.llvmpath), path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
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, "GOPATH=") {
|
||||||
|
newenv = append(newenv, v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gocmdpath, err := exec.LookPath("go")
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
proc, err := os.StartProcess(gocmdpath, append([]string{"go"}, 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")
|
||||||
|
|
||||||
|
args := os.Args[1:]
|
||||||
|
DONE: for {
|
||||||
|
switch {
|
||||||
|
case len(args) == 0:
|
||||||
|
usage()
|
||||||
|
case strings.HasPrefix(args[0], "cc="):
|
||||||
|
cc = args[0][3:]
|
||||||
|
args = args[1:]
|
||||||
|
case strings.HasPrefix(args[0], "cxx="):
|
||||||
|
cxx = args[0][4:]
|
||||||
|
args = args[1:]
|
||||||
|
case strings.HasPrefix(args[0], "cppflags="):
|
||||||
|
cppflags = args[0][9:]
|
||||||
|
args = args[1:]
|
||||||
|
case strings.HasPrefix(args[0], "cxxflags="):
|
||||||
|
cxxflags = args[0][9:]
|
||||||
|
args = args[1:]
|
||||||
|
case strings.HasPrefix(args[0], "ldflags="):
|
||||||
|
ldflags = args[0][8:]
|
||||||
|
args = args[1:]
|
||||||
|
default:
|
||||||
|
break DONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch args[0] {
|
||||||
|
case "build", "get", "install", "run", "test":
|
||||||
|
runGoWithLLVMEnv(args, cc, cxx, cppflags, cxxflags, ldflags)
|
||||||
|
case "print-components":
|
||||||
|
printComponents()
|
||||||
|
case "print-config":
|
||||||
|
printConfig()
|
||||||
|
default:
|
||||||
|
usage()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue