[英]Multi-line bash commands in makefile
考慮到每個命令都在自己的 shell 中運行,在 makefile 中運行多行 bash 命令的最佳方法是什么? 例如,像這樣:
for i in `find`
do
all="$all $i"
done
gcc $all
您可以使用反斜杠進行換行。 但是請注意,shell 接收連接成一行的整個命令,因此您還需要用分號終止某些行:
foo:
for i in `find`; \
do \
all="$$all $$i"; \
done; \
gcc $$all
但是,如果您只想獲取find
調用返回的整個列表並將其傳遞給gcc
,則實際上不一定需要多行命令:
foo:
gcc `find`
或者,使用更傳統的$(command)
方法(注意$
轉義):
foo:
gcc $$(find)
如問題所示,每個子命令都在自己的 shell 中運行。 這使得編寫非平凡的 shell 腳本有點混亂——但這是可能的! 解決方案是將您的腳本合並為 make 將考慮單個子命令(單行)的內容。
$$
逃避腳本對$
的使用;
命令之間\\
轉義行尾set -e
開頭以匹配 make 的規定以在子命令失敗時中止()
或{}
將腳本括起來以強調多行序列的內聚性——這不是典型的 makefile 命令序列這是一個受 OP 啟發的示例:
mytarget:
{ \
set -e ;\
msg="header:" ;\
for i in $$(seq 1 3) ; do msg="$$msg pre_$${i}_post" ; done ;\
msg="$$msg :footer" ;\
echo msg=$$msg ;\
}
ONESHELL 指令允許編寫要在同一個 shell 調用中執行的多行配方。
all: foo
SOURCE_FILES = $(shell find . -name '*.c')
.ONESHELL:
foo: ${SOURCE_FILES}
FILES=()
for F in $^; do
FILES+=($${F})
done
gcc "$${FILES[@]}" -o $@
但是有一個缺點:特殊前綴字符(“@”、“-”和“+”)的解釋不同。
https://www.gnu.org/software/make/manual/html_node/One-Shell.html
當然,編寫 Makefile 的正確方法是實際記錄哪些目標取決於哪些來源。 在微不足道的情況下,建議的解決方案將使foo
依賴於自身,但當然, make
足夠聰明,可以刪除循環依賴。 但是如果你在你的目錄中添加一個臨時文件,它會“神奇地”成為依賴鏈的一部分。 最好一勞永逸地創建一個明確的依賴項列表,也許通過腳本。
GNU make 知道如何運行gcc
以從一組.c
和.h
文件中生成可執行文件,所以也許您真正需要的就是
foo: $(wildcard *.h) $(wildcard *.c)
只調用命令有什么問題?
foo:
echo line1
echo line2
....
對於您的第二個問題,您需要使用$$
來轉義$
,即bash -c '... echo $$a ...'
。
編輯:您的示例可以重寫為這樣的單行腳本:
gcc $(for i in `find`; do echo $i; done)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.