makefile에서 변수를 출력하는 방법


247

내 makefile에 변수 'NDK_PROJECT_PATH'가 있는데, 내 질문은 컴파일 할 때 어떻게 인쇄 할 수 있습니까?

"$ PATH"문자열을 표시하는 파일 에코 작성을 읽고 다음을 시도했습니다.

@echo $(NDK_PROJECT_PATH)
@echo $(value NDK_PROJECT_PATH)

둘 다 나에게 준다

"build-local.mk:102: *** missing separator.  Stop."

왜 그것이 나를 위해 작동하지 않는지 알고 있습니까?

답변:


223

이 메소드를 사용하여 "var"라는 변수를 사용하여 makefile을 읽을 때 (이 질문에 적절하게 태그를 붙인대로 GNU make라고 가정) 변수를 인쇄 할 수 있습니다.

$(info $$var is [${var}])

이 구성을 레시피에 추가하여 make가 쉘에 전달할 내용을 확인할 수 있습니다.

.PHONY: all
all: ; $(info $$var is [${var}])echo Hello world

이제 여기에서 일어나는 일은 전체 레시피 ( $(info $$var is [${var}])echo Hello world)를 재귀 적으로 확장 된 단일 변수로 저장하는 것 입니다. make가 레시피를 실행하기로 결정하면 (예를 들어 build 명령을 할 때 all) 변수를 확장 한 다음 각 결과 행을 개별적으로 쉘에 전달합니다.

따라서 고통스러운 세부 사항 :

  • 확대 $(info $$var is [${var}])echo Hello world
  • 이를 위해 먼저 확장 $(info $$var is [${var}])
    • $$ 리터럴이된다 $
    • ${var}된다 :-)(말)
    • 부작용은 $var is [:-)]표준 출력에 나타납니다
    • $(info...)비록 의 확장 은 비어 있습니다
  • 확인하다 echo Hello world
    • echo Hello world쉘에 무엇을 할 것인지 알려면 stdout에 먼저 인쇄하십시오 .
  • 쉘은 Hello worldstdout에 인쇄합니다 .

2
PHONY 대신 .PHONY 여야합니까?
hammadian

172

당으로 GNU 것은 설명서를 확인 하고 또한 답변을 아래에 'bobbogo'에 의해 지적, 당신이 사용할 수있는 정보 / 경고 / 오류를 표시 텍스트로.

$(error   text…)
$(warning text…)
$(info    text…)

변수를 인쇄하려면

$(error   VAR is $(VAR))
$(warning VAR is $(VAR))
$(info    VAR is $(VAR))

'error'는 오류 문자열을 표시 한 후 make 실행을 중지 합니다.


와우, 몰랐어 로그에서 명령을 복제하는 에코보다 낫습니다.
deepelement


44

단순히 일부 출력을 원한다면 $(info)자체적 으로 사용하고 싶습니다 . Makefile의 어느 곳에서나 할 수 있으며 해당 라인이 평가되면 표시됩니다.

$(info VAR="$(VAR)")

VAR="<value of VAR>"프로세스가 해당 라인을 만들 때마다 출력 됩니다. 이 동작은 위치에 따라 달라 지므로 $(info)수정할 수있는 모든 항목 $(VAR)이 이미 발생한 후에 확장 이 수행되도록해야합니다 !

보다 일반적인 옵션은 변수 값을 인쇄하기위한 특수 규칙을 작성하는 것입니다. 일반적으로 변수가 지정된 후에 규칙이 실행되므로 실제로 사용중인 값이 표시됩니다. ( 규칙에서 변수를 변경할 수 있습니다 .) 올바른 형식을 지정하면 변수가 무엇으로 설정되어 있는지 명확하게하는 데 도움이되고 $(flavor)함수는 변수의 종류를 알려줍니다. 따라서이 규칙에서 :

print-% : ; $(info $* is a $(flavor $*) variable set to [$($*)]) @true
  • $*% 패턴 이 규칙에서 일치 하는 줄기로 확장됩니다 .
  • $($*)로 이름이 지정된 변수의 값으로 확장됩니다 $*.
  • [하고 ]명확 변수 확장을 묘사. 당신은 또한 사용할 수 ""또는 유사한.
  • $(flavor $*)어떤 종류의 변수인지 알려줍니다. 참고 : 확장이 아닌 $(flavor) 변수 이름을 사용 합니다. 그래서 당신이 말하면 make print-LDFLAGS, 당신은 $(flavor LDFLAGS)원하는 것입니다.
  • $(info text)출력을 제공합니다. 확인 인쇄 text확장의 부작용으로는 표준 출력에. $(info)그래도 확장 은 비어 있습니다. 당신은 그것을 생각할 수 @echo있지만 중요한 것은 쉘을 사용하지 않기 때문에 쉘 인용 규칙에 대해 걱정할 필요가 없습니다.
  • @true규칙에 대한 명령을 제공하기 만합니까? 그렇지 않으면 make 도 출력 print-blah is up to date합니다. 나는 @true그것이 no-op라는 것을 더 분명하게 느낀다 .

그것을 실행하면

$ make print-LDFLAGS
LDFLAGS is a recursive variable set to [-L/Users/...]

이것은 질문에 대한 답변을 제공하지 않습니다. 작성자의 의견을 비판하거나 설명을 요청하려면 게시물 아래에 댓글을 남겨주세요. 언제든지 자신의 게시물 에 댓글 수 있으며 평판 이 충분 하면 게시물댓글 수 있습니다 . - 리뷰에서
Dragon Energy

검토해 주셔서 감사합니다. 평판이 충분하면 댓글을 달 수 있지만 그 동안 어떻게해야합니까? 내 답변이 추가 가치를 제공한다고 생각하므로 추가해서는 안됩니까?
Jim Nasby

1
이 답변을 해당 답변에 대한 비현실적인 의견으로 표현하지 않고 의견을 제출 한 답변과 경쟁하는 독립형 답변으로 다시 작성하는 것이 좋습니다.
Charles Duffy

@JimNasby 네, Charles가 제안한 것입니다. 실제로 그것은 "아무리 언급하기에 충분한 답변이 아닙니다"라고 적힌 부분을 제거하기 시작하는 데 도움이 될 수 있습니다. 완전한 답변으로 바꾸면 (원하는대로 편집 할 수 있음) 아주 잘해야합니다. 건배.
드래곤 에너지

훌륭합니다-이것은 지금 훨씬 더 나은 대답입니다. :)
Charles Duffy

6

@echo $ (NDK_PROJECT_PATH)가 좋은 방법입니다. 나는 오류가 거기에서 온다고 생각하지 않습니다. 일반적 으로이 오류는 의도를 잘못 입력했을 때 나타납니다. 탭이 있어야 할 공간이 있다고 생각합니다.


2
'@echo $ (NDK_PROJECT_PATH)'를 시도했지만 여전히 "build-local.mk:102 : *** 구분 기호가 없습니다. 중지"오류가 발생합니다. 'echo'다음에 공백이 하나만 있고 '@echo'앞에 공백이나 탭이 없습니다.
michael

이 줄에서 오류가 발생 했습니까? 이 줄은 규칙에 있습니까? 그녀는 아마 들여 쓰기해야합니다 ...

6

모든 버전의 make명령 줄에는 줄의 첫 문자로 TAB (공백 아님)이 들여 쓰기되어야합니다. 문제의 두 줄 대신 전체 규칙을 보여 주면 더 명확한 답변을 줄 수 있지만 다음과 같이되어야합니다.

myTarget: myDependencies
        @echo hi

여기서 두 번째 줄의 첫 번째 문자는 TAB이어야합니다.


4

실행 make -n; 변수의 값을 보여줍니다.

메이크 파일 ...

all:
        @echo $(NDK_PROJECT_PATH)

명령:

export NDK_PROJECT_PATH=/opt/ndk/project
make -n 

산출:

echo /opt/ndk/project

이것은 매우 유용하지만 실행 대신에--just-print 동일하게 사용 됩니다
Fredrick Gauss

3

makefile'실종 분리'오류 메시지를 생성합니다 :

all
    @echo NDK_PROJECT_PATH=$(NDK_PROJECT_PATH)

done:
        @echo "All done"

@echo "All done"( done:규칙과 액션은 대체로 불필요하지만) 앞에는 있지만 탭 앞에는 탭 이 없습니다 @echo PATH=$(PATH).

문제는 줄 시작 all에 콜론 :이나 등호가 =있어야 목표 줄이나 매크로 줄임 을 나타내며 구분 기호가 없어야합니다 .

변수 값을 반영하는 조치는 대상, 더미 또는 PHONEY 대상과 연관되어야합니다. 그리고 그 대상 줄에는 콜론이 있어야합니다. 예제에서 :이후 를 추가 하고 다음 줄의 선행 공백을 탭으로 바꾸면 제대로 작동하지 않습니다.allmakefile

원본의 102 행 근처에 비슷한 문제가있을 수 있습니다 makefile. 실패한 에코 조작 전에 비 공백 비 주석 라인을 5 개 표시 한 경우 진단을 완료 할 수 있습니다. 그러나 2013 년 5 월 makefile에이 질문이 제기 된 이후, 지금은 고장난 제품 을 아직 이용할 수 없을 것이므로 (2014 년 8 월)이 답변을 공식적으로 확인할 수는 없습니다. 문제가 발생한 그럴듯한 방법을 설명하기 위해서만 사용할 수 있습니다.


3

Makefile을 수정할 필요가 없습니다.

$ cat printvars.mak
print-%:
        @echo '$*=$($*)'

$ cd /to/Makefile/dir
$ make -f ~/printvars.mak -f Makefile print-VARIABLE

2

문제는 echo가 실행 블록에서만 작동한다는 것입니다. 즉, "xx :"뒤에 나오는 것

따라서 첫 번째 실행 블록 위의 것은 초기화 일뿐이므로 실행 명령을 사용할 수 없습니다.

실행 blocl을 작성하십시오.


1

이것은 일반적인 방법으로 수행 될 수 있으며 복잡한 makefile을 디버깅 할 때 매우 유용 할 수 있습니다. 다른 답변 에서 설명한 것과 동일한 기술을 사용 하면 다음을 모든 메이크 파일에 삽입 할 수 있습니다.

# if the first command line argument is "print"
ifeq ($(firstword $(MAKECMDGOALS)),print)

  # take the rest of the arguments as variable names
  VAR_NAMES := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))

  # turn them into do-nothing targets
  $(eval $(VAR_NAMES):;@:))

  # then print them
  .PHONY: print
  print:
          @$(foreach var,$(VAR_NAMES),\
            echo '$(var) = $($(var))';)
endif

그런 다음 "make print"를 수행하여 모든 변수의 값을 덤프 할 수 있습니다.

$ make print CXXFLAGS
CXXFLAGS = -g -Wall


0

Makefile 자체를 수정하지 않으려면 --eval새 대상을 추가 한 다음 새 대상을 실행하는 데 사용할 수 있습니다 (예 :

make --eval='print-tests: @echo TESTS $(TESTS) ' print-tests

명령 줄에 필요한 TAB 문자를 삽입 할 수 있습니다. CTRL-V, TAB

위의 Makefile 예 :

all: do-something

TESTS=
TESTS+='a'
TESTS+='b'
TESTS+='c'

do-something:
        @echo "doing something"
        @echo "running tests $(TESTS)"
        @exit 1

스크립트를 실행하려고하는데 오류가 발생합니다make: *** missing separator. Stop.
Rinaldi Segecin

아 죄송합니다. "인쇄 테스트"대상 끝에 콜론이 없습니다.
Wade

실제로 줄 바꿈과 탭이 필요하지 않으면 세미콜론으로 충분합니다.make --eval='print-tests: ; @echo TESTS $(TESTS)' print-tests
bobbogo

0

android make (mka) @echo $(NDK_PROJECT_PATH)*** missing separator. Stop." 사용 하면 Android make에서 변수를 인쇄하려고하면 작동하지 않으며 오류가 발생 합니다.

NDK_PROJECT_PATH := some_value
$(warning $(NDK_PROJECT_PATH))

그것은 나를 위해 일했다


0

변수 값을보고 싶다면 일반적으로 오류가 발생합니다 (값을보고 싶을 때만 실행이 중지됩니다).

@echo $ (오류 NDK_PROJECT_PATH = $ (NDK_PROJECT_PATH))

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.