前言
为什么要用makefile
?
试想一下,如果你有成百上千个.cpp 文件需要编译,链接,那么在linux中需要写
g++ main.cpp func1.cpp func2.cpp ....
这样无数次的代码,这样很浪费时间,那么学会使用makefile
, 它能够帮助我们一键编译、链接成可执行文件。
先来看源程序:
main.cpp
:
#include "Head.h"
#include <iostream>
using namespace std;
int main(){
cout << "HelloWorld in main()" << endl;
print();
return 0;
}
Head.cpp
:
#include "Head.h"
#include <iostream>
using namespace std;
void print(){
cout << "this is print() in Head.cpp" << endl;
}
Head.h
:
#ifndef _HEAD_H_
#define _HEAD_H_
#include<iostream>
void print();
#endif
在linux环境下需要运行这个程序的话需要在terminal终端输入命令,但这样对于有多个cpp文件的大型程序很明显不适用,所以需要用makefile文件来帮助我们运行程序。
wwx@linux:~/day01/testMakefile$ g++ main.cpp Head.cpp -o app
wwx@linux:~/day01/testMakefile$ ./app
HelloWorld in main()
this is print() in Head.cpp
一.未经处理的Makefile
makefile文件主要分为三个部分:目标、依赖、命令
- makefile的原理就只是帮我们完成了终端命令行的语句输入,左边的main.exe是目标,右边的Head.o 和main.o是依赖,下面的语句是命令:
#版本一:最原始的makefile
main.exe: Head.o main.o
g++ -Wall Head.o main.o -o main.exe
Head.o: Head.cpp
g++ -Wall -c Head.cpp -o Head.o
main.o: main.cpp
g++ -Wall -c main.cpp -o main.o
clean:
rm -rf main.o main.exe Head.o
- 如果每一次都要写那么多.o文件,肯定有些麻烦,所以将一些同类型的文件放到一起更方便处理。
#版本二:
obj=main.o Head.o#.o文件就是依赖文件
target=main.exe#最终要生成的目标文件
CC=g++#编译器
${target}: ${obj}
${CC} -Wall ${obj} -o ${target}
main.o: main.cpp
${CC} -Wall -c main.cpp -o main.o
Head.o: Head.cpp
${CC} -Wall -c Head.cpp -o Head.o
clean:
rm -rf ${obj} ${target}
二.更加方便的makefile
- 对makefile做最后的改进:
- wildcard函数:通配符,将所有的.cpp文件找到并返回src中
- patsubst函数:带模式的字符串替换函数,在src中将找到的.cpp文件转换为.o文件
- $@:所有的目标
- $^:所有的依赖
- $<:第一个依赖
#版本三
CC=g++
CFLAGS=-g -Wall
target=app
src=$(wildcard *.cpp)
obj=$(patsubst %.cpp, %.o, $(src))
$(target):$(obj)
$(CC) $(CFLAGS) $^ -o $@
%.o:%.cpp
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -rf $(target) $(obj)