如何写清洁目标?

时间:2012-12-15 11:15:28

标签: build makefile

首先,我不确定我要问的是我的问题。也许这是别的东西,所以,请不要犹豫,指出这一点。我认为我错误的地方是我的Makefile的clean目标,但它可能完全不同。

以下是发生的情况:运行make clean然后make几个目标,其clean期间删除的结果文件不重建。 (除了我的问题,我有兴趣以一种方式完全取消所有缓存GNU / Make的做法,因为每当我使用它时都会产生很大的痛苦,并且从未产生过任何积极的后果,甚至一次也没有)。

如果我再次运行make,则会重建一些目标。如果我再次运行make,则会重建依赖于上一轮中构建的目标的目标,依此类推。

这是相应的Makefile部分:

PACKAGE = i-iterate
DOCDST = ${PACKAGE}/docs
HTMLDOCDST = ${PACKAGE}/html-docs
DOCSRC = ${PACKAGE}/info
IC = makeinfo
ICO = --force
TEXI2HTML = texi2html
TEXI2HTMLO = --split section --use-nodes
HTML2WIKI = html2wiki
HTML2WIKIO = --dialect GoogleCode
TEXI = $(wildcard $(DOCSRC)/*.texi)
INFO = $(addprefix $(DOCDST)/,$(notdir $(TEXI:.texi=.info)))
WIKIDST = ../wiki
HTML = $(wildcard $(HTMLDOCDST)/*.html)
WIKI = $(addprefix $(WIKIDST)/,$(notdir $(HTML:.html=.wiki)))

$(DOCDST)/%.info: $(DOCSRC)/%.texi
    echo "info builds: $<"
    $(IC) $(ICO) -o $@ $<
    $(TEXI2HTML) $(TEXI2HTMLO) $<

$(WIKIDST)/%.wiki: $(HTMLDOCDST)/%.html
    $(HTML2WIKI) $(HTML2WIKIO) $< > $@

default: prepare $(INFO) move-html $(WIKI) rename-wiki byte-compile
    cp -r lisp info Makefile README i-pkg.el ${PACKAGE}

prepare:
    mkdir -p ${PACKAGE}
    mkdir -p ${DOCDST}
    mkdir -p ${HTMLDOCDST}

move-html:
    $(shell [[ '0' -ne `find ./ -maxdepth 1 -name "*.html" | wc -l` ]] && \
mv -f *.html ${HTMLDOCDST}/)

rename-wiki:
    $(shell cd ${WIKIDST} && rename 'i-iterate' 'Iterate' *.wiki)
    $(shell find ${WIKIDST} -name "*.wiki" -exec sed -i \
's/\[i-iterate/\[Iterate/g;s/\.html\#/\#/g;s/&lt;/\</g;s/&gt;/\>/g' \
'{}' \;)

byte-compile:
    emacs -Q -L ./lisp -batch -f batch-byte-compile ./lisp/*.el

clean:
    rm -f ./lisp/*.elc
    rm -f ./*.html
    rm -rf ${DOCDST}
    rm -rf ${HTMLDOCDST}
    rm -rf ${PACKAGE}

这是输出:

首次运行

$ make
mkdir -p i-iterate
mkdir -p i-iterate/docs
mkdir -p i-iterate/html-docs
emacs -Q -L ./lisp -batch -f batch-byte-compile ./lisp/*.el
Wrote /home/wvxvw/Projects/i-iterate/trunk/lisp/i-iterate.elc
cp -r lisp info Makefile README i-pkg.el i-iterate

第二次运行

$ make
mkdir -p i-iterate
mkdir -p i-iterate/docs
mkdir -p i-iterate/html-docs
echo "info builds: i-iterate/info/i-iterate.texi"
info builds: i-iterate/info/i-iterate.texi
makeinfo --force -o i-iterate/docs/i-iterate.info i-iterate/info/i-iterate.texi
texi2html --split section --use-nodes i-iterate/info/i-iterate.texi
emacs -Q -L ./lisp -batch -f batch-byte-compile ./lisp/*.el
Wrote /home/wvxvw/Projects/i-iterate/trunk/lisp/i-iterate.elc
cp -r lisp info Makefile README i-pkg.el i-iterate

第三次运行

$ make
mkdir -p i-iterate
mkdir -p i-iterate/docs
mkdir -p i-iterate/html-docs
echo "info builds: i-iterate/info/i-iterate.texi"
info builds: i-iterate/info/i-iterate.texi
makeinfo --force -o i-iterate/docs/i-iterate.info i-iterate/info/i-iterate.texi
texi2html --split section --use-nodes i-iterate/info/i-iterate.texi
html2wiki --dialect GoogleCode i-iterate/html-docs/i-iterate_9.html > ../wiki/i-iterate_9.wiki
# ... a bunch more of the documentation pages ...
/i-iterate_5.wiki
html2wiki --dialect GoogleCode i-iterate/html-docs/i-iterate_2.html > ../wiki/i-iterate_2.wiki
emacs -Q -L ./lisp -batch -f batch-byte-compile ./lisp/*.el
Wrote /home/wvxvw/Projects/i-iterate/trunk/lisp/i-iterate.elc
cp -r lisp info Makefile README i-pkg.el i-iterate

正如您所看到的,即使输出文件的目录刚刚被删除并重新创建,第一次运行时甚至都没有输入$(INFO)。当它(不)重建$(WIKI)时会发生完全相同的事情。

编辑:

这是目录结构,#符号后面的文字是评论。

|- info
|  +- documentation.texi
|- lisp
|  +- source.el
|  +- binary.elc # generated during compile
|- docs # should be deleted and created during the build
|  +- documentation.info
|- html-docs # should be deleted and created during the build
|  +- documentation.html
|- i-iterate # sources are copied here for distribution
|  |- info
|  |  +- documentation.texi
|  |- lisp
|  |  +- source.el

原始Makefile的更新,但问题未解决

TEXI = $(wildcard $(DOCSRC)/*.texi)
INFO = $(addprefix $(DOCDST)/,$(notdir $(TEXI:.texi=.info)))
WIKIDST = ../wiki

$(DOCDST)/%.info: $(DOCSRC)/%.texi
    @echo "info builds: $<"
    $(IC) $(ICO) -o $@ $<
    $(TEXI2HTML) $(TEXI2HTMLO) $<

# This rule is not applied! :(
$(WIKIDST)/%.wiki: $(HTMLDOCDST)/%.html
    @echo "Wiki: $<"
    $(HTML2WIKI) $(HTML2WIKIO) $< > $@

default: prepare $(INFO) move-html rename-wiki byte-compile
    cp -r lisp info Makefile README i-pkg.el ${PACKAGE}

prepare:
    mkdir -p ${PACKAGE}
    mkdir -p ${DOCDST}
    mkdir -p ${HTMLDOCDST}

move-html:
    $(shell [[ '0' -ne `find ./ -maxdepth 1 -name "*.html" | wc -l` ]] && \
mv -f *.html ${HTMLDOCDST}/)
    $(eval HTML := $(wildcard $(HTMLDOCDST)/*.html))
    $(eval WIKI := $(addprefix $(WIKIDST)/,$(notdir $(HTML:.html=.wiki))))
    @echo "HTML: $(HTML)"       # prints as expected
    @echo "WIKI: $(WIKI)"       # prints as expected

rename-wiki: $(WIKI)                     # this dependency never triggers
                                         # the $(WIKIDST)/%.wiki rule
    @echo "Renaming: `ls $(HTMLDOCDST)`" # the files are there
    $(shell cd ${WIKIDST} && rename 'i-iterate' 'Iterate' *.wiki)
    $(shell find ${WIKIDST} -name "*.wiki" -exec sed -i \
's/\[i-iterate/\[Iterate/g;s/\.html\#/\#/g;s/&lt;/\</g;s/&gt;/\>/g' \
'{}' \;)

尝试以这种方式执行$(WIKI)不会因某种原因触发相应的规则。

如果我将rename-wiki更改为:

rename-wiki: ../wiki/file.wiki

我得到“没有规则来构建目标。即使$(WIKIDIST)/%.wiki是构建目标的规则。


EDIT2:

最后,我可以像这样实现我想要的目标:

move-html:
    $(shell [[ '0' -ne `find ./ -maxdepth 1 -name "*.html" | wc -l` ]] && \
mv -f *.html $(HTMLDOCDST)/)
    $(foreach html, $(wildcard $(HTMLDOCDST)/*.html), \
$(HTML2WIKI) $(HTML2WIKIO) $(html) > \
$(addprefix $(WIKIDST)/, $(notdir $(html:.html=.wiki))))

不用说我多么喜欢这个解决方案以及让一个人设计的语言。

1 个答案:

答案 0 :(得分:1)

这里有几个问题。这可能需要几次迭代。

首先,当您make clean删除i-iterate/及其中的所有内容时,包括i-iterate/info/whatever.texi。由于没有texi文件,因此推断不需要制作任何信息文件; $(INFO)是一个空列表。

我通过一些黑魔法收集,emacs命令创建一个充满texi文件的info/目录,然后将其复制到i-iterate/(在default规则中) 。那是对的吗?如果它是正确的,那么我们应该在 $(INFO)步之前执行。我怀疑$(WIKI)步骤也是如此,但我们不要超越自己。