還記得之前我們曾經使用 gcc 編譯 dog_meme畫出"this is fine ASCII art"嗎?
為何要用MAKE? 請看已經分享的文章↓
MAKE 總共有幾個部分組成?
makefile指令如何跟gcc指令做對照
.h
檔是用來做啥的? → 這篇簡單介紹,之後會深入介紹,會把相關的內容補在這邊,敬請期待!
如何用MAKE產生執行檔? → 下一篇會介紹
gcc --version
如果你執行了,發現沒有gcc 版本號被印出來就要執行下面的指令安裝gcc!
如果沒有 gcc
sudo apt update
sudo apt install -y build-essential gdb
.h
的檔案結構首先,需要回去參考一下之前寫的文章~
[Day 03] 用gcc編譯我人生第一個 C 程式:不是 Hello World!
以 Day 03 的內容來看我們只是想要單純編譯出一個簡單的執行檔,所以我們把print_dog_meme
的 function 寫在main.c
裡面這樣gcc就只需要指定編一main.c
這個檔案,所以簡簡單單就可以用下面的指令呼叫 gcc進行編譯,且不會出現任何警告標語,因為你沒有要gcc要把這些警告給 print 出來。
所以就可以直接下簡易的指令如下:
gcc main.c -o dog_meme
簡單來說就是 gcc
+ (要編譯.c檔案的名稱)
+ -o 編譯完成後的編譯黨的名稱
-o
是 output file的的意思後面會加上輸出檔名,如果沒有加上 -o
會是預設輸出的檔名a.out
。
這邊有指定檔名,所以執行後就會產生一個叫做dog_meme
的執行檔,接著你就可以再下這個指令,簡簡單單去執行他。
./dog_meme
執行結果:
.h
的概念接下來我們要引入.h的概念,之後的文章中會再詳加介紹,大部分專案中,會把function跟main.c兩個分開寫,這樣在管理專案的時候會更好去做管理,因此在這邊我們要把main跟function的功能拆成兩個檔案來做,樹狀結構如下:
加入.h
概念之後我們可以在往下繼續...
首先,大家要先動手準備一下下面的檔案...
首先你先準備一個階層像是這樣的檔案結構
C_PROJ/
├─ .vscode/
│ ├─ settings.json
│ └─ tasks.json
├─ dog_meme.c ← 實作 print_dog_meme()
├─ dog_meme.h ← 宣告 print_dog_meme()
├─ main.c ← 呼叫 print_dog_meme()
└─ dog_meme* ← 編譯後的產物會在這邊(執行檔)
準備完上面檔案的階層後,請填入檔案的內容:main.c
#include "dog_meme.h"
void main(void) {
print_dog_meme();
}
dog_meme.h
#ifndef DOG_MEME_H
#define DOG_MEME_H
void print_dog_meme(void);
#endif // DOG_MEME_H
dog_meme.c
#include <stdio.h>
#include "dog_meme.h"
void print_dog_meme(void) {
printf("test test") // 內容可以上網自己找XD
}
setting,json
可以保持預設就可以了
{
"files.associations": {
"stdio.h": "c"
}
}
task.json
可以保持空白
我們當然可以用之前的方法直接進行編譯,這樣也可以產生執行檔。但沒有警告標語的情況下必然不會看出程式隱藏的一些問題,也不能活用gcc的各種版本。
gcc main.c dog_meme.c -o dog_meme
# Makefile (simple)
# 直接用最基本的參數編譯
.PHONY: all run clean
TARGET := dog_meme
SRCS := main.c dog_meme.c
all: $(TARGET)
$(TARGET): $(SRCS)
@gcc main.c dog_meme.c -o dog_meme
run: $(TARGET)
@./dog_meme
clean:
@rm -f $(TARGET)
如果想要指定gcc版本的話可以加上下面的指令
C11 (2011的版本)
gcc -std=c11 main.c dog_meme.c -o dog_meme
# Makefile (c11)
# 指定 C 標準為 C11
.PHONY: all run clean
TARGET := dog_meme
SRCS := main.c dog_meme.c
all: $(TARGET)
$(TARGET): $(SRCS)
@gcc -std=c11 main.c dog_meme.c -o dog_meme
run: $(TARGET)
@./dog_meme
clean:
@rm -f $(TARGET)
嚴格警告 + 最常用優化/除錯旗標,並包含目前資料夾的標頭搜尋路徑(-I.)
gcc -Wall -Wextra -O2 -g -std=c11 -I. main.c dog_meme.c -o dog_meme
# Makefile (strict)
# 嚴格警告 + 最常用優化/除錯旗標,並包含目前資料夾的標頭搜尋路徑(-I.)
.PHONY: all run clean
TARGET := dog_meme
SRCS := main.c dog_meme.c
all: $(TARGET)
$(TARGET): $(SRCS)
@gcc -Wall -Wextra -O2 -g -std=c11 -I. main.c dog_meme.c -o dog_meme
run: $(TARGET)
@./dog_meme
clean:
@rm -f $(TARGET)