MAKEFLAGS 中的 findstring 不适用于 ifeq

findstring in MAKEFLAGS don't working with ifeq

我正在尝试使用 find_j=$(findstring j,$(filter-out --%,$(MAKEFLAGS))) 来查找是否有 -j 选项,所以当我 echo $(find_j) 时,值是 j 但是当我比较它时 ifeq (j, $(find_j)) 这返回 false 我不明白问题出在哪里 我的 make 版本是 make-3.99.90

find_j=$(findstring -j,$(filter-out --%,$(MAKEFLAGS))) 
ifneq ( , $(find_j)) 
PARALLEL_ENABLED=true 
endif  
.PHONY: PRINT 
PRINT:  
   $(info $(PARALLEL_ENABLED))  
   $(info $(MAKEFLAGS))     
   $(info $(find_j))
---empty line---
--warn-undefined-variables -ws --jobserver-fds=5,6 -j 
-j

这似乎没有准确记录。虽然 MAKEFLAGS 有标志,例如-s-k 作为其中的 ks-j 标志以另一种方式处理:它没有去除前导破折号 - 并且它不是在 first pass of processing the makefile 中可见。只有在执行规则时,MAKEFLAGS 才会收到一个值,尽管是您提供的值的处理形式。 -j3make 的命令行转录器引发 -j3 --jobserver-auth=3,4 响应,而 -j 保持 -j。那么这对我们意味着什么呢?显然,在运行时检测请求的并行性的功能不稳定,或者有一些充分的理由不访问它们(当您在 GNU 工具中遇到异常行为时,大多数情况下就是这种情况),所以也许您可以给我们更多信息关于您要实现的目标 - 也许有一种方法可以避免访问命令行。

需要注意的一件事是,您使用的 GNU make 版本是 GNU make 4.0 的 beta 版本,它本身是在 2013 年发布的...所以您使用的是本身版本的 beta 8.5岁。

但是,这与此问题无关。

问题是 MAKEFLAGS 变量的最终值在解析完所有 makefile 后才会设置。如果您尝试在解析所有 makefile 之前检查它,它将只包含全部选项集的一个子集。

当您将该变量扩展为 ifeqifneq 语句的一部分时,会在解析 makefile 时发生这种情况,因此(按照上述)只有简单的选项(那些不接受参数:-j 接受一个参数,所以不是“简单的”)可用。

当您将变量扩展为配方的一部分时,会在解析所有 makefile 之后发生:此时 MAKEFLAGS 的最终值已设置。所以你的 $(info ...) 配方中的函数做正确的事情。

这个很容易看出来:

$(info no recipe MAKEFLAGS is '$(MAKEFLAGS)')

all: ; $(info in recipe MAKEFLAGS is '$(MAKEFLAGS)')

如果你 运行 和 -j10 你会得到:

no recipe MAKEFLAGS is ''
in recipe MAKEFLAGS is '-j10 --jobserver-auth=3,4'

(您的“in recipe”标志可能看起来不同,因为您使用的是如此旧版本的 GNU make)。

在下一个版本的 GNU make 中,MAKEFLAGS 的值会保持 up-to-date 不变,因此您可以随时查看它并且它是准确的。但该版本尚不可用。