1.MAKEFILE概述
想要成为专业程序员,mekefile必须懂 !尤其是在Linux下进行软件编译,makefile就不得不自己写。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计其数,并且按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个 Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。 make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
note:MAKEFILE两大好处:1.自动化编译,只需要一个make命令,整个工程完全自动编译,方便编译管理,极大的提高了软件开发的效率。2.增量编译,只编译修改过的文件,执行子任务时它会先检查输入文件是否比输出文件新,如果说输入文件是新的,需要重新生成输出文件,此时才会执行子任务,因此优化了gcc命令编译效率低的问题。
makefile基本结构
makefile是make读入的唯一配置文件
1.由make工具创建的目标体(target),通常是目标文件或可执行文件
2.要创建的目标体所依赖的文件(dependency_file)
3.创建每个目标体时需要运行的命令(command)
注意:命令前必须是一个“TAB键”,否则编译错误为:*** missing separator. Stop.
makefile格式:
target : dependency_files ##dependency_files是依赖的文件
command #注意是一个TAB
例子:
hello.o:hello.c hello.h
gcc -c hello.c -o hello.o
makefile的基本使用实例
新建f1.c、f2.c、main.c、head.h四个文件,并输入一下内容:
- f1.c内容如下:
#include <stdio.h>
void print1(){
printf("Message:f1.c\n");
}
- f2.c内容如下:
#include <stdio.h>
void print2()
{
printf("Message:f2.c\n");
}
head.h内容如下
void print1();
void print2();
- main.c内容如下:
#include <stdio.h>
#include "head.h"#调用自己写的头文件用引号
int main()
{
print1();
print2();
printf("end main\n");
return 0;
}
在没有编写makefile之前可以使用命令gcc *.c -Wall
查看当前代码是否有语法错误。检查没有语法错误以后可以编写makefile文件。
- 新建makefile文件并输入以下内容:
test:f1.o f2.o main.o #生成test文件需要 f1.o f2.o main.o gcc f1.o f2.o main.o -o test f2.o:f2.c #生成f2.o文件需要f2.c gcc -c -Wall f2.c -o f2.o# -Wall允许发出gcc所有有用的报警信息 f1.o:f1.c gcc -c -Wall f1.c -o f1.o#-c表示只编译不链接,生成目标文件“.o” main.o:main.c gcc -c -Wall main.c -o main.o#-o file表示把输出文件输入到file里 .PHONY:clean clean: rm *.o test#删除.o和执行文件
执行makefile文件:
$ make #默认生成第一个文件 $ make '目标名'#选择性的编译
当工程中的文件名和makefile中的目标重名时,就会有伪目标。执行make命令时会发现提示目标文件已经是最新的了,将不被不执行!如果我想让makefile中某个命令永远被执行。可以在makefile目标前加上
.PHONY:'目标名'
CC=gcc #设置变量,编译器,明确设置隐式规则,预先设置的变量就是gcc
CFLAGS=-lm -Wall -g
ALL=test print3 #表示生成 test 和 print3两个可执行文件,否则只会执行第一个test目标
test:main.o print1.o \ # \表示换行
print2.o
$(CC) $(CFLAGS) main.o print1.o print2.o -o test.out
print3:print3.o print1.o print2.o
$(CC) $(CFLAGS) print3.o print2.o print1.o -o print3.out
print1.o:print1.c
$(CC) $(CFLAGS) -c print1.c -o print1.o
print2.o:print2.c
$(CC) $(CFLAGS) -c print2.c -o print2.o
print3.o:print3.c
$(CC) $(CFLAGS) -c print3.c -o print3.o
.PHONY #伪目标
clean:
rm *.out *.o
exect: #伪目标
pdw #获取当前路径
makefile:预定义变量(不完整)
命 令 格 式 含义
AR 库文件维护程序的名称,默认值为ar 创建静态库.a
AS 汇编程序的名称,默认值为as
CC C编译器的名称,默认值为cc
CPP C预编译器的名称,默认值为$(CC) –E
CXX C++编译器的名称,默认值为g++
FC FORTRAN编译器的名称,默认值为f77
RM 文件删除程序的名称,默认值为rm –f
ARFLAGS 库文件维护程序的选项,无默认值
ASFLAGS 汇编程序的选项,无默认值
CFLAGS C编译器的选项,无默认值
CPPFLAGS C预编译的选项,无默认值
CXXFLAGS C++编译器的选项,无默认值
FFLAGS FORTRAN编译器的选项,无默认值
LDFLAGS 告诉链接器从哪里寻找库文件
LIBS 告诉链接器要链接哪些库文件