Linux系统中编译大型C语言项目必备技能之:Makefile文件的编写
文章目录Makefile的介绍Makefile的编写规范——简单举例Makefile的编写规范——复杂举例项目描述编译需求编译思路Makefile的介绍我们在阅读一些大型的C语言项目时,通常会在项目文件夹中看到一个名为makefile的文件。Makefile是Linux系统中用于编译C语言项目的一种编译脚本,传统的Linux通过gcc工具在命令行输入命令来编译C语言程序,但当需要编译的c文件过多时
Makefile的介绍
我们在阅读一些大型的C语言项目时,通常会在项目文件夹中看到一个名为makefile的文件。Makefile是Linux系统中用于编译C语言项目的一种编译脚本,传统的Linux通过gcc工具在命令行输入命令来编译C语言程序,但当需要编译的c文件过多时,频繁的输入编译指令显得十分繁琐。makefile文件能够帮助我们更快速更方便的编写C语言项目。
Makefile的编写规范——简单举例
以一个简单的例子来说明,当我们需要编译一个名为test.c的c语言文件时,我们通常需要在终端输入以下指令:
gcc test.c -o test
当然,这句指令同样可以写入makefile文件中。想要使用makefile来编译以上的代码,我们需要在代码所在文件夹新建一个名为Makefile的文件(写作makefile同样可以,目前的系统对于第一个字母m是否为大小写均认可),并输入以下内容:
test: test.c
gcc test.c -o test
以上是makefile最简单的一种写法,它的含义为:
第一行:第一行顶头的test表示你想要生成的可执行文件名称,后面接一个冒号,冒号后的test.c表示生成该可执行文件所需要的依赖文件。
第二行:gcc编译指令。这里需要注意的是编译指令前必须用tab隔开,如果自己的编辑器不会自动替你用tab隔开,务必加上一个tab。四个空格都不行,必须是tab。
那么以上就是一种最简单的makefile文件的写法。写好该文件后,下次的编译只需要在终端输入:
make
即可代替原本的编译指令,完成对项目的编译了。
当然以上的写法只是最简单的一种写法,接下来我们看一个复杂的项目。
Makefile的编写规范——复杂举例
项目描述
我们有以下几个文件:
main_max.c
main_min.c
max.c
min.c
util.c
command.c
max.h
min.h
util.h
command.h
其中main_max.c和main_min.c是两个包含main函数的程序,
max.c,min.c,util.c和command.c是一些函数的文件,
max.h,min.h,util.h和command.h是其对应的头文件。
编译需求
我们需要将这些c文件和h文件编译出两个可执行文件,分别为main_max和main_min,
main_max需要使用max.c,util.c和command.c中的函数,
main_min需要使用min.c,util.c和command.c中的函数,
编译时需要加上链接选项-lm及debug选项-g。
编译思路
main_max可执行文件的依赖文件,除了包含main_max.c,还包含max.o,util.o和command.o。其中.o文件指.c文件编译出的目标文件。
而max.o文件,又可以通过max.c和max.h文件编译生成,其他同理。故我们可以采用以下写法:
CC = gcc
CFLAGS = -lm -g
all: main_max main_min
main_max: main_max.c max.o util.o command.o
$(CC) $(CFLAGS) main_max.c max.o util.o command.o -o main_max
main_min: main_min.c min.o util.o command.o
$(CC) $(CFLAGS) main_max.c min.o util.o command.o -o main_max
max.o: max.c
$(CC) $(CFLAGS) -c max.c
min.o: min.c
$(CC) $(CFLAGS) -c min.c
util.o: util.c
$(CC) $(CFLAGS) -c util.c
command.o: command.c
$(CC) $(CFLAGS) -c command.c
clean:
rm *.o main_max main_min
.PHONY: all clean
以上内容看起来有些复杂,让我们看一下它与上面简洁版的有什么不同
第一行中的 CC = gcc
表示makefile中的变量。当我们在makefile文件需要频繁输入某段内容时,如gcc,链接指令等,可以将其写成便于理解与修改的变量,在下文将要写到该内容时,用 $(变量名称) 即可表示。这样也方便对重复的内容进行修改。
最后的.PHONY: all clean
.PHONY表示一个声明,声明的含义为冒号后面的内容是一个伪目标。
伪目标是一类不需要在文件中编译出来的目标,如这里的all的作用为批量生成多个可执行文件。如果没有此处的all,makefile文件在执行完第一个命令生成main_max之后,便不再继续生成main_min。需要在第四行处用伪目标all列出所有需要编译出的可执行文件,才能够批量编译。
目标(.o)文件的编译
如max.o文件的编译,需要在其依赖文件也就是.c文件前,加上一个-c选项,意为将该C文件编译为目标文件。先编译为目标文件的好处是,如果我们使用了这种编译方法,那么我们在之后修改代码的过程中,如果修改了其中一个.c文件,其他的.c文件没有修改,那么编译时我们只会对修改的.c文件进行重新编译,而不会对其他文件重复的编译,在工程量大的时候,节省了整个编译过程的时间。
clean命令
通过这种编译方式,会生成可执行文件和大量的目标文件,有时,当我们需要将自己的源代码发布出来的话,文件夹里的目标文件和可执行文件一般都是需要删除掉的。这时就需要使用clean功能。clean命令后是一段Linux的rm指令,“*.o”表示文件夹内所有后缀为.o的文件。在makefile中加入的clean的指令后,我们在终端输入:
make clean
这段指令,即可将所有目标文件和可执行文件全部删除了。
以上就是一段结构完整的makefile文件,当然makefile文件远不止这些功能,更多的功能我们需要通过之后的学习慢慢领悟。
更多推荐
所有评论(0)