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
才会收到一个值,尽管是您提供的值的处理形式。 -j3
从 make
的命令行转录器引发 -j3 --jobserver-auth=3,4
响应,而 -j
保持 -j
。那么这对我们意味着什么呢?显然,在运行时检测请求的并行性的功能不稳定,或者有一些充分的理由不访问它们(当您在 GNU 工具中遇到异常行为时,大多数情况下就是这种情况),所以也许您可以给我们更多信息关于您要实现的目标 - 也许有一种方法可以避免访问命令行。
需要注意的一件事是,您使用的 GNU make 版本是 GNU make 4.0 的 beta 版本,它本身是在 2013 年发布的...所以您使用的是本身版本的 beta 8.5岁。
但是,这与此问题无关。
问题是 MAKEFLAGS
变量的最终值在解析完所有 makefile 后才会设置。如果您尝试在解析所有 makefile 之前检查它,它将只包含全部选项集的一个子集。
当您将该变量扩展为 ifeq
或 ifneq
语句的一部分时,会在解析 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 不变,因此您可以随时查看它并且它是准确的。但该版本尚不可用。
我正在尝试使用 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
才会收到一个值,尽管是您提供的值的处理形式。 -j3
从 make
的命令行转录器引发 -j3 --jobserver-auth=3,4
响应,而 -j
保持 -j
。那么这对我们意味着什么呢?显然,在运行时检测请求的并行性的功能不稳定,或者有一些充分的理由不访问它们(当您在 GNU 工具中遇到异常行为时,大多数情况下就是这种情况),所以也许您可以给我们更多信息关于您要实现的目标 - 也许有一种方法可以避免访问命令行。
需要注意的一件事是,您使用的 GNU make 版本是 GNU make 4.0 的 beta 版本,它本身是在 2013 年发布的...所以您使用的是本身版本的 beta 8.5岁。
但是,这与此问题无关。
问题是 MAKEFLAGS
变量的最终值在解析完所有 makefile 后才会设置。如果您尝试在解析所有 makefile 之前检查它,它将只包含全部选项集的一个子集。
当您将该变量扩展为 ifeq
或 ifneq
语句的一部分时,会在解析 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 不变,因此您可以随时查看它并且它是准确的。但该版本尚不可用。