Makefile은 오프너 아래의 모든 항목을 탭 들여쓰기를 원하지 않는 사람들을 위한 대안입니다.

Makefile은 오프너 아래의 모든 항목을 탭 들여쓰기를 원하지 않는 사람들을 위한 대안입니다.

makemake프로그램(또는 유사한 프로그램) make에서 탭 들여쓰기를 사용하고 싶지 않은 경우 GNU 대안이 있습니까?

예를 들어 를 사용할 때 시작 문자( ) 뒤의 모든 항목을 make들여쓰기해야 합니다 . 다음은 경우에 따라 몇 가지 문제를 해결하는 방법입니다. 예를 들어 저는 크로스 플랫폼으로 작업하고 여러 가지 이유로 Linux 터미널에 붙여넣은 코드에서 탭을 제거하는 Windows10 AutoHotkey 메커니즘을 사용하는데 통과되지 않습니다. 그래서 솔루션을 포함한 탭이 아닌 것이 필요합니다).make% :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이고 파일 간의 종속성을 추적하지 않는 경우 쉘 스크립트를 사용하십시오.

#!/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)

관련 정보