Sed

Makefile:如何正確 sed 來編輯變數

  • December 30, 2020

我正在嘗試編寫一個自定義 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 更容易被謙遜的人理解。

引用自:https://unix.stackexchange.com/questions/626597