首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Makefile 多子目錄遞迴構建:變數展開陷阱與正確 for 迴圈寫法

     編輯:程式設計綜合問答

現象:`SUBDIRS:=./test1/test9 ./test1/test6`,Makefile 中:

subdirs:
	for dir in $(SUBDIRS); do \
		$(MAKE) -C $$dir; \
	done

執行報 `Syntax error: end of file unexpected`。

根因

Make 將整行命令傳給 `/bin/sh -c`,**變數 `$(SUBDIRS)` 在 Make 階段展開**,命令變為:

for dir in ./test1/test9 ./test1/test6; do \
	make -C $dir; \
done

但 Make 又將 `$dir` 視為 Make 變數 (空值),導致傳給 shell 的實際命令是 `make -C ` 缺參數,語法錯誤。

正確寫法:雙重轉義 + 變數展開分離

SUBDIRS := ./test1/test9 ./test1/test6

subdirs:
	@for dir in $(SUBDIRS); do \
		$(MAKE) -C $$dir; \
	done
  • `$$dir` → Make 保留 `$dir` 傳給 shell,shell 再展開迴圈變數。
  • 前綴 `@` 抑制命令回顯,輸出乾淨。

更健壯:支援空格路徑、並行構建

SUBDIRS := ./test1/test9 ./test1/test6

.PHONY: subdirs $(SUBDIRS)

subdirs: $(SUBDIRS)

$(SUBDIRS):
	$(MAKE) -C $@

# 並行構建:make -j4 subdirs
  • 將每個子目錄作為獨立目標,Make 內建支援 `-j` 並行、依賴圖、錯誤停止。
  • 子目錄 Makefile 需有 `all` 或預設目標。

進階:動態發現子目錄

SUBDIRS := $(wildcard */.)
subdirs: $(SUBDIRS)
$(SUBDIRS): ; $(MAKE) -C $@

總結:**Make 變數用 `$(VAR)`,Shell 變數用 `$$VAR`;多目錄遞迴優先用目標依賴而非手寫 for 迴圈。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved