序言
linux中编译代码往往没有windows下直接使用IDE来得方便,但是既然从事了C/C++的开发就必然会涉及到linux下的C/C++编程。既然是编译C/C++代码,那就要学会怎么写makefile文件了,下面来说说怎么使用makefile文件来编译代码。
第一种情况
只有一个main.cpp文件,代码如下:
#include <iostream>
using namespace std;
int main() {
cout<<"I was created by makefile"<<endl;
return 0;
}
正常情况下我们使用g++ mian.cpp -o main.o来编译代码,当使用makefile的时候应该这样写:
main.o: main.cpp
g++ main.cpp -o main.o
clean:
rm main.o
#===============格式如下=================#
(生成目标的文件): (生成目标文件所需要的依赖文件)
命令
为了方便和养成良好习惯,一般再加上个clean,当更新完cpp文件后,重新make之前先输入make clean,makefile文件会执行clean中的shell命令。
第二种情况
main.cpp文件使用了其他cpp文件中的函数,比如下面代码中main.cpp使用了print.cpp的函数。
print.cpp以及其print.h头文件的代码如下
// print.h
#ifndef PRINT_H
#define PRINT_H
#include<iostream>
void printLine(std::string str);
#endif
/*===============================*/
//print.cpp
#include"print.h"
using namespace std;
void printLine(string str){
cout<< str <<endl;
}
//main.cpp
#include <iostream>
#include "print.h"
using namespace std;
int main() {
string str = "I was created by makefile";
printLine(str);
return 0;
}
正常情况下我们需要两步编译:
g++ -c print.cpp #生成print.o依赖文件
然后执行
g++ main.cpp print.o -o main.o
而makefile的写法如下:
main.o: main.cpp print.o (生成main.o的依赖文件有main.cpp和print.o)
g++ main.cpp print.o -o main.o
print.o: print.cpp
g++ -c print.cpp
clean:
rm main.o print.o
makefile的执行步骤是这样的
1.系统打算编译生成main.o,发现了main.o需要main.cpp和print.o。
2.main.cpp已经有了,但是发现print.o没有,于是系统继续往下看,发现了print.o的生成依赖于print.cpp。
3.发现print.cpp存在了,于是执行makefile中的g++ -c print.cpp命令,生成了print.o
4.此时,main.cpp和print.o都存在了,于是系统跳回第一行,执行下面的命令g++ main.cpp print.o -o main.o
注意:所以在修改完CPP文件后,重新编译前要执行make clean,否则makefile发现已经存在的.o依赖文件,那么是不会再次生成新的依赖文件的。
第三种情况
main.cpp中不单单使用了print.cpp和print.h,还使用了其他的cpp和h文件(假如是print_2.cpp和print_2.h),同理只需要把main.o的需要的依赖文件加上就行了,makefile如下:
main.o: main.cpp print.o print_2.o
g++ main.cpp print.o print_2.o -o main.o
print.o: print.cpp
g++ -c print.cpp
print_2.o: print_2.cpp
g++ -c print_2.cpp
clean:
rm main.o print.o print_2.o
第四种情况
需要同时编译出两个不同功能的main文件,即main1.o和main2.o.这时候要用到一个关键字all,如果不使用all的话,makefile编译的时候只会编译第一个main1.o,下面的main2.o就只当成main1.o的依赖文件看待了(如果用不上就不执行),makefile的代码如下
all: main1.o main2.o #注意这里多了一行all打头的代码,表示着我们需要编译的目标文件
main1.o: main1.cpp print.o print_2.o
g++ main1.cpp print.o print_2.o -o main1.o
main2.o: main2.cpp print.o print_2.o
g++ main2.cpp print.o print_2.o -o main2.o
print.o: print.cpp
g++ -c print.cpp
print_2.o: print_2.cpp
g++ -c print_2.cpp
clean:
rm main1.o main2.o print.o print_2.o
第五种情况
有人问到,我想用gcc编译怎么办,但是里面都是g++,要改的话好麻烦。这时候就要对编译的方式进行命名,如下:
CC = g++ #将CC命名为g++或者gcc,as your will
main.o: main.cpp
$(CC) main.cpp -o main.o
clean:
rm main.o
以上我们就使用了**$(CC)**来代替编译方式了
又有人问到,我想用c++11来编译,makefile要怎么写呢,这时候同理我们也用命名大法,将CFLAG命名为 -std=c++11,如下:
CFLAG = -std=c++11 #
main.o: main.cpp
g++ $(CFLAG) main.cpp -o main.o
clean:
rm main.o
**为了方便,**通常我们还把需要生成的.o文件写成一个OBJECTS对象,后面clean的时候操作起来也方便,makefile如下
CFLAG = -std=c++11
OBJECTS = main1.o main2.o print.o print_2.o
all: main1.o main2.o
main1.o: main1.cpp print.o print_2.o
g++ main1.cpp print.o print_2.o -o main1.o $(CFLAG)
main2.o: main2.cpp print.o print_2.o
g++ main2.cpp print.o print_2.o -o main2.o
print.o: print.cpp
g++ -c print.cpp
print_2.o: print_2.cpp
g++ -c print_2.cpp
clean:
rm $(OBJECTS)
#===================================#
clean的写法其实写成下面的形式好点:
.PHONY:clean
clean:
-rm $(OBJECTS)
这种形式表示clean是个伪文件,当clean途中发生错误的时候,可以跳过这个错误的文件,继续clean下面的文件
其他的我就不讲了,这只是基本的makefile写法,如果帮到你就点个赞哈,写了2小时哩。