Hi I like this runner and it does simplify the compile, link, and run
process. I've made a bit change to have it support go supported
platforms and add more comments. It seems to be a useful cmd, if you
like, we can see if it can be added into the go tool set. Here is the
revised version, please take a look.
// all-in-one go cmd to compile, link and exec the target .go source
file.
// Original author:
mal...@gmail.com (Dimiter malkia Stanev)
// Modified to support multiple platforms:
i3dm...@gmail.com
(Yongjian Xu)
package main
import (
"flag";
"fmt";
"os";
"strings";
)
// Error raised when target architecture is not supported by the go
language.
var UnSupportedArchError os.Error = os.ErrorString("Unsupported
Architecture")
// Struct to hold the go binaries for the current system.
// ext => the object file extension.
// gcompiler => gc compiler name.
// linker => linker name.
// compiler => C compiler name.
// assembler => Assembler name.
type toolChain struct {
ext string;
gcompiler string;
linker string;
compiler string;
assembler string;
}
// Return the toolchain binaries for the target system.
func getTooChain(arch string) (*toolChain, os.Error) {
toolchain := new(toolChain);
switch {
case arch == "amd64":
toolchain.ext = ".6";
toolchain.gcompiler = "6g";
toolchain.linker = "6l";
toolchain.compiler = "6c";
toolchain.assembler = "6a";
return toolchain, nil;
case arch == "386":
toolchain.ext = ".8";
toolchain.gcompiler = "8g";
toolchain.linker = "8l";
toolchain.compiler = "8c";
toolchain.assembler = "8a";
return toolchain, nil;
case arch == "arm":
toolchain.ext = ".5";
toolchain.gcompiler = "5g";
toolchain.linker = "5l";
toolchain.compiler = "5c";
toolchain.assembler = "5a";
return toolchain, nil;
}
return nil, UnSupportedArchError
}
// Check the command error status. Return false if command fails,
// otherwise, return true.
func chk(cmd string, e os.Error) bool
{
if(e != nil) {
fmt.Fprintf(os.Stderr, "%s: %s\n", e, cmd);
return false;
}
return true;
}
// Fork a subprocess and execute the command.
// If failed, exit immediately, otherwise, return true.
func exec(args []string) bool
{
cmd := strings.Join(args, " ");
fmt.Fprintf(os.Stderr, "Exec: %s\n", cmd);
p, e1 := os.ForkExec(args[0], args, os.Environ(), "", nil);
if !chk(cmd, e1) {
fmt.Fprintf(os.Stderr, "%s: exec err: %s\n", cmd, e1);
os.Exit(1);
}
m, e2 := os.Wait(p, 0);
if !chk(cmd, e2) {
fmt.Fprintf(os.Stderr, "%s: wait failed: %s\n", cmd, e2);
os.Exit(1);
}
if(m.WaitStatus != 0) {
fmt.Fprintf(os.Stderr, "%s\n", m);
os.Exit(1);
}
return true;
}
func main() {
if flag.NArg() <= 0 {
println("Compile, link and execute the target.");
fmt.Printf("Usage of %s:\n", os.Args[0]);
fmt.Printf("\t%s <target> [ args ]\n", os.Args[0]);
os.Exit(0);
}
args := flag.Args();
gobin := os.Getenv("GOBIN") + "/";
fmt.Fprintf(os.Stderr, "GOBIN: %s\n", gobin);
wd, _ := os.Getwd();
fmt.Fprintf(os.Stderr, "Current dir: %s\n", wd);
toolchain, err := getTooChain(os.Getenv("GOARCH"));
if err == nil {
if len(args) > 0 {
target := args[0];
exec([]string{gobin + toolchain.gcompiler, target + ".go"});
exec([]string{gobin + toolchain.linker, "-o", target, target +
toolchain.ext});
os.Exec(wd + "/" + target, args, os.Environ());
}
} else {
fmt.Fprintf(os.Stderr, "%s\n", err);
os.Exit(1);
}
}
On Nov 25, 1:45 am, "Dimiter \"malkia\" Stanev" <
mal...@gmail.com>
wrote:
> /*
> # Makefile forgo.go
> # once build use the "go" command like this:
> # gotest
> # would compile & link test.goand run it
> # future versions would automatically parse test.goto detect other