序言
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小時哩。