-
Notifications
You must be signed in to change notification settings - Fork 0
/
self.go
116 lines (102 loc) · 2.99 KB
/
self.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//This example uses a generated makefile to compile itself
package main
import (
"log"
"os"
makefile "github.com/panux/go-makefile"
)
func chkerr(err error) {
if err != nil {
panic(err)
}
}
func main() {
//open Makefile for writing
f, err := os.OpenFile("self.mk", os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
log.Fatalf("Failed to open self.mk: %q\n", err.Error())
}
defer f.Close()
//create Makefile builder
b := makefile.NewBuilder()
defer func() { //save at the end
//write to file
_, err = b.WriteTo(f)
if err != nil {
log.Fatalf("Failed to write Makefile: %q\n", err.Error())
}
}()
//Add comment at the top saying that this is autogenerated
b.Comment().
Line("AUTOGENERATED DO NOT EDIT").
Line("run `make` to regenerate")
b.BlankLine()
//add all target
b.NewRule(makefile.RawText("all")).AddDep(makefile.RawText("self.mk")).Phony()
//add go commands
gobin := makefile.MakeVar("GOBIN")
gofmt := makefile.MakeVar("GOFMT")
goget := makefile.MakeVar("GOGET")
gobuild := makefile.MakeVar("GOBUILD")
b.Comment().
Line("go commands")
b.SetVar(gobin, makefile.RawText("go")).
SetVarSlice(gofmt, []makefile.Text{gobin.Sub(), makefile.RawText("fmt")}).
SetVarSlice(goget, []makefile.Text{gobin.Sub(), makefile.RawText("get")}).
SetVarSlice(gobuild, []makefile.Text{gobin.Sub(), makefile.RawText("build")}).
BlankLine()
//add gopath rules & variable
gopath := makefile.MakeVar("GOPATH")
b.Comment().
Line("GOPATH defaults to a subdir of this directory called gopath").
Line("it will be created if it does not exist")
b.SetVar(gopath, makefile.JoinText("/",
makefile.NewCmd(makefile.RawText("pwd")).Sub(),
makefile.FilePath("gopath"),
)).
NewRule(gopath.Sub()).
NewCmd("mkdir").
AddArg(makefile.RawText("-p")).
AddArg(gopath.Sub())
shgopath := makefile.ShellVar(gopath)
b.BlankLine()
//add fmt target
b.NewRule(makefile.RawText("fmt")).Print(makefile.RawText("Formatting")).
AddCmd(
makefile.NewCmd(gofmt.Sub()).
SetEnv(shgopath, gopath.Sub()).
SetNoPrint(),
).Phony()
defer b.AppendPhony()
//add .godeps target
godeps := makefile.RawText(".godeps")
b.NewRule(godeps).AddDep(gopath.Sub()).Print(makefile.RawText("Running go get")).
AddCmd(
makefile.NewCmd(goget.Sub()).
SetEnv(shgopath, gopath.Sub()).
AddArg(makefile.FilePath("github.com/panux/go-makefile")).
SetNoPrint(),
).
NewCmd("touch").AddArg(makefile.Target).SetNoPrint()
//add build target
b.NewRule(makefile.ExtPattern("o")).
AddDep(makefile.ExtPattern("go")).
AddDep(godeps).
Print(makefile.JoinText(" ",
makefile.RawText("GOBUILD"),
makefile.Dep1,
)).
AddCmd(
makefile.NewCmd(gobuild.Sub()).
AddArgSlice([]makefile.Text{
makefile.RawText("-o"),
makefile.Target,
makefile.Dep1,
}).
SetEnv(shgopath, gopath.Sub()).
SetNoPrint(),
)
//add self.mk target
b.NewRule(makefile.RawText("self.mk")).
AddDep(makefile.RawText("self.o")).Print(makefile.RawText("Regenerating makefile")).NewCmd("./self.o").SetNoPrint()
}