type
status
date
slug
summary
tags
category
icon
password
🗓️学习日期规划
2023/6/20
😦Makefile是啥
一种用于自动化构建和管理软件项目的文件。和make命令搭配使用
📝写一个简单的Makefile
编辑 Makefile,写入一个最简单的
然后运行 make hello,可以发现输出了
➜ make hello
echo "hello world"
hello world
当然,我们可以在其中插入更多的过程(但是这个过程是不严谨的,因为hello此时应该是要被构建的目标,只有echo是不足以构建的,也就是make必须要产生点东西,在这里就是要产生hello,最差的做法都必须要 echo “hello world” > hello
尝试将makefile修改成这样,然后写入一些简单的东西
很神奇
📓配合C语言进行编译与使用
首先写一个简单的 main.c
然后仿照我们日常使用的make命令,写一个简单的makefile
尝试 make build, make install 后直接在控制台执行 hello 试试
再试试 make uninstall, make clean 等操作
工作很正常
插入变量
自定义变量
Makefile中也可以使用变量,我们可以这样尝试,在makefile的开头插入 target_name = hello,并重新尝试 make build, make install等操作
预定义变量
除此之外,makefile还会有一些预定义变量,我们可以这么编写一个来查看
环境变量
还可以查看一些环境变量,比如 PATH 之类的
在参考文章内,还可以发现有一些其他的环境变量
Makefile 常用的环境变量有下面这些:
$*
:不包含扩展名的目标文件名称
$<
:第一个依赖文件名称
$?
:所有时间戳比目标文件晚的依赖文件
$@
:目标文件完整名称
$^
:所有不重复的依赖文件
Makefile 切换工作目录
需要注意的是,makefile每一行的命令是独立的,不会说上一条cd了以后工作目录就变了。如果需要跨目录执行,则需要在同一行使用 && 拼接,以下是拼接后的结果
Makefile 伪目标
伪目标(Phony Target)是一种特殊类型的目标,其名称与实际文件名或目标不相关。伪目标通常用于定义一些不生成对应输出文件的操作或命令。它们用于表示一些常见的动作或规则,并提供一种方便的方式来执行这些操作。
伪目标在Makefile中以特殊的方式声明,使用伪目标可以避免与实际文件名冲突,并且即使存在同名的文件,也能确保这些规则被执行。伪目标在Makefile中没有依赖关系,即使依赖项的文件存在,伪目标的规则也会被执行。
罗里吧嗦的讲了一大堆,结果我自己都没看懂,那就实际写个东西看看吧
对于单个构建
尝试写一个这样的makefile
然后再创建一个test1,尝试make test1
可以发现,test1所在的构建没法正常执行了,这是因为make判断当前目录下已经有test1这个文件了,那你已经构建完成了,我就没必要给你重复执行这个过程了,而.PHONY: test1就是告诉make,你这个构建过程不产生一个叫test1的文件,如果没有.PHONY,那么我一看到你有test1这个文件我就不会执行了。而如果有.PHONY,我不管你有没有test1,我都去执行test1这个过程。
加上 .PHONY: test1 ,我们再来试试
加上了,可以发现,这时候make test1已经不管你目录下是否有test1了,我都照样执行。
对于依赖关系
尝试写一个这样的makefile,注意这里 test1: test2 test3 是放在同一行的,目的是为了让它执行test2和test3的构建,而不是将test2和test3当成命令。
在文件目录没有 test* 的时候,它执行的结果是这样的
我们尝试创建一个test2,再重新执行一遍
发现了吗,少了一个test2。
我们再尝试创建一个test3
又少了一个。
然后我们尝试加入这个传说中的伪目标
发现了吗,明明test2这个文件是存在的,但它还是执行了test2,我们再把test3加上。
test3也回来了,删掉test2和test3也是同样的结果。
至此,就可以发现,.PHONY的加入,可以让 Makefile 不再去看对应构建是否存在该文件再去判断是否执行。
Makefile 包含
如果在不同目录下有不同的 Makefile,可以用下面的方法来嵌套
注意,这里include了build文件夹的Makefile以后,使用的是哪个目录下的makefile,那么工作目录就在那个目录,不会说工作目录变成了build
尝试在工作目录 make build2,成功执行,且文件生成到了 ./build/hello。
Makefile 条件判断
makefile也可以进行条件判断,但是只能进行一些简单的判断,如 ifeq, ifneq, ifdef, ifndef
需要注意的是,条件判断语句不能直接放在规则的命令部分,因为这些语句需要在 Makefile 的解析阶段进行处理,而不是在命令执行阶段。
即以下的写法是错误的
它会抛出以下异常
Makefile 管理命令
makefile还有许多管理命令,用--help就能看到,这里就不赘述了
⁉️自问自答
- 像make xxx这样的指令,xxx就是在makefile中定义好过程的吗?
确实是。我们可以尝试新建一个Makefile,输入 hello: echo “Hello World”
然后输入 make hello
➜ make hello
echo "hello world"
hello world
- 只有C/C++能用makefile吗
从上面就能看得出来,并不是这样的,只不过比较常用的是这个而已?它就是描述一个过程,使用make xxx会执行一系列的命令,所以,当然我们可以在其中放一些恶意代码。makefile会像执行shell一样执行下来。
- 什么是 Makefile 伪目标(?)
伪目标(Phony Target)是一种特殊类型的目标,其名称与实际文件名或目标不相关。伪目标通常用于定义一些不生成对应输出文件的操作或命令。它们用于表示一些常见的动作或规则,并提供一种方便的方式来执行这些操作。
伪目标在Makefile中以特殊的方式声明,使用伪目标可以避免与实际文件名冲突,并且即使存在同名的文件,也能确保这些规则被执行。伪目标在Makefile中没有依赖关系,即使依赖项的文件存在,伪目标的规则也会被执行。
解决方案看上面
- Makefile 怎么切换目录执行
不能直接在一行cd后在下一行执行,而是需要在需要切换目录命令同一行前面加上cd &&
例如:cd build && pwd,否则下一行目录就会变回去了
- make 的多线程编译?
🤗鸣谢
- 的 Arch-Playground
- 的 技术支持与规划
🔖参考文章
本文以学习为目的,大部分内容都参考了以下文章,十分感谢以下的文章。