Gnu make 使用gnumake在新生成的文件上运行命令的规则
我对make很陌生。我有一个生成三个latex文件的perl脚本。我想创建一个makefile,它将执行perl脚本,然后在新生成的tex文件上运行lualatex。到目前为止,我有以下几点:Gnu make 使用gnumake在新生成的文件上运行命令的规则,gnu-make,Gnu Make,我对make很陌生。我有一个生成三个latex文件的perl脚本。我想创建一个makefile,它将执行perl脚本,然后在新生成的tex文件上运行lualatex。到目前为止,我有以下几点: make: perl diff.pl pdf: make $(eval LIST := $(shell ls *.tex)) lualatex $(LIST).tex make clean clean: rm -rf *.log *.aux 输出: lu
make:
perl diff.pl
pdf:
make
$(eval LIST := $(shell ls *.tex))
lualatex $(LIST).tex
make clean
clean:
rm -rf *.log *.aux
输出:
lualatex FLAT_FLAT_AVDD.tex FLAT_FLAT_VDD.tex FLAT_FLAT_VSS.tex.tex
我只得到一个pdfFLAT\u FLAT\u AVDD.pdf。
如何在所有文件上运行lualatex?
我可以声明三个变量,然后运行make。但是,我如何实现自动化呢?make中是否有循环概念?使用“硬编码”文件名实现这一点的更好方法是什么
谢谢。
编辑:
我试图将合并到foreach
make:
perl diff.pl
list:
$(eval LIST := $(shell ls *.tex))
pdf:
make list
$(foreach tex,$(LIST),$(lualatex $(tex)))
make clean
clean:
rm -rf *.log *.aux
然后我运行,makepdf
我在终端中得到了以下输出
dedehog01:tislam1:243 > make pdf
make list
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make[1]: `list' is up to date.
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
make clean
make[1]: Entering directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
rm -rf *.log *.aux
make[1]: Leaving directory `/home/tislam1/Documents/THESIS/Script_v0.1/BOX_approach/Modified_Layout_mesh/IR_Report_mesh/flat_flat/make'
如果希望在每次make调用时运行perl脚本,make并不是真正有用的。shell脚本也可以这样做。但如果您真的想将所有这些都放在一个生成文件中:
.PHONY: all clean
all:
perl diff.pl && \
for t in *.tex; do \
lualatex $$t; \
done
clean:
rm -rf *.log *.aux
否则,您必须提前知道乳胶源的列表。您可能应该坚持maketarget先决条件原则,即表示所有依赖项和相应的配方:
LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))
all: $(PDFS)
$(LATEXSOURCES): diff.pl
perl diff.pl
$(PDFS): %.pdf: %.tex
lualatex $<
clean:
rm -rf *.log *.aux
LATEXSOURCES:=foo.tex bar.tex。。。cuz.tex
pdf:=$(patsubst%.tex,%.pdf,$(LATEXSOURCES))
全部:$(PDF)
$(LATEXSOURCES):diff.pl
perl diff.pl
$(pdf):%.pdf:%.tex
羽扇豆$<
清洁:
rm-rf*.log*.aux
但是,正如所注意到的,使用第二个选项,perl脚本的运行次数与LaTeX源文件的运行次数相同。模式规则解决了这一问题:
LATEXSOURCES := foo.tex bar.tex ... cuz.tex
PDFS := $(patsubst %.tex,%.pdf,$(LATEXSOURCES))
all: $(PDFS)
$(LATEXSOURCES): %.tex: diff.pl
@echo "Rebuilding $(LATEXSOURCES)"
perl diff.pl
$(PDFS): %.pdf: %.tex
lualatex $<
clean:
rm -rf *.log *.aux
LATEXSOURCES:=foo.tex bar.tex。。。cuz.tex
pdf:=$(patsubst%.tex,%.pdf,$(LATEXSOURCES))
全部:$(PDF)
$(最新来源):%.tex:diff.pl
@echo“正在重建$(LATEXSOURCES)”
perl diff.pl
$(pdf):%.pdf:%.tex
羽扇豆$<
清洁:
rm-rf*.log*.aux
现在我们有了一个真正的解决方案:
- 仅当缺少一个LaTeX源文件或perl脚本自上次生成以来发生更改时,才重建LaTeX源文件
- 只执行一次perl脚本以生成所有LaTeX源文件
- 表示各种文件之间的所有依赖关系
但是,仍然存在一个问题:如果只有一个LaTeX源文件丢失,而其他文件是最新的,那么将运行perl脚本,所有LaTeX源文件都将重建,并且它们的最后修改时间也将因此而更改。只有缺少的一个将被编译,但在下一次make调用中,其他的也将被重新编译,这是一种浪费。”s使用中间LaTeX源的建议解决了这个问题。假设您事先知道三个
.tex
文件的名称,您可以无条件地运行perl,然后仅当新文件与旧文件实际不同时才更新.tex
文件。Make会处理好的
tex := 1.tex 2.tex 3.tex
intermediates := ${tex:%.tex=%-new.tex}# 1-new.tex 2-new.tex 3-new.tex
pdfs := ${intermediates:%.tex=%.pdf}# 1-new.pdf etc.
.PHONY: perl
perl: ; perl diff.pl
${intermediates}: %-new.tex: %.tex | perl
cmp -s $< $@ || mv $< $@
${pdfs}: %.pdf: %.tex
lualatex $<
.PHONY: all
all: ${pdfs}
: $@ Success
tex:=1.tex 2.tex 3.tex
中间体:=${tex:%.tex=%-new.tex}#1-new.tex 2-new.tex 3-new.tex
pdf:=${中间产物:%.tex=%.pdf}1-new.pdf等。
.PHONY:perl
perl:;perl diff.pl
${mediates}:%-new.tex:%.tex|perl
cmp-s$<$@| mv$<$@
${pdfs}:%.pdf:%.tex
羽扇豆$<
冒牌货:全部
全部:${PDF}
:$@成功
假设perl生成1.tex
,2.tex
和3.tex
- 我们无条件地运行perl生成这三个文件的新副本
- 然后我们从
更新1.tex
,但前提是这两个文件不同1-new.tex
- 通知任何已更改的文件,并根据需要运行lualatex
这是并行安全的(对任何makefile都是一个很好的测试)。使用
-j3
运行,一次运行3份lualatex。您确实有4个CPU,不是吗?您绘制的草图将运行perl多次。只需运行一次即可创建三个.tex
文件。这不会在diff.pl
更改时重建LaTeX源,而是在每次make调用时;-)。对的它每次都会重建LaTeX源,但只在源文件更改时重建pdf。我认为运行perl要比运行lualatex快得多。此方案涵盖对diff.pl
进行更改的情况。如果更改对乳胶没有影响,则PDF已经是最新的。