主要原因在於 makefile 容易被寫成 shell 指令字串的串接器,就是一旦把它當成跑 shell 指令的工具 的工具的話,他就會被 shell/OS語法或是版本的差異綁死。
雖然 [Day 13]有介紹到makefile強大的地方在於可以適應不同環境的編譯器,例如可以透過偵測環境的部分選擇要用clang 或是 gcc做編譯之類的,
不過這樣的話就會造成專案維護日益困難,例如:
CC ?= cc
CXX ?= c++
AR ?= ar
RANLIB ?= ranlib
UNAME_S := $(shell uname -s 2>/dev/null || echo Unknown)
# 嘗試判斷 MSVC(最穩是讓使用者以環境變數帶入)
# 簡單法:若偵測到 cl.exe(Visual Studio 的編譯器)
MSVC := $(shell where cl 1>nul 2>nul && echo 1 || echo 0)
ifeq ($(MSVC),1)
# MSVC 旗標
CC := cl
CXX := cl
AR := lib
RANLIB := echo (msvc-no-ranlib)
CFLAGS := /nologo /W4 /EHsc /std:c11
CXXFLAGS := /nologo /W4 /EHsc /std:c++17
LDFLAGS :=
# 產物命名/路徑(Windows 用反斜線也要小心)
EXE_EXT := .exe
else
# GCC/Clang 旗標
CFLAGS := -std=c11 -Wall -Wextra -O2
CXXFLAGS := -std=c++17 -Wall -Wextra -O2
LDFLAGS :=
EXE_EXT :=
endif
-MMD -MP
產生 .d
檔並正確 -include
,標頭改了卻沒重編很常發生