1. Greg Ward
  2. fubsy

Commits

Greg Ward  committed a2620d4

build scripts: factor out configure.sh; start using .build directory

configure.sh is responsible for probing the system, downloading
dependencies, and building dependencies. It's OK to be slow, because
it should run rarely. build.sh builds Fubsy, so it should be fast.

Both of these scripts should write build products to .build/1, the
"stage 1" build directory. Stage 2 will be for the self-hosted build,
i.e. using the "fubsy" binary from stage 1 to build itself. Not quite
there yet!

  • Participants
  • Parent commits 32635d1
  • Branches default

Comments (0)

Files changed (6)

File .hgignore

View file
+^\.build$
 ^pkg$
 ^bin$
 ~$

File README.rst

View file
 on Unix, you already have Go installed, and you don't care about
 satisfying Fubsy's optional dependencies, just run ::
 
-    ./build.sh
+    ./configure.sh && ./build.sh
 
-Otherwise, see ``doc/build.txt``.
+For more information, see ``doc/build.txt``.
 
 Using
 -----

File build.sh

View file
     eval $1
 }
 
+checkexists() {
+    test=$1   # "-d", "-f", etc.
+    file=$2
+    if [ ! $test $file ]; then
+        echo "error: $file not found (did you run ./configure.sh?)" >&2
+        exit 1
+    fi
+}
+
+# stage 1 build dir, created by configure.sh
+build1=".build/1"
+checkexists -d $build1
+
 tests=""
 if [ $# -eq 1 ]; then
     tests="-test.run=$1"
 fi
 
-export GOPATH=$PWD
+top=`pwd`
+export GOPATH=$top:$top/.build/1
+echo "GOPATH=$GOPATH"
+
+# set build tags based on what configure.sh found when it probed
+tagdir=".build/tags"
+checkexists -d $tagdir
+buildtags=`cd $tagdir && echo *`
+
 set -e
 
-# by default, build with no optional features -- they will be enabled
-# based on what exists on the build system
-buildtags=""
+golex="$build1/bin/golex"
+checkexists -f $golex
 
-set +e
-run "pkg-config --silence-errors --cflags kyotocabinet"
-status=$?
-set -e
-if [ $status -eq 0 ]; then
-    buildtags="$buildtags kyotodb"
-fi
-
-golex=bin/golex
-if [ ! -f $golex ]; then
-    run "go install github.com/cznic/golex"
-fi
-
-gocov=bin/gocov
-if [ ! -f $gocov ]; then
-    run "go install github.com/axw/gocov/gocov"
-fi
+gocov="$build1/bin/gocov"
+checkexists -f $gocov
 
 run "$golex -o src/fubsy/dsl/fulex.go src/fubsy/dsl/fulex.l"
 run "go tool yacc -p fu -o src/fubsy/dsl/fugrammar.go src/fubsy/dsl/fugrammar.y"

File configure.sh

View file
+#!/bin/sh
+
+# auto-configuration script for Fubsy; needed until Fubsy has builtin
+# auto-configuration capabilities
+#
+# the goals here are
+# 1) probe the build system to see what features
+#    are present, recording the results in files under .build
+# 2) download dependencies (mainly Go libraries, not packages we expect
+#    to find installed)
+#
+# To clarify, Fubsy has three kinds of dependencies (apart from Go
+# itself):
+#   * optional, written in C or C++ (Kyoto Cabinet, Python)
+#   * optional, written in Go (typically wrappers for optional
+#     C/C++ dependencies)
+#   * required, written in Go (golex, go-bit, ...).
+#
+# We generally expect optional C/C++ dependencies to be installed
+# separately on the build system, and carry on without them if they
+# are not there. Go dependencies are either included directly in
+# Fubsy's source repository or downloaded here: either way, if they
+# are required, the build process guarantees they will be present (or
+# the build will fail).
+
+top=`pwd`
+log=".build/config/log"
+tagdir=".build/tags"
+goos=`go env GOOS`
+goarch=`go env GOARCH`
+goplatform="${goos}_${goarch}"
+
+# high-level functions
+
+setup() {
+    rm -rf .build
+    mkdir -p $tagdir .build/config
+}
+
+probe() {
+    echo "probing build system ..."
+    tagif kyotodb "pkg-config --cflags kyotocabinet"
+
+    # Probe for "python" last because on Arch Linux, "python" is
+    # Python 3. We want Python 2.6 or 2.7 (I suspect -- have not tried
+    # older versions).
+    tagif python \
+        "pkg-config --cflags python2" \
+        "pkg-config --cflags python-2.6" \
+        "pkg-config --cflags python-2.7" \
+        "pkg-config --cflags python"
+
+    echo ""
+    echo "build tags:"
+    (cd $tagdir && echo *)
+}
+
+getdeps() {
+    echo ""
+    echo "downloading dependencies ..."
+
+    # directory for the "stage 1" build, done with shell scripts
+    # rather then with Fubsy itself
+    build1=".build/1"
+
+    export GOPATH="$top/$build1"
+    if tagset python; then
+        run "go get -v -d github.com/sbinet/go-python/pkg/python"
+    fi
+
+    # we build separate from download mainly because of go-python,
+    # which has a Makefile for good reasons of its own
+    # (also, perhaps building should be done in build.sh...?)
+
+    echo ""
+    echo "building dependencies ..."
+    mkdir -p $build1/bin
+    mkdir -p $build1/pkg/$goplatform/github.com
+
+    rm -rf pkg/$goplatform/github.com/cznic
+    run "GOPATH=$top go install -v github.com/cznic/..."
+    run "mv pkg/$goplatform/github.com/cznic $build1/pkg/$goplatform/github.com/."
+    run "mv bin/golex $build1/bin/."
+
+    rm -rf pkg/$goplatform/github.com/axw
+    run "GOPATH=$top go install -v github.com/axw/gocov/gocov"
+    run "mv pkg/$goplatform/github.com/axw $build1/pkg/$goplatform/github.com/."
+    run "mv bin/gocov $build1/bin/."
+
+    if tagset python; then
+        run "make -C $build1/src/github.com/sbinet/go-python/pkg/python install"
+    fi
+}
+
+# utility functions
+
+run() {
+    echo $1
+    echo '$' $1 >> $log
+    eval $1 >> $log 2>&1
+    status=$?
+    if [ $status -ne 0 ]; then
+        echo "error: command failed: see $log for details" >&2
+        exit $status
+    fi
+    echo >> $log
+}
+
+check() {
+    echo -n "$1 ... "
+    echo '$' $1 >> $log
+    eval $1 >> $log 2>&1
+    status=$?
+    echo >> $log
+
+    if [ $status -eq 0 ]; then
+        echo "ok"
+    else
+        echo "fail"
+    fi
+    return $status
+}
+
+tagif() {
+    tag=$1 ; shift
+    for cmd in "$@"; do
+        if check "$cmd"; then
+            touch $tagdir/$tag
+            return
+        fi
+    done
+}
+
+tagset() {
+    test -f $tagdir/$1
+}
+
+# main program
+
+setup
+probe
+getdeps

File coverage.sh

View file
 github.com/ogier/pflag"
 
 echo "testing packages: $packages"
+build1=".build/1"
 set -e
 for pkg in $packages; do
     json=coverage-`basename $pkg`.json
     report=coverage-`basename $pkg`.txt
-    run "./bin/gocov test -exclude $exclude $pkg > $json"
-    run "./bin/gocov report $json > $report"
+    run "$build1/bin/gocov test -exclude $exclude $pkg > $json"
+    run "$build1/bin/gocov report $json > $report"
 done

File doc/build.txt

View file
 
 I'm not currently distributing Fubsy binaries -- so if you want to
 give it a try, you'll have to build it from source. The same procedure
-applies whether you are building in a Mercurial working dir or from a
-release tarball.
+applies whether you are building in a working dir checked out from
+source control (Mercurial) or from a release tarball.
 
 Requirements
 ------------
 
-Fubsy is written in Go and (optionally) uses Kyoto Cabinet for
-persistent storage [1]. Thus:
+Fubsy is written in Go and (optionally) uses various C/C++ packages.
+Thus:
 
   * you must have Go 1.0.x installed
 
   * you should have Kyoto Cabinet (including headers and development
-    library) installed
+    library) installed [1]
+
+  * you may want Python (including headers and development library)
+    installed
 
 Details follow.
 
      `the Go project downloads page
      <http://code.google.com/p/go/downloads/list>`_
 
-  #. unpack it to a dedicated directory, e.g. ::
+  #. unpack it to a dedicated directory, e.g. (as root)::
 
        cd /usr/local
        rm -rf go
 without a package manager, the source is here:
 http://fallabs.com/kyotocabinet/pkg/ .
 
+Installing Python
+-----------------
+
+Remember: this is an optional dependency. If you can't get it to work,
+just skip it. You'll get a Fubsy binary that can't run Python plugins,
+but you should still be able to get a taste for how Fubsy works.
+
+Fubsy works with Python 2.6 or 2.7; 3.x is untested.
+
+On Debian/Ubuntu, try ::
+
+    sudo apt-get install python-dev
+
+On Fedora/Red Hat, try (untested!) ::
+
+    sudo yum install python-devel
+
+On Mac OS X with MacPorts, try (untested!) ::
+
+    sudo port install python27
+
+On Mac OS X with Homebrew, try (untested!) ::
+
+    brew install python
+
 Building
 --------
 
 To build Fubsy and run all unit tests (Unix only)::
 
-    ./build.sh
+    ./configure.sh && ./build.sh
 
 Obviously this won't work on Windows, and I haven't written an
 equivalent batch file yet. Patches are welcome!
 
+If you're hacking on Fubsy and need to build it repeatedly, just
+re-run ::
+
+    ./build.sh
+
+You don't need to re-run ``configure.sh``, since it consists of slow
+steps that don't need to be repeated very often, like probing the
+build system and downloading some dependencies.
+
 To prove that Fubsy can build itself using its own build script:
 
     ./bin/fubsy
 
-(If that fails because you don't have Kyoto Cabinet installed, you'll
-have to edit ``main.fubsy``. Fubsy doesn't have a auto-configuration
-feature yet, although it's in the plan.)
+Note that the self-hosting build script (``main.fubsy``) assumes all
+C/C++ dependencies are installed. If not, you'll have to edit it and
+change the ``tagflags`` variable. (Fubsy isn't smart enough to do this
+yet, although it's in the plan.)