在学习linux的过程中,Makefile的写法很重要,现在总结下自己所学如何写makefile
1、首先要了解下程序的编程过程
语言主要分为两种,编译语言和解释语言
编译语言:在程序运行之前需要经过两步:编译和链接。首先是编译阶段,编译阶段主要是检查程序的函数语法是否正确,变量的声明是否正确。只要没有错误的语法,编译器就可以成功将源文件编译成为目标文件,每个源文件对应生成一个目标文件。第二步是链接,即链接器将目标文件链接为可执行文件,链接器是并不管函数所在的源文件,而是只考虑目标文件。目标文件的后缀在windown和linux不同,在window中,目标文件后缀为.obj,而在linux或者Unix中,后缀为.o。
有些工程的源文件比较多,生成的源文件也比较多,等链接器链接目标文件时比价复杂,为此,可以将目标文件进行打包。在window中,将多个目标文件.obj打包为库,后缀为.lib,在linux中,将多个目标文件.o打包为.a库。
编译语言在生成可执行文件之前,需要进行编译和链接的过程,但是仅需要执行一次,在后续的再次执行时,是不需要再次进行编译连接,所以编译语言的效率比较高。常用的有c、c++
解释语言:边执行边解释,执行一句解释一句。每个语句都是在执行的时候才进行翻译。所以解释语言每运行一次就需要一次解释。但是解释语言也有自己的优点,即他在不同操作系统的兼容性比较好。常用的解释语言有Python、java或者Ruby等
2、make和makefile的编译链接规则:
在执行make命令的时候,系统会默认在当前目录下寻找Makefile或者makefile文件,以告诉make命令如何去编译和链接源代码
假如一个工程包含多个源文件和头文件,对其进行编译和链接需要以下几个规则:
1)如果这个工程没有编译过,那么所有的源文件都需要被编译链接;
2)如果某几个.c源文件修改,则需要重新对这几个源文件进行编译生成目标文件,再重新链接生成最终的可执行文件;
3)如果头文件发生变化或者修改,则需要重新编译包含这几个头文件的源文件生成目标文件,然后重新编译生成最终的可执行文件;
3、 makefile的写法:(两种写法)
方法一:
target:prerequisites
command
注意:若command和target:prerequisites不在同一行时,command前面必须是TAB键
方法二:
target:prerequisites;command
注意:若command和target:prerequisites在同一行,之间用分号。
target 目标文件:既可以是可执行文件也可以是目标文件
prerequisite:生成target所需的源文件、头文件或者是目标文件
command:prerequisites->到target所需要进行的操作
注意:若prerequisites的文件比target新,那么就需要重新编译链接
eg:
edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
备注:红色代表的是target;紫色代表的是prerequisites;绿色表示的command
可执行文件edit依赖于多个.o目标文件,而每个.o文件又依赖于各自的.h头文件和.c源文件。
4、makefile引用其他的makefile
makefile也可能包含其他的makefile,书写语法类似于c语言的include,可以利用关键字include包含其他的makefile文件。在执行makefile的时候,会把include包含的makefile内容放置在当前的位置。
5、make具有自动推导功能
在执行make命令的时候,make具有自动的推导功能,即在看到目标target和prerequisites后,可以推导出command。所以我们可以简化makefile,比如第三小节的例子可以简写如下:
edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
main.o : main.c defs.h
kbd.o : kbd.c defs.h command.h
command.o : command.c defs.h command.h
display.o : display.c defs.h buffer.h
insert.o : insert.c defs.h buffer.h
search.o : search.c defs.h buffer.h
files.o : files.c defs.h buffer.h command.h
utils.o : utils.c defs.h
clean :
rm edit main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
6、makefile寻找文件
makefile在寻找源文件或者目标文件时,遵循的原则如下:
1)先寻找makefile中指定的路径寻找,若没找到;
2)在当前目录下寻找,若没有;
3)默认去/usr/local/bin和/usr/local/inlude去寻找相应的文件。
makefile的总结