You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/03/19 01:09:34 UTC

[14/19] lucy-clownfish git commit: Install .cfh and static lib under $GOPATH/pkg.

Install .cfh and static lib under $GOPATH/pkg.

*   Install C static archive into $GOPATH/pkg/$PACKAGE/_lib/
*   Install .cfh headers into a main include directory, also under `pkg`.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/063b499e
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/063b499e
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/063b499e

Branch: refs/heads/master
Commit: 063b499ec701883acffac02f8db9a2b42ae679b3
Parents: cd5158c
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Mon Nov 10 09:11:03 2014 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Sun Mar 15 19:01:11 2015 -0700

----------------------------------------------------------------------
 compiler/go/build.go   | 59 ++++++++++++++++++++++++++++++++++----
 compiler/go/cfc/cfc.go | 38 +++++++++++++++++++++++++
 runtime/go/build.go    | 69 +++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 158 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/063b499e/compiler/go/build.go
----------------------------------------------------------------------
diff --git a/compiler/go/build.go b/compiler/go/build.go
index d4a585b..80612f5 100644
--- a/compiler/go/build.go
+++ b/compiler/go/build.go
@@ -20,11 +20,13 @@ package main
 
 import "flag"
 import "fmt"
+import "io"
 import "io/ioutil"
 import "log"
 import "os"
 import "os/exec"
 import "path"
+import "path/filepath"
 import "runtime"
 
 var packageName string = "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/compiler/go/cfc"
@@ -34,11 +36,24 @@ var charmonyH string = "charmony.h"
 var buildDir string
 var buildGO string
 var configGO string
+var installDir string
+var cfIncludeDir string
 
 func init() {
 	_, buildGO, _, _ = runtime.Caller(1)
 	buildDir = path.Dir(buildGO)
 	configGO = path.Join(buildDir, "cfc", "config.go")
+
+	// Compute include dir for clownfish headers.
+	goPathDirs := filepath.SplitList(os.Getenv("GOPATH"))
+	if len(goPathDirs) == 0 {
+		log.Fatal("GOPATH environment variable not set")
+	}
+	commonDir := path.Join(goPathDirs[0], "pkg",
+		runtime.GOOS+"_"+runtime.GOARCH, "git-wip-us.apache.org", "repos",
+		"asf", "lucy-clownfish.git")
+	cfIncludeDir = path.Join(commonDir, "_include")
+	installDir = path.Join(commonDir, "compiler", "go", "cfc")
 }
 
 func main() {
@@ -118,23 +133,57 @@ func test() {
 	runCommand("go", "test", packageName)
 }
 
+func makePath(dir string) {
+	if _, err := os.Stat(dir); os.IsNotExist(err) {
+		err = os.MkdirAll(dir, 0755)
+		if err != nil {
+			log.Fatalf("Can't create dir '%s': %s", dir, err)
+		}
+	}
+}
+
+func copyFile(source, dest string) {
+	sourceFH, err := os.Open(source)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer sourceFH.Close()
+	destFH, err := os.Create(dest)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer destFH.Close()
+	_, err = io.Copy(destFH, sourceFH)
+	if err != nil {
+		log.Fatalf("io.Copy from %s to %s failed: %s", source, dest, err)
+	}
+}
+
 func install() {
 	prep()
 	runCommand("go", "install", packageName)
+	makePath(cfIncludeDir)
+	installedLibDir := path.Join(installDir, "_lib")
+	makePath(installedLibDir)
+	installedLibPath := path.Join(installedLibDir, "libcfc.a")
+	copyFile("libcfc.a", installedLibPath)
 }
 
 func writeConfigGO() {
 	if current(buildGO, configGO) {
 		return
 	}
-	libPath := path.Join(buildDir, "libcfc.a")
+	installedLibDir := path.Join(installDir, "_lib")
 	content := fmt.Sprintf(
-		"// Auto-generated by build.go, specifying absolute path to static lib.\n"+
+		"// Auto-generated by build.go\n"+
 			"package cfc\n"+
 			"// #cgo CFLAGS: -I%s/../include -I%s/../src -I%s\n"+
-			"// #cgo LDFLAGS: %s\n"+
-			"import \"C\"\n",
-		buildDir, buildDir, buildDir, libPath)
+			"// #cgo LDFLAGS: -L%s\n"+
+			"// #cgo LDFLAGS: -L%s\n"+
+			"// #cgo LDFLAGS: -lcfc\n"+
+			"import \"C\"\n"+
+			"var mainIncDir string = \"%s\"\n",
+		buildDir, buildDir, buildDir, buildDir, installedLibDir, cfIncludeDir)
 	ioutil.WriteFile(configGO, []byte(content), 0666)
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/063b499e/compiler/go/cfc/cfc.go
----------------------------------------------------------------------
diff --git a/compiler/go/cfc/cfc.go b/compiler/go/cfc/cfc.go
index 6533a0a..fb38bfb 100644
--- a/compiler/go/cfc/cfc.go
+++ b/compiler/go/cfc/cfc.go
@@ -22,9 +22,46 @@ package cfc
 // #include <stdlib.h>
 import "C"
 
+import "os"
+import "path"
+import "path/filepath"
 import "runtime"
+import "strings"
 import "unsafe"
 
+// Return the path of the main include directory holding clownfish parcel and
+// header files.
+func MainIncludeDir() string {
+	return mainIncDir
+}
+
+type CFCError struct {
+	mess string
+}
+
+func (e CFCError) Error() string {
+	return e.mess
+}
+
+// Given a package name for a Clownfish parcel with Go bindings, return the
+// install path for its C static archive.
+//
+// TODO: It would be better if we could embed the C archive contents within
+// the installed Go archive.
+func InstalledLibPath(packageName string) (string, error) {
+	goPathDirs := filepath.SplitList(os.Getenv("GOPATH"))
+	if len(goPathDirs) == 0 {
+		return "", CFCError{"GOPATH environment variable not set"}
+	}
+	packageParts := strings.Split(packageName, "/")
+	filename := "lib" + packageParts[len(packageParts)-1] + ".a"
+	parts := []string{goPathDirs[0], "pkg"}
+	parts = append(parts, runtime.GOOS+"_"+runtime.GOARCH)
+	parts = append(parts, packageParts...)
+	parts = append(parts, "_lib", filename)
+	return path.Join(parts...), nil
+}
+
 func DoStuff() {
 	hierarchy := NewHierarchy("autogen")
 	hierarchy.Build()
@@ -46,6 +83,7 @@ func NewHierarchy(dest string) Hierarchy {
 	destCString := C.CString(dest)
 	defer C.free(unsafe.Pointer(destCString))
 	obj := Hierarchy{C.CFCHierarchy_new(destCString)}
+	obj.AddIncludeDir(mainIncDir)
 	runtime.SetFinalizer(&obj, (*Hierarchy).RunDecRef)
 	return obj
 }

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/063b499e/runtime/go/build.go
----------------------------------------------------------------------
diff --git a/runtime/go/build.go b/runtime/go/build.go
index 269290b..8411504 100644
--- a/runtime/go/build.go
+++ b/runtime/go/build.go
@@ -20,11 +20,14 @@ package main
 
 import "flag"
 import "fmt"
+import "io"
 import "io/ioutil"
 import "log"
 import "os"
 import "os/exec"
 import "path"
+import "path/filepath"
+import "strings"
 import "runtime"
 
 import "git-wip-us.apache.org/repos/asf/lucy-clownfish.git/compiler/go/cfc"
@@ -36,11 +39,17 @@ var charmonyH string = "charmony.h"
 var buildDir string
 var buildGO string
 var configGO string
+var installedLibPath string
 
 func init() {
 	_, buildGO, _, _ = runtime.Caller(1)
 	buildDir = path.Dir(buildGO)
 	configGO = path.Join(buildDir, "clownfish", "config.go")
+	var err error
+	installedLibPath, err = cfc.InstalledLibPath(packageName)
+	if err != nil {
+		log.Fatal(err)
+	}
 }
 
 func main() {
@@ -124,6 +133,7 @@ func prep() {
 	runCFC()
 	runCommand("make", "-j", "static")
 	writeConfigGO()
+	runCommand("go", "build", packageName)
 }
 
 func build() {
@@ -136,25 +146,78 @@ func test() {
 	runCommand("go", "test", packageName)
 }
 
+func copyFile(source, dest string) {
+	sourceFH, err := os.Open(source)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer sourceFH.Close()
+	destFH, err := os.Create(dest)
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer destFH.Close()
+	_, err = io.Copy(destFH, sourceFH)
+	if err != nil {
+		log.Fatalf("io.Copy from %s to %s failed: %s", source, dest, err)
+	}
+}
+
+func installHeaders() {
+	coreDir := "../core"
+	incDir := cfc.MainIncludeDir()
+	doInstall := func(source string, info os.FileInfo, err error) error {
+		if strings.HasSuffix(source, ".cfp") || strings.HasSuffix(source, ".cfh") {
+			dest := path.Join(incDir, strings.TrimPrefix(source, coreDir))
+			destDir := path.Dir(dest)
+			if _, err := os.Stat(destDir); os.IsNotExist(err) {
+				err = os.MkdirAll(destDir, 0755)
+				if err != nil {
+					log.Fatalf("Can't create dir '%s': %s", destDir, err)
+				}
+			}
+			os.Remove(dest)
+			copyFile(source, dest)
+		}
+		return nil
+	}
+	filepath.Walk("../core", doInstall)
+}
+
+func installStaticLib() {
+	tempLibPath := path.Join(buildDir, "libclownfish.a")
+	destDir := path.Dir(installedLibPath)
+	if _, err := os.Stat(destDir); os.IsNotExist(err) {
+		err = os.MkdirAll(destDir, 0755)
+		if err != nil {
+			log.Fatalf("Can't create dir '%s': %s", destDir, err)
+		}
+	}
+	os.Remove(installedLibPath)
+	copyFile(tempLibPath, installedLibPath)
+}
+
 func install() {
 	prep()
 	runCommand("go", "install", packageName)
+	installHeaders()
+	installStaticLib()
 }
 
 func writeConfigGO() {
 	if current(buildGO, configGO) {
 		return
 	}
-	libPath := path.Join(buildDir, "libcfish.a")
 	content := fmt.Sprintf(
 		"// Auto-generated by build.go, specifying absolute path to static lib.\n"+
 			"package clownfish\n"+
 			"// #cgo CFLAGS: -I%s/../core\n"+
 			"// #cgo CFLAGS: -I%s\n"+
 			"// #cgo CFLAGS: -I%s/autogen/include\n"+
-			"// #cgo LDFLAGS: %s\n"+
+			"// #cgo LDFLAGS: -L%s\n"+
+			"// #cgo LDFLAGS: -lclownfish\n"+
 			"import \"C\"\n",
-		buildDir, buildDir, buildDir, libPath)
+		buildDir, buildDir, buildDir, buildDir)
 	ioutil.WriteFile(configGO, []byte(content), 0666)
 }