0

我想在 Debian 和 Windows 10 上都使用这个 Makefile。

我有一组测量值(并不断添加更多),原始数据文件进入名为“measurement-12-Apr-2020”的子目录(包含我进行测量的日期)。在这些原始数据文件上,我运行了一系列后处理步骤,每个步骤都封装在自己的小工具中,创建新的输出文件并相互构建。这些不同的输出文件具有不同的扩展名:.raw 用于原始数据文件,.rot 用于坐标旋转,.off 用于偏移移除等。我的 Makefile 中有这些步骤的模式规则。对于一些这样的步骤,我计算了特殊的转换矩阵,当然它们只匹配他们的数据文件集。我称之为“transform.calibrate”或“transform.aligne”

到目前为止,Makefile 只在一个目录中运行,我手动将数据文件移入和移出它们的目录。

现在我希望我的顶级 Makefile 及其模式规则对子目录中的数据进行操作。

我如何让它查看与“测量日期”模式匹配的目录中的文件?以及如何使用本地转换文件让模式规则对一个数据集进行操作?

这是我的带有递归生成文件的代码。BIN := ${CURDIR}/../bin当Makefile在子目录中运行时,我想要一个没有丑陋和半好变量使用和内容的非递归makefile 。此外,我得到一个 python 错误 9009,因为我切换到子目录和 bin 目录(这很可能是相关的,但实际上是另一个问题。)。

ifdef OS
   RM = del /Q
   FixPath = $(subst /,\,$1)
   COPY = copy
   PYTHON = "c:\Users\Blah\AppData\Local\Programs\Python\Python37\python.exe"
else
   ifeq ($(shell uname), Linux)
      RM = rm -f
      FixPath = $1
   endif
   COPY = cp
   PYTHON = python
endif

.PHONY: test default
.DEFAULT_GOAL := default

# This is for running inside PyCharm
export PATH:=${CURDIR}/venv/bin:${PATH}

# file endings:
# raw
# calibrate  file ending for transformation matrix
# cal calibrated data file
# ali alignement transformation
# rot rotated, aligned sensors
# off offset removed
# pha phase and

measurement_dirs :=  $(filter %/, $(wildcard messung-*/))
BIN := ../bin

DIRS_CMD = $(foreach subdir, $(measurement_dirs), make-rule/$(subdir))
# Makefiles = $(foreach subdir, $(measurements_dirs), $(subdir)Makefile )

default: transform.align transform.calibrate $(wildcard messung-*.pha)

all: $(DIRS_CMD)
    @echo $(BIN)

transform.calibrate: calibrationsequence.raw
    $(PYTHON) $(BIN)/calculateCalibration.py $<

%.cal: transform.calibrate %.raw
    $(PYTHON) $(BIN)/applyCalibration.py $*.raw

transform.align: calibrationsequence.cal transform.calibrate
    $(PYTHON) $(BIN)/calulateAlignement.py calibrationsequence.cal

%.rot: transform.align %.cal
    $(PYTHON) $(BIN)/applyAlignment.py $*.cal

%.off: %.rot
    $(PYTHON) $(BIN)/clearOffset.py $*.rot

%.pha: %.off
    $(PYTHON) $(BIN)/demodulateSignals.py $*.off

test: test_%.py
    $(PYTHON) pytest -v test

make-rule/%:
    cp Makefile $* && cd $* && make
4

1 回答 1

1

问题的核心是涉及两个变量并且事先未知:目录的名称和原始文件的名称。Make 可以轻松处理一个变量,但处理两个变量时遇到了困难。

假设我们有一个目录,messung-12-Apr-2020,其中包含三个原始文件alpha.rawbeta.rawcalibrationsequence.raw

规则很简单:

.PHONY: 12-Apr-2020                                                                                               
12-Apr-2020: messung-12-Apr-2020/apha.pha messung-12-Apr-2020/beta.pha messung-12-Apr-2020/calibrationsequence.pha
    @echo $@ done

如果我们事先不知道原始文件的名称,我们可以推导出它们:

RAW_FILES := $(wildcard messung-12-Apr-2020/*.raw)
PHA_FILES := $(patsubst %.raw,%.pha,$(RAW_FILES))

12-Apr-2020:$(PHA_FILES)
    @echo $@ done

如果我们事先不知道目录的名称,我们可以使用subst代替patsubst并将所有内容放入模式规则中:

TARGETS := 12-Apr-2020

.SECONDEXPANSION:
$(TARGETS): %: $$(subst .raw,.pha,$$(wildcard messung-%/*.raw))
    @echo $@ done

(注意使用$$。)只要文件名中没有嵌入“.raw”的机会,这是安全的。有一种更安全、更严谨的方法,但也更复杂;如果您需要它,请在评论中告诉我,我会发布它。

现在生成目标列表:

TARGETS := $(patsubst messung-%,%,$(wildcard messung-*))

.PHONY: all $(TARGETS)

all: $(TARGETS)

并修改要从主目录执行的其他模式规则:

%.pha: %.off
    cd $(dir $*); $(PYTHON) $(BIN)/demodulateSignals.py $(notdir $*).off

(笨拙,但有效。)应该清楚如何修改、、和的模式规则%.off,方法相同。%.rot%.cal%/transform.calibrate%/transform.align

于 2020-05-06T05:27:11.707 回答