我正在尝试编写一个make函数来触摸/创建一个空文件和/或在可能的情况下设置权限,用户和组,或者如果没有则发出警告。但是,我的函数中的每个条件检查似乎都评估为真。
我的Makefile的基本要素是
INSTALL_USER := fileUser
INSTALL_GROUP := fileGroup
.PHONY: test
test:
$(call touchFile,~/test.ini)
define touchFile
$(eval fileName := $(strip $(1)))
-touch $(fileName)
-chmod -c 664 $(fileName)
$(info filename info $(fileName))
$(info $(shell stat -c "%a %U:%G" $(fileName)))
$(if ifeq "foo" "bar", @echo match is broken, @echo match works)
$(if ifneq "foo" "bar", @echo match works, @echo match is broken)
$(if ifneq ($(shell stat -c %a $(fileName)),664), $(warning Error - $(fileName) does not have expected permissions of 664))
-chgrp -c $(INSTALL_GROUP) $(fileName)
$(if ifneq ($(shell stat -c %G $(fileName)),$(INSTALL_GROUP)), $(warning Error - $(fileName) does not belong to $(INSTALL_GROUP) group))
-chown -c $(INSTALL_USER) $(fileName)
$(if ifneq ($(shell stat -c %U $(fileName)),$(INSTALL_USER)), $(warning Error - $(fileName) does not belong to $(INSTALL_USER) user))
endef
运行make test
输出
filename info ~/test.ini
664 myUserName:myGroup
Makefile:7: Error - ~/test.ini does not have expected permissions of 664
Makefile:7: Error - ~/test.ini does not belong to common group
Makefile:7: Error - ~/test.ini does not belong to netserve user
touch ~/test.ini
chmod -c 664 ~/test.ini
match is broken
match works
chgrp -c fileGroup ~/test.ini
changed group of `/home/myUserName/test.ini' to fileGroup
chown -c fileUser ~/test.ini
chown: changing ownership of `/home/myUserName/test.ini': Operation not permitted
make: [test] Error 1 (ignored)
我考虑过/尝试了以下内容:
ifeq "foo" "bar"
也会产生无效结果。此外,$(info ...)
在“编译时”正确评估$(fileName)
。$(if ifeq...)
之外,我还尝试了$(ifeq ...)
,这似乎被忽略了。if
(即ifeq
没有$(if...)
)在函数内部提供/bin/sh: ifeq: command not found
。有人可以帮助确定为什么我的条件不符合我的预期(或者为什么我会期待错误的事情)?
警告:我知道如果文件不存在仍然存在缺陷,但与此障碍相比,这应该是微不足道的。
答案 0 :(得分:41)
$(if ...)
conditional function求值为true
。在你的情况下,条件是文字文本:ifeq "foo" "bar"
,显然是非空的。
ifeq
/ifneq
conditionals实际上是指令,而不是函数。它们不能在变量定义和函数内使用。
回到你的例子,在条件中测试字符串是否相等,使用像filter
and findstring
这样的函数:
$(if $(filter foo,bar),@echo match is broken,@echo match works)
$(if $(filter-out foo,bar),@echo match works,@echo match is broken)
顺便说一下,这也可以变成一个内联形式,以提高可读性:
@echo match $(if $(filter foo,bar),is broken,works)
@echo match $(if $(filter-out foo,bar),works,is broken)
答案 1 :(得分:7)
我遇到了这个问题,我发现你可以在“if”功能的“条件”部分使用“过滤”功能的结果。这是一个用于在Linux中打开pdf(带有“evince”)或在带有“打开”的OSX中打开pdf的示例。
uname :=$(shell uname -s)
is_darwin :=$(filter Darwin,$(uname))
viewpdf :=$(if $(is_darwin), open, evince)
答案 2 :(得分:2)
您似乎误解了$(if
的工作方式。来自make info docs:
$(如果条件,那么[,部分]) `if'函数为a中的条件扩展提供支持 功能背景
第一个参数CONDITION首先包含所有前面的和 尾部空白被剥离,然后被扩展。如果它扩大到 任何非空字符串,则该条件被认为是真的。 如果它扩展为空字符串,则考虑条件 是假的。
在所有示例中,您的条件类似于ifeq SOMETHING OTHERTHING
- 这是一个非空字符串(来自ifeq
而不管其他内容是什么),因此被视为真
答案 3 :(得分:1)
如果您想检查您的操作系统版本是Linux还是其他版本,如果它是Linux,那么您想要打印一些消息,那么您可以按照以下步骤操作:
ifneq ($(TARGETOS), Linux)
target: server
@echo
@echo $(MSG) $(TARGETOS)
else
target: server
@echo $(MSG) $(TARGET)
endif
之前我尝试使用ifeq,但它只打印了else部分。 我的操作系统是Linux,ubuntu。
如果有人发现这个答案应该被修改,那么他们也可以给出更好的答案。