Build cgo and llgo-go

Differential Revision: http://reviews.llvm.org/D7629

llvm-svn: 229211
GitOrigin-RevId: 7ddf832e0e35f8c461711ae4fedb3590e85b2525
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e9b6bc5..3b55ca4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,17 +40,82 @@
   ssaopt/esc.go
 )
 
+string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" LLGO_VERSION
+  ${PACKAGE_VERSION})
+
+configure_file(
+  cmd/go/zdefaultcc.go.in
+  ${CMAKE_CURRENT_BINARY_DIR}/cmd/go/zdefaultcc.go)
+
+set(LLGO_GO_SOURCES
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/build.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/clean.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/context.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/discovery.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/doc.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/env.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/fix.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/fmt.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/get.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/go11.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/help.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/http.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/list.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/main.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/pkg.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/run.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/signal.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/signal_unix.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/testflag.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/test.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/tool.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/vcs.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/version.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/go/vet.go
+  ${CMAKE_CURRENT_BINARY_DIR}/cmd/go/zdefaultcc.go
+)
+
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/llgo-go
+  COMMAND ${CMAKE_BINARY_DIR}/bin/llgo -static-libgo -o ${CMAKE_BINARY_DIR}/bin/llgo-go
+          ${LLGO_GO_SOURCES}
+  DEPENDS llgo libgo ${LLGO_GO_SOURCES}
+  COMMENT "Building Go executable llgo-go"
+  VERBATIM)
+add_custom_target(llgo-go ALL DEPENDS ${CMAKE_BINARY_DIR}/bin/llgo-go)
+
+set(LLGO_CGO_SOURCES
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/ast.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/doc.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/gcc.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/godefs.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/main.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/out.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gofrontend/libgo/go/cmd/cgo/util.go
+  ${CMAKE_CURRENT_SOURCE_DIR}/cmd/cgo/zdefaultcc.go
+)
+
+add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/lib/go/llgo-${LLGO_VERSION}/cgo
+  COMMAND ${CMAKE_BINARY_DIR}/bin/llgo -static-libgo
+          -o ${CMAKE_BINARY_DIR}/lib/go/llgo-${LLGO_VERSION}/cgo
+          ${LLGO_CGO_SOURCES}
+  DEPENDS llgo libgo ${LLGO_CGO_SOURCES}
+  COMMENT "Building Go executable cgo"
+  VERBATIM)
+add_custom_target(cgo ALL DEPENDS ${CMAKE_BINARY_DIR}/lib/go/llgo-${LLGO_VERSION}/cgo)
+
 llvm_add_go_executable(llgo-stage2 llvm.org/llgo/cmd/gllgo
   DEPENDS libgo ${CMAKE_BINARY_DIR}/bin/llgo${CMAKE_EXECUTABLE_SUFFIX}
+          ${CMAKE_BINARY_DIR}/bin/llgo-go${CMAKE_EXECUTABLE_SUFFIX}
   GOFLAGS "cc=${CMAKE_BINARY_DIR}/bin/clang"
           "cxx=${CMAKE_BINARY_DIR}/bin/clang++"
-          "llgo=${CMAKE_BINARY_DIR}/bin/llgo${CMAKE_EXECUTABLE_SUFFIX}"
+          "go=${CMAKE_BINARY_DIR}/bin/llgo-go"
 )
 
 llvm_add_go_executable(llgo-stage3 llvm.org/llgo/cmd/gllgo
   DEPENDS libgo ${CMAKE_BINARY_DIR}/bin/llgo-stage2${CMAKE_EXECUTABLE_SUFFIX}
   GOFLAGS "cc=${CMAKE_BINARY_DIR}/bin/clang"
           "cxx=${CMAKE_BINARY_DIR}/bin/clang++"
+          "go=${CMAKE_BINARY_DIR}/bin/llgo-go"
           "llgo=${CMAKE_BINARY_DIR}/bin/llgo-stage2${CMAKE_EXECUTABLE_SUFFIX}"
 )
 
@@ -60,11 +125,12 @@
 
 llvm_add_go_executable(llgoi llvm.org/llgo/cmd/llgoi
   DEPENDS libgo ${CMAKE_BINARY_DIR}/bin/llgo${CMAKE_EXECUTABLE_SUFFIX}
+          ${CMAKE_BINARY_DIR}/bin/llgo-go${CMAKE_EXECUTABLE_SUFFIX}
           cmd/llgoi/isatty_posix.go
           cmd/llgoi/llgoi.go
   GOFLAGS "cc=${CMAKE_BINARY_DIR}/bin/clang"
           "cxx=${CMAKE_BINARY_DIR}/bin/clang++"
-          "llgo=${CMAKE_BINARY_DIR}/bin/llgo${CMAKE_EXECUTABLE_SUFFIX}"
+          "go=${CMAKE_BINARY_DIR}/bin/llgo-go"
 )
 
 install(FILES ${CMAKE_BINARY_DIR}/bin/llgo${CMAKE_EXECUTABLE_SUFFIX}
diff --git a/cmd/cgo/zdefaultcc.go b/cmd/cgo/zdefaultcc.go
new file mode 100644
index 0000000..8db2769
--- /dev/null
+++ b/cmd/cgo/zdefaultcc.go
@@ -0,0 +1,46 @@
+//===- zdefaultcc.go - default compiler locations -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a default location for cc.
+//
+//===----------------------------------------------------------------------===//
+
+package main
+
+import (
+	"path/filepath"
+	"os"
+	"os/exec"
+)
+
+var defaultCC string
+
+func getInstPrefix() (string, error) {
+	path, err := exec.LookPath(os.Args[0])
+	if err != nil {
+		return "", err
+	}
+
+	path, err = filepath.EvalSymlinks(path)
+	if err != nil {
+		return "", err
+	}
+
+	prefix := filepath.Join(path, "..", "..", "..", "..")
+	return prefix, nil
+}
+
+func init() {
+	prefix, err := getInstPrefix()
+	if err != nil {
+		panic(err.Error())
+	}
+
+	defaultCC = filepath.Join(prefix, "bin", "clang")
+}
diff --git a/cmd/go/zdefaultcc.go.in b/cmd/go/zdefaultcc.go.in
new file mode 100644
index 0000000..2ca6c94
--- /dev/null
+++ b/cmd/go/zdefaultcc.go.in
@@ -0,0 +1,55 @@
+//===- zdefaultcc.go - default compiler locations -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides default locations for cc, cxx and llgo.
+//
+//===----------------------------------------------------------------------===//
+
+package main
+
+import (
+	"path/filepath"
+	"os"
+	"os/exec"
+)
+
+var defaultGCCGO, defaultCC, defaultCXX string
+
+func getInstPrefix() (string, error) {
+	path, err := exec.LookPath(os.Args[0])
+	if err != nil {
+		return "", err
+	}
+
+	path, err = filepath.EvalSymlinks(path)
+	if err != nil {
+		return "", err
+	}
+
+	prefix := filepath.Join(path, "..", "..")
+	return prefix, nil
+}
+
+func init() {
+	prefix, err := getInstPrefix()
+	if err != nil {
+		panic(err.Error())
+	}
+
+	defaultCC = filepath.Join(prefix, "bin", "clang")
+	defaultCXX = filepath.Join(prefix, "bin", "clang++")
+	defaultGCCGO = filepath.Join(prefix, "bin", "llgo")
+	toolDir = filepath.Join(prefix, "lib", "go", "llgo-@LLGO_VERSION@")
+
+	gccgoName = os.Getenv("GCCGO")
+	if gccgoName == "" {
+		gccgoName = defaultGCCGO
+	}
+	gccgoBin, _ = exec.LookPath(gccgoName)
+}