一次心血來潮的C程式編譯 && makefile
前言
想複習下資料結構,所以看了看相關的課程後打算手寫一些東西,比如連結串列或者說其他的常用資料結構。
環境
- MacOSX
- VSCode
本來打算在xcode上直接寫純C的程式的,但是寫了幾行就發現。。真雞兒麻煩啊,而且我xcode用的也不好,各種快捷鍵也不熟就被勸退了。然後看到公司同事(server)很多都在用VSCode,可能是因為大家都在用mac筆記本的原因裝visualstudio基本上就是扯淡,然後vscode也比較不錯就採用了這個ide。
前置條件
-
安裝外掛 其實也就是這三個c/c+ c/c++ Clang CodeRunner
-
編譯環境配置
- vscode下:command+shift+p 調出控制中心 輸入Tasks: Configure Task 來配置任務
- vscode除錯介面選中齒輪設定按鈕 選擇c/c++(也就是一開始我們安裝的那幾個外掛提供的) 基本不需要改動就是program也就是執行程式裡我改成了alex也就是我的這個程式名,這個隨意。
- vscode下:command+shift+p 調出控制中心 輸入Tasks: Configure Task 來配置任務
以上就具備了在vscode下除錯c/c++程式的功能了
編寫程式碼
- list.h 連結串列標頭檔案 宣告 結構體 以及幾個 連結串列操作方法
- list.c 連結串列普通操作方法的實現
- main.c 入口檔案 引入list.h
問題暴露
要想執行一個c的程式必須經過 編譯+連結+執行 這三個階段至於每個階段都幹了什麼可以搜尋其他相關文文章。這裡我開始只是想簡單的編譯跑一下,那個時候我還沒有使用makefile的方式,而是命令列(配置在task中)截圖看下:
解決方案MakeFile
發現了上面暴露的問題之後,我就開始搜尋相關的內容和文章來看如何把以來檔案也進行編譯。找到了幾篇相關的文章 linux+vsCode+makefile – 除錯C Makefile簡易教程 我這裡是根據第二篇文章進行學習的,第一篇文章給了我啟發。
MakeFile
一個普通的makefile
calc: main.c getch.c getop.c stack.c
gcc -o calc main.c getch.c getop.c stack.c
它主要分成了三個部分,第一行冒號之前的calc,我們稱之為目標(target),被認為是這條語句所要處理的物件,具體到這裡就是我們所要編譯的這個程式calc。冒號後面的部分(main.c getch.c getop.c stack.c),我們稱之為依賴關係表,也就是編譯calc所需要的檔案,這些檔案只要有一個發生了變化,就會觸發該語句的第三部分,我們稱其為命令部分,相信你也看得出這就是一條編譯命令。現在我們只要將上面這兩行語句寫入一個名為Makefile或者makefile的檔案,然後在終端中輸入make命令,就會看到它按照我們的設定去編譯程式了。 但是這個問題很多 ex: 沒能解決當我們只修改一個檔案時就要全部重新編譯的問題 ex: 如果我們需要往工程中新增一個.c或.h,可能同時就要再手動為obj常量再新增第一個.o檔案,如果這列表很長,程式碼會非常難看
一個最終的makefile
cc = gcc
prom = alex
deps = $(shell find ./ -name "*.h")
src = $(shell find ./ -name "*.c")
obj = $(src:%.c=%.o)
$(prom): $(obj)
$(cc) -o $(prom) $(obj)
%.o: %.c $(deps)
$(cc) -g -c $< -o [email protected]
clean:
rm -rf $(obj) $(prom)
這裡解釋一下makefile裡的特殊符號
- %.o:%.c,這是一個模式規則,表示所有的.o目標都依賴於與它同名的.c檔案(當然還有deps中列出的標頭檔案)
- $<代表的是依賴關係表中的第一項(如果我們想引用的是整個關係表,那麼就應該使用$^),具體到我們這裡就是%.c。
- [email protected]代表的是當前語句的目標,即%.o。這樣一來,make命令就會自動將所有的.c原始檔編譯成同名的.o檔案。不用我們一項一項去指定了。
- shell函式主要用於執行shell命令,具體到這裡就是找出當前目錄下所有的.c和.h檔案。
- $(src:%.c=%.o)則是一個字元替換函式,它會將src所有的.c字串替換成.o,實際上就等於列出了所有.c檔案要編譯的結果
終於跑起來
按照makefile的方式編輯好後,在main.c下按鍵command+shift+B來編譯工程 可以看到根據我們編寫的makefile逐步處理ex:我們編譯alex這個程式需要mian.c list.c … 這裡就會逐個編譯list.c->list.o 一次類推,最後生成我們的目標檔案-o alex 以來 xxx.o xx.o。 同樣因為我們在命令里加了-g所以可以在vscode裡進行除錯(反之我們去掉-g就不能除錯了)