Ubuntu——Makefile文件与make命令

  • 时间:
  • 来源:互联网
  • 文章标签:

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

  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博客

本文链接http://www.taodudu.cc/news/show-647375.html