makefile의 변수가 설정 / 값 지정되지 않은 상태에서 make / makefile 실행을 어떻게 중단 할 수 있습니까?
나는 이것을 생각해 냈지만 호출자가 대상을 명시 적으로 실행하지 않으면 (즉, 실행 make
만) 작동 합니다.
ifeq ($(MY_FLAG),)
abort: ## This MUST be the first target :( ugly
@echo Variable MY_FLAG not set && false
endif
all:
@echo MY_FLAG=$(MY_FLAG)
나는 이것과 같은 것이 좋은 생각이라고 생각하지만 make 매뉴얼에서 아무것도 찾지 못했습니다 :
ifndef MY_FLAG
.ABORT
endif
답변
TL; DR : error
기능 사용 :
ifndef MY_FLAG
$(error MY_FLAG is not set)
endif
줄을 들여 쓰면 안됩니다. 보다 정확하게는이 행 앞에 탭이 없어야합니다.
일반적인 솔루션
많은 변수를 테스트하려는 경우 보조 함수를 정의하는 것이 좋습니다.
# Check that given variables are set and all have non-empty values,
# die with an error otherwise.
#
# Params:
# 1. Variable name(s) to test.
# 2. (optional) Error message to print.
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))))
사용 방법은 다음과 같습니다.
$(call check_defined, MY_FLAG)
$(call check_defined, OUT_DIR, build directory)
$(call check_defined, BIN_DIR, where to put binary artifacts)
$(call check_defined, \
LIB_INCLUDE_DIR \
LIB_SOURCE_DIR, \
library path)
다음과 같은 오류가 출력됩니다.
Makefile:17: *** Undefined OUT_DIR (build directory). Stop.
노트:
실제 확인은 다음과 같습니다.
$(if $(value $1),,$(error ...))
이는 ifndef
빈 값으로 정의 된 변수도 “정의되지 않은”것으로 간주되도록 조건부 동작을 반영합니다 . 그러나 이것은 간단한 변수와 명시 적으로 빈 재귀 변수에 대해서만 적용됩니다.
# ifndef and check_defined consider these UNDEFINED:
explicitly_empty =
simple_empty := $(explicitly_empty)
# ifndef and check_defined consider it OK (defined):
recursive_empty = $(explicitly_empty)
의견에서 @VictorSergienko가 제안한 것처럼 약간 다른 동작이 필요할 수 있습니다.
$(if $(value $1)
값이 비어 있지 않은지 테스트합니다. 변수가 빈 값으로 정의되어 있으면 때때로 괜찮습니다 . 나는 사용할 것이다$(if $(filter undefined,$(origin $1)) ...
과:
또한 디렉토리이고 검사가 실행될 때 존재 해야하는 경우을 사용
$(if $(wildcard $1))
합니다. 그러나 다른 기능이 될 것입니다.
대상별 점검
특정 대상이 호출 된 경우에만 변수를 요구할 수 있도록 솔루션을 확장 할 수도 있습니다.
$(call check_defined, ...)
레시피 내부에서
수표를 레시피로 옮기십시오.
foo :
@:$(call check_defined, BAR, baz value)
선행 @
부호는 명령 에코를 끄고 :
실제 명령, 쉘 no-op 스텁 입니다.
대상 이름 표시
check_defined
함수는 출력 (스루 제공 대상 이름을 향상시킬 수있다 $@
변수)
check_defined = \
$(strip $(foreach 1,$1, \
$(call __check_defined,$1,$(strip $(value 2)))))
__check_defined = \
$(if $(value $1),, \
$(error Undefined $1$(if $2, ($2))$(if $(value @), \
required by target `$@')))
따라서 실패한 검사는 형식이 좋은 출력을 생성합니다.
Makefile:7: *** Undefined BAR (baz value) required by target `foo'. Stop.
check-defined-MY_FLAG
특별한 목표
개인적으로 위의 간단하고 간단한 솔루션을 사용합니다. 그러나 예를 들어, 이 답변 은 실제 확인을 수행하기 위해 특수 대상을 사용하도록 제안합니다. 이를 일반화하고 대상을 암시 적 패턴 규칙으로 정의하려고 시도 할 수 있습니다.
# Check that a variable specified through the stem is defined and has
# a non-empty value, die with an error otherwise.
#
# %: The name of the variable to test.
#
check-defined-% : __check_defined_FORCE
@:$(call check_defined, $*, target-specific)
# Since pattern rules can't be listed as prerequisites of .PHONY,
# we use the old-school and hackish FORCE workaround.
# You could go without this, but otherwise a check can be missed
# in case a file named like `check-defined-...` exists in the root
# directory, e.g. left by an accidental `make -t` invocation.
.PHONY : __check_defined_FORCE
__check_defined_FORCE :
용법:
foo :|check-defined-BAR
는 것을 알 수 check-defined-BAR
로 표시됩니다 위해 전용 ( |...
) 필수.
장점 :
- (논쟁 적으로) 더 깨끗한 문법
단점 :
- 사용자 정의 오류 메시지를 지정할 수 없습니다
- 실행
make -t
(참조 대신 조리법을 실행 중 의 많은 루트 디렉토리를 오염 것)check-defined-...
파일입니다. 이것은 패턴 규칙 을 선언 할 수 없다는.PHONY
사실의 슬픈 결점입니다 .
나는 가치가 확실하지 않지만 eval
마법과 보조 확장 핵을 사용하여 이러한 제한을 극복 할 수 있다고 생각 합니다.
답변
쉘 기능을 사용하십시오 test
:
foo:
test $(something)
용법:
$ make foo
test
Makefile:2: recipe for target 'foo' failed
make: *** [foo] Error 1
$ make foo something=x
test x
답변
IF를 사용하여 다음을 테스트 할 수 있습니다.
check:
@[ "${var}" ] || ( echo ">> var is not set"; exit 1 )
결과:
$ make check
>> var is not set
Makefile:2: recipe for target 'check' failed
make: *** [check] Error 1
답변
설정되지 않은 변수에 대해 쉘 오류 처리를 사용하십시오 (double 참조 $
).
$ cat Makefile
foo:
echo "something is set to $${something:?}"
$ make foo
echo "something is set to ${something:?}"
/bin/sh: something: parameter null or not set
make: *** [foo] Error 127
$ make foo something=x
echo "something is set to ${something:?}"
something is set to x
사용자 정의 오류 메시지가 필요한 경우 다음 뒤에 추가하십시오 ?
.
$ cat Makefile
hello:
echo "hello $${name:?please tell me who you are via \$$name}"
$ make hello
echo "hello ${name:?please tell me who you are via \$name}"
/bin/sh: name: please tell me who you are via $name
make: *** [hello] Error 127
$ make hello name=jesus
echo "hello ${name:?please tell me who you are via \$name}"
hello jesus
답변
단순성과 간결성을 위해 :
$ cat Makefile
check-%:
@: $(if $(value $*),,$(error $* is undefined))
bar:| check-foo
echo "foo is $$foo"
출력 :
$ make bar
Makefile:2: *** foo is undefined. Stop.
$ make bar foo="something"
echo "foo is $$foo"
foo is something