文章目录
1.语法规则
目标: 依赖1 依赖2 ...依赖n
命令1
命令2
...
命令n
1.1 简单实例
1. 在makefile中输入如下内容:
说明: test1和test2没有依赖, test3 依赖test2
test1:
echo "hello this is test1"
test2:
@echo "hello this is test2"
test3: test2
@echo "hello this is test3"
2. 执行test
在命令行输入: make test1
结果如下:
echo "hello this is test1"
hello this is test1
在命令行输入: make test2
结果如下:
hello this is test2
在命令行输入: make test3
结果如下:
hello this is test2
hello this is test3
3. 总结:
命令前没有@符号时, 会把当前执行的命令输出, 然后再输出命令执行的结果
命令前有@符号时, 只会输出命令执行的结果
目标有依赖时, 会先按顺序执行所有的依赖, 然后再执行当前目标内的命令
2. make语法
2.1. 变量赋值
= 这个是相当于指针赋值,该值随着变量的值变化而变化
:= 这个是值赋值,该值不会变化
?= 这个是判断当前变量是否存在, 不存在则赋值
+= 这个是在变量的基础上累加新的值
$(变量名) 是对变量的取值
name1 = jean
message1=hello,$(name1)
name1 = jean2
message2=hello,$(name1)
message3:=hello,$(name1)
name1 := jean3
message3 ?= new message3
message4 ?= new message4
message5 += new message5
main:
@echo name1: $(name1)
@echo message1: $(message1)
@echo message2: $(message2)
@echo message3: $(message3)
@echo message3: $(message4)
@echo message3: $(message5)
执行结果如下 make main:
name1: jean3
message1: hello,jean3
message2: hello,jean3
message3: hello,jean2
message3: new message4
message3: new message5
变量中执行命令:
##### go 执行命令变量
GO := go
##### go版本号,通过执行shell命令: go env GOVERSION获取
GOVERSION := $(shell $(GO) env GOVERSION)
##### 当前路径,通过执行shell命令: pwd 获取
PWD := $(shell pwd)
##### 当前路径,通过执行make函数abspath获取
ASBPATH :=$(abspath .)
main:
@echo $(GO)
@echo $(GOVERSION)
@echo $(PWD)
@echo $(PWD)
执行结果如下 make main:
go
go1.19.1
/Users/Je*****ao/Documents/workspace/gRpc-demo
/Users/Je*****ao/Documents/workspace/gRpc-demo
2.2 目标&依赖
1. 正常target
说明:
$@: 当前target
$<: 第一个依赖
$^: 所有依赖
main: link1
@echo "haha"
link1: link2 link3
##### $@: 当前target
@echo "running link1 self: $@"
##### $<: 第一个依赖
@echo "running link1 first : $<"
##### $^: 所有依赖
@echo "running link1 all: $^"
link2:
@echo ">> running $@"
link3:
@echo ">> running $@"
main 依赖link1, link1 依赖link2, link3, 执行结果如下make main:
>> running link2
>> running link3
##### link1: 当前target
running link1 self: link1
##### link2: 第一个依赖
running link1 first : link2
##### link2 link3: 所有依赖
running link1 all: link2 link3
haha
2. %target
%是一个通配符, make的时候通配符的位置去匹配对应的目标还是依赖
说明main 依赖api.link1, 匹配到%.link1,匹配的值为api
main: api.link1
@echo "haha"
%.link1: %.link2
@echo ">> running $@"
%.link2:
@echo ">> running $@"
执行结果如下make main:
>> running api.link2
>> running api.link1
haha
2.3 逻辑判断if
ifndef ROOT_DIR
ROOT_DIR := $(shell pwd)
else
ROOT_DIR := "ROOT_DIR not find"
endif
name := hello
##### if name == hello
ifeq ($(name), hello)
s := "true"
else
s := "false"
endif
##### if name != hello
ifneq ($(name), haha)
s1 := "true"
else
s1 := "false"
endif
main:
@echo $(ROOT_DIR)
@echo $(s)
@echo $(s1)
执行结果如下make:
/Users/Je****ao/Documents/workspace/gRpc-demo
2.4 伪目标.PHONY
2.4.1 对于目标
说明:make 的target一般是文件路径,如果该文件存在, 则放弃执行当前命令
ReadMe.md:
@echo "haha test"
当前makefile同目录下存在ReadMe.md文件,执行结果如下:
make: `ReadMe.md' is up to date.
.PHONY的作用就是,无需判断文件是否存在,都执行对应的命令, 如下:
ReadMe.md:
@echo "haha test"
.PHONY: ReadMe.md
当前makefile同目录下存在ReadMe.md文件,执行结果如下make:
haha test
2.4.2 对于依赖
假如makefile文件如下, name1 依赖name2, 但是name2 没有定义, 如下:
name1: name2
@echo "name1"
执行make命令报错如下, 因为name2没有找到对应的target:
make: *** No rule to make target `name2', needed by `name1'. Stop.
如何让name1可以顺利执行呢,可以有如下三种方法:
- 在makefile中定义name2, 比如:
- 在与makefile同一个文件夹下创建name2文件
- 在 makefile 中添加伪目标 .PHONY: ReadMe.md, 如下所示:
name1: name2
@echo "name1"
.PHONY: name2
执行结果如下:
name1
2.5 文件依赖
include {path}/demo.mk
3. 实例
需要对当前项目下proto文件夹中所有的*.proto文件 生成对应的grpc文件
项目路径如下:
makefile 如下:
GO := go
ifndef ROOT_DIR
ROOT_DIR := $(shell pwd)
endif
# 查找项目根目录下所有.proto文件, 剔除依赖文件: $(ROOT_DIR)/proto/validate/*.proto
PROTOS := $(shell find $(ROOT_DIR)/proto -type d \( -path $(ROOT_DIR)/proto/validate \) -prune -o -type f -iname '*.proto' -print)
##### 生成grpc代码文件, 依赖%.pb.gateway.go
%.pb.go: %.proto %.pb.gateway.go
@echo ">> generating $@"
$(ROOT_DIR)/make/protoc-go.sh $<
##### 生成grpc的gateway代码文件
%.pb.gateway.go: %.proto
@echo ">> generating gateway $@"
$(ROOT_DIR)/make/protoc-gateway.sh $<
##### 生成grpc的validate代码文件
%.pb.validate.go: %.proto
@echo ">> generating validate $@"
$(ROOT_DIR)/make/protoc-validate.sh $<
generate: grpc-generate
##### 所有proto文件生成pb.go
grpc-generate: $(patsubst %.proto,%.pb.go,$(PROTOS))
##### 所有proto文件生成pb.validate.go
grpc-generate: $(patsubst %.proto,%.pb.validate.go,$(PROTOS))
##### 指定文件生成gateway
grpc-gateway: proto/gateway.pb.gateway.go
.PHONY: grpc-generate generate grpc-gateway
执行make:
生成的文件: