做石材外貿(mào)用什么網(wǎng)站宣傳推廣圖片
今天學習linuxC編程。首先要熟悉linux下編寫c程序的過程。
編寫程序Hello World!
首先創(chuàng)建存放程序的文件夾,如下圖所示:
接下來在創(chuàng)建一個文件夾來保存這節(jié)要編寫的代碼。指令:mkdir 3.1
接下來我們要設(shè)置VIM編輯器的一些配置,比如設(shè)置tab的字符數(shù)為4、以及設(shè)置VIM編輯器的行號。在文件/etc/vim/vimrc 中添加代碼:
set nu
set ts=4
然后創(chuàng)建main.c文件。
編寫程序完事后,使用“gcc main.c –o main”來編譯 main.c 文件,使用參數(shù)“-o”來指定編譯生成的可執(zhí)行文件名字。
GCC編譯器
gcc 命令
在上一小節(jié)我們已經(jīng)使用過 GCC 編譯器來編譯 C 文件了,我們使用到是 gcc 命令,gcc 命令格式如下:
gcc [選項] [文件名字]
主要選項如下:
-c:只編譯不鏈接為可執(zhí)行文件,編譯器將輸入的.c 文件編譯為.o 的目標文件。
-o:<輸出文件名>用來指定編譯結(jié)束以后的輸出文件名,如果不使用這個選項的話 GCC 默
認編譯出來的可執(zhí)行文件名字為 a.out。
-g:添加調(diào)試信息,如果要使用調(diào)試工具(如 GDB)的話就必須加入此選項,此選項指示編
譯的時候生成調(diào)試所需的符號信息。
-O:對程序進行優(yōu)化編譯,如果使用此選項的話整個源代碼在編譯、鏈接的的時候都會進
行優(yōu)化,這樣產(chǎn)生的可執(zhí)行文件執(zhí)行效率就高。
-O2:比-O 更幅度更大的優(yōu)化,生成的可執(zhí)行效率更高,但是整個編譯過程會很慢。
編譯流程
GCC 編譯器的編譯流程是:預(yù)處理、編譯、匯編和鏈接。預(yù)處理就是展開所有的頭文件、替換程序中的宏、解析條件編譯并添加到文件中。編譯是將經(jīng)過預(yù)編譯處理的代碼編譯成匯編代碼,也就是我們常說的程序編譯。匯編就是將匯編語言文件編譯成二進制目標文件。鏈接就是將匯編出來的多個二進制目標文件鏈接在一起,形成最終的可執(zhí)行文件,鏈接的時候還會涉及到靜態(tài)庫和動態(tài)庫等問題。上一小節(jié)演示的例程都只有一個文件,而且文件非常簡單,因此可以直接使用 gcc 命令生成可執(zhí)行文件,并沒有先將 c 文件編譯成.o 文件,然后再鏈接在一起。
Makefile 基礎(chǔ)
當文件有幾十、上百甚至上萬個的時候用終端輸入 GCC 命令的方法顯然是不現(xiàn)實的。如果我們能夠編寫一個文件,這個文件描述了編譯哪些源碼文件、如何編譯那就好了,每次需要編譯工程的時只需要使用這個文件就行了。這種問題怎么可能難倒聰明的程序員,為此提出了一個解決大工程編譯的工具:make,描述哪些文件需要編譯、哪些需要重新編譯的文件就叫做 Makefile,Makefile 就跟腳本文件一樣,Makefile 里面還可以執(zhí)行系統(tǒng)命令。使用的時候只需要一個 make命令即可完成整個工程的自動編譯,極大的提高了軟件開發(fā)的效率。如果大家以前一直使用 IDE來編寫 C 語言的話肯定沒有聽說過 Makefile 這個東西,其實這些 IDE 是有的,只不過這些 IDE對其進行了封裝,提供給大家的是已經(jīng)經(jīng)過封裝后的圖形界面了,我們在 IDE 中添加要編譯的
C 文件,然后點擊按鈕就完成了編譯。在 Linux 下用的最多的是 GCC 編譯器,這是個沒有 UI的編譯器,因此 Makefile 就需要我們自己來編寫了。
Makefile 語法
Makefile 規(guī)則格式
Makefile 里面是由一系列的規(guī)則組成的,這些規(guī)則格式如下:
目標…... : 依賴文件集合……
命令 1
命令 2
……
main : main.o input.o calcu.ogcc -o main main.o input.o calcu.o
第一行定義了一個規(guī)則,它告訴make命令如何構(gòu)建目標main。在這里,main是一個目標(通常是最終要生成的程序或文件),而main.o、input.o和calcu.o是這個目標的依賴項,意味著在構(gòu)建main之前,必須首先存在或構(gòu)建這些依賴項。
目標(target):main是這條規(guī)則的目標,也就是這條規(guī)則想要構(gòu)建或更新的文件。
依賴(dependencies):main.o、input.o和calcu.o是目標的依賴項,這意味著在嘗試構(gòu)建main之前,make會確保所有的依賴項都是最新的。
gcc是GNU編譯器集合中的C編譯器,用于編譯C語言程序。-o main選項告訴gcc將鏈接生成的可執(zhí)行文件命名為main。main.o、input.o和calcu.o是gcc需要鏈接的對象文件。這些對象文件之前已經(jīng)由gcc從相應(yīng)的源文件編譯生成。
命令列表中的每條命令必須以 TAB 鍵開始,不能使用空格!
make 命令會為 Makefile 中的每個以 TAB 開始的命令創(chuàng)建一個 Shell 進程去執(zhí)行。了解了 Makefile 的基本運行規(guī)則以后我們再來分析一下 3.3 節(jié)中“示例代碼 3.3.2.6”中的Makefile,代碼如下:、
上述代碼中一共有 5 條規(guī)則,1~2 行為第一條規(guī)則,3~4 行為第二條規(guī)則,5~6 行為第三條規(guī)則,7~8 行為第四條規(guī)則,10~12 為第五條規(guī)則,make 命令在執(zhí)行這個 Makefile 的時候其執(zhí)行步驟如下:首先更新第一條規(guī)則中的 main,第一條規(guī)則的目標成為默認目標,只要默認目標更新了那么就認為 Makefile 的工作。在第一次編譯的時候由于 main 還不存在,因此第一條規(guī)則會執(zhí)行,第一條規(guī)則依賴于文件 main.o、input.o 和 calcu.o 這個三個.o 文件,這三個.o 文件目前還都沒有,因此必須先更新這三個文件。make 會查找以這三個.o 文件為目標的規(guī)則并執(zhí)行。以 main.o為例,發(fā)現(xiàn)更新 main.o 的是第二條規(guī)則,因此會執(zhí)行第二條規(guī)則,第二條規(guī)則里面的命令為“gcc–c main.c”,這行命令很熟悉了吧,就是不鏈接編譯 main.c,生成 main.o,其它兩個.o 文件同理。最后一個規(guī)則目標是 clean,它沒有依賴文件,因此會默認為依賴文件都是最新的,所以其對應(yīng)的命令不會執(zhí)行,當我們想要執(zhí)行 clean 的話可以直接使用命令“make clean”,執(zhí)行以后就會刪除當前目錄下所有的.o 文件以及 main,因此 clean 的功能就是完成工程的清理,
總結(jié)一下 Make 的執(zhí)行過程:
1、make 命令會在當前目錄下查找以 Makefile(makefile 其實也可以)命名的文件。
2、當找到 Makefile 文件以后就會按照 Makefile 中定義的規(guī)則去編譯生成最終的目標文件。
3、當發(fā)現(xiàn)目標文件不存在,或者目標所依賴的文件比目標文件新(也就是最后修改時間比目標文件晚)的話就會執(zhí)行后面的命令來更新目標。
原子文檔總結(jié)的很形象。具體執(zhí)行的過程就如上圖所示:
Makefile 變量
跟 C 語言一樣 Makefile 也支持變量的,先看一下前面的例子:
main: main.o input.o calcu.ogcc -o main main.o input.o calcu.o
上述 Makefile 語句中,main.o input.o 和 calcue.o 這三個依賴文件,我們輸入了兩遍,我們這個 Makefile 比較小,如果 Makefile 復(fù)雜的時候這種重復(fù)輸入的工作就會非常費時間,而且非常容易輸錯,為了解決這個問題,Makefile 加入了變量支持。不像 C 語言中的變量有 int、char等各種類型,Makefile 中的變量都是字符串!類似 C 語言中的宏。使用變量將上面的代碼修改,修改以后如下所示:
1 #Makefile 變量的使用
2 objects = main.o input.o calcu.o
3 main: $(objects)
4 gcc -o main $(objects)
第 1 行是注釋,Makefile 中可以寫注釋,注釋開頭要用符號“#”,不能用 C 語言中的“//”或者“/**/”!第 2 行我們定義了一個變量 objects,并且給這個變量進行了賦值,其值為字符串“main.o input.o calcu.o”,第 3 和 4行使用到了變量 objects,Makefile 中變量的引用方法是“ ( 變量名 ) ”,比如本例中的“ (變量名)”,比如本例中的“ (變量名)”,比如本例中的“(objects)”就是使用變量 objects。在“示例代碼 3.4.2.1”中我們在定義變量 objects 的時候使用“=”對其進行了賦值,Makefile變量的賦值符還有其它兩個“:=”和“?=”,我們來看一下這三種賦值符的區(qū)別:
1、賦值符“=”
示例代碼 3.4.2.1 賦值符"="使用
1 name = zzk
2 curname = $(name)
3 name = zuozhongkai
4
5 print:
6 @echo curname: $(curname)
2、賦值符“:=”
賦值符“:=”不會使用后面定義的變量,只能使用前面已經(jīng)定義好的,這就是“=”和“:=”兩個的區(qū)別。
3、賦值符“?=”
“?=”是一個很有用的賦值符,比如下面這行代碼:
curname ?= zuozhongkai
上述代碼的意思就是,如果變量 curname 前面沒有被賦值,那么此變量就是“zuozhongkai”,
如果前面已經(jīng)賦過值了,那么就使用前面賦的值。
4、變量追加“+=”
Makefile 中的變量是字符串,有時候我們需要給前面已經(jīng)定義好的變量添加一些字符串進
去,此時就要使用到符號“+=”,比如如下所示代碼:
objects = main.o input.o
objects += calcu.o
一開始變量 objects 的值為“main.o input.o”,后面我們給他追加了一個“calcu.o”,因此變量 objects 變成了“main.o input.o calcu.o”,這個就是變量的追加。
Makefile 模式規(guī)則
模式規(guī)則中,至少在規(guī)則的目標定定義中要包涵“%”,否則就是一般規(guī)則,目標中的“%”表示對文件名的匹配,“%”表示長度任意的非空字符串,比如“%.c”就是所有的以.c 結(jié)尾的文件,類似與通配符,a.%.c 就表示以 a.開頭,以.c 結(jié)束的所有文件。
當“%”出現(xiàn)在目標中的時候,目標中“%”所代表的值決定了依賴中的“%”值,