前言
如果想编写好Makefile
,你需要了解 Makefile
的 语法、变量、函数 等相关知识,并且能够熟练运用
编写help
忘记从哪里copy的了,不过很好用
只要在 tagert 上方 以 ## ......
写注释,就能被help伪目标解析
Makefile:
.PHONY: help
help: Makefile
@echo -e "\nUsage: make <TARGETS> <OPTIONS> ...\n\nTargets:"
@sed -n 's/^##//p' $< | column -t -s ':' | sed -e 's/^/ /'
@echo "$$USAGE_OPTIONS"
## eq: 提供测试ifeq的例子 make eq flag=1
eq:
# ifeq 后跟一个空格,不然你会报错哦 Makefile:4: *** missing separator. Stop.
ifeq ($(flag),1)
@echo is product
else
@echo is dev
endif
## neq: 提供不等于的测试
neq:
ifneq ($(flag),0)
@echo is product
else
@echo is dev
endif
第二行的Makefile(和当前Makefile文件名保持一致)是和第四行的$<(自动化变量)相对应的,可以参考
Makefile 变量
合理的结构
- makefile中放置常用和简单的命令
- 如果命令比较复杂,可以将其放到其它目录中(如:install.sh),在makefile中调用scripts中的
- 如果命令不常用,应该放到其它mk中去(如:scripts/make-rules/gen.mk),在makefile中 include
- 不常用的命令也应该进行归类 如:gen.mk(生成一类的命令),install.mk(安装一类的)
- 通过include引入的mk的target应该带上归类名称
scripts/make-rules/gen.mk
## 符合c 进行了归类
## 符合d target 带上了 gen 分类
gen.sql:
@echo "生成sql"
gen.data:
@echo "生成数据"
scripts/make-rules/install.mk
## 符合c 进行了归类
## 符合d target 带上了 gen 分类
install.mysql:
@echo "install mysql"
install.nginx:
@echo "install nginx"
Makefile
## 符合b 不常用的命令通过include引入
include scripts/make-rules/gen.mk
include scripts/make-rules/install.mk
## 符合a 调用复杂的命令
fz:
scripts/install.sh
通配符加自动变量
能解决很多类似的东西
Makefile
install.%:
@echo "正在安装 $*"
善用函数
就像写代码用已有的函数肯定比自己实现快
统一的输出目录
构建的,打包的,临时的 … ,放在同一个目录下,方便查找和清理
/output/build
/output/pack
/output/once
定义环境变量
这里的环境变量不是特指在linux中定义的环境变量,是指不是固定写死的变量(易修改的变量)
bad :
换1.8 需要修改两处
a:
go.17 build main.go
b:
go.17 build hello.go
good :
go = go.18
a:
$(go) build main.go
b:
$(go) build hello.go
自己调用自己
如果 makefile 的 target 比较通用,可能在其它的 target 中 被 调用
MAKEFLAGS += --no-print-directory
all:
@echo "all"
@$(MAKE) install.all
install.%:
@echo "开始安装 $*"
MAKEFLAGS += --no-print-directory
不打印切换目录相关信息, 自己调用自己有一个切换目录过程