c语言 自动化编译环境,《C编程.开始C》3.编译基础
在介紹了C編程的基本概念之后,我們現(xiàn)在可以簡(jiǎn)要地討論編譯過(guò)程。
像任何編程語(yǔ)言一樣,C本身對(duì)于微處理器來(lái)說(shuō)是完全不可理解的。它的目的是提供一種用于人類(lèi)是提供一種能夠很容易地轉(zhuǎn)換成機(jī)器代碼指令以直觀的方式是理解到微處理器。該編譯器是什么翻譯我們?nèi)祟?lèi)可讀的源代碼轉(zhuǎn)換成機(jī)器代碼。
對(duì)于那些剛接觸編程的人來(lái)說(shuō),這似乎相當(dāng)簡(jiǎn)單。一個(gè)天真的編譯器可能會(huì)讀入每個(gè)源文件,將所有內(nèi)容轉(zhuǎn)換為機(jī)器代碼,并寫(xiě)出可執(zhí)行文件。這可行,但有兩個(gè)嚴(yán)重的問(wèn)題。首先,對(duì)于大型項(xiàng)目,計(jì)算機(jī)可能沒(méi)有足夠的內(nèi)存來(lái)一次讀取所有源代碼。其次,如果對(duì)單個(gè)源文件進(jìn)行更改,則必須重新編譯整個(gè)應(yīng)用程序。
為了解決這些問(wèn)題,編譯器將工作分解為步驟。對(duì)于每個(gè)源文件(每個(gè).c文件),編譯器讀取文件,讀取它通過(guò)#include指令引用的文件,并將它們轉(zhuǎn)換為機(jī)器代碼。結(jié)果是“目標(biāo)文件”(.o)。創(chuàng)建所有目標(biāo)文件后,“鏈接器”程序?qū)⑹占心繕?biāo)文件并寫(xiě)入實(shí)際的可執(zhí)行程序。這樣,如果您更改了一個(gè)源文件,則只需要重新編譯該文件,之后,需要重新鏈接該應(yīng)用程序。
沒(méi)有詳細(xì)說(shuō)明,對(duì)編譯過(guò)程有一個(gè)膚淺的理解是有益的。
預(yù)處理器
預(yù)處理器提供了包含所謂的頭文件,宏擴(kuò)展,條件編譯和行控制的能力。很多時(shí)候,您需要向編譯器提供特殊指令。這可以通過(guò)在代碼中插入預(yù)處理程序指令來(lái)完成。當(dāng)您開(kāi)始編譯代碼時(shí),一個(gè)稱(chēng)為預(yù)處理器的特殊程序會(huì)掃描源代碼,并根據(jù)預(yù)定義的規(guī)則為其他代碼執(zhí)行令牌字符串的簡(jiǎn)單替換。C預(yù)處理器不是C語(yǔ)言的一部分。
所有預(yù)處理程序指令都以井號(hào)字符(#)開(kāi)頭。您可以在Hello world程序中看到一個(gè)預(yù)處理程序指令。例:
#include
該指令使stdio標(biāo)頭包含在您的程序中。其他指令,如#pragma控制編譯器設(shè)置和宏。預(yù)處理階段的結(jié)果是文本字符串。您可以將預(yù)處理器視為非交互式文本編輯器,為編譯準(zhǔn)備代碼。預(yù)處理程序指令的語(yǔ)言與C的語(yǔ)法無(wú)關(guān),因此C預(yù)處理程序也可以獨(dú)立用于處理其他類(lèi)型的文本文件。
語(yǔ)法檢查
此步驟確保代碼有效并將序列化為可執(zhí)行程序。在大多數(shù)編譯器下,您可能會(huì)收到消息或警告,指出程序可能存在的問(wèn)題(例如條件語(yǔ)句總是為真或假等)
當(dāng)在程序中檢測(cè)到錯(cuò)誤時(shí),編譯器通常會(huì)報(bào)告阻止編譯的文件名和行。
對(duì)象代碼
編譯器生成與源代碼等效的機(jī)器代碼,可以鏈接到最終程序中。此時(shí)代碼本身無(wú)法執(zhí)行,因?yàn)樗枰溄硬拍軋?zhí)行。
在討論編譯是“單行道”的基礎(chǔ)知識(shí)之后,請(qǐng)務(wù)必注意。也就是說(shuō),將C源文件編譯成機(jī)器代碼很容易,但“反編譯”(將機(jī)器代碼轉(zhuǎn)換為創(chuàng)建它的C源代碼)則不然。C的反編譯器確實(shí)存在,但它們創(chuàng)建的代碼很難理解,只對(duì)逆向工程有用。
鏈接
聯(lián)通過(guò)集成庫(kù)和代碼并產(chǎn)生任一種結(jié)合了單獨(dú)的對(duì)象文件合并為一個(gè)完整的程序的可執(zhí)行程序或庫(kù)。鏈接由鏈接器程序執(zhí)行,該程序通常是編譯器套件的一部分。
此階段的常見(jiàn)錯(cuò)誤是缺少或重復(fù)的功能。
自動(dòng)化
對(duì)于大型C項(xiàng)目,許多程序員選擇自動(dòng)編譯,以減少用戶(hù)交互需求并通過(guò)重新編譯僅修改過(guò)的文件來(lái)加快進(jìn)程。
大多數(shù)集成開(kāi)發(fā)環(huán)境都有某種項(xiàng)目管理,這使得這種自動(dòng)化非常容易。但是,項(xiàng)目管理文件通常只能由同一集成開(kāi)發(fā)環(huán)境的用戶(hù)使用,因此任何希望修改項(xiàng)目的人都需要使用相同的IDE。
在類(lèi)UNIX系統(tǒng)上,make和Makefiles通常用于完成相同的操作。Make是傳統(tǒng)且靈活的,可作為大多數(shù)Unix和GNU發(fā)行版的標(biāo)準(zhǔn)開(kāi)發(fā)人員工具之一。
GNU Autotools擴(kuò)展了Makefile?,由Automake和Autoconf組成,用于使軟件可編譯,可測(cè)試,可翻譯和可在許多類(lèi)型的機(jī)器上配置。Automake和Autoconf在各自的手冊(cè)中有詳細(xì)描述。
Autotools通常被認(rèn)為是復(fù)雜的,并且已經(jīng)開(kāi)發(fā)了各種更簡(jiǎn)單的構(gòu)建系統(tǒng)。GNOME項(xiàng)目的許多組件現(xiàn)在使用聲明性的Meson構(gòu)建系統(tǒng),該系統(tǒng)不太靈活,而是專(zhuān)注于以簡(jiǎn)單的方式提供構(gòu)建系統(tǒng)中最常需要的功能。用C語(yǔ)言編寫(xiě)的程序的其他流行的構(gòu)建系統(tǒng)包括CMake和Waf。
安裝gcc后,可以使用已編寫(xiě)但尚未編譯的c源文件列表調(diào)用它。例如,如果文件main.c包含myfun.h中描述的函數(shù)并在myfun_a.c和myfun_b.c中實(shí)現(xiàn),那么就足夠了
gcc main.c myfun_a.c myfun_b.c
myfun.h包含在main.c中,但如果它位于單獨(dú)的頭文件目錄中,那么該目錄可以在“-I”開(kāi)關(guān)后列出。
在較大的程序中,Makefile和gnu make程序可以將c文件編譯成以后綴.o結(jié)尾的中間文件,可以通過(guò)gcc鏈接。
如何編譯每個(gè)目標(biāo)文件通常在Makefile中描述,目標(biāo)文件作為標(biāo)簽以冒號(hào)結(jié)尾,后跟兩個(gè)空格(制表符經(jīng)常導(dǎo)致問(wèn)題),后面是依賴(lài)項(xiàng)的其他文件列表,例如.c文件和.c文件。 o在另一個(gè)部分編譯的文件,在下一行,調(diào)用所需的gcc。打字?man make?或?info make經(jīng)常提供如何使用make以及gcc所需的信息。雖然gcc有很多選項(xiàng)開(kāi)關(guān),但經(jīng)常使用的是-g來(lái)生成gdb的調(diào)試信息,以允許gdb在機(jī)器代碼程序的逐步執(zhí)行期間顯示源代碼。gdb有一個(gè)’h’命令顯示它可以做什么,如果a.out是由gcc編譯的匿名可執(zhí)行機(jī)器代碼文件,它通常以’gdb a.out’開(kāi)頭。
總結(jié)
以上是生活随笔為你收集整理的c语言 自动化编译环境,《C编程.开始C》3.编译基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何保护python代码_如何在发布之前
- 下一篇: asyncio oracle 异步,带有