惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The Register - Security
The Register - Security
美团技术团队
Recent Announcements
Recent Announcements
MongoDB | Blog
MongoDB | Blog
Jina AI
Jina AI
C
Check Point Blog
aimingoo的专栏
aimingoo的专栏
I
InfoQ
S
Securelist
T
Tor Project blog
GbyAI
GbyAI
L
LINUX DO - 热门话题
V
Visual Studio Blog
AWS News Blog
AWS News Blog
The Cloudflare Blog
腾讯CDC
K
Kaspersky official blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recorded Future
Recorded Future
李成银的技术随笔
W
WeLiveSecurity
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
M
Microsoft Research Blog - Microsoft Research
G
Google Developers Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Schneier on Security
Schneier on Security
B
Blog
IT之家
IT之家
爱范儿
爱范儿
H
Help Net Security
Simon Willison's Weblog
Simon Willison's Weblog
NISL@THU
NISL@THU
J
Java Code Geeks
博客园 - 聂微东
T
The Exploit Database - CXSecurity.com
Cyberwarzone
Cyberwarzone
博客园 - 叶小钗
MyScale Blog
MyScale Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Project Zero
Project Zero
F
Future of Privacy Forum
D
Darknet – Hacking Tools, Hacker News & Cyber Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Hacker News: Ask HN
Hacker News: Ask HN
D
Docker
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
V
Vulnerabilities – Threatpost

ABB00717

788. Rotated Digits 396. Rotate Function 幫耳機補血! 週刊 做過的夢(旅行) 週刊 Vol.18 週刊 Vol.17 週刊 Vol.16 做過的夢(火箭推進器和追蹤導彈) 部落格聚集地 在 Ubuntu 24.04 中安裝 python2 和 pip2 動態牆 音樂 用 miniflux 和 Cloudflare Tunnel 自架 RSS Reader 關於用了 GCC 擴充功能,而被批評不夠 Clean Code 這檔事 週記 Vol.15 GDB TwoMillion 週記 Vol.14 Hack The Box 週記 Vol.13 ABB00717's Blog 1980. Find Unique Binary String Leetcode 週記 Vol.12 在互聯網上,什麼該說,什麼又不該說? 週記 Vol.8 週記 Vol.7 週記 Vol.6 天才之於一種義務 就算 LLM 能解答所有問題,你也不該放棄學習 書籍 週記 Vol.5 《絕佳時間》 Stack-Based Buffer Overflow 偽深刻的自我解構 Linux 雜項筆記 解決 Ubuntu 待機後喚醒異常的問題 將應用程式新增到 GNOME 的 Activities Overview 週記 Vol.4 Assembly Language 筆記 週記 Vol.3
Makefile
2026-03-29 · via ABB00717

你就想像你在寫 BashPython 這種腳本語言,只不過 make 更針對編譯這個情境設計。

既然是腳本語言,那肯定以下幾個是不能少的:

  • 指令
  • 變數
  • 函式
  • 條件判斷

四大要件

指令

就是你在命令列(Command Line)會打的那些命令。但請注意,指令前面必須要是以 <Tab> 縮排,不能用空白鍵!

變數

在 Makefile 習慣變數名稱用大寫,要取變數值必須用 $(VAR)${VAR}

變數賦值

  • := (立即賦值 / Simple Assignment):定義的當下就會把值並確定下來,最常用且最推薦。
  • = (延遲賦值 / Recursive Assignment):用到該變數時,才會去尋找並展開它當下的值。這可能導致無窮迴圈或非預期結果。
  • ?= (條件賦值 / Conditional Assignment):如果這個變數前面還沒有被定義過,才會賦予它這個值;如果已經有值了,這行就會被忽略。
  • += (附加賦值 / Append):將後面的字串接在原本變數內容的後面(會自動用一個空白字元隔開)。

自動化變數

  • $@ 工作目標檔名
  • $* 工作目標的主檔名
  • $< 第一個必要條件的檔名
  • $^ 所有必要條件的檔名,並以空格隔開這些檔名
  • $? 所有比工作目標還要新的必要條件檔名

其他符號修飾

  • % 代表所有字串,像是 Regex 的 *
  • @ 不要顯示當前執行的命令
  • - 就算當前命令出錯,也不要中斷後續的執行

函式

在 Makefile 中叫做目標(Target),和函式一樣可以被呼叫和依賴:

all:
    # Compile Commands
clean:
    # Clean Commands

我們可以像呼叫函式那樣呼叫任意區塊,那當然也可能會有參數(依賴條件):

target: <obj1> <obj2>
    # Commands

Makefile 如果在呼叫 make 不接任何參數,就會執行第一個區塊。而 make 會先確認參數裡的每個區塊都準備完畢,才會執行該區塊:

FILE = main.l
NAME = $(basename $(FILE))

run: $(NAME)
    ./$(NAME)

$(NAME): lex.yy.c
    cc -o $(NAME) -O lex.yy.c -ll

lex.yy.c: $(FILE)
    lex $(FILE)

這就是 run $(NAME) lex.yy.c $(FILE),也就是只要有 FILE,其實就可以執行 run 了。因此要運行上述腳本,只須 make FILE=test.l 即可!

真實的內建函式

除了把 Target 當作函式,Makefile 也有提供真正的字串與檔案處理函式,語法通常是 $(function_name arguments)

  • $(wildcard *.c):抓取當前目錄下所有 .c 結尾的檔案。
  • $(patsubst %.c,%.o,$(SRCS)):字串替換,把 $(SRCS) 裡所有 .c 結尾的字串換成 .o
  • $(shell ls -la):執行外部的 Shell 指令並捕捉其輸出結果。

條件判斷

Makefile 也支援條件判斷(ifeq, ifneq, ifdef, ifndef),最常用來判斷不同的作業系統或編譯環境:

OS := $(shell uname)

ifeq ($(OS), Darwin)
    CC = clang
    CFLAGS += -D MAC_OS
else ifeq ($(OS), Linux)
    CC = gcc
    CFLAGS += -D LINUX_OS
else
    CC = cc
endif

build:
    $(CC) $(CFLAGS) main.c -o main