makefile의 여러 줄 bash 명령어
모든 명령어가 자체 셸에서 실행된다는 점을 고려할 때 makefile에서 multi-line bash 명령을 실행하는 가장 좋은 방법은 무엇입니까?예를 들어 다음과 같습니다.
for i in `find`
do
all="$all $i"
done
gcc $all
회선 연속에는 백슬래시를 사용할 수 있습니다.단, 셸은 단일 행에 연결된 명령어 전체를 수신하므로 일부 행은 세미콜론으로 종료해야 합니다.
foo:
for i in `find`; \
do \
all="$$all $$i"; \
done; \
gcc $$all
하지만 만약 당신이 단지 반환된 모든 목록을 가져가길 원한다면find호출하여 전달하다gcc는 실제로 여러 줄의 명령어가 필요하지 않습니다.
foo:
gcc `find`
또는 보다 일반적인 셸을 사용하여$(command)어프로치(접근)$이스케이프(다만):
foo:
gcc $$(find)
질문에 나타난 바와 같이 모든 하위 명령은 자체 셸에서 실행됩니다.이로 인해 사소한 셸 스크립트의 작성이 다소 번거로워집니다만, 가능합니다.솔루션은 스크립트를 하나의 하위 명령어(한 줄)로 통합하는 것입니다.
makefile 내에 셸 스크립트를 작성하기 위한 힌트:
- 스크립트의 사용을 회피하다
$로 대체함으로써$$ - 삽입하여 스크립트를 한 줄로 변환합니다.
;명령어 사이 - 스크립트를 여러 줄에 쓰려면 다음 명령어를 사용하여 엔드 오브 라인에서 탈출합니다.
\ - 옵션으로 시작
set -e하위 명령 실패 시 중단하도록 규정을 일치시킵니다. - 이것은 완전히 옵션입니다만, 스크립트는 다음과 같이 묶을 수 있습니다.
()또는{}여러 줄 시퀀스의 일관성을 강조합니다. 이것은 일반적인 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 ;\
}
ONESHEL 디렉티브를 사용하면 동일한 셸 호출로 실행되는 여러 줄의 레시피를 쓸 수 있습니다.
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 실행 방법을 .gcc .c ★★★★★★★★★★★★★★★★★」.h있기 에, 한 것은 「」, 「」, 「」뿐일 가능성이 있습니다.
foo: $(wildcard *.h) $(wildcard *.c)
명령만 발동하면 뭐가 문제죠?
foo:
echo line1
echo line2
....
두 이합니다.$를 사용하여$$ 즉, 대, ,, ,, ,, ,, instead, instead.bash -c '... echo $$a ...'.
편집: 예제를 다음과 같이 한 줄의 스크립트로 다시 작성할 수 있습니다.
gcc $(for i in `find`; do echo $i; done)
Makefile에서 도커가 실행 중인지 확인하는 방법을 찾다가 이 게시물을 발견했습니다. 예를 찾을 수 없어서 작성했습니다.여기 컨텍스트의 GNUmake 파일이 있습니다...
https://github.com/RandyMcMillan/make-docker-start
OS :=$(shell uname -s)
export OS
.ONESHELL:
docker-start:## detect whether docker is running...
@( \
while ! docker system info > /dev/null 2>&1; do\
echo 'Waiting for docker to start...';\
if [[ '$(OS)' == 'Linux' ]]; then\
systemctl restart docker.service;\
fi;\
if [[ '$(OS)' == 'Darwin' ]]; then\
open --background -a /./Applications/Docker.app/Contents/MacOS/Docker;\
fi;\
sleep 1;\
done\
)
docker-pull:docker-start## pull alpine image
docker pull alpine
언급URL : https://stackoverflow.com/questions/10121182/multi-line-bash-commands-in-makefile
'programing' 카테고리의 다른 글
| 날짜 시간 문자열을 Bash에서 에폭으로 변환 (0) | 2023.04.14 |
|---|---|
| C#에서 범용 목록을 복제하려면 어떻게 해야 하나요? (0) | 2023.04.14 |
| Linux는 DOS 일시 중지에 상당합니까? (0) | 2023.04.14 |
| 데이터 바인딩을 통해 WPF 하이퍼링크의 텍스트를 설정하려면 어떻게 해야 합니까? (0) | 2023.04.14 |
| WPF 버튼을 링크처럼 보이게 하려면 어떻게 해야 하나요? (0) | 2023.04.14 |