概述
在Shell脚本中使用make命令来进行编译,尤其在C/C++开发中,make命令通过makefile文件中描述源程序之间的依赖关系进行自动编译;makefile文件是按照规定格式编写,需说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系;
很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之间的依赖关系不知会多复杂。
文章目录
- make
- make常见指令
- make如何工作
- Makefile文件
- 目标target
- 前置条件prerequisites
- 命令commands
- 语法
- 赋值运算符
- 自动变量
- 判断语句
- 循环
- 参考
make
make常见指令
make命令后接参数,称为目标;常见目标如下图所示:
指令 | 含义 |
---|---|
make all | 编译所有目标 |
make -j | 使用所有的核心编译目标 |
make -j8 | 使用8个核心编译目标 |
make install | 安装已编译的程序 |
make uninstall | 卸载已安装的程序 |
make clean | 删除由make命令产生的文件,通常删除目标文件.o |
make distclean | 删除由./configure产生的文件 |
make check | 测试刚编译的软件 |
make installcheck | 检查安装的库和程序 |
make dist | 重新打包成packname-version.tar.gz |
执行make命令时,需要一个Makefile文件,以告诉make命令如何编译和链接程序;
make如何工作
- make在当前目录下寻找“Makefile”或“makefile”文件
- 若找到,查找文件中的第一个目标文件.o
- 若目标文件不存在,根据依赖关系查找.s文件
- 若.s文件不存在,根据依赖关系查找.i文件
- 若.i文件不存在,根据依赖关系查找.c文件,此时.c文件一定存在,于是生成一个.o文件,再去执行
Makefile文件
Makefile文件由一系列规则rules构成,每条规则形式如下:
<target>: <prerequisites>
[Tab]<commands>
第一行冒号前为目标,冒号后为前置条件;第二行必须由一个Tab键起首,后接命令;目标是必须的,不可省略;前置条件和命令是可选的,但两者必须至少存在一个。
目标target
目标可以是文件名,指明make命令所要构建的对象;也可以是某个操作名称,称“伪目标”;
clean:
rm *.o
以上代码目标是clean,命令是rm *.o;
执行make clean命令,实现对象文件的删除;
前置条件prerequisites
前置条件通常是一组文件名,用空格隔开;
指定目标是否重新构建的判断标准——只要有一个前置条件不存在或有更新,则该目标需重新构建;
result.txt:source.txt
cp source.txt result.txt
若当前路径下source.txt存在,make result.txt可正常执行,否则需再写一条规则,用于生成source.txt;
source.txt:
echo "This is a source file." > source.txt
source.txt没有前置条件,与其他文件文官,只要该文件不存在,每次执行make source.txt命令都会生成该文件;
命令commands
命令表示如何更新目标文件,由一行或多行shell命令组成;
注:
shell命令一定是写在命令中,否则会被make忽略;
每行命令前必须有一个Tab键;
每行命令在一个独立的shell中执行,shell之间没有继承关系,因此上一行为的变量赋值,在下一行无效;
若前后两条命令有共享数据,可写在一行,用分号隔开;
var-kept:
export foo=bar;echo "foo=[$$foo]"
语法
指令 | 含义 |
---|---|
# | 注释 |
echoing | 正常情况下,make打印每条命令,再执行该命令,称回声;在命令前加@,关闭回声,即只输出命令的执行结果,出错则停止执行 |
% | make命令允许对文件名进行类似正则运算的匹配,主要用到% |
$() | 调用变量,将变量名放在$()中 |
赋值运算符
指令 | 含义 |
---|---|
= | 递归展开赋值,默认赋值方式 |
:= | 直接赋值,不会递归展开,若引用的变量不存在,则为空串 |
?= | 若未初始化,则赋值 |
+= | 将值追加到现有内容末尾 |
自动变量
指令 | 含义 |
---|---|
$@ | 当前目标 |
$< | 第一个前置条件 |
$? | 所有比目标更新的前置条件 |
$^ | 所有前置条件 |
判断语句
<条件语句>
<条件为真,执行程序段>
else
<条件为假,执行程序段>
endif
1. 比较两个参数值是否相等
ifeq (arg1, arg2)
ifeq 'arg1' 'arg2'
ifeq "arg1" "arg2"
ifeq 'arg1' "arg2"
ifeq "arg1" 'arg2'
注:参数还可用make函数,如ifeq ($(strip $(foo)),);
2. ifneq 比较两个参数值是否不等
ifneq (arg1, arg2)
ifneq 'arg1' 'arg2'
ifneq "arg1" "arg2"
ifneq 'arg1' "arg2"
ifneq "arg1" 'arg2'
3. ifdef 判断变量是否有值
ifdef var
4. ifndef 判断变量是否无值
ifndef var
循环
LIST变量是Makefile变量,引用Makefile变量需使用$()
括起来;
而all目标后的命令是shell命令,其中定义的变量也是shell变量,引用shell变量需使用$$作为开头,但shell变量不需括号;
LIST = one two three
all:
for i in $(LIST); do
echo $$i;
done
all:
for i in one two three; do
echo $$i;
done
参考
makefile中使用shell 命令 - CSDN博客
Makefile经典教程(掌握这些足够) - CSDN博客
Shell脚本——make命令和Makefile文件 - CSDN博客
最后
以上就是奋斗小霸王为你收集整理的Ubuntu——Makefile文件与make命令makeMakefile文件参考的全部内容,希望文章能够帮你解决Ubuntu——Makefile文件与make命令makeMakefile文件参考所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复