如果variables未设置,则中止makefile
我怎么能放弃基于makefile的variables不被设置/赋值的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的手册中没有find任何东西:
 ifndef MY_FLAG .ABORT endif 
	
 使用errorfunction : 
 ifndef MY_FLAG $(error MY_FLAG is not set) endif 
请注意,行不能缩进。 更确切地说,没有标签必须在这些行之前。
通用解决scheme
如果你要testing许多variables,那么值得定义一个辅助函数:
 # 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. 
目标特定的检查
也可以扩展解决scheme,以便只有在调用某个目标时才需要variables。
  $(call check_defined, ...)从配方里面 
只需将支票移入配方:
 foo : @:$(call check_defined, BAR, baz value) 
 前导的@符号closures命令回显,而:是实际的命令,一个shell 无操作存根 。 
显示目标名称
 可以改进check_defined函数以输出目标名称(通过$@variables提供): 
 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特殊目标 
就我个人而言,我会使用上面的简单和直接的解决scheme。 但是,例如, 这个答案build议使用一个特殊的目标来执行实际的检查。 人们可以尝试将其推广并将目标定义为隐式模式规则:
 # 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, eg 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魔术和二次扩展黑客来克服,尽pipe我不确定这是否值得。 
 使用shell函数test : 
 foo: test $(something) 
用法:
 $ make foo test Makefile:2: recipe for target 'foo' failed make: *** [foo] Error 1 $ make foo something=x test x