




下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、C/C+ 程序編譯步驟詳解新一篇 : MakefileC/C+ 語言很多人都比較熟悉, 這基本上是每位大學(xué)生必學(xué)的一門編程語言, 通常還都是作為程序設(shè)計(jì)入門語言學(xué)的,并且課程大多安排在大一。 剛上大學(xué),孩子們還都很乖,學(xué)習(xí)也比較認(rèn)真,用心。所以,C/C+語言掌握地也都不錯(cuò), 不用說編譯程序, 就是寫個(gè)上幾百行的程序都不在話下, 但是他們真的知道 C/C + 程序編譯的步驟么?我想很多人都不甚清楚,如果他接下來學(xué)過 多編譯的細(xì)節(jié),這無疑降低了初學(xué)者的入門門檻,但是也 西只能死記硬背,遇到相關(guān)問題就 楚 C/C+總體來說,多數(shù)時(shí)候,F(xiàn)ile: hw.c編譯原理 ”,也許能說個(gè)大概。 VC 的“舒適
2、 ”開發(fā)環(huán)境屏蔽了很 剝奪”了他們 “知其所以然 ”的權(quán)利,致使很多東 丈二 ”。實(shí)際上,我也是在學(xué)習(xí) Linux 環(huán)境下編程的過程中才逐漸弄清 源代碼是如何一步步變成可執(zhí)行文件的。C/C+ 源代碼要經(jīng)過:預(yù)處理、編譯、匯編和連接四步才能變成相應(yīng)平臺(tái)下的可執(zhí)行文件。大程序員通過一個(gè)命令就能完成上述四個(gè)步驟。比如下面這段C 的 “Hello world ! ”代碼 :#include <stdio.h>int main(int argc, char *argv)printf("Hello World!n");return 0;如果用 gcc 編譯,只需要一個(gè)命令就
3、可以生成可執(zhí)行文件 hw:xiaosuogentux hw $ gcc -o hw hw.cxiaosuogentux hw $ ./hw Hello World!我們可以用 -v 參數(shù)來看看 gcc 到底在背后都做了些什么動(dòng)作Reading specs from /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/specsConfiguredwith:/var/tmp/portage/sys-devel/gcc-3.4.6-r2/work/gcc-3.4.6/configure-prefix=/usr-bindir=/usr/i686-pc-linux-gnu/gcc
4、-bin/3.4.6-includedir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include -datadir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6 -mandir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6/man -infodir=/usr/share/gcc-data/i686-pc-linux-gnu/3.4.6/info-with-gxx-include-dir=/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include/
5、g+-v3-host=i686-pc-linux-gnu-build=i686-pc-linux-gnu-disable-altivec-enable-nls-without-included-gettext-with-system-zlib-disable-checking-disable-werror-enable-secureplt-disable-libunwind-exceptions-disable-multilib-disable-libgcj-enable-languages=c,c+,f77-enable-shared-enable-threads=posix-enable-
6、_cxa_atexit -enable-clocale=gnuThread model: posixgcc version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1-quiet -v hw.c -quiet-dumpbase hw.c-mtune=pentiumpro -auxbase hw -version -o /tmp/ccYB6UwR.s ignoring nonexistent directory "/usr/local/inc
7、lude"ignoringnonexistentdirectory"/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/././././i686-pc-linux-gnu/include" #include "." search starts here: #include <.> search starts here: /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/include /usr/includeEnd of search list.GNU C version 3.4.6 (
8、Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10) (i686-pc-linux-gnu)compiled by GNU C version 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.9). GGC heuristics: -param ggc-min-expand=81 -param ggc-min-heapsize=97004/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/././././i686-pc-linux-gnu/bin/as-V-Qy -o/tmp/ccq8uGED
9、.o /tmp/ccYB6UwR.sGNU assembler version 2.17 (i686-pc-linux-gnu) using BFD version 2.17/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/collect2-eh-frame-hdr-melf_i386-dynamic-linker /lib/ld-linux.so.2-o hw /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/./././crt1.o/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/./././crti.o/us
10、r/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/././././i686-pc-linux-gnu/lib-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/./././tmp/ccq8uGED.o-lgcc -as-needed-lgcc_s-no-as-needed-lc-lgcc-as-neede
11、d-lgcc_s-no-as-needed/usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/./././crtn.o 稍微整理一下,去掉一些冗余信息后,如下 cc1 hw.c -o /tmp/ccYB6UwR.s as -o /tmp/ccq8uGED.o /tmp/ccYB6UwR.s ld -o hw /tmp/ccq8uGED.o以上三個(gè)命令分別對(duì)應(yīng)于編譯步驟中的預(yù)處理+ 編譯、匯編和連接。預(yù)處理和編譯還是放在了一個(gè)命令cc1 )中進(jìn)行的,可以把它再次拆分為以下兩步 cpp
12、 -o hw.i hw.c cc1 hw.i -o /tmp/ccYB6UwR.s一個(gè)精簡(jiǎn)過的能編譯以上 hw.c 文件的 Makefile 如下 : .PHONY: clean all: hw hw: hw.old -dynamic-linker /lib/ld-linux.so.2 -o hw /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbegin.o hw.o -lc /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtend.o /usr/lib/crtn.o
13、hw.o: hw.sas -o hw.o hw.s hw.s: hw.i/usr/libexec/gcc/i686-pc-linux-gnu/3.4.6/cc1 -o hw.s hw.c hw.i: hw.ccpp -o hw.i hw.c clean:rm -rf hw.i hw.s hw.o 當(dāng)然,上面 Makefile 中的一些路徑是我系統(tǒng)上的具體情況,你的可能與我的不同。接下來我們按照編譯順序看看編譯器每一步都做了什么。首先是預(yù)處理,預(yù)處理后的文件 hw.i: # 1 "hw.c" # 1 "<built-in>" # 1 "
14、;<command line>"_extension_ typedef _quad_t _off64_t;_extension_ typedef int _pid_t;_extension_ typedef struct int _val2; _fsid_t;extern int remove (_const char *_filename) _attribute_ (_nothrow_);extern int rename(_constchar*_old,constchar *_new)attribute(_nothrow_);int main(int argc, ch
15、ar *argv)printf("Hello World!n");return 0;注:由于文件比較大,所以只留下了少部分具有代表性的內(nèi)容??梢钥匆婎A(yù)處理器把所有要包含( include )的文件(包括遞歸包含的文件)的內(nèi)容都添加到了原始的 源文件中,然后把其輸出到輸出文件,除此之外,它還展開了所有的宏定義,所以在預(yù)處理器的輸出文件 中你將找不到任何宏。這也提供了一個(gè)查看宏展開結(jié)果的簡(jiǎn)便方法。第二步 “編譯”,就是把 C/C+ 代碼 “翻譯 ”成匯編代碼: .file "hw.c".section .rodata .LC0:.string "H
16、ello World!n".text .globl main.type main, function main:pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp subl $12, %esp pushl $.LC0 call printf addl $16, %esp movl $0, %eax leaveret.size main, .-main
17、.section .note.GNU-stack,"",progbits.ident "GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r2, ssp-3.4.6-1.0, pie-8.7.10)"這個(gè)匯編文件比預(yù)處理后的 C/C+ 文件小了很多,去除了很多不必要的東西,比如說沒用到的類型聲明和函數(shù)聲明等。第三步 “匯編”,將第二步輸出的匯編代碼翻譯成符合一定格式的機(jī)器代碼,在 標(biāo)文件。Linux 上一般表現(xiàn)為 ELF 目xiaosuogentux hw $ file hw.ohw.o: ELF 32-bit LSB relocatable
18、, Intel 80386, version 1 (SYSV), not stripped最后一步 “連接 ”,將上步生成的目標(biāo)文件和系統(tǒng)庫的目標(biāo)文件和庫文件連接起來, 平臺(tái)運(yùn)行的可執(zhí)行文件。為什么還要連接系統(tǒng)庫中的某些目標(biāo)文件( crt1.o, crti.o 等)呢?這些目標(biāo)文件 都是用來初始化或者回收 C 運(yùn)行時(shí)環(huán)境的,比如說堆內(nèi)存分配上下文環(huán)境的初始化等,實(shí)際上最終生成了可以在特定crt 也正是C RunTime 的縮寫。這也暗示了另外一點(diǎn):程序并不是從 口開始的,在 Linux 上此入口是 態(tài)連接的可執(zhí)行文件需要將 Makefile 中的相應(yīng)段修改:start 。以上 Makefilemain 函數(shù)開始執(zhí)行的,而是從 crt 中的某個(gè)入生成的是動(dòng)態(tài)連接的可執(zhí)行文件,如果要生成靜hw: hw.old -m elf_i386 -static -o hw /usr/lib/crt1.o .o /usr/lib/crti.o /usr/lib/gcc/i686-pc-linux-gnu/3.4.6/crtbeginT-L/usr/lib/gcc/i686-pc-linux-gnu/3.4.6 -L/usr/i686-pc-linux-gnu/lib -L/usr/lib/ hw.o -start-group -lgcc -lgcc_eh -lc -end-grou
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 游戲產(chǎn)業(yè)與智能設(shè)備融合創(chuàng)新考核試卷
- 海上溢油應(yīng)急響應(yīng)與處理技術(shù)考核試卷
- 社區(qū)團(tuán)購廣告考核試卷
- 口腔科用牙科綜合治療臺(tái)電氣安全考核試卷
- 電氣設(shè)備節(jié)能技術(shù)考核試卷
- 全國(guó)卷語文高考的作文
- 硅冶煉過程中的物理冶金考核試卷
- 糖果的食品安全法律法規(guī)深度解讀考核試卷
- 紡織設(shè)備振動(dòng)與噪聲控制考核試卷
- 急性胰腺炎PBL護(hù)理查房
- 辦公設(shè)備維保服務(wù)投標(biāo)方案
- 政府投資項(xiàng)目審計(jì)
- 技術(shù)制作類科學(xué)教育活動(dòng)的設(shè)計(jì)與組織指導(dǎo)課件
- 藥事管理法律法規(guī)相關(guān)知識(shí)培訓(xùn)
- PQR-按ASME要求填寫的焊接工藝評(píng)定報(bào)告
- 醫(yī)院中央空調(diào)維保合同范本
- 勞動(dòng)工傷起訴狀
- 第4章-選區(qū)激光熔化工藝及材料課件
- 2023屆高考寫作指導(dǎo):“尋找溫暖”與“成為燈火”課件
- 2022年上海市工業(yè)技術(shù)學(xué)校招聘考試真題
- 臨時(shí)用電演示文稿
評(píng)論
0/150
提交評(píng)論