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 <[email protected]>
Authored: Mon Nov 10 09:11:03 2014 -0800
Committer: Marvin Humphrey <[email protected]>
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)
 }
 

Reply via email to