如何访问Makefile中的make选项
我想检测Makefile命令行中是否设置了“-s”。是否有一个变量可以捕获我可以测试的选项 例如,我想做如下事情: 生成文件:如何访问Makefile中的make选项,makefile,Makefile,我想检测Makefile命令行中是否设置了“-s”。是否有一个变量可以捕获我可以测试的选项 例如,我想做如下事情: 生成文件: if ($(MAKE_OPTIONS), -s) #do something endif 调用: make $(MAKEFILE_OPTIONS) -C some_dir 您要查找的变量是MAKEFLAGS ifeq ($(filter s, $(MAKEFLAGS)),s) # do something endif 否,过滤器不是唯一的过滤器。使用fin
if ($(MAKE_OPTIONS), -s)
#do something
endif
调用:
make $(MAKEFILE_OPTIONS) -C some_dir
您要查找的变量是
MAKEFLAGS
ifeq ($(filter s, $(MAKEFLAGS)),s)
# do something
endif
否,
过滤器
不是唯一的过滤器。使用findstring
:
ifneq ($(findstring s, $(MAKEFLAGS)),)
或
不幸的是,要找到一种真正可移植(跨GNU make的不同版本)的方法来实现这一点是很困难的。如果您在名称中设置了任何带有“s”的标志(例如,
--警告未定义的变量
),则Mark的解决方案会给出误报
在GNU make 4.0及更高版本中,MAKEFLAGS的布局定义良好,您可以使用:
$(findstring s,$(firstword -$(MAKEFLAGS))
$(findstring s,$(firstword -$(MAKEFLAGS)))$(filter -s,$(MAKEFLAGS))
可靠可靠地判断是否给出了-s
。然而,这在4.0之前的GNU make版本中无法可靠地工作。您可以使用以下选项:
$(findstring s,$(firstword -$(MAKEFLAGS))
$(findstring s,$(firstword -$(MAKEFLAGS)))$(filter -s,$(MAKEFLAGS))
如果未给出
-s
,则扩展为空字符串;如果未给出,则扩展为非空字符串。我相信这在GNU make的所有版本中都会起作用。事实证明,MAKEFLAGS
的情况甚至更多,如下所示
功能不完全包括:
find_s = $(findstring s,$(firstword -$(MAKEFLAGS)))$(filter -s,$(MAKEFLAGS))
考虑下面显示MAKEFLAGS
值的Makefile
,两者都是
配方的内部和外部,以及find_s
功能的结果:
find_s = $(findstring s,$(firstword -$(MAKEFLAGS)))$(filter -s,$(MAKEFLAGS))
$(info Outside a recipe, MAKEFLAGS="$(MAKEFLAGS)")
$(info $(if $(find_s),-s was detected,-s not found))
all:
@echo 'Inside a recipe, MAKEFLAGS="$(MAKEFLAGS)"'
@echo '$(if $(find_s),-s was detected,-s not found)'
这将正确检测标志-s
的缺失或存在,或
没有其他单字符开关,如-n
,例如:
$ make-3.81
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS=""
-s not found
$ make-4.1
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS=""
-s not found
$ make-3.81 -s
Outside a recipe, MAKEFLAGS="s"
-s was detected
Inside a recipe, MAKEFLAGS="s"
-s was detected
$ make-4.1 -s
Outside a recipe, MAKEFLAGS="s"
-s was detected
Inside a recipe, MAKEFLAGS="s"
-s was detected
$ make-3.81 -s -n
Outside a recipe, MAKEFLAGS="sn"
-s was detected
echo 'Inside a recipe, MAKEFLAGS="sn"'
echo '-s was detected'
$ make-4.1 -s -n
Outside a recipe, MAKEFLAGS="ns"
-s was detected
echo 'Inside a recipe, MAKEFLAGS="ns"'
echo '-s was detected'
一种常见情况是使用“long”开关调用make
(从
--
)以及多个单字符开关。这些单字
开关将在Make 3.81中的MAKEFLAGS
中组合在一个单词中:
$ make-3.81 -n -s --warn-undefined-variables
Outside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"
-s not found
echo 'Inside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"'
echo '-s not found'
$ make-4.1 -n -s --warn-undefined-variables
Outside a recipe, MAKEFLAGS="ns --warn-undefined-variables"
-s was detected
echo 'Inside a recipe, MAKEFLAGS="ns --warn-undefined-variables"'
echo '-s was detected'
开关的分组意味着$(filter-s,$(MAKEFLAGS))
表达式无法使用Make 3.81检测到-s
可以通过如下更改find_s
来解决此问题:
find_s = $(findstring s,$(filter-out --%,$(MAKEFLAGS)))
以--
开头的开关被过滤掉,然后剩下的内容被删除
扫描所需开关(s
),产生正确的检测结果:
$ make-3.81 -n -s --warn-undefined-variables
Outside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"
-s was detected
echo 'Inside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"'
echo '-s was detected'
当变量赋值为
在命令行上传递(例如,make var=value
);在本例中,变量
MAKEFLAGS
将另外包含这些变量赋值。具有
仔细选择的值,两种版本的检测逻辑find\s
仍然可以
被愚弄,例如:
$ make-3.81 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS="var=fake\ -s"
-s was detected
$ make-4.1 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS=" -- var=fake\ -s"
-s was detected
解决第二个问题的最简单方法是保存MAKEFLAGS
在另一个变量中,并在配方中使用该变量,因为幸运的是
配方,MAKEFLAGS
不包含这些变量赋值;否则
下面更复杂的逻辑将解析MAKEFLAGS
,然后停止处理
过滤掉以开头的开关时遇到单词=
或--
--
:
此新的find_s
可在以下所有情况下正确检测-s
:
$ make-3.81 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS="var=fake\ -s"
-s not found
$ make-4.1 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS=" -- var=fake\ -s"
-s not found
$ make-3.81 var='fake -s' -ns --warn-undefined-variables
Outside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"
-s was detected
echo 'Inside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn -- var=fake\ -s"'
echo '-s was detected'
$ make-4.1 var='fake -s' -ns --warn-undefined-variables
Outside a recipe, MAKEFLAGS="ns --warn-undefined-variables"
-s was detected
echo 'Inside a recipe, MAKEFLAGS="ns --warn-undefined-variables -- var=fake\ -s"'
echo '-s was detected'
我希望上述技术能在广泛的品牌中发挥作用
版本,但有这么多角落的情况,很难说;也许是疯狂的科学家
(GNU Make maintainer)可以在这方面发挥作用。哦,天哪,我忘了你可以有这么多选择。谢谢,先生,我可以再来一杯吗!我没有注意到4.0已经发布。我在哪个星球上?谢谢你,保罗!这里还潜伏着其他一些角落案件;有关详细信息,请参阅。
$ make-3.81 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS="var=fake\ -s"
-s not found
$ make-4.1 var='fake -s'
Outside a recipe, MAKEFLAGS=""
-s not found
Inside a recipe, MAKEFLAGS=" -- var=fake\ -s"
-s not found
$ make-3.81 var='fake -s' -ns --warn-undefined-variables
Outside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn"
-s was detected
echo 'Inside a recipe, MAKEFLAGS=" --warn-undefined-variables -sn -- var=fake\ -s"'
echo '-s was detected'
$ make-4.1 var='fake -s' -ns --warn-undefined-variables
Outside a recipe, MAKEFLAGS="ns --warn-undefined-variables"
-s was detected
echo 'Inside a recipe, MAKEFLAGS="ns --warn-undefined-variables -- var=fake\ -s"'
echo '-s was detected'