make
如果不想在我的make
程序(或make
类似程序)中使用制表符缩进,是否有 GNU替代方案?
例如,当我使用 时make
,我需要缩进make
开头符 ( % :
) 之后的所有内容。这是在某些情况下解决某些问题的方法(例如,我跨平台工作,并且我使用 Windows10 AutoHotkey 机制,该机制从我出于不同原因粘贴到 Linux 终端的代码中删除选项卡,并且它不会传递,make
因此我需要一个非选项卡,包括解决方案)。
必须用制表符缩进所有内容,% :
这使得我的工作make
不流畅。
这是make
我用来创建新的虚拟主机配置文件。我用以下命令执行它make domain.tld.conf
:
% :
printf '%s\n' \
'<VirtualHost *:80>' \
'DocumentRoot "/var/www/html/$@"' \
'ServerName $@' \
'<Directory "/var/www/html/$@">' \
'Options +SymLinksIfOwnerMatch' \
'Require all granted' \
'</Directory>' \
'ServerAlias www.$@' \
'</VirtualHost>' \
> "$@"
a2ensite "$@"
systemctl restart apache2.service
有没有其他选择,也许 Unix 本身自带的东西可以提供类似的功能,但不必在模式文件本身中使用制表符缩进?
答案1
GNU 品牌.RECIPEPREFIX
多变的(笔记:不是特殊目标)可用于更改引发配方行的字符。
例如:
.RECIPEPREFIX=>
%:
>printf '%s\n' \
>'<VirtualHost *:80>' \
>'DocumentRoot "/var/www/html/$@"' \
>'ServerName $@' \
>'<Directory "/var/www/html/$@">' \
>'Options +SymLinksIfOwnerMatch' \
>'Require all granted' \
>'</Directory>' \
>'ServerAlias www.$@' \
>'</VirtualHost>' \
>> "$@"
>a2ensite "$@"
>systemctl restart apache2.service
答案2
如果这是您的整个 Makefile,并且您没有跟踪文件之间的任何依赖关系,则只需使用 shell 脚本:
#!/bin/sh
for domain; do
> "/etc/apache2/sites-available/${domain}.conf" cat <<EOF
<VirtualHost *:80>
DocumentRoot "/var/www/html/${domain}"
ServerName "${domain}"
<Directory "/var/www/html/${domain}">
Options +SymLinksIfOwnerMatch
Require all granted
</Directory>
ServerAlias www.${domain}
</VirtualHost>
EOF
a2ensite "${domain}"
done
systemctl restart apache2.service
将以上内容复制到名为 example 的文件中create-vhost
,使其可执行:
chmod 755 create-vhost
然后运行它
./create-vhost domain.tld
这甚至支持创建多个虚拟主机的配置文件(最后重新启动一次):
./create-vhost domain1.tld domain2.tld
答案3
我有一个“最新”的 bash 函数,其用法如下:
newest ${target} ${dependencies} || {
${command} ${dependencies} > $target
}
它不会解析它所属的脚本;我从来不喜欢 make 的“传递闭包”功能,因此只需要对“makefile”中的指令进行排序即可。
使用稍高级别的函数“bystdout”和“bycommand”
bystdout ${target} ${command} ${dependencies}
bycommand ${target} ${command} ${dependencies}
其中“bycommand”包装了那些可以从依赖关系中推断出输出的命令。
我曾经疯狂地编写了一种 awk 解析的语言来解开嵌套依赖项:
output ={ command }{ dependencies }.
这并不是什么大任务。
答案4
如果您正在使用,GNU make
那么您可以充分利用用户定义的函数并完成您想要的任务:
# variables utilized
NULL :=
SPC := $(NULL) $(NULL)
TAB := $(NULL)$(shell printf '\t\n')$(NULL)
# macro to repeat a string ($2) ($1) times
_rep_str = $(if $(filter $1,$(words $3)),$(strip $3),$(call _rep_str,$1,$2,$3 $2))
rep_str = $(subst $(SPC),$(NULL),$(subst x,$2,$(call _rep_str,$1,x)))
# TABs for depth of 1, 2, 3, ...
T1 := $(call rep_str,1,$(TAB))
T2 := $(call rep_str,2,$(TAB))
T3 := $(call rep_str,3,$(TAB))
# multiline macro to be used in recipes for generating .conf files
define create_conf
printf '%s\n' \
'<VirtualHost *:80>' \
'$(T1)DocumentRoot "/var/www/html/$@"' \
'$(T1)ServerName $@' \
'$(T1)<Directory "/var/www/html/$@">' \
'$(T2)Options +SymLinksIfOwnerMatch' \
'$(T2)Require all granted' \
'$(T1)</Directory>' \
'$(T1)ServerAlias www.$@' \
'</VirtualHost>' > $@
a2ensite "$@"
systemctl restart apache2.service
endef
# Now there are no leading TABs/spaces in the makefile
% :; @$(call create_conf)