2

我有一个这样的目录树:

├── dir_a
│   └── file_1.txt
├── dir_b
│   └── dir_c
│       ├── file_2.txt
|       └── file_3.txt
└── file_4.txt

我想镜像这个目录结构来保存处理每个文本文件的命令的结果。即,输出将如下所示:

├── build
│   ├── dir_a
│   │   └── processed_file_1.txt
│   ├── dir_b
│   │   └── dir_c
│   │       ├── processed_file_2.txt
│   |       └── processed_file_3.txt
│   └── processed_file_4.txt
├── dir_a
│   └── file_1.txt
├── dir_b
│   └── dir_c
│       ├── file_2.txt
|       └── file_3.txt
└── file_4.txt

我对 Makefile 不是很熟练,所以我的问题是:如何获得 Makefile 来重新创建目录结构并递归处理所有文本文件以将它们放置到构建目录中的正确位置?随着输入文件的变化,我将重复运行它,因此不处理未更改文件的 Makefile 似乎是正确的方法。

更新:我还应该提到新的输入文件会经常添加,所以我不希望 Makefile 明确命名它们。

4

2 回答 2

2

如果您使用具有不同后缀的词干而不是插入“processed_”字符串会更容易,但这里有一个适用于我的示例:

OUTPUTS := build/dir_a/processed_file_1.txt       \
           build/dir_b/dir_c/processed_file_2.txt \
           build/dir_b/dir_c/processed_file_3.txt \
           build/processed_file_4.txt

all: $(OUTPUTS)

.SECONDEXPANSION:
$(OUTPUTS): build/% : $$(subst processed_file_,file_,%)
    mkdir -p $(dir $@)
    cp $< $@

clean:
    rm -rf build

.SECONDEXPANSION您可以通过更改文件名的结尾而不是开头来消除复杂性:

OUTPUTS := build/dir_a/file_1.out       \
           build/dir_b/dir_c/file_2.out \
           build/dir_b/dir_c/file_3.out \
           build/file_4.out

all: $(OUTPUTS)

$(OUTPUTS) : build/%.out : %.txt
    mkdir -p $(dir $@)
    cp $< $@

clean:
    rm -rf build
于 2012-07-05T17:27:10.903 回答
0

正如 Carl 建议的那样,您可以使用辅助扩展,但要与仅订购的先决条件结合使用。

BUILD_DIR = build

IN_FILES := dir_a/file_1.out       \
            dir_b/dir_c/file_2.out \
            dir_b/dir_c/file_3.out \
            file_4.out

OUT_FILES := $(IN_FILES:%=$(BUILD_DIR)/%)

all: $(OUT_FILES)

.SECONDEXPANSION:
$(OUT_FILES) : $(BUILD_DIR)/%.out : %.txt | $$(@D)/.
    # your text processing rule here...

%/. :
    mkdir -p $*

| $$(@D)方法:

  • 在二次扩展期间计算$(@D) 自动变量的值(这是目标的目录部分),并且
  • 添加对它的仅订单依赖,即确保目录存在,但如果它比目录旧,则不要考虑重新制作目标(这是一种常见情况)
于 2012-07-05T17:49:13.330 回答