是否可以创建一个针对不同文件重复执行操作的目标?

时间:2019-03-30 15:20:41

标签: makefile

我正在尝试构建一个Makefile,以简化C赋值的编译。 Makefile暂时可以正常工作,但是,我想添加一个新目标,该目标执行先前的目标并创建文件。

目标如下:

  • 编译给定程序(figures.c
  • 执行它(这将创建一堆.gv文件)
  • 将每个.gv文件转换为.pdf文件

我知道如何转换单个文件(我有命令),但似乎无法弄清楚如何遍历每个文件,而无需全部输入。

我已经尝试过执行其他类型的目标,但是不起作用(请参阅已注释的目标)

# COMPILATION

CC=gcc
CFLAGS=-Wall -ansi -pedantic

# DOSSIERS

SOURCEDOC=sourcedoc
DOC=doc
SRC=src
INC=inc
OBJ=build
FIGS=images

FILES=$(wildcard $(FIGS)/*.gv)

.PHONY: clean doc archive author all

.SILENT : clean


#                  Targets

all : clean test images

test : $(OBJ)/Test_arbre.o $(OBJ)/aux.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/arbres.o
    $(CC) $^ -o $@ $(CFLAGS)

figures : $(OBJ)/figures.o $(OBJ)/Affichage.o $(OBJ)/ArbreBinaire.o $(OBJ)/aux.o $(OBJ)/arbres.o
    $(CC) $^ -o $@ $(CFLAGS)

%.pdf: $(FIGS)/%.gv
    dot -Tpdf -o $(FIGS)/$@ $^

#$(FILES): $(FIGS)/%.pdf : $(FIGS)/%.gv
#   dot -Tpdf -o $@ $^

images : figures $(FILES)

#=========== Objets ===========

$(OBJ)/arbres.o : $(INC)/arbres.h $(INC)/aux.h $(INC)/Affichage.h $(INC)/ArbreBinaire.h

$(OBJ)/Affichage.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h

$(OBJ)/exemple*_arbre.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h

$(OBJ)/aux.o : $(INC)/aux.h

$(OBJ)/figures.o : $(INC)/Affichage.h $(INC)/ArbreBinaire.h $(INC)/arbres.h

$(OBJ)/Test_arbre.o : $(INC)/arbres.h $(INC)/ArbreBinaire.h $(INC)/Affichage.h


#                  Dummy rule

$(OBJ)/%.o : $(SRC)/%.c
    @mkdir -p $(@D)
    @$(CC) $< $(CFLAGS) -I $(INC)/ -c -o $@


#                 Miscellaneous

clean:
    rm -f *~ */*~
    rm -rf __pycache__ src/__pycache__
    rm -rf $(DOC)
    rm -f $(PROJECT)_$(AUTHOR12)_$(AUTHOR22).zip
    rm -f conf.py-e
    rm -rf $(OBJ)
    rm -f $(FIGS)/*.pdf $(FIGS)/*.gv
    rm -f test

当前的Makefile在除图像以外的所有其他命令上都可以正常工作。

如果你们中的任何一个能帮上忙,那将意味着很多!

2 个答案:

答案 0 :(得分:1)

您对FILES的定义应将*.gv文件映射到相应的*.pdf文件;

FILES=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))

说明如何生成PDF的规则应排除目录名称;

%.pdf: %.gv
    dot -Tpdf -o $@ $^

现在,如果make尝试创建$(FIGS)/ick.pdf,则输入将为$(FIGS)/ick.gv-模式说用扩展名.gv替换扩展名.pdf ,其余文件名则保持不变,完全与您想要的一样。像

这样的规则
%.pdf: $(FIGS)/%.gv  # error, don't use

说您需要在子目录$(FIGS)中找到源文件;因此,如果您尝试制作$(FIGS)/ick.pdf,则意味着make将需要根据此规则查找或生成$(FIGS)/$(FIGS)/ick.gv作为输入。

答案 1 :(得分:1)

如果您绝对不能预测在步骤(2)上将创建什么文件(并且仅限于使用$(wildcard ...)),则仍必须在完成(em)(2)之后执行

这很丑陋,但是我想不出比使用“递归make”更好的选择。我的意思是这样的:

...
.PHONY: images pdf
images: figures
    # use figures to generate all .gv files
    #@figures --create-all-gv-files
    # invoke make recursively
    @$(MAKE) --no-print-directory pdf

# ensure $(wildcard ...) is invoked only if needed
ifeq ($(MAKECMDGOALS),pdf)
    PDF_FILES:=$(patsubst %.gv,%.pdf,$(wildcard $(FIGS)/*.gv))
endif

pdf: $(PDF_FILES)
%.pdf: %.gv
    dot -Tpdf -o $@ $<