系統(tǒng)運(yùn)維
我們?cè)谇度胧降拈_(kāi)發(fā)中經(jīng)常會(huì)見(jiàn)到 GCC 和 gcc,那么它們兩有何不同呢?GCC(GNU Compile Collection) 是指 GNU 編譯器集合,包含眾多語(yǔ)言的編譯器,如 C、C++、Java、D、Objective-C 等;而 gcc 則是特指 GCC 中的 C 語(yǔ)言編譯器。那么 GCC 與嵌入式的關(guān)系是怎樣的呢?多數(shù)嵌入式操作系統(tǒng)都是基于 GCC 進(jìn)行源碼編譯,如 Linux、VxWorks 以及 Android 等。在實(shí)際的開(kāi)發(fā)中,內(nèi)核相關(guān)的開(kāi)發(fā)用的是 gcc,而應(yīng)用開(kāi)發(fā)用的是 gcc/g++/gdc 等。
容縣網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)公司!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、響應(yīng)式網(wǎng)站設(shè)計(jì)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)公司于2013年成立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)公司。下來(lái)我們來(lái)看看一個(gè)嵌入式開(kāi)發(fā)中的高端大氣上檔次的詞語(yǔ):交叉編譯。那么為什么會(huì)有交叉編譯呢?在以往的嵌入式設(shè)備往往都是資源受限的,不可能直接在嵌入式上直接對(duì)處理器進(jìn)行編程。那么此時(shí)的解決方案便是在開(kāi)發(fā)主機(jī)(PC)上對(duì)源碼進(jìn)行編譯,最終生成目標(biāo)主機(jī)(嵌入式設(shè)備)的可執(zhí)行程序。gcc 是如何進(jìn)行交叉編譯的呢?1、配置目標(biāo)主機(jī)的編譯工具鏈(如arm-linux);2、配置工具鏈的具體版本:根據(jù)具體的目標(biāo)代碼選擇相應(yīng)的工具鏈版本,正確使用關(guān)于硬件體系的特殊編譯選項(xiàng)。下來(lái)我們來(lái)看看大型企業(yè)的嵌入式開(kāi)發(fā)環(huán)境是怎樣的,如下
這個(gè)服務(wù)器集群相當(dāng)于是我們自己公司的內(nèi)部服務(wù)器,版本控制則是指由原來(lái)的版本經(jīng)過(guò)我們一些代碼的修改之后產(chǎn)生的新版本,用于各個(gè)版本的控制的。文件追蹤則是指在服務(wù)器上面可以看到那部分的代碼是具體由哪個(gè)人進(jìn)行改寫(xiě)的,可具體到文件以及部分代碼。我們來(lái)看看編譯器是怎樣的,如下
編譯器其實(shí)是由預(yù)處理期、編譯器、匯編器以及鏈接器構(gòu)成的。我們平時(shí)所說(shuō)的由哪個(gè)編譯器編譯生成的文件,此時(shí)的編譯器便是指廣范圍的編譯器。那么狹義上的編譯器則是指我們?cè)谄綍r(shí)所聽(tīng)到的生產(chǎn)一個(gè)某語(yǔ)言的編譯器,此時(shí)的編譯器則是指將具體的語(yǔ)言翻譯成目標(biāo)平臺(tái)代碼而已。我們來(lái)看看一個(gè) .c 文件是怎樣編譯成 .o 文件的,具體步驟如下所示
我們看到并不是我們所想象的直接一步就由 .c 文件直接編譯成為 .o 可執(zhí)行文件了,而是經(jīng)過(guò)那么多的步驟才會(huì)生成最終的可執(zhí)行程序的。那么此時(shí)便擴(kuò)展一個(gè)問(wèn)題,我們是如何理解“多語(yǔ)言混合開(kāi)發(fā)”?我們?cè)谄綍r(shí)可能會(huì)聽(tīng)到多語(yǔ)言混合開(kāi)發(fā),是指由好幾種語(yǔ)言混合進(jìn)行一個(gè)應(yīng)用程序開(kāi)發(fā)的。那么為什么會(huì)產(chǎn)生這種混合的開(kāi)發(fā)方式呢?比如說(shuō)一個(gè)項(xiàng)目是由 C++ 完成的,但是其中的某些部分是可以通過(guò) C# 完成的,此時(shí)精通 C++ 的人很少(相應(yīng)工資就要的很高了),而 C# 的工程師由一大堆,我們就可以需要兩個(gè)精通 C++ 的工程師和好幾個(gè) C# 的工程師來(lái)共同完成這個(gè)項(xiàng)目,達(dá)到以最小的開(kāi)支完成此項(xiàng)目的效果?;蛘呤悄銈冃〗M內(nèi)每個(gè)人擅長(zhǎng)的語(yǔ)言方向不一樣,為了發(fā)揮每個(gè)人的效率便可以采取這種混合開(kāi)發(fā)的方式。下來(lái)我們來(lái)看看幾種多語(yǔ)言混合開(kāi)發(fā)的方式
方式一,如下
此方式是通過(guò)由幾種語(yǔ)言經(jīng)過(guò)匯編得到目標(biāo)平臺(tái)的匯編語(yǔ)言,再由目標(biāo)平臺(tái)匯編器統(tǒng)一鏈接生成可執(zhí)行程序。行業(yè)典型的案例就是 .net framework,它便是由 C#、C++ 以及 VB 混合開(kāi)發(fā)得到的,如下
方式二,如下
它是由各自的語(yǔ)言生成相應(yīng)的庫(kù)再通過(guò)目標(biāo)平臺(tái)鏈接器統(tǒng)一鏈接為可執(zhí)行程序。典型的案例便是 QQ 了,如下
方式三,如下
它是經(jīng)過(guò)各自的編譯器先生成可執(zhí)行程序 .exe,再通過(guò)進(jìn)程間通信協(xié)議進(jìn)而生成可執(zhí)行程序。行業(yè)案例:Eclipse,如下
下來(lái)我們來(lái)看看 gcc 關(guān)鍵編譯選項(xiàng)。
gcc 關(guān)鍵編譯選項(xiàng)一:a> 預(yù)處理指令是:gcc -E file.c -o file.i;b > 編譯指令:gcc -S file.i -o file.s;c> 匯編指令:gcc -c file.s -o file.o。
下來(lái)我們來(lái)看看效果分別是怎樣的
func.h 源碼
#include<stdio.h> voidfunc() { #ifdefTEST printf("TEST=%s\\n",TEST); #endif return; }
test.c 源碼
#include<stdio.h> #include"func.h" intg_global=0; intg_test=1; intmain(intargc,char*argv[]) { func(); printf("&g_global=%p\\n",&g_global); printf("&g_test=%p\\n",&g_test); printf("&func=%p\\n",&func); printf("&main=%p\\n",&main); return0; }
我們來(lái)看看預(yù)處理的效果,打開(kāi) test.i 文件看看,開(kāi)頭是這樣的
第一行的 1 表示下面的內(nèi)容是屬于 test.c 文件的內(nèi)容,下面是一些頭文件的包含。
# 2 "test.c" 2 的意思是 test.c 頭文件的包含已經(jīng)結(jié)束了,# 1 "func.h" 1 表示 func.h 相關(guān)內(nèi)容的開(kāi)始。最后便是 test.c 文件 main 函數(shù)的內(nèi)容了。下面看看編譯指令生成的 .s 文件
都是一些生成的匯編命令。下面來(lái)看看最后的匯編指令生成 .o 文件
gcc 關(guān)鍵編譯選項(xiàng)二:a> 生成映射文件:gcc -WI,-Map=test.map file.c;b> 宏定義:gcc -D'TEST="test"' file.c;c> 獲取系統(tǒng)頭文件路徑:gcc -v file.c。
gcc 關(guān)鍵編譯選項(xiàng)三:生成依賴關(guān)系。a> 獲取目標(biāo)完整的依賴關(guān)系:gcc -M test.c;b> 獲取目標(biāo)的部分依賴關(guān)系:gcc -MM test.c。
下來(lái)我們來(lái)看看 -M 和 -MM 的效果分別是怎樣的,如下
我們看到包含了那么多的頭文件,它的格式類似于 makefile 中的目標(biāo)與依賴的關(guān)系。其中依賴是 test.c 和眾多的頭文件以及我們自己包含的 func.h 頭文件。再來(lái)看看 -MM 的效果
我們看到 -MM 的效果是指依賴于 test.c 和 func.h,并沒(méi)有那些別的頭文件。
gcc 關(guān)鍵編譯選項(xiàng)四:指定庫(kù)文件及庫(kù)文件搜索路徑。-L 選項(xiàng)是指定庫(kù)文件的搜索路徑;-l 是指定庫(kù)文件,如 gcc test.c -L -lfunc。
func.c 源碼
#include<stdio.h> voidfunc() { #ifdefTEST printf("TEST=%s\\n",TEST); #endif return; }
test.c 源碼
#include<stdio.h> intg_global=0; intg_test=1; intmain(intargc,char*argv[]) { func(); printf("&g_global=%p\\n",&g_global); printf("&g_test=%p\\n",&g_test); printf("&func=%p\\n",&func); printf("&main=%p\\n",&main); return0; }
編譯結(jié)果如下
我們看到經(jīng)過(guò) ar crs 命令將 func.o 打包成 libfunc.a 文件后,再通過(guò) gcc test.c -L. -lfunc 命令生成可執(zhí)行程序 a.out(其中 -L 后面的點(diǎn)代表在當(dāng)前目錄下)。
分享標(biāo)題:嵌入式之C語(yǔ)言編譯器(五)
轉(zhuǎn)載注明:http://jinyejixie.com/article34/chddpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開(kāi)發(fā)、軟件開(kāi)發(fā)、商城網(wǎng)站、虛擬主機(jī)、自適應(yīng)網(wǎng)站、用戶體驗(yàn)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容