iT邦幫忙

2025 iThome 鐵人賽

DAY 10
0
Software Development

30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰系列 第 10

[Day 10] 有了makefile了? 那我們開始編譯吧!

  • 分享至 

  • xImage
  •  

前一篇文章裡面我們知道gcc makefile 指令的對照之後,我們接下來要學習怎麼實際用makefile編譯出執行檔!

在這篇文章中,我們會了解...

  • Makefile 裡面怎麼把 .c 變成可執行檔
  • 大概了解Makefile是在做啥的
  • 簡單看懂Makefile的語法、命名規則
  • 得到一份很小的 Makefile

在看這篇文章之前,可以先問問這幾個問題

  • 有了makefile後要怎麼產生可執行檔?
    • 請看文章的最後一個章節 下指令編譯
  • makefile 要放在哪邊
    • 請看makefile 相對專案的位置

這篇文章會延伸的問題 (後面的章節會再講到)

  • 除了下 make 編譯之外還有哪些 常用 make 參數(例如 make -j/-n/-k/-C/-f/-B/-s)與指令覆寫技巧(make CC=clang
  • 哪裡可以查字典:GNU make / gcc 官方手冊、DevDocs、man/info、pkg-config
  • Makefile的大概架構
  • CC / CFLAGS / CPPFLAGS / LDFLAGS / LDLIBS 這些變數各自做什麼

makefile轉成編譯檔

首先我們要延續Day09的內容...
[Day 09] 了解makefile用途了齁? 那我們來對照一下Makefile跟gcc的語法!
如何用MAKE產生執行檔./dog_meme

建立 makefile

接下來請建立一個makefile把下面的內容貼上去
如下圖,把makefile放在專案同階層的位置

makefile 相對專案的位置

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*            ← 編譯後的產物會在這邊(執行檔)
└─ makefile             ← makefile加在這邊

如下圖
https://ithelp.ithome.com.tw/upload/images/20250909/2017848448NkOHdhqA.png

makefile內容

請先準備好把這個文字貼入你的專案

# =========================
# Makefile for C_PROJ
# =========================
# 編譯器與通用參數
CC      := gcc
CSTD    := c11
WARN    := -Wall -Wextra -Wpedantic
OPT     := -O2
DBG     := -g
INC     := -I.
CFLAGS  := -std=$(CSTD) $(WARN) $(OPT) $(DBG) $(INC) -MMD -MP
LDFLAGS :=
LDLIBS  :=
TARGET := dog_meme_strict
SRCS   := main.c dog_meme.c
OBJS   := $(SRCS:.c=.o)
DEPS   := $(OBJS:.o=.d)
# ---------------------------------
# 預設:嚴格參數編譯
# 等同於 gcc -Wall -Wextra -O2 -g -std=c11 -I. main.c dog_meme.c -o dog_meme
# ---------------------------------
all: $(TARGET)
$(TARGET): $(OBJS)
    $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@
-include $(DEPS)
# 各種 gcc 指令編譯出來的檔案名稱
day03_single: main.c
    $(CC) main.c -o dog_meme_without_h
build_simple:
    $(CC) main.c dog_meme.c -o dog_meme_with_h
build_c11:
    $(CC) -std=$(CSTD) main.c dog_meme.c -o $(TARGET)
# 預設走的路徑
build_strict: CFLAGS := -std=$(CSTD) $(WARN) -Werror $(OPT) $(DBG) $(INC) -MMD -MP -fsanitize=address,undefined
build_strict: LDFLAGS := -fsanitize=address,undefined
build_strict:
    @echo "[build_strict] 使用嚴格旗標:$(CFLAGS) | LDFLAGS=$(LDFLAGS)"
    $(MAKE) clean
    $(MAKE) all
run: $(TARGET)
    ./$(TARGET)
run_single: day03_single
    ./dog_meme_without_h
run_build_simple: build_simple
    ./dog_meme_without_h
clean:
    rm -f $(TARGET) dog_meme_single $(OBJS) $(DEPS)
rebuild: clean all
.PHONY: all build_simple build_c11 build_strict day03_single run run_single clean rebuild

下指令編譯

接下來打開專案同階層的terminal 下 make
因為上面的預設有把警告標語打開,所以你應該會看到下面的警告標語,但實際上還是可以編譯出執行檔
https://ithelp.ithome.com.tw/upload/images/20250909/20178484qB4Umwrn7B.png
因為你上面的makefile 有定義三種編譯方式,所以你可以試試看下下面三個指令
make 產生 dog_meme 搭配 make run 執行
make build_simple產生 dog_meme_with_h 搭配 make run run_build_simple 執行
make build_c11 產生 dog_meme_without_h 搭配 make run day03_single 執行


上一篇
[Day 09] 了解makefile用途了齁? 那我們來對照一下makefile跟gcc的語法!
下一篇
[Day 11]
系列文
30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言