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

推荐订阅源

Forbes - Security
Forbes - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
量子位
GbyAI
GbyAI
B
Blog RSS Feed
月光博客
月光博客
人人都是产品经理
人人都是产品经理
腾讯CDC
Recent Announcements
Recent Announcements
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
The Cloudflare Blog
D
Docker
Cyberwarzone
Cyberwarzone
U
Unit 42
NISL@THU
NISL@THU
C
Check Point Blog
B
Blog
大猫的无限游戏
大猫的无限游戏
Cisco Talos Blog
Cisco Talos Blog
Recorded Future
Recorded Future
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
G
GRAHAM CLULEY
Engineering at Meta
Engineering at Meta
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 叶小钗
P
Proofpoint News Feed
F
Fortinet All Blogs
V
V2EX
T
Threat Research - Cisco Blogs
T
Threatpost
S
SegmentFault 最新的问题
Know Your Adversary
Know Your Adversary
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园 - 司徒正美
P
Privacy & Cybersecurity Law Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
TaoSecurity Blog
TaoSecurity Blog
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Y
Y Combinator Blog
P
Privacy International News Feed
L
Lohrmann on Cybersecurity
AWS News Blog
AWS News Blog
G
Google Developers Blog
美团技术团队

ABB00717

medusa 找不到 ssh module 中文文案排版指北 BugBounty Playbook 小知識 透過 Ubuntu 26 設定 Windows 11 雙系統並使用 Image Recovery 之踩坑全紀錄 清除 git history 中的機敏資料 編譯器筆記 部落格聚集地 HTB - Busqueda 788. Rotated Digits 396. Rotate Function 幫耳機補血! 紀錄/週刊/ 做過的夢(旅行) 做過的夢 週刊 Vol.18 週刊 Vol.17 週刊 Vol.16 做過的夢(火箭推進器和追蹤導彈) 在 Ubuntu 24.04 中安裝 python2 和 pip2 動態牆 紀錄/音樂/ 用 miniflux 和 Cloudflare Tunnel 自架 RSS Reader 週記 Vol.15 關於用了 GCC 擴充功能,而被批評不夠 Clean Code 這檔事 GDB HTB - TwoMillion 週記 Vol.14 紀錄/Hack-The-Box/ 週記 Vol.13 ABB00717's Blog 1980. Find Unique Binary String 週記 Vol.12 紀錄/Leetcode/ 在互聯網上,什麼該說,什麼又不該說? 週記 Vol.8 週記 Vol.7 週記 Vol.6 天才之於一種義務 就算 LLM 能解答所有問題,你也不該放棄學習 Stack-Based Buffer Overflow 筆記/書籍/ 《絕佳時間》 週記 Vol.5 偽深刻的自我解構 筆記/Linux-雜項筆記/ 解決 Ubuntu 待機後喚醒異常的問題 將應用程式新增到 GNOME 的 Activities Overview 週記 Vol.4 Assembly Language 週記 Vol.3 筆記/ 文章/ 紀錄/ 資源/ 挑戰 週記 Vol.2 部落格該有的東西 週記 Vol.1 數學符號表 Advent of Code Day 8 Advent of Code Day 7 Obsidian 無痛轉成 Blog Advent of Code Day 6
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