如何知道makefile变量是字符串还是数字?
这听起来可能很简单,但我无法找到将makefile变量分类为文本或数字的方法。我的伪代码如下所示:如何知道makefile变量是字符串还是数字?,makefile,pattern-matching,gnu-make,Makefile,Pattern Matching,Gnu Make,这听起来可能很简单,但我无法找到将makefile变量分类为文本或数字的方法。我的伪代码如下所示: ifeq ($N, 'numeric') CFLAGS+=-D$N endif define is_number $(shell test '$(1)' -eq '$(1)' 2>/dev/null && echo yes || echo no) endef ifeq ($(call is_number, $(N)),yes) default: @echo N i
ifeq ($N, 'numeric')
CFLAGS+=-D$N
endif
define is_number
$(shell test '$(1)' -eq '$(1)' 2>/dev/null && echo yes || echo no)
endef
ifeq ($(call is_number, $(N)),yes)
default:
@echo N is a number
else
default:
@echo N is not a number
endif
如何做到这一点?我正在使用GNU Make(在cygwin/Windows中)。我读了它附带的make.pdf,但找不到方法
提前感谢所有make变量都是字符串。要确定字符串实际上是否是数字,需要一些基本的文本分析函数。GNU make本身在这方面没有提供任何便利,但您可以运行shell命令来完成这项工作,可能如下所示:
ifeq ($N, 'numeric')
CFLAGS+=-D$N
endif
define is_number
$(shell test '$(1)' -eq '$(1)' 2>/dev/null && echo yes || echo no)
endef
ifeq ($(call is_number, $(N)),yes)
default:
@echo N is a number
else
default:
@echo N is not a number
endif
这导致:
$ make N=5
N is a number
$ make N=string
N is not a number
但是,如果字符串包含特殊字符,则此类字符串处理可能非常不可靠。所有make变量都是字符串。要确定字符串实际上是否是数字,需要一些基本的文本分析函数。GNU make本身在这方面没有提供任何便利,但您可以运行shell命令来完成这项工作,可能如下所示:
ifeq ($N, 'numeric')
CFLAGS+=-D$N
endif
define is_number
$(shell test '$(1)' -eq '$(1)' 2>/dev/null && echo yes || echo no)
endef
ifeq ($(call is_number, $(N)),yes)
default:
@echo N is a number
else
default:
@echo N is not a number
endif
这导致:
$ make N=5
N is a number
$ make N=string
N is not a number
但是,如果字符串包含特殊字符,则此类字符串处理可能非常不可靠。编辑:采纳了bobbogo的建议,该建议不依赖于要清除的字符数 我想您使用GNU make。这是一个只生成的解决方案,不需要调用shell。出于性能原因,根据您对它的使用情况,它可能更可取。此外,这并不取决于shell使用的是哪一个。最后但并非最不重要的一点是,它使用递归,我喜欢递归:
define PURGE
$(if $(2),$(call PURGE,$(subst $(firstword $(2)),,$(1)),$(filter-out $(firstword $(2)),$(2))),$(1))
endef
DIGITS := 0 1 2 3 4 5 6 7 8 9
define IS_NOT_A_NUMBER
$(call PURGE,$(1),$(DIGITS))
endef
CFLAGS += $(if $(call IS_NOT_A_NUMBER,$(N)),,-D$(N))
all:
$(info N=$(N) => CFLAGS=$(CFLAGS))
演示:
说明:PURGE
是一个带两个参数的递归宏。第一个($(1)
)是要测试的字符串,第二个($(2)
)是要匹配的单词列表。如果$(2)
是空列表清除
返回$(1)
。否则,它会使用两个新参数调用自己:
的值,其中$(1)
的第一个单词被零替换$(2)
已从中删除第一个单词$(2)
并返回结果。因此,如果您使用字符串和所有数字的列表调用
PURGE
,则当且仅当字符串仅包含数字时,它将返回空字符串。EDIT:采纳了bobbogo的建议,该建议不依赖于要清除的字符数
我想您使用GNU make。这是一个只生成的解决方案,不需要调用shell。出于性能原因,根据您对它的使用情况,它可能更可取。此外,这并不取决于shell使用的是哪一个。最后但并非最不重要的一点是,它使用递归,我喜欢递归:
define PURGE
$(if $(2),$(call PURGE,$(subst $(firstword $(2)),,$(1)),$(filter-out $(firstword $(2)),$(2))),$(1))
endef
DIGITS := 0 1 2 3 4 5 6 7 8 9
define IS_NOT_A_NUMBER
$(call PURGE,$(1),$(DIGITS))
endef
CFLAGS += $(if $(call IS_NOT_A_NUMBER,$(N)),,-D$(N))
all:
$(info N=$(N) => CFLAGS=$(CFLAGS))
演示:
说明:PURGE
是一个带两个参数的递归宏。第一个($(1)
)是要测试的字符串,第二个($(2)
)是要匹配的单词列表。如果$(2)
是空列表清除
返回$(1)
。否则,它会使用两个新参数调用自己:
的值,其中$(1)
的第一个单词被零替换$(2)
已从中删除第一个单词$(2)
并返回结果。因此,如果您使用字符串和所有数字的列表调用
PURGE
,当且仅当字符串仅包含数字时,它才会返回空字符串。要在表上添加另一个选项:。要在表上添加另一个选项:。$(wordlist 2,10,$2)
会自动将您限制为10个字符<代码>$(过滤掉$(第一个单词$2),$2)也许吧?@bobbogo:建议不错。我编辑了我的答案以使用它。谢谢。$(wordlist 2,10,$2)
正在悄悄地将您限制为10个字符<代码>$(过滤掉$(第一个单词$2),$2)也许吧?@bobbogo:建议不错。我编辑了我的答案以使用它。谢谢