多個文件編譯在linux下編譯恩商,下面有三個文件,分別是1.cpp 和 2.cpp 和myhead.h 文件。
1.cpp
#include <iostream>
#include "myhead.h"
using namespace std;
int main(){
print();
cout<<"yes !"<<endl;
return 0;
}
2.cpp
#include <iostream>
#include "myhead.h"
using namespace std;
void print(){
std::cout<<" print "<<std::endl;
cout<<
}
myhead.h
#ifndef __myhead_h
#define __myhead_h
void print();
#endif
假如他們都在一個目錄下面,那么編譯流程:
g++ -c 2.cpp #將2.cpp 編譯成2.o 文件
g++ 1.cpp -o a.out 2.o #多個文件一起鏈接
or
g++ -c 2.cpp
g++ -c 1.cpp
g++ 1.o 2.o -o test
當(dāng)然垮媒,沒有頭文件,兩個.c文件也是可以編譯的航棱。如下:
1.cpp文件
#include <iostream>
using namespace std;
void fn();
int main(){
cout<<"123"<<endl;
fn();
return 0;
}
2.cpp文件
#include <iostream>
void fn(){
std::cout<<"fn"<<std::endl;
}
編譯:
g++ -c 1.cpp
g++ -c 2.cpp
g++ -o test 1.o 2.o
在稍微大一點的項目里面睡雇,一般都會包含多個文件。尤其是包含多個頭文件丧诺,各自頭文件的實現(xiàn)入桂,和包含main函數(shù)的文件。這樣的好處就是更容易開發(fā)和維護驳阎。
舉一個簡單的例子抗愁,main.cpp 文件是包含main函數(shù)的文件,在myinclude的文件下呵晚,包含了myhead.h 和 myhead.cpp 文件蜘腌。分別是頭文件的定義和實現(xiàn)。
main.cpp :
#include <iostream>
#include <myhead.h>
using namespace std;
int main(){
//fun_head();
cout<<"in main"<<endl;
int x=100;
int y=200;
cout<<"sum : "<<sum(x,y);
return 0;
}
myhead.h
#ifndef __myhead_h
#define __muhead_h
void print();
int sum(int a,int b);
#endif
myhead.cpp
#include "myhead.h"
#include <iostream>
using namespace std;
void print(){
cout<<"in fun head"<<endl;
}
int sum(int a,int b){
return a+b;
}
下面開始編譯:
假如在當(dāng)前目錄直接編譯的話:
zhaozheng@ubuntu:~/code/c++/test_compile/src$ g++ main.cpp -o main
main.cpp:2:20: fatal error: myhead.h: No such file or directory
compilation terminated.
直接編譯的結(jié)果就是報錯了饵隙,錯誤的原因是 默認(rèn)的include目錄下面沒有 myhead.h 頭文件撮珠。
如果不知道include的默認(rèn)的頭文件,請看:
http://www.reibang.com/p/3eb25114576e
那么通過 -I 選項 鏈接上去金矛。重新編譯
zhaozheng@ubuntu:~/code/c++/test_compile/src$ g++ main.cpp -o main -I ../myinclude/
/tmp/ccH3BlLo.o: In function `main':
main.cpp:(.text+0x3e): undefined reference to `sum(int, int)'
collect2: error: ld returned 1 exit status
有報錯芯急,錯誤的原因是頭文件雖然找到了,但是沒有提示錯誤驶俊,沒有定義sum函數(shù)娶耍。sum函數(shù)是在myhead.cpp文件上面定義的。也就是需要把myhead.cpp文件編譯一下饼酿。
zhaozheng@ubuntu:~/code/c++/test_compile/myinclude$ g++ -c myhead.cpp -o myhead.o
編譯通過:
最后榕酒,再一次的編譯:
zhaozheng@ubuntu:~/code/c++/test_compile/src$ g++ main.cpp -o main -I ../myinclude/ ../myinclude/myhead.o
zhaozheng@ubuntu:~/code/c++/test_compile/src$
運行結(jié)果:
PS : 上面寫得是胚膊,如果編譯,鏈接多個文件想鹰,如果好奇編譯和鏈接的具體過程紊婉,請看 :
http://www.reibang.com/writer#/notebooks/10152412/notes/9498296
PS:
gcc/g++ 里面的-c選項指的是,比如
gcc -c myhead.cpp -o myhead.o
將一個文件編譯辑舷,但是不鏈接喻犁。將代碼變成機器碼。
比如惩妇,
gcc -c main.cpp -o main.o
將main.cpp文件編譯為main.o 文件
那么鏈接器的作用是什么?
gcc -o main main.o ../myinclude/myhead.o
這樣將兩個.o文件和依賴庫的文件鏈接起來株汉,編程可執(zhí)行的文件筐乳。
<br />
PPS:
- 以后再來寫歌殃,什么是編譯,什么是鏈接蝙云。
- 動態(tài)庫和靜態(tài)庫的區(qū)別
多個文件編譯的時候氓皱,可以順便理解一下static,extern兩個關(guān)鍵字的意思勃刨。
-
extern
如下所示的代碼:
如果在2.cpp文件里面定義了一個變量波材,在1.cpp這個文件里面去訪問這個變量。在鏈接的時候身隐,2.cpp里面的變量對1.cpp是可以的廷区。1.cpp里面是可以訪問這個變量的,但是贾铝,需要使用extern聲明這個變量是賴在其他文件的隙轻。
編譯
g++ -c 1.cpp
g++ -c 2.cpp
g++ 1.o 2.o -o test
但是,如果去掉extern的話垢揩,那么鏈接的時候玖绿,就會報一個錯誤
錯誤提示,連接的時候 兩個文件里面的value都是彼此可以的叁巨,所以斑匪,提示變量被定義了多次。
2.o:(.data+0x0): multiple definition of `value'
1.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
改正這個錯誤锋勺,除了可以加上extern 之外蚀瘸,還可以加上static,改變變量的可見范圍庶橱。(加上static之后贮勃,變量只能在當(dāng)前文件里面可見。)
- static
static 聲明一個變量的時候悬包,除了可以將變量的空間開辟在全局區(qū)衙猪。第二個就是改變變量的可見范圍,這個變量只能在文件內(nèi)部可以。