gollvm: initial cmake rules for gotools (cmd/go etc)
Initial rules for building the gotools programs. Does not
include check target yet.
Change-Id: I288efc7616d4acceb3a4b2f4bf2426de273627ae
Reviewed-on: https://go-review.googlesource.com/92615
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 24520dc..9f73ae4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -90,3 +90,6 @@
# Go standard library
add_subdirectory(libgo)
+
+# Go tools (go, gofmt, etc)
+add_subdirectory(gotools)
diff --git a/cmake/AutoGenGo.cmake b/cmake/AutoGenGo.cmake
index 931dd2d..c32d614 100644
--- a/cmake/AutoGenGo.cmake
+++ b/cmake/AutoGenGo.cmake
@@ -267,25 +267,45 @@
#
# Unnamed parameters:
#
+# * package to use for generated Go code
# * output file to target
# * path to gollvm driver binary
# * C compiler path
# * C++ compiler path
#
-function(mkzdefaultcc outfile driverpath ccpath cxxpath)
+# Named parameters:
+#
+# EXPORT Generated public functions (ex: DefaultCC not defaultCC).
+#
+function(mkzdefaultcc package outfile driverpath ccpath cxxpath)
+ CMAKE_PARSE_ARGUMENTS(ARG "EXPORT" "" "" ${ARGN})
+
file(REMOVE ${outfile})
- file(WRITE ${outfile} "package cfg\n\n")
+ file(WRITE ${outfile} "package ${package}\n\n")
# FIXME: once again, this is a problematic function since in theory
# we don't yet know yet where things are going to be installed. For
# the time being, just use that paths of the host build C/C++
# compiler and the gollvm driver executable.
- file(APPEND ${outfile} "func DefaultGCCGO(goos, goarch string) string { return \"${driverpath}\" }\n")
- file(APPEND ${outfile} "func DefaultCC(goos, goarch string) string { return \"${ccpath}\" }\n")
- file(APPEND ${outfile} "func DefaultCXX(goos, goarch string) string { return \"${cxxpath}\" }\n")
- file(APPEND ${outfile} "const DefaultPkgConfig = \"pkg-config\"\n")
- file(APPEND ${outfile} "var OSArchSupportsCgo = map[string]bool{}\n")
+ set(f1 "defaultGCCGO")
+ set(f2 "defaultCC")
+ set(f3 "defaultCXX")
+ set(f4 "defaultPkgConfig")
+ set(v1 "oSArchSupportsCgo")
+ if( ${ARG_EXPORT} )
+ upperfirst(${f1} "f1")
+ upperfirst(${f2} "f2")
+ upperfirst(${f3} "f3")
+ upperfirst(${f4} "f4")
+ upperfirst(${v1} "v1")
+ endif()
+
+ file(APPEND ${outfile} "func ${f1}(goos, goarch string) string { return \"${driverpath}\" }\n")
+ file(APPEND ${outfile} "func ${f2}(goos, goarch string) string { return \"${ccpath}\" }\n")
+ file(APPEND ${outfile} "func ${f3}(goos, goarch string) string { return \"${cxxpath}\" }\n")
+ file(APPEND ${outfile} "const ${f4} = \"pkg-config\"\n")
+ file(APPEND ${outfile} "var ${v1} = map[string]bool{}\n")
endfunction()
#----------------------------------------------------------------------
diff --git a/cmake/GoProgram.cmake b/cmake/GoProgram.cmake
new file mode 100644
index 0000000..09ad398
--- /dev/null
+++ b/cmake/GoProgram.cmake
@@ -0,0 +1,49 @@
+
+# This function adds a target for a specific Go program (executable),
+# for example "gofmt" or "cgo".
+#
+# Example usage:
+#
+# add_go_program(name target libgodir destdir
+# GOSRC .../x.go .../y.go ... GOLIB abc.a foo.so ...)
+#
+# Unnamed parameters:
+#
+# * Program name, e.g. "gofmt"
+# * Target name, e.g. "gotools_cmd_go"
+# * Directory containing libgo build artifacts (ex: runtime.o)
+# * Destination directory for program build artifacts (e.g. executable)
+#
+# Named parameters:
+#
+# GOSRC Full paths of go source files to build.
+# GOLIB Libraries to link against.
+# GODEP Targets on which this program should be dependent.
+# GOCFLAGS Additional arguments passed to Go compiler.
+
+function(add_go_program progname target libgodir destdir)
+ CMAKE_PARSE_ARGUMENTS(ARG "" "" "GOSRC;GOLIB;GODEP;GOCFLAGS" ${ARGN})
+
+ # Target of build
+ set(program_exe "${destdir}/${progname}")
+
+ # Deps
+ set(deps ${ARG_GOSRC})
+ list(APPEND deps ${ARG_GODEP})
+
+ # Command to build executable.
+ add_custom_command(
+ OUTPUT ${program_exe}
+ COMMAND "${gocompiler}" "-o" ${program_exe} ${ARG_GOSRC} ${ARG_GOCFLAGS}
+ -I ${libgodir} -L ${libgodir} ${ARG_GOLIB}
+ DEPENDS ${deps}
+ COMMENT "Building go program ${progname}"
+ VERBATIM)
+
+ # Create target
+ add_custom_target(${target} ALL DEPENDS ${program_exe})
+ set_target_properties(${target} PROPERTIES FOLDER "Tools")
+
+ # TODO: add install rules
+
+endfunction()
diff --git a/gotools/CMakeLists.txt b/gotools/CMakeLists.txt
new file mode 100644
index 0000000..1eaa67e
--- /dev/null
+++ b/gotools/CMakeLists.txt
@@ -0,0 +1,88 @@
+
+# Gotools build requires libgo; if libgo is stubbed out then don't
+# try to build gotools either.
+
+if(DISABLE_LIBGO_BUILD)
+ return()
+endif()
+
+include(GoProgram)
+
+message(STATUS "starting gotools configuration.")
+
+include(GoVars)
+
+# FIXME: rewrite this to locate llvm-goparse in a more official way
+# set(driver "${bin}/../bin/llvm-goparse")
+get_target_property(driverdir llvm-goparse RUNTIME_OUTPUT_DIRECTORY)
+set(gollvm_driver "${driverdir}/llvm-goparse")
+#set(gocompiler ${gollvm_driver})
+
+# FIXME: still need to use wrapper for compilation, since
+# llvm-goparse functionality not yet complete.
+set(gocompiler "gccgo")
+
+set(cmd_srcroot "${GOLLVM_SOURCE_DIR}/gofrontend/libgo/go/cmd")
+
+set(gotools_binroot "${CMAKE_CURRENT_BINARY_DIR}")
+set(libgo_binroot "${CMAKE_CURRENT_BINARY_DIR}/../libgo")
+
+set(libgotool_archive "${libgo_binroot}/libgotool.a")
+
+# Cgo needs a copy of the defaultCC function.
+set(cgozdefaultccdotgo "${gotools_binroot}/zdefaultcc.go")
+set(cgozdefaultcctmp "${gotools_binroot}/zdefaultcc.go.tmp")
+mkzdefaultcc("main" ${cgozdefaultcctmp} ${gollvm_driver}
+ ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER})
+copy_if_different(${cgozdefaultcctmp} ${cgozdefaultccdotgo})
+
+set(libgo_scriptroot "${GOLLVM_SOURCE_DIR}/gofrontend/libgo")
+set(matchdotsh "${libgo_scriptroot}/match.sh")
+
+set(cgo_extra_go_files "${cgozdefaultccdotgo}")
+
+# Loop over each of the tools of interest.
+set(tools "go" "gofmt" "cgo" "vet" "buildid" "test2json")
+set(allgotools)
+foreach(tool ${tools})
+
+ # Check for tool dir
+ if(NOT EXISTS "${cmd_srcroot}/${tool}")
+ message(SEND_ERROR "Go tool directory ${tool} does not exist.")
+ else()
+ set(tool_target "gotools_cmd_${tool}")
+
+ # Invoke match.sh to collect Go files of interest for this
+ # tool, via shell script. Read result into variable.
+ execute_process(COMMAND "${shell}" "${matchdotsh}"
+ "--goarch=${goarch}" "--goos=${goos}"
+ "--srcdir=${cmd_srcroot}/${tool}"
+ OUTPUT_VARIABLE toolfiles
+ ERROR_VARIABLE errmsg
+ RESULT_VARIABLE exitstatus)
+ if(NOT ${exitstatus} MATCHES 0)
+ message(FATAL_ERROR "match.sh invocation failed: ${errmsg}")
+ endif()
+ string(STRIP ${toolfiles} toolfiles)
+ separate_arguments(toolfiles)
+
+ # Incorporate extras.
+ if(NOT "${${tool}_extra_go_files}" STREQUAL "")
+ list(APPEND toolfiles "${${tool}_extra_go_files}")
+ endif()
+
+ # Create target for program.
+ add_go_program(${tool} ${tool_target}
+ ${libgo_binroot} ${gotools_binroot}
+ GOSRC ${toolfiles}
+ GOLIB ${libgotool_archive}
+ GODEP libgotool libgo_shared libgo_static)
+ list(APPEND allgotools ${tool_target})
+ endif()
+endforeach()
+
+add_custom_target(gotools_all DEPENDS ${allgotools})
+
+# FIXME: add install rules
+
+message(STATUS "gotools configuration complete.")
diff --git a/libgo/CMakeLists.txt b/libgo/CMakeLists.txt
index dd15b20..e679320 100644
--- a/libgo/CMakeLists.txt
+++ b/libgo/CMakeLists.txt
@@ -192,11 +192,10 @@
# Rules for zdefaultcc.go
set(zdefaultccdotgo "${libgo_binroot}/zdefaultcc.go")
set(zdefaultcctmp "${libgo_binroot}/zdefaultcc.go.tmp")
-mkzdefaultcc(${zdefaultcctmp} ${gollvm_driver}
- ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER})
+mkzdefaultcc("cfg" ${zdefaultcctmp} ${gollvm_driver}
+ ${CMAKE_C_COMPILER} ${CMAKE_CXX_COMPILER} EXPORT)
copy_if_different(${zdefaultcctmp} ${zdefaultccdotgo})
-
# FIXME: Use a rule that copies in an archived copy of this source
# file, since for the moment there is no clang support for the
# -fdump-go-spec option (better to implement that as a bitcode pass,