Makefile에 bash 간접 변수 할당을 포함하는 방법

Makefile에 bash 간접 변수 할당을 포함하는 방법

Bash의 간접 변수 설정은 다음과 같이 수행할 수 있습니다.그래서:

#!/bin/bash
foo=bar
ind=foo
echo ${!ind}   # prints `bar'

(GNU) Makefile 레시피와 동일하게 실행해 보세요.

# Makefile
test:
    foo=bar
    ind=foo
    echo $$\{!ind\}
    echo $${!ind}

문자가 이스케이프되었는지 여부에 관계없이 {}다음 메시지와 함께 실패합니다.

foo=bar
ind=foo
echo $\{!ind\}
${!ind}
echo ${!ind}
/bin/sh: 1: Bad substitution
/tmp/Makefile:2: recipe for target 'test' failed
make: *** [test] Error 2

문제는 Makefile에서 특수 문자가 누락되거나 잘못 이스케이프되었을 수 있습니다.

또는 변수 확장의 순서/타이밍일 수도 있습니다.Make의 2차 확장.

어떤 아이디어가 있나요?

중요하다면 이것은 bash 4.4.12(1)-release이고 make 입니다.GNU Make 4.1

답변1

너희들은 정말 대단하다. 질문을 게시한 지 10분도 채 지나지 않아 귀하는 저에게 올바른 해결책을 안내해 주셨는데, 이는 다음과 같습니다.

# Makefile
SHELL=/bin/bash
test:
    foo=bar; \
    ind=foo; \
    echo $${!ind}

스틸드라이버님, 초로바님, 감사합니다.

답변2

여기에는 두 가지 질문이 있습니다.

  1. 레시피의 기본 셸은 이므로 비슷한 구문을 이해하려면 레시피를 sh사용해야 합니다.SHELL=/bin/bash${!ind}
  2. 레시피의 각 라인은 별도의 셸에 의해 실행되므로 레시피에 변수를 정의하면 동일한 레시피의 다음 라인에서 해당 변수가 손실됩니다. 이는 .ONESHELL특별한 목표를 통해 해결 됩니다.

따라서 실제 예는 다음과 같습니다.

# Makefile
.ONESHELL:
SHELL=/bin/bash
test:
    foo=bar
    ind=foo
    echo $$\{!ind\}
    echo $${!ind}

더 자세한 (그리고 공식적인) 설명을 보려면 다음 사이트를 방문하세요. https://www.gnu.org/software/make/manual/make.html#Execution

관련 정보