学习写Makefile文件
2015-01-10 21:12
141 查看
Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不能算是一个合格的专业程序员,至少不能称得上是 Unix程序员。。在 Linux(unix )环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。
那么问题出来了,Makefile究竟应该怎么编写?
下面看下面程序(Test.c):
因此他们觉得用不用Makefile无所谓。其实不然,我们看下面程序:
程序有三个文件:Test.c、add.h 、add.c
Test.c 文件
add.h 文件
add.c 文件
此时,如果你再用命令去编译链接时候就显得比较麻烦了,如果代码文件更多呢?那就不可想象了,因此我们要学会写Makefile文件。
Makefile是一个文件文件形式的脚本文件,其中包含一些规则告诉make编译哪些文件怎么编译以及在什么条件下编译。
让我们先来粗略地看一看Makefile的规则。[
target:dependency
command
...
目标:依赖
执行指令 ...
注意每个command 第一个字符必须是tab键,而不是4个空格。不然的话make会报错停止。执行的时候make空格后接目标,当然也可以不输入目标。这时make就会默认只执行第一个目标。
下面就由简单到复杂编写Makefile文件:
1.写一个最简单的Makefile
在命令输入make回车即可完成编译和链接。
2..将编译和链接分开
这里出现两个目标(target)start,和Test.o如果在make时候没有加上目标的话,其只会执行第一个目标,除非有依赖才执行下面的(如2)。这里当你在命令行中输入make后面没有更任何参数时候其会从start开始执行,发现其依赖Test.o文件,其就往下找,就会执行Test.o这个目标。
当然这里可以make Test.o ,就不会执行第一个目标了。
3.引入变量
为什么要引入变量CC,SRCS等(变量习惯使用大写),后面在使用变量的时候要这样写:$(变量名)。引入变量的原因,主要是方便修改,比如要换编译器,要换文件等比较方便。
4.进一步完善
OBJS = $(SRCS:.c=.o) 这句话意思是把SRSC字符中.c替换成.o
5.再完善
.SUFFIXES:.c .o 表示任何x.c 和x.o相关联如果这里使用是cpp文件则改为:.SUFFIXES:.cpp .o (注意cpp和.o之间有个空格)
OBJS = $(SRCS:.cpp=.o)
$@和$<是make预定义的变量。$@为规则目标所对应的文件名,$<规则中第一个相关的文件名(这里可以理解为.c文件)。
6.如果有多个.c或者.cpp文件怎么办?Test..c 和add.c 文件存在。
这里\ 相当于换行链接。三个可以写成这样
如果文件非常多也可以这样写,
执行结果:
那么问题出来了,Makefile究竟应该怎么编写?
下面看下面程序(Test.c):
#include <stdio.h> int main(int argc,char *argv[]) { printf("hello world\n"); return 0; }初学者很多都直接在命令行编译链接:gcc–o Test Test.c
因此他们觉得用不用Makefile无所谓。其实不然,我们看下面程序:
程序有三个文件:Test.c、add.h 、add.c
Test.c 文件
#include <stdio.h> #include"add.h" int main(int argc,char *argv[]) { printf("%d \n",add(1,2)); return 0; }
add.h 文件
#ifndef ADD_H_ #define ADD_H_ int add(int a,int b); #endif /* ADD_H_ */
add.c 文件
int add(inta,intb) { return a+b; }
此时,如果你再用命令去编译链接时候就显得比较麻烦了,如果代码文件更多呢?那就不可想象了,因此我们要学会写Makefile文件。
Makefile是一个文件文件形式的脚本文件,其中包含一些规则告诉make编译哪些文件怎么编译以及在什么条件下编译。
让我们先来粗略地看一看Makefile的规则。[
target:dependency
command
...
目标:依赖
执行指令 ...
注意每个command 第一个字符必须是tab键,而不是4个空格。不然的话make会报错停止。执行的时候make空格后接目标,当然也可以不输入目标。这时make就会默认只执行第一个目标。
下面就由简单到复杂编写Makefile文件:
1.写一个最简单的Makefile
start: gcc –o test Test.c
在命令输入make回车即可完成编译和链接。
2..将编译和链接分开
start:Test.o gcc -o Test Test.o Test.o:Test.c gcc -o Test.o -c Test.c
这里出现两个目标(target)start,和Test.o如果在make时候没有加上目标的话,其只会执行第一个目标,除非有依赖才执行下面的(如2)。这里当你在命令行中输入make后面没有更任何参数时候其会从start开始执行,发现其依赖Test.o文件,其就往下找,就会执行Test.o这个目标。
当然这里可以make Test.o ,就不会执行第一个目标了。
3.引入变量
CC = gcc SRCS = Test.c OBJS = Test.o EXEC = Test start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) $(OBJS):$(SRCS) $(CC) -o $(OBJS) -c$(SRCS)
为什么要引入变量CC,SRCS等(变量习惯使用大写),后面在使用变量的时候要这样写:$(变量名)。引入变量的原因,主要是方便修改,比如要换编译器,要换文件等比较方便。
4.进一步完善
CC = gcc SRCS = Test.c OBJS = $(SRCS:.c=.o) EXEC = Test start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) $(OBJS): $(CC) -o $(OBJS) -c$(SRCS) clean: rm -f $(OBJS)
OBJS = $(SRCS:.c=.o) 这句话意思是把SRSC字符中.c替换成.o
5.再完善
.SUFFIXES:.c .o CC = gcc SRCS = Test.c OBJS = $(SRCS:.c=.o) EXEC = Test start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) .c.o: $(CC) -o $@ -c $< clean: rm -f $(OBJS)
.SUFFIXES:.c .o 表示任何x.c 和x.o相关联如果这里使用是cpp文件则改为:.SUFFIXES:.cpp .o (注意cpp和.o之间有个空格)
OBJS = $(SRCS:.cpp=.o)
$@和$<是make预定义的变量。$@为规则目标所对应的文件名,$<规则中第一个相关的文件名(这里可以理解为.c文件)。
6.如果有多个.c或者.cpp文件怎么办?Test..c 和add.c 文件存在。
.SUFFIXES:.c .o CC = gcc SRCS = Test.c\ add.c OBJS = $(SRCS:.c=.o) EXEC = Test start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) .c.o: $(CC) -o $@ -c $< clean: rm -f $(OBJS)
这里\ 相当于换行链接。三个可以写成这样
如果文件非常多也可以这样写,
.SUFFIXES:.c .o CC = gcc SRCS = $(shell ls *.c) OBJS = $(SRCS:.c=.o) EXEC = Test start:$(OBJS) $(CC) -o $(EXEC) $(OBJS) .c.o: $(CC) -o $@ -c $< clean: rm -f $(OBJS)
$(shell ls *.c) 表示使用shell 查找符合条件文件
执行结果:
相关文章推荐
- Kconfig和Makefile文件的学习总结
- Gnu make手册学习【3】——编写makefile文件
- Linux学习笔记——例说makefile 头文件查找路径
- 跟我一起写Makefile学习笔记1——文件搜寻&伪目标&静态模式
- makefile学习——编译生成动态库文件
- Makefile学习笔记1:Linux平台Makefile文件的编写基础篇(zz)
- *Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile
- 实例学习写Makefile文件
- Linux学习之Makefile和Configure文件说明
- Makefile 文件学习——001
- 国嵌视屏学习第一天——makefile文件的编写
- makefile学习经验(三)----编译生成动态库文件(方式一)
- makefile学习经验(二)----编译生成静态库文件
- Linux学习笔记——例说makefile 多个文件
- Makefile 学习之简单的文件编译处理
- autoconf 和 automake 生成 Makefile 文件学习
- 从初学者的角度分析学习makefile,看完后能让你读懂绝大部分makefile文件!
- 简单的makefile文件三种写法学习笔记
- linux helloworld 通过makefile文件 编译菜鸟学习记录
- makefile学习经验(三)----编译生成动态库文件(方式一)