csv 来自一个脚本的多个目标,复制到Makefile中的多个不同目录

r3i60tvu  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(89)

场景

我正在更新一个脚本,该脚本在构建时为每个构建生成CJava的源代码文件。
这需要在Windows和Linux上运行。
需要为每种语言创建两种文件类型:枚举
每组四个文件(C Enum、C Table、Java Enum、Java Table)都是从相应的CSV文件生成的。
给定名为A.csv的输入CSV文件,输出文件为AEnum.incATable.incAEnum.javaATable.java
所有四个文件都可以通过调用python脚本来创建,并激活venv,如下所示:

python main.py --input A.csv --output ./output --enum-c --table-c --enum-java --table-java

这在makefile中用一个名为run_autogen_all的函数缩短。
创建文件后,需要将它们复制到不同的目录:

  • C枚举和表进入$(C_AUTOGEN)/
  • Java枚举进入$(JAVA_ENUM)/
  • Java表放在$(JAVA_TABLE)/

问题

我还没能弄清楚如何确保python脚本只运行一次(运行时是不可忽略的),同时还将所有文件复制到正确的目录。
如何使用Make实现此行为?

尝试解决

下面是我目前的解决方案,它 * 工作 *,但它运行了两次python脚本,复制文件两次。

MAIN_4_CSV_FILES = A.CSV B.CSV C.CSV D.CSV E.CSV F.CSV G.CSV H.CSV I.CSV J.CSV K.CSV L.CSV M.CSV N.CSV O.CSV P.CSV Q.CSV R.CSV S.CSV T.CSV U.CSV V.CSV W.CSV X.CSV Y.CSV Z.CSV
.PHONY : JavaFiles CFiles
JavaFiles : *.java
CFiles : *.inc

*.java *.inc : $(MAIN_4_CSV_FILES)
    $(call run_autogen_all,$^)
    $(COPYF) *Enum.java $(JAVA_ENUM)
    $(COPYF) *Table.java $(JAVA_TABLE)
    $(COPYF) *.inc $(C_AUTOGEN)

运行make JavaFiles CFiles -n将得到以下输出

python "../../../../../build/Common/CSV_Parser/autogenerate_from_csv.py" --output "./" --csv-files A.CSV B.CSV C.CSV D.CSV E.CSV F.CSV G.CSV H.CSV I.CSV J.CSV K.CSV L.CSV M.CSV N.CSV O.CSV P.CSV Q.CSV R.CSV S.CSV T.CSV U.CSV V.CSV W.CSV X.CSV Y.CSV Z.CSV
cp -f *Enum.java ../../../../Project/java/enums
cp -f *Table.java ../../../../Project/java/tables
cp -f *Enum.inc ../../../../Project/c
cp -f *Table.inc ../../../../Project/c
python "../../../../../build/Common/CSV_Parser/autogenerate_from_csv.py" --output "./" --csv-files A.CSV B.CSV C.CSV D.CSV E.CSV F.CSV G.CSV H.CSV I.CSV J.CSV K.CSV L.CSV M.CSV N.CSV O.CSV P.CSV Q.CSV R.CSV S.CSV T.CSV U.CSV V.CSV W.CSV X.CSV Y.CSV Z.CSV
cp -f *Enum.java ../../../../Project/java/enums
cp -f *Table.java ../../../../Project/java/tables
cp -f *Enum.inc ../../../../Project/c
cp -f *Table.inc ../../../../Project/c

之前尝试

我尝试了很多方法,这里有几个不起作用

%Enum.inc %Enum.java %Table.inc %Table.java :
    $(call run_autogen_all,$<)
    $(call copy_attrib,$(notdir $@),$@)

AFiles = $(C_AUTOGEN)/AEnum.c $(C_AUTOGEN)/ATable.c $(JAVA_ENUM)/AEnum.java $(JAVA_TABLE)/ATable.java
$(AFiles) : A.csv
[...]
JavaEnums : $(JAVA_ENUM)/AEnum.java $(JAVA_ENUM)/BEnum.java [...]

$(JAVA_ENUM)/%Enum.java : %Enum.java
    $(call run_autogen_all,$*.csv)
    $(call copy_attrib,$(notdir $@),$@)
[...]
%Enum.java %Enum.c %Table.java %Table.c : %.csv
    $(call run_autogen_all,$<)
    $(call copy_attrib,$(notdir $@),$@)
[...]

我也试过乱用.INTERMEDIATE.SECONDARY也无济于事。

5t7ly7z5

5t7ly7z51#

假设您使用GNUmake,并且所有生成的文件都在当前目录中生成,您可以使用具有4个目标的模式规则。

MAIN_4_CSV_FILES := $(wildcard *.CSV)
TARGETS          := $(patsubst %.CSV,$(C_AUTOGEN)/%Enum.inc,$(MAIN_4_CSV_FILES))
TARGETS          += $(patsubst %.CSV,$(C_AUTOGEN)/%Table.inc,$(MAIN_4_CSV_FILES))
TARGETS          += $(patsubst %.CSV,$(JAVA_ENUM)/%Enum.java,$(MAIN_4_CSV_FILES))
TARGETS          += $(patsubst %.CSV,$(JAVA_TABLE)/%Table.java,$(MAIN_4_CSV_FILES))

.PHONY: all
all: $(TARGETS)

$(C_AUTOGEN)/%Enum.inc $(C_AUTOGEN)/%Table.inc $(JAVA_ENUM)/%Enum.java $(JAVA_TABLE)/%Table.java: %.CSV
   python main.py --input $< --output ./output --enum-c --table-c --enum-java --table-java
   mv $*Enum.inc $*Table.inc $(C_AUTOGEN)
   mv $*Enum.java $(JAVA_ENUM)
   mv $*Table.java $(JAVA_TABLE)

GNUmake将这4个目标视为一组,并只运行一次配方来构建它们。不要在这类规则的配方中使用$@(至少在阅读文档之前不要使用)。
一旦你已经测试过了,也许可以尝试重新引入你的宏。

相关问题