Ubuntu——Makefile文件与make命令

在Shell脚本中使用make命令来进行编译,尤其在C/C++开发中,make命令通过makefile文件中描述源程序之间的依赖关系进行自动编译;makefile文件是按照规定格式编写,需说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系;
  很多大型项目的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项目中各种库和代码之间的依赖关系不知会多复杂。

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如何工作

  1. make在当前目录下寻找“Makefile”或“makefile”文件
  2. 若找到,查找文件中的第一个目标文件.o
  3. 若目标文件不存在,根据依赖关系查找.s文件
  4. 若.s文件不存在,根据依赖关系查找.i文件
  5. 若.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博客

  • 23
    点赞
  • 195
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值