[llvm] r220462 - Add llvm-go tool.
Peter Collingbourne
peter at pcc.me.uk
Wed Oct 22 19:33:23 PDT 2014
Author: pcc
Date: Wed Oct 22 21:33:23 2014
New Revision: 220462
URL: http://llvm.org/viewvc/llvm-project?rev=220462&view=rev
Log:
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
Added:
llvm/trunk/tools/llvm-go/
llvm/trunk/tools/llvm-go/CMakeLists.txt
llvm/trunk/tools/llvm-go/Makefile
llvm/trunk/tools/llvm-go/llvm-go.go
Modified:
llvm/trunk/bindings/go/build.sh
llvm/trunk/cmake/config-ix.cmake
llvm/trunk/test/Bindings/Go/go.test
llvm/trunk/test/CMakeLists.txt
llvm/trunk/test/lit.cfg
llvm/trunk/tools/CMakeLists.txt
llvm/trunk/tools/Makefile
Modified: llvm/trunk/bindings/go/build.sh
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/go/build.sh?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/bindings/go/build.sh (original)
+++ llvm/trunk/bindings/go/build.sh Wed Oct 22 21:33:23 2014
@@ -1,36 +1,5 @@
#!/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
workdir=$gollvmdir/workdir
@@ -41,12 +10,14 @@ mkdir -p $llvm_builddir
cmake_flags="../../../../.. $@"
llvm_config="$llvm_builddir/bin/llvm-config"
+llvm_go="$llvm_builddir/bin/llvm-go"
if test -n "`which ninja`" ; then
# If Ninja is available, we can speed up the build by building only the
# required subset of LLVM.
(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')"
ninja -C $llvm_builddir $llvm_buildtargets FileCheck
else
@@ -54,14 +25,7 @@ else
make -C $llvm_builddir -j4
fi
+$llvm_go print-config > $gollvmdir/llvm_config.go
+
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
Modified: llvm/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/cmake/config-ix.cmake?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/cmake/config-ix.cmake (original)
+++ llvm/trunk/cmake/config-ix.cmake Wed Oct 22 21:33:23 2014
@@ -493,16 +493,20 @@ else()
endif()
set(LLVM_BINDINGS "")
-find_program(GO_EXECUTABLE NAMES go DOC "go executable")
-if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
+if(WIN32)
message(STATUS "Go bindings disabled.")
else()
- 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.")
+ find_program(GO_EXECUTABLE NAMES go DOC "go executable")
+ if(GO_EXECUTABLE STREQUAL "GO_EXECUTABLE-NOTFOUND")
+ message(STATUS "Go bindings disabled.")
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()
Modified: llvm/trunk/test/Bindings/Go/go.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Bindings/Go/go.test?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/test/Bindings/Go/go.test (original)
+++ llvm/trunk/test/Bindings/Go/go.test Wed Oct 22 21:33:23 2014
@@ -1,8 +1,3 @@
-; RUN: cd %S/../../../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 .
+; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
; REQUIRES: shell
Modified: llvm/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/test/CMakeLists.txt (original)
+++ llvm/trunk/test/CMakeLists.txt Wed Oct 22 21:33:23 2014
@@ -30,8 +30,9 @@ set(LLVM_TEST_DEPENDS
llvm-cov
llvm-diff
llvm-dis
- llvm-extract
llvm-dwarfdump
+ llvm-extract
+ llvm-go
llvm-link
llvm-lto
llvm-mc
Modified: llvm/trunk/test/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/test/lit.cfg (original)
+++ llvm/trunk/test/lit.cfg Wed Oct 22 21:33:23 2014
@@ -200,6 +200,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
r"\bllvm-dis\b",
r"\bllvm-dwarfdump\b",
r"\bllvm-extract\b",
+ r"\bllvm-go\b",
r"\bllvm-link\b",
r"\bllvm-lto\b",
r"\bllvm-mc\b",
Modified: llvm/trunk/tools/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/CMakeLists.txt?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/tools/CMakeLists.txt (original)
+++ llvm/trunk/tools/CMakeLists.txt Wed Oct 22 21:33:23 2014
@@ -52,6 +52,8 @@ add_llvm_tool_subdirectory(llvm-c-test)
add_llvm_tool_subdirectory(obj2yaml)
add_llvm_tool_subdirectory(yaml2obj)
+add_llvm_tool_subdirectory(llvm-go)
+
if(NOT CYGWIN AND LLVM_ENABLE_PIC)
add_llvm_tool_subdirectory(lto)
add_llvm_tool_subdirectory(llvm-lto)
Modified: llvm/trunk/tools/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/Makefile?rev=220462&r1=220461&r2=220462&view=diff
==============================================================================
--- llvm/trunk/tools/Makefile (original)
+++ llvm/trunk/tools/Makefile Wed Oct 22 21:33:23 2014
@@ -74,4 +74,8 @@ ifneq ($(ENABLE_SHARED),1)
endif
endif
+ifneq (,$(filter go,$(BINDINGS_TO_BUILD)))
+ PARALLEL_DIRS += llvm-go
+endif
+
include $(LEVEL)/Makefile.common
Added: llvm/trunk/tools/llvm-go/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-go/CMakeLists.txt?rev=220462&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-go/CMakeLists.txt (added)
+++ llvm/trunk/tools/llvm-go/CMakeLists.txt Wed Oct 22 21:33:23 2014
@@ -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()
Added: llvm/trunk/tools/llvm-go/Makefile
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-go/Makefile?rev=220462&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-go/Makefile (added)
+++ llvm/trunk/tools/llvm-go/Makefile Wed Oct 22 21:33:23 2014
@@ -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 $@ $<
Added: llvm/trunk/tools/llvm-go/llvm-go.go
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-go/llvm-go.go?rev=220462&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-go/llvm-go.go (added)
+++ llvm/trunk/tools/llvm-go/llvm-go.go Wed Oct 22 21:33:23 2014
@@ -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()
+ }
+}
More information about the llvm-commits
mailing list