前一篇文章裡面我們知道gcc makefile 指令的對照之後,我們接下來要學習怎麼實際用makefile編譯出執行檔!
下指令編譯
makefile 相對專案的位置
make
編譯之外還有哪些 常用 make 參數(例如 make -j/-n/-k/-C/-f/-B/-s
)與指令覆寫技巧(make CC=clang
)CC / CFLAGS / CPPFLAGS / LDFLAGS / LDLIBS
這些變數各自做什麼
首先我們要延續Day09的內容...
[Day 09] 了解makefile用途了齁? 那我們來對照一下Makefile跟gcc的語法!
如何用MAKE產生執行檔./dog_meme
接下來請建立一個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加在這邊
如下圖
請先準備好把這個文字貼入你的專案
# =========================
# 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
因為上面的預設有把警告標語打開,所以你應該會看到下面的警告標語,但實際上還是可以編譯出執行檔
因為你上面的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
執行