Unix 生成文件,在dirs上迭代并排除一些

Unix 生成文件,在dirs上迭代并排除一些,unix,makefile,Unix,Makefile,在顶级(unix,GNU)Makefile中,我希望迭代子目录列表并在其中执行任务,但排除其中的一些任务。在这种情况下,排除以下划线(\u1)开头的所有子曲面 下面的代码用于迭代,但忽略了排除正则表达式。它仍然访问dir“\u exclude” 特别是,我认为它忽略了“字符串的开头”^(或者从字面上理解)。我尝试过其他正则表达式,它们确实有效。知道怎么解决吗?或者,如果您知道如何消除剥离或不使用GNU makefile扩展名 SHELL=/bin/bash EXCLUDE_DIRS_REGEX=

在顶级(unix,GNU)Makefile中,我希望迭代子目录列表并在其中执行任务,但排除其中的一些任务。在这种情况下,排除以下划线(\u1)开头的所有子曲面

下面的代码用于迭代,但忽略了排除正则表达式。它仍然访问dir“\u exclude”

特别是,我认为它忽略了“字符串的开头”^(或者从字面上理解)。我尝试过其他正则表达式,它们确实有效。知道怎么解决吗?或者,如果您知道如何消除剥离或不使用GNU makefile扩展名

SHELL=/bin/bash
EXCLUDE_DIRS_REGEX=^_
# later addition:
ALLMAKEFILES = $(shell find . -maxdepth 2 -type f -name Makefile)
SUBDIRS   = $(filter-out ./,$(dir $(ALLMAKEFILES)))

all:
    for dir in $(SUBDIRS); do \
        if [[ "$$dir" =~ $(EXCLUDE_DIRS_REGEX) ]]; then continue; fi; \
        make -C $$dir all; \
    done

您有两个问题需要解决:

  • 计算目标目录的列表
  • 把他们每个人都叫进来
  • 对于第一种,make和shell函数或内置函数的混合可以是:

    REGEX       := ^_
    ALLMAKEDIRS := $(patsubst %/,%,$(dir $(wildcard */Makefile)))
    SUBDIRS     := $(shell for d in $(ALLMAKEDIRS); \
        do ! [[ "$$d" =~ $(REGEX) ]] && echo "$$d"; done)
    
    我保留了
    REGEX
    ,以防您有更复杂的正则表达式,或者您希望它易于修改。但当然,如果它确实是
    ^ 
    ,并且您从未更改过它,那么以下情况更简单:

    SUBDIRS := $(filter-out _%,$(patsubst %/,%,$(dir $(wildcard */Makefile))))
    
    对于第二种情况,你的方法不是很有说服力。更好的方法是每个子目录有一条规则。以下是一个例子:

    .PHONY: all $(SUBDIRS)
    
    all: $(SUBDIRS)
    
    $(SUBDIRS):
        $(MAKE) -C $@ all
    
    它有几个优点:

    • 不需要在复杂的配方中循环子目录,make会为您完成
    • make可以并行启动多个作业(请参阅),这将加快构建速度

    注意:不建议在Makefile中调用
    make
    。首选
    $(MAKE)
    。有关详细信息,请参阅。

    如果
    SUBDIRS
    是一个变量,请尝试
    $(foreach d,$(SUBDIRS),$(patsubst,,$(d))
    @tripleee非常好的主意,谢谢。我把太多的注意力放在了外壳部分。我已经修改了我的帖子,以显示
    SUBDIRS
    的来源。
    allmakefile=$(shell find.-maxdepth 2-not-path'*/*'-type f-name Makefile)
    find
    期间进行过滤,效果很好。谢谢@tripleeeye您的正则表达式匹配以下划线开头的字符串,当然,
    find
    的任何结果都不会匹配
    (^ 124;/124;)
    将匹配并在开头或斜杠后面加下划线。噢,谢谢!现在我明白了为什么bash正则表达式不起作用了!谢谢你。我完全支持更多的“制造”解决方案!