对于那些不希望制表符缩进开场白下所有内容的人来说,Makefile 是替代方案

对于那些不希望制表符缩进开场白下所有内容的人来说,Makefile 是替代方案

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)

相关内容