Linux-程序編譯調試-gcc和makefile

一、gcc基本使用

1、gcc編譯過程

源文件—>預處理—>彙編—>編譯—>鏈接—>可執行文件

2、gcc編譯c文件

命令:gcc [選項] <文件名>

選項:-o 指定輸出的文件名,默認生成可執行文件名爲a.out

​ -E 預處理階段:對包含的頭文件(#include)和宏定義(#define、#ifdef等)進行處理,生成.i文件,不 加-o選項,默認輸出爲標準輸出(屏幕)

​ -S 彙編階段:檢查代碼規範性、語法錯誤等,在檢查無誤後把代碼翻譯成彙編語言,生成.s文件,不加-o 選項,默認生成sourcename.s文件

​ -c 編譯階段:將彙編文件翻譯成機器碼,生成.o文件,不加-o默認生成sourcename.o文件

​ -D 宏定義選項,如-DPI=3.14表示#define PI 3.14

​ -l 添加頭文件搜索路徑,可用此選項指定搜索路徑

​ -w 禁止所有警告信息(warning)

​ -wall 打開所有警告選項,輸出警告信息

dream:1_線性表(順序存儲) dream$ gcc -E -o item.i item.c 
dream:1_線性表(順序存儲) dream$ ls
item.c	item.i
dream:1_線性表(順序存儲) dream$ gcc -S -o item.s item.i
dream:1_線性表(順序存儲) dream$ ls
item.c	item.i	item.s
dream:1_線性表(順序存儲) dream$ gcc -c -o item.o item.s
dream:1_線性表(順序存儲) dream$ ls
item.c	item.i	item.o	item.s
dream:1_線性表(順序存儲) dream$ gcc -o item.exe item.o
dream:1_線性表(順序存儲) dream$ ls
item.c		item.exe	item.i		item.o		item.s
dream:1_線性表(順序存儲) dream$ ./item.exe 
申請內存成功!
表爲空!
插入成功!
插入成功!
插入成功!
插入成功!
插入位置大於表現有長度,其餘位置初始化爲0!
表的內容是:10 999 1000 1000 0 10000 

也可以直接一步生成可執行文件,即直接使用gcc命令,不加選項,則包含了以上四個過程,如下

dream:1_線性表(順序存儲) dream$ gcc -o main.exe main.c
dream:1_線性表(順序存儲) dream$ ls
main.c		main.exe
dream:1_線性表(順序存儲) dream$ ./main.exe 
申請內存成功!
表爲空!
插入成功!
插入成功!
插入成功!
插入成功!
插入位置大於表現有長度,其餘位置初始化爲0!
表的內容是:10 999 1000 1000 0 10000 

二、makefile基本使用

1、makefile介紹

(1)make命令用來編譯源文件和鏈接目標文件

  • 編譯:將源代碼編譯成目標文件(即機器碼,後綴名爲.o或.obj)
  • 鏈接:使用目標文件鏈接應用程序生成可執行文件

(2)Makefile文件則是用來告訴make命令怎麼去編譯和鏈接程序

一個工程中的源文件不計數,其按***類型、功能、模塊***分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至於進行更復雜的功能操作,因爲makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率。

2、Makefile規則

(1)Makefile的編譯規則

  • 如果這個工程沒有編譯過,那麼我們的所有C文件都要編譯並被鏈接。
  • 如果這個工程的某幾個C文件被修改,那麼我們只編譯被修改的C文件,並鏈接目標程序。
  • 如果這個工程的頭文件被改變了,那麼我們需要編譯引用了這幾個頭文件的C文件,並鏈接目標程序。

(2)Makefile的語法

target(目標):Dependent object(依賴對象)
	command(shell命令)
  • target:可以是目標文件(.o),也可以是可執行文件(.exe),還可以是label(這個沒有去深入瞭解)
  • Dependent object:目標依賴的對象,就是生成目標所需要的文件或者其它目標
  • command:任意的shell命令,注意command前面有一個製表符

(3)Makefile的語法解釋

生成target需要Dependent object,如果Dependent object不存在或者Dependent object更改過,那麼就會執行command以生成所需要的目標或文件

3、示例

(1)不使用make和Makefile,手動編譯程序

現在以一個示例來說明make和Makefile,在一個test目錄下,有2個頭文件和3個.c文件,如果不使用make來編譯,手動編譯的過程如下:

dream:test dream$ ls
main.c	tool1.c	tool1.h	tool2.c	tool2.h
dream:test dream$ gcc -w -c main.c
dream:test dream$ gcc -w -c tool1.c
dream:test dream$ gcc -w -c tool2.c
dream:test dream$ gcc -o main main.o tool1.o tool2.o
dream:test dream$ ls
main	main.c	main.o	tool1.c	tool1.h	tool1.o	tool2.c	tool2.h	tool2.o
dream:test dream$ ./main
This is write1
This is write2!!!!

(2)使用make編譯程序

文件夾的內容同上,Makefile的內容如下:

main: main.o tool1.o tool2.o
	gcc -o main.exe main.o tool1.o tool2.o
main.o: main.c tool1.h tool2.h
	gcc -w -c main.c
tool1.o: tool1.c tool1.h
	gcc -w -c tool1.c
tool2.o: tool2.c tool2.h
	gcc -w -c tool2.c
clean:
	rm -rf *.o *.exe

編寫好Makefile後,使用make命令看一下效果

dream:makefile的示例 dream$ ls
Makefile	tool1.c		tool2.c
main.c		tool1.h		tool2.h
dream:makefile的示例 dream$ make										# 寫好Makefile後,直接使用make命令編譯
gcc -w -c main.c
gcc -w -c tool1.c
gcc -w -c tool2.c
gcc -o main.exe main.o tool1.o tool2.o
dream:makefile的示例 dream$ ls
Makefile	main.exe	tool1.c		tool1.o		tool2.h
main.c		main.o		tool1.h		tool2.c		tool2.o
dream:makefile的示例 dream$ ./main.exe 
This is write1
This is write2!!!!
dream:makefile的示例 dream$ make clean							# 使用make clean一鍵刪除.o和.exe文件
rm -rf *.o *.exe
dream:makefile的示例 dream$ ls
Makefile	tool1.c		tool2.c
main.c		tool1.h		tool2.h

參考資料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章