【问题标题】:How to check a string whether contain a substring in Makefile commands如何检查字符串是否包含 Makefile 命令中的子字符串
【发布时间】:2020-10-20 14:16:10
【问题描述】:

我想检查一个字符串变量是否包含 Makefile 中的指定子字符串。目的是清理子文件夹。 我使用了下面的代码,但它不起作用。

SERVICES_LIST = A_Service B_Service C_Service #example
SPECIFIC_SERVICE_LIST = A_Service B_Service
clean:
    @list='$(SERVICES_LIST)';for subdir in $$list;do \
                echo "clean in $$subdir";\
                if [[ "*$$subdir*" == "$(SPECIFIC_SERVICE_LIST)" ]];then\
                make $$subdir clean;\
                fi;\
   done;\

【问题讨论】:

  • 请使用 SO 的格式化功能格式化您的问题,以便于阅读。另外,在提问时请不要说“没用”之类的话;这无助于任何人了解情况。相反,显示你输入的命令和你得到的输出(或者,如果有很多输出,至少是所有的错误消息——不仅仅是最后几行!!事实上,FIRST 错误消息几乎总是比最后一个,尽管最好包括所有错误,除非有太多)。
  • 颠倒相等测试的顺序,将星号放在引号中:if [[ "$(SPECIFIC_SERVICE_LIST)" == *"$$subdir"* ]]
  • 无论哪种方式,@Beta、== 都会执行字符串比较,而不是模式匹配比较。
  • @JohnBollinger:在这种情况下它有效。

标签: bash makefile gnu-make


【解决方案1】:

这与make 没有太大关系,因为基本上所有涉及的逻辑都是用shell 语言表达的。特别是,您似乎在假设bash。

问题出在这里:

                if [[ "*$$subdir*" == "$(SPECIFIC_SERVICE_LIST)" ]];then\

您似乎试图将(make 的扩展)"$(SPECIFIC_SERVICE_LIST)" 与形成为(make 的扩展)"*$$subdir*" 的全局模式匹配。但是左侧是引用的,所以它不会被解释为模式,== 运算符执行(精确)字符串匹配,而不是模式匹配。

在 shell 语言中应用这种模式匹配测试的主要方法之一是使用 case 构造,因为与它一起使用的选择表达式总是被解释为 glob。在您的 makefile 中可能看起来像这样:

case "$(SPECIFIC_SERVICE_LIST)" in *$$subdir*) make $$subdir clean ;; esac

但整个事情看起来很不习惯。一般来说,makefile 会针对项目进行调整。即使它是部分或全部动态生成的,设计你的构建系统也是合理和适当的,这样干净的目标可以做更多这样的事情:

clean:
    for subdir in $(SPECIFIC_SERVICE_LIST); do make -C $$subdir clean; done

...或者可能是这样的:

clean: clean_services
    ...

clean_services:
    for subdir in $(SPECIFIC_SERVICE_LIST); do make -C $$subdir clean; done

【讨论】:

  • 我改成 if [[ "$(SPECIFIC_SERVICE_LIST)" == *"$$subdir"* ]],但是好像你说的,不是模式匹配,只是字符串比较。只是为了确认一下,有没有办法在 Make 命令部分使用 if 来进行模式字符串匹配?谢谢!
【解决方案2】:

我会通过定义一个目标来清理任何受支持的服务,然后调用所有必需的清理目标作为clean 的先决条件,从而使其更加make 方式。与严格顺序的 shell 循环相比,使用 -j 选项运行时,这具有并行清理的额外优势。

$ cat Makefile
SERVICES_LIST = A_Service B_Service C_Service #example
SPECIFIC_SERVICE_LIST = A_Service B_Service

.PHONY: $(addsuffix -clean, $(SERVICES_LIST))
$(addsuffix -clean, $(SERVICES_LIST)): %-clean:
        $(MAKE) -C $* clean

.PHONY: clean
clean: $(addsuffix -clean, $(SPECIFIC_SERVICE_LIST))

【讨论】:

    猜你喜欢
    • 2011-11-09
    • 2013-05-18
    • 2018-01-06
    • 1970-01-01
    • 2021-12-20
    • 2010-12-19
    • 2012-01-05
    相关资源
    最近更新 更多