Sed
Makefile:如何正確 sed 來編輯變數
我正在嘗試編寫一個自定義 Makefile,在其中收集所有源文件以針對 main 進行編譯。首先我收集他們的名字:
# other sources to compile against (without extensions, separated by spaces) DEPENDENT_FILES = greet farewell
然後我想附加
.o
到每個單詞。在外殼中,我可以通過多種方式做到這一點,例如echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g' # but I know, it's UNIX dependant # or ... echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g'
兩者都在
greet.o farewell.o
終端上導致,但在此過程中失敗(導致空字元串)make
。我把它們寫成DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g') # or ... DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g') # but they result in $(info DEPENDENCIES is $(DEPENDENCIES)) # "DEPENDENCIES is "
我不知道我在這裡做錯了什麼,我懷疑它可能與 Makefiles 中的迴聲或管道有關,但我無法弄清楚。
請,我更喜歡與工作 sed 和 echo 解決方案相關的答案,而不提出不同的方法:這不是我第一次遇到 Makefile 中的 echo 和管道問題,我仍然不知道我的方法有什麼問題.
您需要意識到,儘管它們的語法有很多相似之處,但它們之間存在很大差異,
make
因此shell
必須非常小心地使用它們。更糟糕的是,make 對它的警告非常吝嗇。您在
make
程式碼中的兩個地方犯了錯誤:## bad code DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
- 沒有
GNU make
名為的內置函式echo l
,因為這就是 make 理解它的意思。- 當您需要執行外部實用程序時,您需要做的是呼叫 gnu make 內置
$(shell ...)
函式。- 現在,在您編寫 make 程式碼的方式中潛伏著一個陰險的問題,那就是變數
$DEPENDENT_FILES
. make 會將其解析為 make 變數 $D 後跟字元串文字 EPENDENT !這是因為當沒有括起來的括號或大括號僅是單個字母時,它會生成變數,其餘的被視為文字字元串。- 注意 shell vars vegin 和 $$ 除非 eval 正在執行。
然後我想將 .o 附加到每個單詞。
無需通過外殼進行往返。Make 足夠強大,可以為 像這樣的文件名的常見操作提供幫助。在您的情況下,您需要具有不言自明名稱的函式
addsuffix
:DEPENDENCIES = $(addsuffix .o, $(DEPENDENT_FILES))
這讓你
a.o b.o c.o
得到一個輸入列表a b c
。一個更完整的例子:units = a b c inc = $(addsuffix .h,$(units)) obj = $(addsuffix .o,$(units)) myprog: $(obj) gcc -o $@ $(obj) header-bundle.h: $(inc) cat $< >$@
如果您需要更複雜的替換,還有各種通用字元串操作 ,但只要它們足夠,文件操作就更方便,而且 IMO 更容易被謙遜的人理解。