我编写了一个makefile,它接受一个Word DOCX文件,并且(在tei-xslt、xslt脚本和saxon的帮助下)用TEI-XML、HTML文件和zip文件生成一个表示形式,以便将接收者放入发布软件中。不同的步骤应该是这样:
DOCX -> TEI-XML -> HTML -> (manifest.yml) -> ZIP # (Expected)问题是,在进入HTML到ZIP规则之前,make在一个循环中运行TEI到HTML规则三次:
DOCX -> TEI-XML -> -> -> HTML -> (manifest.yml) -> ZIP # (What happens)
3x更令人惊讶的是,只有在构建过程之前至少已经运行过一次,而且所有其他文件都已经处于某种早期状态时,才会发生这种情况。如果该文件夹仅包含DOCX文件,则一切都按预期工作。此外,使用make all和只使用make没有什么区别。即使没有文件更改,Make始终运行整个构建过程。
make文件如下:
SELF_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
include ${SELF_DIR}config.mk
MANUSCRIPTFILE:=$(shell ls *.docx)
MANUSCRIPTNAME:=$(shell basename ${MANUSCRIPTFILE} .docx)
SERIES:=$(shell echo "${MANUSCRIPTNAME}" | cut -d _ -f 1)
.PHONY : all tei clean
all: manifold/${MANUSCRIPTNAME}.zip
tei: tei/${MANUSCRIPTNAME}.xml
tei/${MANUSCRIPTNAME}.xml: ${MANUSCRIPTNAME}.docx
@echo -e "\n[BUILD] Convert Word DOCX to TEI-XML via docxtotei and melusina scripts\n"
# Make available relevant XSL stylesheets to the master styleshet
@mkdir -p ${TRANSFORMDIR}/melusina/docx/current
# BUG hier findet er das vorhandene Dokument nicht
@cp ${TRANSFORMDIR}/melusina/docx/specific/${SERIES}.xsl ${TRANSFORMDIR}/melusina/docx/current/series.xsl
@if [ -e ${TRANSFORMDIR}/melusina/docx/specific/${SERIES}/${MANUSCRIPTNAME}.xsl ]; then\
cp ${TRANSFORMDIR}/melusina/docx/specific/${SERIES}/${MANUSCRIPTNAME}.xsl ${TRANSFORMDIR}/melusina/docx/current/publication.xsl;\
else\
cp ${TRANSFORMDIR}/melusina/empty.xsl ${TRANSFORMDIR}/melusina/docx/current/publication.xsl;\
fi
@mkdir -p tei/media
@${BINDIR}/docxtotei --profiledir=${PROFDIR} --profile=melusina $< $@
@cp ../../assets/*.png tei/media/
@cp -r assets/* tei/media/
@rm -rf ${TRANSFORMDIR}/melusina/docx/current
xhtml/*.html: tei/${MANUSCRIPTNAME}.xml
@echo -e "\n[BUILD] Convert Word TEI-XML to HTML via teitohtml and melusina scripts\n"
# Make available relevant XSL stylesheets to the master styleshet
@mkdir -p ${TRANSFORMDIR}/melusina/html/current
@cp ${TRANSFORMDIR}/melusina/html/specific/${SERIES}.xsl ${TRANSFORMDIR}/melusina/html/current/series.xsl
@if [ -e ${TRANSFORMDIR}/melusina/html/specific/${SERIES}/${MANUSCRIPTNAME}.xsl ]; then\
cp ${TRANSFORMDIR}/melusina/html/specific/${SERIES}/${MANUSCRIPTNAME}.xsl ${TRANSFORMDIR}/melusina/html/current/publication.xsl;\
else\
cp ${TRANSFORMDIR}/melusina/empty.xsl ${TRANSFORMDIR}/melusina/html/current/publication.xsl;\
fi
@mkdir -p xhtml
# generate front matter
@java -jar ${SAXON}/saxon9he.jar -o:xhtml/front.html $< ${TRANSFORMDIR}/other/html_front_matter.xsl series=${SERIES}
# copy assets from tei folder
@if [ -e tei/media ]; then\
cp -r tei/media xhtml/;\
else\
mkdir -p xhtml/media;\
fi
# copy stylesheets
@cp ${TRANSFORMDIR}/css/melusina.css xhtml/
@cp ${TRANSFORMDIR}/css/specific/${SERIES}.css xhtml/publication.css
# transform tei xml to html
@${BINDIR}/teitohtml --profiledir=${PROFDIR} --profile=melusina $< xhtml/${MANUSCRIPTNAME}.html
@rm -rf ${TRANSFORMDIR}/melusina/html/current
manifold/manifest.yml: tei/${MANUSCRIPTNAME}.xml
@echo -e "\n[BUILD] Generate manifest.yml from TEI-XML via Saxon and melusina scripts\n"
@mkdir -p manifold
@java -jar ${SAXON}/saxon9he.jar -o:manifold/manifest.yml $< ${TRANSFORMDIR}/other/manifold_manifest.xsl
manifold/${MANUSCRIPTNAME}.zip: xhtml/*.html manifold/manifest.yml
@echo -e "\n[BUILD] Generate Manifold package by collecting manifest.yml and HTML files\n"
@if [ -e tei/media ]; then\
cp -r tei/media manifold/;\
else\
mkdir -p manifold/media;\
fi
@cd xhtml && cp -r cover.html second_cover.html editorial.html *.css ../manifold/
# generate chapter html
@java -jar ${SAXON}/saxon9he.jar -o:xhtml/sections.html xhtml/${MANUSCRIPTNAME}.html ${TRANSFORMDIR}/other/split_html_sections.xsl
@cd manifold && zip -r ${MANUSCRIPTNAME}.zip manifest.yml media *.html *.css
# rm -rf manifold/media manifold/${MANUSCRIPTNAME}.html manifest.yml
clean:
@echo "[BUILD] Delete everything but the Word DOCX manuscript"
@rm -rf tei xhtml manifold pdf发布于 2020-04-01 17:46:50
问题是,这些规则无法发挥作用:
xhtml/*.html: tei/${MANUSCRIPTNAME}.xml
manifold/${MANUSCRIPTNAME}.zip: xhtml/*.html manifold/manifest.yml使用通配符查找需要由make构建的目标是不正确的,因为当您第一次运行make时,不存在与这些通配符匹配的文件,因此它们无法展开。
它看起来起作用的原因是,就像shell一样,如果通配符与任何值不匹配,它就返回通配符本身。因此,如果没有任何文件与xhtml/*.html匹配,则结果是文字字符串xhtml/*.html。如果您有三个匹配的文件,那么结果是像xhtml/ONE.html xhtml/TWO.html xhtml/THREE.html这样的三个文件。
因此,当您第一次运行这个makefile时,没有匹配的目标,所以make想要构建一个名为xhtml/*.html的目标,并且有一条与目标匹配的规则,所以这一切都是有效的。
第二次运行这个makefile时,有三个目标希望构建,并且有这样的规则:
xhtml/ONE.html xhtml/TWO.html xhtml/THREE.html: tei/${MANUSCRIPTNAME}.xml
...recipe...这是什么意思?您可能认为这意味着一次对食谱的调用将构建所有三个目标,但这并不意味着要创建。要做到这一点,这与编写以下内容完全相同:
xhtml/ONE.html: tei/${MANUSCRIPTNAME}.xml
...recipe...
xhtml/TWO.html: tei/${MANUSCRIPTNAME}.xml
...recipe...
xhtml/THREE.html: tei/${MANUSCRIPTNAME}.xml
...recipe...也就是说,它将为每个目标运行一次配方。我不可能理解大量shell脚本的功能,因此我无法解释为什么总是要重新构建:必须是这些文件不是由目标实际创建的,或者是它们的修改时间没有被正确设置。
如果这个规则真的用一次调用构建所有html文件,那么您需要使用某种伪目标来跟踪它的修改时间,如下所示:
xhtml/.buildhtml: tei/${MANUSCRIPTNAME}.xml
... recipe ...
@touch $@
manifold/${MANUSCRIPTNAME}.zip: xhtml/.buildhtml manifold/manifest.yml或者,如果您知道可以使用最新的GNUmake4.3版本,则可以利用新的“分组目标”特征、&:,并编写如下所示的makefile:
ALLHTML = xhtml/ONE.html xhtml/TWO.html xhtml/THREE.html
$(ALLHTML) &: tei/${MANUSCRIPTNAME}.xml
...recipe...
manifold/${MANUSCRIPTNAME}.zip: $(ALLHTML) manifold/manifest.yml(出于上述原因,您仍然不能使用*.html )。
https://stackoverflow.com/questions/60975235
复制相似问题