Exemplo n.º 1
0
func locateLcgExtAsset(version string) (io.ReadCloser, error) {
	dir, err := gas.Abs("github.com/hwaf/hwaf-gen-lcgcmt")
	if err != nil {
		return nil, err
	}
	fname := filepath.Join(dir, fmt.Sprintf("lcgexternals_%s.txt", version))
	f, err := os.Open(fname)
	if err != nil {
		return nil, err
	}
	return f, err
}
Exemplo n.º 2
0
func hwaf_run_cmd_init(cmd *commander.Command, args []string) error {
	var err error
	n := "hwaf-" + cmd.Name()
	dirname := ""

	switch len(args) {
	case 0:
		dirname = "."
	case 1:
		dirname = args[0]
	default:
		return fmt.Errorf("%s: you need to give a directory name", n)
	}

	dirname = os.ExpandEnv(dirname)
	dirname = filepath.Clean(dirname)

	verbose := cmd.Flag.Lookup("v").Value.Get().(bool)
	proj_name := dirname
	if proj_name == "." {
		pwd, err := os.Getwd()
		if err != nil {
			return err
		}
		proj_name = filepath.Base(pwd)
	} else {
		proj_name = filepath.Base(dirname)
	}

	if verbose {
		fmt.Printf("%s: creating workarea [%s]...\n", n, dirname)
	}

	if !path_exists(dirname) {
		err = os.MkdirAll(dirname, 0700)
		if err != nil {
			return err
		}
	}

	pwd, err := os.Getwd()
	if err != nil {
		return err
	}
	defer os.Chdir(pwd)

	err = os.Chdir(dirname)
	if err != nil {
		return err
	}

	// setup hep-waf-tools
	if verbose {
		fmt.Printf("%s: add .hwaf/tools...\n", n)
	}
	hwaf_tools_dir := ""
	switch g_ctx.Root {
	default:
		hwaf_tools_dir = filepath.Join(g_ctx.Root, "share", "hwaf", "tools")
	case "":
		hwaf_tools_dir, err = gas.Abs("github.com/hwaf/hwaf/py-hwaftools")
		if err != nil {
			return err
		}
	}

	hwaf_tools_dir = os.ExpandEnv(hwaf_tools_dir)
	if verbose {
		fmt.Printf("%s: using hwaf/tools from [%s]...\n", n, hwaf_tools_dir)
	}
	if !path_exists(hwaf_tools_dir) {
		return fmt.Errorf("no such directory [%s]", hwaf_tools_dir)
	}
	if !path_exists(".hwaf") {
		err = os.MkdirAll(".hwaf", 0700)
		if err != nil {
			return err
		}
	}

	// add waf-bin
	{
		if verbose {
			fmt.Printf("%s: add .hwaf/bin...\n", n)
		}
		hwaf_bin_dir := ""
		switch g_ctx.Root {
		default:
			hwaf_bin_dir = filepath.Join(g_ctx.Root, "bin")
		case "":
			hwaf_bin_dir, err = gas.Abs("github.com/hwaf/hwaf")
			if err != nil {
				return err
			}
		}
		hwaf_bin_dir = os.ExpandEnv(hwaf_bin_dir)
		if verbose {
			fmt.Printf("%s: using hwaf-bin from [%s]...\n", n, hwaf_bin_dir)
		}
		if !path_exists(hwaf_bin_dir) {
			err = fmt.Errorf("no such hwaf-bin dir [%s]", hwaf_bin_dir)
			if err != nil {
				return err
			}
		}
		src_waf, err := os.Open(filepath.Join(hwaf_bin_dir, "waf"))
		if err != nil {
			return err
		}
		defer src_waf.Close()

		if !path_exists(".hwaf/bin") {
			err = os.MkdirAll(".hwaf/bin", 0700)
			if err != nil {
				return err
			}
		}

		waf_bin, err := os.Create(filepath.Join(".hwaf", "bin", "waf"))
		if err != nil {
			return err
		}
		defer waf_bin.Close()

		if runtime.GOOS != "windows" {
			err = waf_bin.Chmod(0755)
			if err != nil {
				return err
			}
		}

		_, err = io.Copy(waf_bin, src_waf)
		if err != nil {
			return err
		}

		err = waf_bin.Sync()
		if err != nil {
			return err
		}
	}

	// add pkgdb
	err = ioutil.WriteFile(
		filepath.Join(".hwaf", "pkgdb.json"),
		[]byte("{}\n"),
		0755,
	)
	if err != nil {
		return err
	}

	// add template wscript
	if verbose {
		fmt.Printf("%s: add top-level wscript...\n", n)
	}

	if !path_exists("wscript") {
		wscript_tmpl, err := os.Open(filepath.Join(hwaf_tools_dir, "hwaf-wscript"))
		if err != nil {
			return err
		}
		defer wscript_tmpl.Close()

		wscript_b, err := ioutil.ReadAll(wscript_tmpl)
		if err != nil {
			return err
		}

		// replace 'hwaf-workarea' with workarea name
		wscript_s := strings.Replace(
			string(wscript_b),
			"APPNAME = 'hwaf-workarea'",
			fmt.Sprintf("APPNAME = '%s'", proj_name),
			-1)

		wscript, err := os.Create("wscript")
		if err != nil {
			return err
		}
		defer wscript.Close()

		_, err = io.WriteString(wscript, wscript_s)
		if err != nil {
			return err
		}
		err = wscript.Sync()
		if err != nil {
			return err
		}
		err = wscript.Close()
		if err != nil {
			return err
		}
	}

	// create 'src' directory
	if !path_exists("src") {
		err = os.MkdirAll("src", 0700)
		if err != nil {
			return err
		}
	}

	if verbose {
		fmt.Printf("%s: creating workarea [%s]... [ok]\n", n, dirname)
	}

	return err
}
Exemplo n.º 3
0
func (ctx *Context) init() error {
	var err error
	root := hwaf_root()
	if root == "" {
		//return ErrNoHwafRootDir
	}
	ctx.Root = root

	// initialize signal handler
	go func() {
		ch := make(chan os.Signal)
		signal.Notify(ch, os.Interrupt)
		<-ch
		ctx.Exit(1)
	}()

	ctx.gcfg, err = ctx.GlobalCfg()
	if err != nil {
		return err
	}

	// configure environment
	err = ctx.load_env_from_cfg(ctx.gcfg)
	if err != nil {
		return fmt.Errorf("hwaf: problem loading environment from global config: %v", err)
	}

	ctx.lcfg, err = ctx.LocalCfg()
	if ctx.lcfg != nil && err == nil {
		err = ctx.load_env_from_cfg(ctx.lcfg)
		if err != nil {
			return fmt.Errorf("hwaf: problem loading environment from local config:\n%v", err)
		}
	}
	err = nil

	setup_env := func(topdir string) error {
		topdir = os.ExpandEnv(topdir)
		if !path_exists(topdir) {
			return fmt.Errorf("hwaf: no such directory [%s]", topdir)
		}
		// add hepwaf-tools to the python environment
		pypath := os.Getenv("PYTHONPATH")
		hwaftools := ""
		if topdir == ctx.Root {
			hwaftools = filepath.Join(topdir, "share", "hwaf", "tools")
		} else {
			hwaftools = filepath.Join(topdir, "py-hwaftools")
		}
		if !path_exists(hwaftools) {
			return fmt.Errorf("hwaf: no such directory [%s]", hwaftools)
		}
		if pypath == "" {
			pypath = hwaftools
		} else {
			pypath = pypath + string(os.PathListSeparator) + hwaftools
		}

		os.Setenv("PYTHONPATH", pypath)
		os.Setenv("HWAF_VERSION", ctx.Version())
		os.Setenv("HWAF_REVISION", ctx.Revision())
		return nil
	}

	// setup environment.
	// order matters:
	switch ctx.Root {
	default:
		err = setup_env(ctx.Root)
		if err != nil {
			return err
		}
	case "":
		topdir, err := gas.Abs("github.com/hwaf/hwaf")
		if err != nil {
			return err
		}
		err = setup_env(topdir)
		if err != nil {
			return err
		}
	}

	// FIXME: get sitedir from globalcfg and/or localcfg.
	ctx.sitedir = os.Getenv("HWAF_SITEDIR")
	if ctx.sitedir == "" {
		sitedir := filepath.Join(string(os.PathSeparator), "opt", "sw")
		//ctx.Warn("no $HWAF_SITEDIR env. variable. will use [%s]\n", sitedir)
		ctx.sitedir = sitedir
	}

	// init cmtcfg
	// FIXME: also get it from globalcfg/localcfg
	if ctx.cmtcfg == "" {
		if cmtcfg := os.Getenv("CMTCFG"); cmtcfg != "" {
			ctx.cmtcfg = cmtcfg
		} else {
			ctx.cmtcfg = ctx.DefaultCmtcfg()
		}
	}

	// init local pkg db
	_, _ = ctx.Workarea()
	if ctx.workarea != nil {
		fname := filepath.Join(*ctx.workarea, ".hwaf", "pkgdb.json")
		ctx.PkgDb = NewPackageDb(fname)
		if path_exists(fname) {
			err = ctx.PkgDb.Load(fname)
			if err != nil {
				return err
			}
		}
	}
	return err
}
Exemplo n.º 4
0
Arquivo: context.go Projeto: hwaf/hwaf
func (ctx *Context) init() error {
	var err error
	root := hwaf_root()
	if root == "" {
		//return ErrNoHwafRootDir
	}
	ctx.Root = root

	// initialize signal handler
	go func() {
		ch := make(chan os.Signal)
		signal.Notify(ch, os.Interrupt, os.Kill)
		for {
			select {
			case sig := <-ch:
				// fmt.Fprintf(os.Stderr, "\n>>>>>>>>>\ncaught %#v\n", sig)
				// fmt.Fprintf(os.Stderr, "subcmds: %d %#v\n", len(ctx.subcmds), ctx.subcmds)
				for _, cmd := range ctx.subcmds {
					// fmt.Fprintf(os.Stderr, ">>> icmd %d...\n", icmd)
					if cmd == nil {
						// fmt.Fprintf(os.Stderr, ">>> cmd nil\n")
						continue
					}
					// fmt.Fprintf(os.Stderr, ">>> sync-ing\n")
					if stdout, ok := cmd.Stdout.(interface {
						Sync() error
					}); ok {
						stdout.Sync()
					}
					if stderr, ok := cmd.Stderr.(interface {
						Sync() error
					}); ok {
						stderr.Sync()
					}
					proc := cmd.Process
					if proc == nil {
						continue
					}
					// fmt.Fprintf(os.Stderr, ">>> signaling...\n")
					_ = proc.Signal(sig)
					// fmt.Fprintf(os.Stderr, ">>> signaling... [done]\n")
					ps, pserr := proc.Wait()
					if pserr != nil {
						// fmt.Fprintf(os.Stderr, "waited and got: %#v\n", pserr)
					} else {
						if !ps.Exited() {
							// fmt.Fprintf(os.Stderr, ">>> killing...\n")
							proc.Kill()
							// fmt.Fprintf(os.Stderr, ">>> killing... [done]\n")
						}
					}
					if stdout, ok := cmd.Stdout.(interface {
						Sync() error
					}); ok {
						stdout.Sync()
					}
					if stderr, ok := cmd.Stderr.(interface {
						Sync() error
					}); ok {
						stderr.Sync()
					}
					// fmt.Fprintf(os.Stderr, ">>> re-sync-ing... [done]\n")
				}
				// fmt.Fprintf(os.Stderr, "flushing\n")
				_ = os.Stderr.Sync()
				_ = os.Stdout.Sync()
				// fmt.Fprintf(os.Stderr, "flushed\n")
				ctx.Exit(1)
				return
			}
		}
	}()

	ctx.gcfg, err = ctx.GlobalCfg()
	if err != nil {
		return err
	}

	// configure environment
	err = ctx.load_env_from_cfg(ctx.gcfg)
	if err != nil {
		return fmt.Errorf("hwaf: problem loading environment from global config: %v", err)
	}

	ctx.lcfg, err = ctx.LocalCfg()
	if ctx.lcfg != nil && err == nil {
		err = ctx.load_env_from_cfg(ctx.lcfg)
		if err != nil {
			return fmt.Errorf("hwaf: problem loading environment from local config:\n%v", err)
		}
	}
	err = nil

	// load local config
	if ctx.lcfg != nil {
		ctx.variant, err = ctx.lcfg.String("hwaf-cfg", "variant")
		if err != nil {
			err = nil
			ctx.variant = ""
		}
	}

	setup_env := func(topdir string) error {
		topdir = os.ExpandEnv(topdir)
		if !path_exists(topdir) {
			return fmt.Errorf("hwaf: no such directory [%s]", topdir)
		}
		// add hepwaf-tools to the python environment
		pypath := os.Getenv("PYTHONPATH")
		pyhwafdir := ""
		if topdir == ctx.Root {
			pyhwafdir = filepath.Join(topdir, "share", "hwaf", "tools")
		} else {
			pyhwafdir = filepath.Join(topdir, "py-hwaftools")
		}
		if !path_exists(pyhwafdir) {
			return fmt.Errorf("hwaf: no such directory [%s]", pyhwafdir)
		}
		hwaftools := strings.Join(
			[]string{
				pyhwafdir,
				filepath.Join(pyhwafdir, "orch"),
			},
			string(os.PathListSeparator),
		)
		if pypath == "" {
			pypath = hwaftools
		} else {
			pypath = pypath + string(os.PathListSeparator) + hwaftools
		}

		os.Setenv("PYTHONPATH", pypath)
		os.Setenv("HWAF_VERSION", ctx.Version())
		os.Setenv("HWAF_REVISION", ctx.Revision())
		return nil
	}

	// setup environment.
	// order matters:
	switch ctx.Root {
	default:
		err = setup_env(ctx.Root)
		if err != nil {
			return err
		}
	case "":
		topdir, err := gas.Abs("github.com/hwaf/hwaf")
		if err != nil {
			return err
		}
		err = setup_env(topdir)
		if err != nil {
			return err
		}
	}

	// FIXME: get sitedir from globalcfg and/or localcfg.
	ctx.sitedir = os.Getenv("HWAF_SITEDIR")
	if ctx.sitedir == "" {
		sitedir := filepath.Join(string(os.PathSeparator), "opt", "sw")
		//ctx.Warn("no $HWAF_SITEDIR env. variable. will use [%s]\n", sitedir)
		ctx.sitedir = sitedir
	}

	// init variant
	// FIXME: also get it from globalcfg/localcfg
	if ctx.variant == "" {
		if variant := os.Getenv("HWAF_VARIANT"); variant != "" {
			ctx.variant = variant
		} else {
			ctx.variant = ctx.DefaultVariant()
		}
	}

	// init local pkg db
	_, _ = ctx.Workarea()
	if ctx.workarea != nil {
		fname := filepath.Join(*ctx.workarea, ".hwaf", "pkgdb.json")
		ctx.PkgDb = NewPackageDb(fname)
		if path_exists(fname) {
			err = ctx.PkgDb.Load(fname)
			if err != nil {
				return err
			}
		}
	}
	return err
}
Exemplo n.º 5
0
func hwaf_run_cmd_self_bdist(cmd *commander.Command, args []string) error {
	var err error

	n := "hwaf-self-" + cmd.Name()

	switch len(args) {
	case 0:
		// ok
	default:
		return fmt.Errorf("%s: does NOT take any argument", n)
	}

	verbose := cmd.Flag.Lookup("v").Value.Get().(bool)

	bdist_name := "hwaf"
	bdist_vers := cmd.Flag.Lookup("version").Value.Get().(string)
	bdist_variant := fmt.Sprintf("%s-%s", runtime.GOOS, runtime.GOARCH)

	if bdist_vers == "" {
		bdist_vers = time.Now().Format("20060102")
	}

	dirname := fmt.Sprintf("%s-%s-%s", bdist_name, bdist_vers, bdist_variant)
	fname := dirname + ".tar.gz"

	if verbose {
		fmt.Printf("%s [%s]...\n", n, fname)
	}

	tmpdir, err := ioutil.TempDir("", "hwaf-self-bdist-")
	if err != nil {
		return err
	}
	defer os.RemoveAll(tmpdir)
	//fmt.Printf(">>> [%s]\n", tmpdir)

	//
	top := filepath.Join(tmpdir, dirname)
	// create hierarchy of dirs for bdist
	for _, dir := range []string{
		"bin",
		"share",
		filepath.Join("share", "hwaf"),
	} {
		err = os.MkdirAll(filepath.Join(top, dir), 0755)
		if err != nil {
			return err
		}
	}

	// add hep-waftools cache
	hwaf_dir, err := gas.Abs("github.com/hwaf/hwaf")
	if err != nil {
		return err
	}

	src_hwaf_tools := filepath.Join(hwaf_dir, "py-hwaftools")
	hwaf_tools := filepath.Join(top, "share", "hwaf", "tools")

	err = copytree(hwaf_tools, src_hwaf_tools)
	if err != nil {
		return err
	}

	// remove git stuff
	err = os.RemoveAll(filepath.Join(hwaf_tools, ".git"))
	if err != nil {
		return err
	}

	// add share/hwaf/hwaf.conf
	err = ioutil.WriteFile(
		filepath.Join(top, "share", "hwaf", "hwaf.conf"),
		[]byte(`# hwaf config file
[hwaf]

## EOF ##
`),
		0644,
	)
	if err != nil {
		return err
	}

	// temporary GOPATH - install go-deps
	gopath := filepath.Join(tmpdir, "gocode")
	err = os.MkdirAll(gopath, 0755)
	if err != nil {
		return err
	}

	orig_gopath := os.Getenv("GOPATH")
	err = os.Setenv("GOPATH", gopath)
	if err != nil {
		return err
	}
	defer os.Setenv("GOPATH", orig_gopath)

	for _, gopkg := range []string{
		"github.com/hwaf/hwaf",
		"github.com/hwaf/hwaf-cmt2yml",
		"github.com/hwaf/hwaf-gen-extpackdist",
		"github.com/hwaf/hwaf-gen-lcgcmt",
		"github.com/hwaf/hwaf-rcore2yml",
	} {
		goget := exec.Command("go", "get", "-v", gopkg)
		goget.Dir = gopath
		if verbose {
			goget.Stdout = os.Stdout
			goget.Stderr = os.Stderr
		}
		err = goget.Run()
		if err != nil {
			return err
		}

		// install under /bin
		dst_fname := filepath.Join(top, "bin", filepath.Base(gopkg))
		dst, err := os.OpenFile(dst_fname, os.O_WRONLY|os.O_CREATE, 0755)
		if err != nil {
			return err
		}
		defer func(dst *os.File) error {
			err := dst.Sync()
			if err != nil {
				return err
			}
			err = dst.Close()
			return err
		}(dst)

		src_fname := filepath.Join(gopath, "bin", filepath.Base(gopkg))
		if !path_exists(src_fname) {
			// maybe a cross-compilation ?
			src_fname = filepath.Join(gopath, "bin", runtime.GOOS+"_"+runtime.GOARCH, filepath.Base(gopkg))
		}
		src, err := os.Open(src_fname)
		if err != nil {
			return err
		}
		defer func(src *os.File) error {
			return src.Close()
		}(src)

		_, err = io.Copy(dst, src)
		if err != nil {
			return err
		}
	}

	// add waf-bin
	waf_fname := filepath.Join(top, "bin", "waf")
	if path_exists(waf_fname) {
		err = os.Remove(waf_fname)
		if err != nil {
			return err
		}
	}
	waf_dst, err := os.OpenFile(waf_fname, os.O_WRONLY|os.O_CREATE, 0777)
	if err != nil {
		return err
	}
	defer func() error {
		err = waf_dst.Sync()
		if err != nil {
			return err
		}
		err = waf_dst.Close()
		if err != nil {
			return err
		}
		return err
	}()

	waf_src, err := os.Open(filepath.Join(
		gopath, "src", "github.com", "hwaf", "hwaf", "waf"),
	)
	if err != nil {
		return err
	}
	defer waf_src.Close()
	_, err = io.Copy(waf_dst, waf_src)
	if err != nil {
		return err
	}

	const bq = "`"
	// add setup.sh
	setup_fname, err := os.Create(filepath.Join(top, "setup-hwaf.sh"))
	if err != nil {
		return err
	}
	defer setup_fname.Close()
	_, err = fmt.Fprintf(setup_fname, `#!/bin/sh 

if [ "x${BASH_ARGV[0]}" = "x" ]; then
    ## assume zsh
    SOURCE="$0"
else
    SOURCE="${BASH_SOURCE[0]}"
fi

DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
echo ":: adding [$DIR/bin] to PATH"
export PATH=$DIR/bin:$PATH
## EOF
`)
	if err != nil {
		return err
	}

	err = setup_fname.Sync()
	if err != nil {
		return err
	}

	// add setup.csh
	csetup_fname, err := os.Create(filepath.Join(top, "setup-hwaf.csh"))
	if err != nil {
		return err
	}
	defer csetup_fname.Close()
	_, err = fmt.Fprintf(csetup_fname, `#!/bin/csh
# Absolute path to this script
set SCRIPT=%sreadlink -f "$0"%s
# Absolute path this script is in
set SCRIPTPATH=%sdirname "$SCRIPT"%s
echo ":: adding [$SCRIPTPATH/bin] to PATH"
setenv PATH $SCRIPTPATH/bin:$PATH

## EOF
`, bq, bq, bq, bq)
	if err != nil {
		return err
	}
	err = csetup_fname.Sync()
	if err != nil {
		return err
	}

	pwd, err := os.Getwd()
	if err != nil {
		return err
	}

	// package everything up
	err = _tar_gz(filepath.Join(pwd, fname), top)
	if err != nil {
		return err
	}

	if verbose {
		fmt.Printf("%s [%s]... [ok]\n", n, fname)
	}

	return err
}
Exemplo n.º 6
0
func hwaf_run_cmd_self_bdist(cmd *commander.Command, args []string) {
	var err error

	n := "hwaf-self-" + cmd.Name()

	switch len(args) {
	case 0:
		// ok
	default:
		err = fmt.Errorf("%s: does NOT take any argument", n)
		handle_err(err)
	}

	verbose := cmd.Flag.Lookup("v").Value.Get().(bool)

	bdist_name := "hwaf"
	bdist_vers := cmd.Flag.Lookup("version").Value.Get().(string)
	bdist_cmtcfg := fmt.Sprintf("%s-%s", runtime.GOOS, runtime.GOARCH)

	if bdist_vers == "" {
		bdist_vers = time.Now().Format("20060102")
	}

	dirname := fmt.Sprintf("%s-%s-%s", bdist_name, bdist_vers, bdist_cmtcfg)
	fname := dirname + ".tar.gz"

	if verbose {
		fmt.Printf("%s [%s]...\n", n, fname)
	}

	tmpdir, err := ioutil.TempDir("", "hwaf-self-bdist-")
	handle_err(err)
	defer os.RemoveAll(tmpdir)
	//fmt.Printf(">>> [%s]\n", tmpdir)

	//
	top := filepath.Join(tmpdir, dirname)
	// create hierarchy of dirs for bdist
	for _, dir := range []string{
		"bin",
		"share",
		filepath.Join("share", "hwaf"),
	} {
		err = os.MkdirAll(filepath.Join(top, dir), 0755)
		handle_err(err)
	}

	// add hep-waftools cache
	hwaf_dir, err := gas.Abs("github.com/hwaf/hwaf")
	handle_err(err)

	src_hwaf_tools := filepath.Join(hwaf_dir, "py-hwaftools")
	hwaf_tools := filepath.Join(top, "share", "hwaf", "tools")

	err = copytree(hwaf_tools, src_hwaf_tools)
	handle_err(err)

	// remove git stuff
	err = os.RemoveAll(filepath.Join(hwaf_tools, ".git"))
	handle_err(err)

	// add share/hwaf/hwaf.conf
	err = ioutil.WriteFile(
		filepath.Join(top, "share", "hwaf", "hwaf.conf"),
		[]byte(`# hwaf config file
[hwaf]

## EOF ##
`),
		0644,
	)
	handle_err(err)

	// temporary GOPATH - install go-deps
	gopath := filepath.Join(tmpdir, "gocode")
	err = os.MkdirAll(gopath, 0755)
	handle_err(err)

	orig_gopath := os.Getenv("GOPATH")
	err = os.Setenv("GOPATH", gopath)
	handle_err(err)
	defer os.Setenv("GOPATH", orig_gopath)

	for _, gopkg := range []string{
		"github.com/hwaf/hwaf",
		"github.com/hwaf/git-tools/git-archive-all",
		"github.com/hwaf/git-tools/git-rm-submodule",
		"github.com/hwaf/git-tools/git-check-clean",
		"github.com/hwaf/git-tools/git-check-non-tracking",
		"github.com/hwaf/git-tools/git-check-unpushed",
	} {
		goget := exec.Command("go", "get", "-v", gopkg)
		goget.Dir = gopath
		if verbose {
			goget.Stdout = os.Stdout
			goget.Stderr = os.Stderr
		}
		err = goget.Run()
		handle_err(err)

		// install under /bin
		dst_fname := filepath.Join(top, "bin", filepath.Base(gopkg))
		dst, err := os.OpenFile(dst_fname, os.O_WRONLY|os.O_CREATE, 0755)
		handle_err(err)
		defer func(dst *os.File) {
			err := dst.Sync()
			handle_err(err)
			err = dst.Close()
			handle_err(err)
		}(dst)

		src_fname := filepath.Join(gopath, "bin", filepath.Base(gopkg))
		if !path_exists(src_fname) {
			// maybe a cross-compilation ?
			src_fname = filepath.Join(gopath, "bin", runtime.GOOS+"_"+runtime.GOARCH, filepath.Base(gopkg))
		}
		src, err := os.Open(src_fname)
		handle_err(err)
		defer func(src *os.File) {
			err := src.Close()
			handle_err(err)
		}(src)

		_, err = io.Copy(dst, src)
		handle_err(err)
	}

	// add waf-bin
	waf_fname := filepath.Join(top, "bin", "waf")
	if path_exists(waf_fname) {
		err = os.Remove(waf_fname)
		handle_err(err)
	}
	waf_dst, err := os.OpenFile(waf_fname, os.O_WRONLY|os.O_CREATE, 0777)
	handle_err(err)
	defer func() {
		err = waf_dst.Sync()
		handle_err(err)
		err = waf_dst.Close()
		handle_err(err)
	}()

	waf_src, err := os.Open(filepath.Join(
		gopath, "src", "github.com", "hwaf", "hwaf", "waf"),
	)
	handle_err(err)
	defer waf_src.Close()
	_, err = io.Copy(waf_dst, waf_src)
	handle_err(err)

	pwd, err := os.Getwd()
	handle_err(err)

	// package everything up
	err = _tar_gz(filepath.Join(pwd, fname), top)
	handle_err(err)

	if verbose {
		fmt.Printf("%s [%s]... [ok]\n", n, fname)
	}
}