前言
在linux或unix环境中构建应用时,根据官方文档的指导,常常会使用到 make xxx 这个指令,在执行后就会为我们安装某个应用所需要的依赖,那么这个 make 到底是什么呢?
make 是什么?
make 是一个在软件开发中所使用的工具程序(Utility software),经由读取 “makefile” 的文件以自动化建构软件。它是一种转化文件形式的工具,转换的目标称为“target”;与此同时,它也检查文件的依赖关系,如果需要的话,它会调用一些外部软件来完成任务。
顾名思义,make 当然是用于创造的,它的功能就是基于一个 makefile 文件的描述去构建应用所需要依赖,makefile文件中定义了一系列需要执行的任务。就例如前端开发中 npm 包管理器一样, 我们需要一个 package.json 去描述我们所需要的依赖。
在执行make命令后,会在当前目录下找名字叫 Makefile 或 makefile 的文件。
make 的能力有以下几点:
-
Make 使最终用户 无需知晓构建的细节 就能够构建和安装某个包,因为这些细节都记录在应用提供的 makefile 中。
-
Make 根据已更改的源文件 自动计算出需要更新的文件。它还会自动确定更新文件的正确顺序,以防一个非源文件依赖于另一个非源文件。
因此,如果您更改了一些源文件然后运行 Make,它不需要重新编译您的所有程序。它仅更新那些直接或间接依赖于您更改的源文件的非源文件。
-
Make 不限定语言。对于程序中的每个非源文件,makefile 指定了计算它的 shell 命令。这些 shell 命令可以运行编译器来生成目标文件,运行链接器来生成可执行文件。
-
Make 不仅局限于构建一个包。还可以使用 Make 来安装或卸载包,为其生成标签表。还可以写入一些在构建时需要执行的命令,就像p ackage.json 中的 scripts 字段那样。
makefile语法
简单来说 makefile 中就是集成了很多脚本,当我们使用 make xxx
命令时会将我们传入的 xxx
进行条件判断,看看匹配上了哪一个就执行哪一段脚本。makefile中大部分的语法与 shell 或 bash 相同。
基本格式
# 用“#”号表明注释。
target(要生成的文件): dependencies(被依赖的文件)
# 命令前面用的是“tab”而非空格。误用空格是初学者容易犯的错误!
命令1
命令2
命令3
...
命令n
# 可以使用“\”表示续行。注意,“\”之后不能有空格!
例如我们创建一个新的makefile,在其中写入以下代码:
.DEFAULT_GOAL := mkdir
hello:
@echo "Hello I'm oil"
mkdir:
@echo "create a new dir"
mkdir test
rmdir:
@echo "delete a dir"
rm -rf test
分析一下上面的代码,当我们执行 make
时,会按照我们代码中的目标顺序从上往下执行,但是在上面的代码中并不会执行 hello 而是执行 mkdir,因为我们在文件头部写入了 .DEFAULT_GOAL := mkdir
如果Make命令运行时没有指定目标,默认会执行Makefile文件的第一个目标。。
target
是必需的,不可省略,而 dependencies
和 要执行的命令
都是可选的,但是后两者之中必须至少存在一个。
一个 target 就构成一条规则。指明Make命令所要构建的对象。target 除了可以是文件名以外,还可以是某个操作名,也称为 伪目标 。伪目标可以使用 .PHONY: target(目标名称)
来定义。
.PHONY: help
help:
$(call func_echo_success_status, "Makefile rules:")
更多的内置目标大家可以查看这个文档:https://www.gnu.org/software/make/manual/html_node/Special-Targets.html#Special-Targets
dependencies(被依赖的文件)决定了目标文件是否重新构建,一般使用空格分隔的一组文件名,只要有一个前置文件不存在,或者前置文件的 last-modification 时间戳比目标的时间戳新,目标文件就需要重新构建。
a.txt:b.txt c.txt
@echo "Hello I'm oil"
b.txt:c.txt
touch b.txt
c.txt:
touch c.txt
在上面的代码中,如果三个文件都不存在,如果执行第一次执行 make a.txt
就会根据依赖去创建 c.txt 和 b.txt ,如果再执行一次的话就满足了 a.txt 所需的依赖文件生成。
定义变量
在 makefile 中可以直接使用 =
号定义变量,使用 $(变量名)
使用变量。
A = hello
B = world
hello:
@echo $(A) $(B)
mkdir:
@echo "create a new dir"
mkdir test
rmdir:
@echo "delete a dir"
rm -rf test
关闭回声
在执行 make 命令时,如果没有做其他处理,为了让开发者知晓目前在执行哪个命令控制台默认会打印每一条命令,也就是回声机制。如果想要控制台不打印可以通过在命令前添加 @
号关闭回声。
test:
@# 不打印内容
# 打印内容
更多的 makefile 语法大家可以查看这个文档:https://gist.github.com/isaacs/62a2d1825d04437c6f08
总结
第一次写 Linux 相关的内容,为了学习上手服务端的技术还有很多知识点等待学习,这几天要开始爆肝了,不能止步于前端,争取在一个月的时间内对服务端的大部分知识点有具体的认知~