前言
1.在Linux开发环境中,编写Makefile文件是一个必须的技能,虽然现在有好多IDE可以自动生成所需要的Makefile文件,但有时能看懂Makefile文件也是更好的了解项目的编译过程。
2.我在这里只演示入门级Makefile文件的编写,我使用的系统是Ubuntu16.04这个版本,使用的演示源码语言是C++。
源文件准备
1.假设我们现在有main.cpp,other.cpp,other.h这三个源文件,其中main.cpp是主函数,它调用了other.h里面的函数。
main.cpp代码如下:
#include "other.h"
int main(void)
{
int i = add(45,50);
cout << "i = " << i << endl;
return 0;
}
other.cpp
#include "other.h"
int add(int i, int j)
{
return i+j;
}
other.h
#ifndef OTHER_H
#define OTHER_H
#include <iostream>
using namespace std;
int add(int, int);
#endif // OTHER_H
2.如果现在我们使用g++进行编译,则是直接生成用-o编译,生成可执行文件.
g++ main.cpp other.cpp -o add
然后运行可执行文件:
./add
3.如是只有一两个源文件,这样编译是没有问题的,但有几十个或者上百个时,这样编译是不现实的,那就要Makefile文件做这一步。
(1)Makefile文件的编写规则是:
规则:依赖
命令
规则:依赖
命令
(2)那用Makefile编译上面的源码的步骤是:
A、在存放源码的路径下新建一个Makefile文件,不要任何后缀,用vim打开。
B、按上面给的规则写好Makefile文件:
add:main.cpp other.cpp
g++ main.cpp other.cpp -o add
test:
./add
clean:
rm add
C、保存,退出,在当前目录下执行make这个命令:
可以看到,在当前目录下多了一个add的可执行文件,返回看上面的makefile的代码,我写了三个规则,但Make是默认只执行第一个规则而已。
接下我执行:
make test
执行了第二条规则,以此类推,要执行第三条规则,则在make后面加上规则名。
D.依赖项的意思是,如果依赖的其中的文件有更新则重新编译,但只编译有变化的文件。
4.这只是简单的介绍了Makefile文件的编写方式,那真正项目中的Makefile文件是这样子的,会使用一些通配符,Makefile文件能调用的库函数等,但原理不变。
EXE = subject #给变量赋值
#src放源代码文件,object是放项目的路径
SUBDIR = src object
#用迭代器把所有的子目录下的cpp找到
CXX_SURCES = $(foreach dir,$(SUBDIR),$(wildcard $(dir))/*.cpp)
#patsubst函数把列表的文件替换
CXX_OBJECTS=$(patsubst %.cpp,%.o,$(CXX_SURCES))
#得到.d文件
DEP_FILES=$(patsubst %.cpp,%.d,$(CXX_SURCES))
$(EXE):$(CXX_OBJECTS) #编译命令
g++ $(CXX_OBJECTS) -o $(EXE)
%.o:%.cpp #链接命令
g++ -c -MMD $< -o $@ #$<(依赖项列表) $@(当前规则) -MMD(生成.d文件为生.h的依赖)
-include $(DEP_FILES) #简化头文件依赖
cleran:
rm -rf $(EXE) $(DEP_FILES) $(CXX_OBJECTS)