在linux下使用gcc/g++編譯多個.h .c 文件

多個文件編譯在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

編譯通過:


image.png

最后榕酒,再一次的編譯:

zhaozheng@ubuntu:~/code/c++/test_compile/src$ g++ main.cpp -o main -I ../myinclude/    ../myinclude/myhead.o
zhaozheng@ubuntu:~/code/c++/test_compile/src$ 
image.png

運行結(jié)果:


image.png

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:

  1. 以后再來寫歌殃,什么是編譯,什么是鏈接蝙云。
  2. 動態(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)部可以。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末垫释,一起剝皮案震驚了整個濱河市丝格,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌棵譬,老刑警劉巖显蝌,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異订咸,居然都是意外死亡曼尊,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門脏嚷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骆撇,“玉大人,你說我怎么就攤上這事父叙∩窠迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵趾唱,是天一觀的道長涌乳。 經(jīng)常有香客問我,道長甜癞,這世上最難降的妖魔是什么夕晓? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮悠咱,結(jié)果婚禮上蒸辆,老公的妹妹穿的比我還像新娘。我一直安慰自己乔煞,他們只是感情好吁朦,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著渡贾,像睡著了一般逗宜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上空骚,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天纺讲,我揣著相機與錄音,去河邊找鬼囤屹。 笑死熬甚,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肋坚。 我是一名探鬼主播乡括,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼肃廓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诲泌?” 一聲冷哼從身側(cè)響起盲赊,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎敷扫,沒想到半個月后哀蘑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡葵第,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年绘迁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卒密。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缀台,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栅受,到底是詐尸還是另有隱情将硝,我是刑警寧澤恭朗,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布屏镊,位于F島的核電站,受9級特大地震影響痰腮,放射性物質(zhì)發(fā)生泄漏而芥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一膀值、第九天 我趴在偏房一處隱蔽的房頂上張望棍丐。 院中可真熱鬧,春花似錦沧踏、人聲如沸歌逢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秘案。三九已至,卻和暖如春潦匈,著一層夾襖步出監(jiān)牢的瞬間阱高,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工茬缩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留赤惊,地道東北人。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓凰锡,卻偏偏與公主長得像未舟,于是被迫代替她去往敵國和親圈暗。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容