当前位置:   article > 正文

Makefile 学习笔记_makefile文件命名

makefile文件命名


前言

       一般在工程中,有不计其数的源文件,这些文件按类型、功能、模块分别放置在若干目录中,而这些源文件在使用前一般需要进行编译,如果一个个单独进行编译,将需要进行大量重复性操作,对此Makefile提供了解决办法,通过定义一系列规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至进行更为复杂的功能操作。

       对此,本文针对Makefile的使用规则进行讲解,介绍。

Makefile的使用规则

1、Makefile的文件命名规则

Makefile或者makefile,一般使用Makefile

2、Makefile基本语法

目标:依赖

[tab] 命令

目标:一般是指要编译的目标,也可以是一个动作。

依赖:指执行当前目标所要依赖的先项,包括其他目标,某个具体文件或库等;

           一个目标可以有多个依赖。

命令:该目标下要执行的具体命令,可以没有,也可以多条命令,当有多条命令时,每条命令单独一行。

  1. hello : hello.c
  2. gcc hello.c -o hello

3、Makefile 工作原理

当调用make命令执行Makefile时,make会先找到Makefile文件中的第一条规则,分析并执行相应动作。而当执行命令中的依赖不存在时,会自动检测下面是否有生成该依赖的规则,若存在,则执行该规则的命令。

4、文件时间戳

make命令在执行的时候会根据文件的时间戳进行判断,是否需要执行Makefile中有涉及的规则。具体表现如下:

1、一般情况下,目标文件通过依赖文件形成的,所以目标文件的时间戳小于所有依赖文件的时间戳;

2、当出现某一依赖文件的时间戳大于目标文件的时间戳,此时目标文件将通过该规则中的命令被重新生成。

5、变量

Makefile在进行规则定义时,为了避免脚本过于冗长,且增加灵活性,可以使用变量。

Makefile中的变量主要分为三种:

(1)自定义变量:用户可以设定自己的变量,并且在Makefile中变量没有类型,只需要直接创建变量并赋值即可。

(2)预定义变量:Makefile中预先定义的变量,用户可直接引用,无需重复定义;

常见预定义变量如下表所示:

变量名含义
AR生成静态库库文件的程序名称
AS汇编编译器的名称
CCC语言编译器的名称
CXXC++语言编译器
FCFORTRAN 语言编译器的名称
RM删除文件程序的名称
ARFLAGS生成静态库库文件程序的选项
ASFLAGS汇编语言编译器的编译选项
CFLAGSC语言编译器的编译选项
CXXFLAGSC++语言编译器的编译选项
FFLAGSFORTRAN 语言编译器的编译选项

(3)自动变量:自动变量只能在规则中的命令使用,可以对一些目标以及依赖进行指代。具体使用方法如下:

变量含义
$*表示目标文件的名称,不包含目标文件的扩展名
$@表示目标文件的名称,包含目标文件的扩展名
$+表示所有依赖文件,这些依赖文件之间以空格分开,按照出现的先后为顺序,其中可能包含重复的依赖文件
$<表示依赖项中第一个依赖文件的名称
$?依赖项中,所有比目标文件时间戳晚的依赖文件,依赖文件之间以空格分开
$^依赖项中,所有不重复的依赖文件,这些文件之间以空格分开

6、模式匹配

在编写Makefile过程中,可能出现许多规则做一样的事情,而由于文件名不同,需要逐一编写规则,这会导致Makefile变得冗长。而通过模式匹配的方法可以完美解决该问题。模式匹配可以将相同操作整理成一个模板,使所有操作都会通过模板执行,大幅缩短脚本代码量。

  1. app : main.o helloworld.o dev.o add.o
  2. gcc main.o helloworld.o dev.o add.o -o app
  3. #当需要将所有.c文件生成.o文件时,一个个编写过于繁琐,如下所示
  4. main.o : main.c
  5. gcc main.c -o main.o
  6. helloworld.o : helloworld.c
  7. gcc helloworld.c -o helloworld.o
  8. dev.o : dev.c
  9. gcc dev.c -o dev.o
  10. add.o : add.c
  11. gcc add.c -o add.o
  12. #通过模式匹配则可以完美解决该问题,利用以下两行代码即可实现。其中%为通配符,用于匹配文件名
  13. %.o : %.c
  14. gcc $^ -o $@

 7、函数

Makefile中也可以使用函数,其中所有函数均有返回值,写法为:

$(函数名 参数1, 参数2, 参数3,...)

下面介绍一些函数

wildcard:获得指定目录下指定类型的文件名,返回值以空格分割。

  1. #该函数的参数只有一个,但该参数可以通过空格分割
  2. $(wildcard PATTERN ...)
  3. #示例
  4. $(wildcard .c ./LinuxStudy/.c)
  5. #返回值为当前目录下的.c文件以及LinuxStudy下的.c文件

patsubst:查找<text>中的单词是否符合<pattern>,若匹配则用<replacement>替换

  1. #该函数有三个参数,参数之间使用逗号隔开
  2. $(patsubst <pattern>,<replacement>,<text>)
  3. #示例
  4. a = main.c hello.c dev.c add.c
  5. # 要将变量a中所有文件名的后缀.c替换为.o时可以进行如下操作
  6. obj= $(patsubst %.c, %.o, $(a))
  7. #obj的值为:main.o hello.o dev.o add.o

8、Makefile clean规则

在执行make指令后,我们发现在目录下会生成许多.o文件,而我们只需要目标文件,其他文件都是多余的,这时候就需要增加一条clean命令来处理。

最终一个简单的Makefile脚本就可以写成如下

  1. src=$(wildcard ./*.c)
  2. obj=$(patsubst %.c, %.o, $(src))
  3. target : $(obj)
  4. $(CC) $(obj) -o $@
  5. %.o : %.c
  6. $(CC) $< -o $@
  7. clean:
  8. rm $(obj) -f

 Makefile运行示例

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/640936
推荐阅读
相关标签
  

闽ICP备14008679号