编译简单的Makefile
从hello world开始
go文件
package main
import "fmt"
func main() {
fmt.Println("Hello, world!")
}
执行命令
➜ golang git:(master) ✗ vim main.go
➜ golang git:(master) ✗ go build main.go
➜ golang git:(master) ✗ ./main
hello world!
如果重新执行make需要对源文件进行
编写Makefile并执行make
执行命令
➜ golang git:(master) ✗ vim Makefile
➜ golang git:(master) ✗ make
go build main.go
➜ golang git:(master) ✗ ./main
hello world!
编写Makefile
#Makefile
main:main.go
go build main.go
Makefile三要素
- main:代表命令指向的目标
- main.go 命令执行依赖的文件
- go build main.go 命令
对main.go进行简单的修改
增加bar.go
package main
import "fmt"
type Rst struct {
Name string
}
func NewRst(name string) *Rst {
return &Rst{Name: name}
}
func (r *Rst) Hello() {
fmt.Println("Hello, " + r.Name)
}
修改main.go
package main
func main() {
rst := NewRst("小明")
rst.Hello()
}
这样的话对应的Makefile也要修改
#Makefile
main:main.go bar.go
go build main.go bar.go
如果修改或者增加文件都要对Makefile文件修改就太麻烦,这时候可以使用Makefile的wildcard 函数(wildcard function)来达到这一目的。
wildcard函数
Makefile函数的写法是:$(function arguments),
wildcard函数的写法:$(wildcard pattern…)
修改后的Makefile:通配符*可以匹配任意长度的字符
#Makefile
main : $(wildcard *.go)
go build $(wildcard *.go)
修改main.go重新执行make
➜ golang git:(master) ✗ make
go build main.go bar.go
变量
还可以用变量来提高效率,使用方法和go的 var:= value 赋值一样 变量的使用方法是$(var)
#Makefile
go_file := $(wildcard *.go)
main : $(go_file)
go build $(go_file)
常用变量
-
=和:=的区别是这个符号在赋值的时候不在意声明变量的先后顺序,会优先展开调用的参数fo = a as = $(fo) b fo = aa这种情况as的值是aab,= 赋值的时候会根据最后的值决定,:= 会赋当前值
-
:=等同go的:= -
+=等同go的+= -
?=等同redis的SETNX命令,如果已赋值就不赋值,没有就赋当前值
froeach函数
foreach的函数意义和for循环相似$(foreach var,list,text),具体是循环从list中取数据,然后赋值给var,并且展开text
arr := ./model
arr += ./test
INCS := $(foreach dir,$(arr),$(dir)/*.go)
dir = ./model 展开 $(dir)/.go, INCS += ./model/.go
dir = ./test 同理
patsubst函数,
$(patsubst pattern,replacement,text)
字符串替换函数,匹配text中pattern模版部分,替换成replacement
arr := main.go
tmp := $(patsubst %.go,%_bak.go,$(arr))
%通配符的作用就是匹配以.go结尾的文字,成replacement的%就是%.go的%挪过来
伪目标
在Makefile中我们需要执行某些动作,比如清理缓存,可以定一个clean目标,执行make clean
tmp := ./tmp
clean:
rm -r $(tmp)
go中这个方法很有用,go build可以指定编译地址,而且有go module管理依赖,不用担心依赖问题
终端输出
@指令
执行Makefile会把命令打印到终端中,这样看起来会比较杂乱,命令加上@会禁止输出到终端中
tmp := ./tmp
clean:
@rm -r $(tmp)
echo
Makefile可以使用终端的指令集,所以可以用echo来自定义输出
tmp := ./tmp
clean:
@echo trying
@rm -r $(tmp)
@echo complete