iT邦幫忙

2025 iThome 鐵人賽

DAY 13
0
Software Development

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

[Day 13] 解決 VSCode + WSL 權限問題 Makefile 符號 Cheat Sheet

  • 分享至 

  • xImage
  •  

你今天會學到

內容會那麼跳痛的原因XDD

主要是因為[Day 12]中我們有使用到WSL + VSCode 做基本的編譯,裡面涉及一些WSL還有VSCode的操作技巧,其實內容加起來蠻複雜的,然後有收到有人來信說透過vscode打開wsl會有安裝改檔權限相關的問題,所以今天才特別設定一個篇章說明

這篇整理makefile相關的指令,大致上可以分成下面幾類:

  • PS: 下面會有點複雜繁瑣,如果你比較喜歡簡單一點可以直接掉到後面的表格去看 XD

  • 標準變數 CC/ CPPFLAGS / CFLAGS / CXXFLAGS / LDFLAGS / LDLIBS

    • GNU Make 官方手冊有專門一節 Variables Used by Implicit Rules主要就在講這個相關內容
    • GNU Make + GNU 編譯工具鏈的慣例名稱
    • 如果你使用上面這些名稱的話,GNU make 會自動帶入內建的隱含規則
    • 如果你不特別指定 CC = cc (通常 cc 會是系統上 gcc 的符號連結,也可以設定成clang)
    • 標準變數的分類
      • 編譯器類
        • CC → C 編譯器(預設 cc)
        • CXX → C++ 編譯器(預設 g++ 或 c++)
        • FC / F77 → Fortran 編譯器
        • AS → Assembler(組譯器)
        • AR → 建立靜態函式庫的工具(預設 ar)
        • LD → 連結器(通常預設為 $(CC))
      • 編譯旗標類
        • CPPFLAGS → 前處理器選項(-I, -D 等)
        • CFLAGS → C 編譯器選項(警告、最佳化、除錯符號等)
        • CXXFLAGS → C++ 編譯器選項
        • FFLAGS / FCFLAGS → Fortran 編譯器選項
      • 連結旗標類
        • LDFLAGS → 連結器選項(路徑、rpath、特殊 flag)
        • LDLIBS → 要連的函式庫(-lm -lpthread 這種)
  • 自動變數 $@、$<、$^、$?、$+、$*、$$ → 偏向 目標感知

    • $@ → 當前目標檔名 EX:$(CC) … -o $@ → app
    • $< → 第一個相依檔(常用於 %.o : %.c)EX:$(CC) -c $< -o $@ → $< = main.c
    • $^ → 所有相依檔(去重複) EX:$^ = main.o util.o
    • $+ → 所有相依檔(保留重複與順序)
    • $? → 所有比目標新的相依檔(用於增量 build)
    • $* → pattern stem(檔名前綴)
    • $$ → 字面上的 $(在 shell 裡變成單一 $)
  • 特殊目標 → 特殊行為的導向

    • .PHONY → 宣告假目標,避免與檔案同名衝突
    • .SUFFIXES → 定義隱含規則要處理的副檔名;可清空加速
    • .DEFAULT → 沒有規則匹配時執行的 recipe
    • .PRECIOUS → 防止中斷/錯誤時刪掉產物
    • .DELETE_ON_ERROR → 失敗時刪掉不完整產物
    • .ONESHELL → 同一規則的多行命令在同一個 shell 執行
    • .NOTPARALLEL → 禁止此目標平行執行(避免資源衝突)
    • .EXPORT_ALL_VARIABLES → 把變數自動 export 給子 make
  • 運算子與語法符號 (可以直接看後面表格整理)

  • 常用函數 → make語法中的function 都偏向 GNU MAKE內建文字處理函數 (可以直接看後面表格整理)

補充說明: WSL 使用方法

  • 遇到上述問題主要有一個間單的解法,就是每次打開wsl都預設用root 打開,這樣一來就可以預設root 開起來執行
    設定步驟說明
  • 方法一: 直接在powershell 等地方執行
	wsl -l -v # 找出你的環境名稱

下下面的指令可以把預設開起來的使用者改成 root 的權限,root的權限預設可以直接修改檔案

wsl -d Ubuntu-22.04(這是你上面得到的環境名稱) -u root

如果你想要永久修改的話

ubuntu2204 config --default-user root

  • 方法二 : 修改 Windows Terminal 的設定
wsl.exe -d Ubuntu-22.04 -u root
  • 方法三 : 修改 wsl.conf(推薦做法)

打開powershell 打 wsl 進入wsl terminal

sudo nano /etc/wsl.conf

你會看到下面的介面

https://ithelp.ithome.com.tw/upload/images/20250912/20178484vWW54ijf0e.png
介面中加上這一行,ctrl + X存檔

[user]
default=root

上面的方法完成設定這樣你的vscode wsl 打開就會是預設的root使用者了

Makefile 常用符號與自動變數整理表

更詳細的內容可以參考下面的網頁連結

https://www.gnu.org/s/make/manual/html_node/Automatic-Variables.html
https://earthly.dev/blog/makefile-variables/
https://www.gnu.org/software/make/manual/make.html

1. 編譯參數分類

變數名 用途 範例
CPPFLAGS 前處理器選項(Preprocessor flags) -Iinclude -DDEBUG
CFLAGS C 語言編譯選項 -Wall -O2 -g
CXXFLAGS C++ 編譯選項 -std=c++17 -fno-exceptions
FFLAGS Fortran 編譯選項 -O3 -fcheck=all
LDFLAGS 連結器選項 -Llib -Wl,-rpath,./lib
LDLIBS 連結所需函式庫 -lm -lpthread

2. 自動變數

符號 意義 範例
$@ 目前規則的目標(target) main.o
$< 第一個相依檔(first prerequisite) main.c
$^ 所有相依檔(去重複) main.c calc.c
$+ 所有相依檔(保留重複與順序) main.c main.c
$? 所有比目標新的相依檔 calc.c
$* 不含副檔名的檔名(stem) main
$$ 輸出 $ 本身 echo $$PATH

3. 特殊目標

符號 功能
.PHONY 標記假目標,避免與檔案同名衝突
.SUFFIXES 定義隱含規則處理的副檔名
.DEFAULT 沒有符合規則時執行
.PRECIOUS 避免中斷時刪掉產物
.DELETE_ON_ERROR 規則失敗時刪掉不完整的檔案
.ONESHELL 同一規則的多行命令在同一個 shell 中執行

4. 運算子與語法符號

符號 功能 範例
: 一般相依,左邊目標依賴右邊檔案 main.o: main.c
**` `** order-only 相依:必須存在,但時間戳不觸發重建
% pattern rule 萬用字元 %.o: %.c
@ 隱藏命令本身的輸出 @echo "build..."
- 忽略錯誤繼續執行 -rm -f *.o
?= 僅在未被設定時才賦值(預設值) CC ?= gcc
+= 在原有值後累加內容 CFLAGS += -Wall

5. 常用函數

函數 功能 範例
$(wildcard *.c) 展開符合條件的檔案 main.c utils.c
$(patsubst %.c,%.o,$(SRCS)) 替換副檔名 .c → .o
$(dir $@) 取路徑 src/main.o → src/
$(notdir $@) 取檔名 src/main.o → main.o
$(basename $@) 去副檔名 main.c → main
$(addprefix obj/,$(SRCS)) 加前綴 obj/main.c
$(addsuffix .o,$(FILES)) 加後綴 main.o util.o

上一篇
[Day 12] make 專案目錄規劃實作解析
下一篇
[Day 14] 看過有一個makefile的專案了? 那我們來看看兩個以上makefile專案怎麼寫
系列文
30 天精通 C 語言建置與除錯:從 Makefile 到 CMake 跨平台實戰14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言