目录
为什么要用makefile?
main.cpp xx.cpp文件用g++编译
g++ -o myapp main.cpp
编译生成一个可执行文件myapp
如果有a.cpp b.cpp c.cpp
可以一起编译:g++ a.cpp b.cpp c.cpp -o myapp
但如果有很多.cpp,这种方式是不行的。
编写Makefile文件可以处理多个文件一起编译的问题。
一、 写makefile文件(初级写法):
gcc参数:(g++和gcc只是编译不同的文件)
-o 指定输出文件名
-c 只编译,不能链接 编译生成的是.o文件
命令:vi makefile 开始写makefile
假如有main.cpp和a.cpp两个文件
start:
g++ -o main.o -c main.cpp
g++ -o a.o -c a.cpp
g++ -o myapp a.o main.o
注意:(以上三行g++前是一个tab键,不是空格,空格会出错)
使用makefile文件:
输入:make
输出:g++ -o main.o -c main.cpp
g++ -o a.o -c a.cpp
g++ -o myapp a.o main.o
start:
g++ -o main.o -c main.cpp
g++ -o a.o -c a.cpp
g++ -o myapp a.o main.o
clean:
rm -rf main.o a.o #(删除main.o和a.o)
输入:make clean(执行clean后面的命令)
输出:rm -rf main.o a.o
二、 改进makefile:
nakefile支持变量,一般写成大写
CC=g++ 定义了一个变量CC,等于g++
$(CC) 使用变量CC,可以将上面makefile文件里面的g++都替换成CC
makefile里有依赖,例如:
CC=g++
start:a.o main.o #(注释:start依赖a.o和main.o)
$(CC) -o myapp a.o main.o
a.o:
$(CC) -o a.o -c a.cpp
main.o:
$(CC) -o main.o -c main.cpp
clean:
rm -rf main.o a.o
二、 makefile及格写法:
CC=g++
start:a.o main.o
$(CC) -o myapp a.o main.o
.cpp.o:
$(CC) -o $@ -c $<
clean:
rm -rf main.o a.o
解释以上写法:
makefile一般不会将.cpp /.o单独写,.o文件(a.o/main.o)是来自于**.cpp**文件, .cpp.o将两种文件关联起来,start后面依赖的.o都得从.cpp获得。首先判断是否有.o文件,(这里判断是否有a.o和main.o),如果都没有就执行两次.cpp.o,(根据依赖判断执行几次.cpp.o命令,如果有某个.o文件则表示满足依赖,就少执行一次.cpp.o命令)如果a.o满足(满足就是有这玩意)则只执行一次.cpp.o。其中,$@代表相应的.o文件,$<代表相应的.cpp文件。
(假如没有a.o文件,
输入make,
输出:
g++ -o a.o -c a.cpp
g++ -o myapp a.o main.o
$@ 就是a.o $< 就是a.cpp )
四、 makefile继续优化:
SRCS=main.cpp\
a.cpp\
b.cpp
(多写几行,直观)
(SRCS源文件,可以等于多个.cpp)
OBJS=main.o\
a.o\
b.o
EXEC=myapp
(SRCS/OBJS/EXEC都算是变量)
优化后的makefile:
CC=g++
SRCS=main.cpp\
a.cpp
OBJS=main.o\
a.o
EXEC=myapp
start:$(OBJS)
$(CC) -o $(EXEC) $(OBJS)
.cpp.o:
$(CC) -o $@ -c $<
clean:
rm -rf $(OBJS)
如果多了一个b.cpp或更多.cpp,SRCS/OBJS都需要更改,很麻烦。
继续优化:
OBJS=$(SRCS:.cpp=.o)
把SRCS作为字符串,将字符串中所有的.cpp都替换成.o
五、好的makefile(维护起来简单):
CC=g++
SRCS=main.cpp\
a.cpp
OBJS=$(SRCS:.cpp=.o)
EXEC=myapp
start:$(OBJS)
$(CC) -o $(EXEC) $(OBJS)
.cpp.o:
$(CC) -o $@ -c $<
clean:
rm -rf $(OBJS)
makefile管理项目的时候只编译更改过的文件,它是根据文件的最后修改时间判断是否需要编译,如果.o文件不存在,make会失去判断,那么一定会编译.cpp文件。makefile不关心.h文件和.cpp文件的关系,他们是由编译器管理的。