user797257
user797257

Reputation:

How to write clean target?

First of all, I am not sure that what I am going to ask is my problem. Perhaps it is something else, so, please, don't hesitate to point that out. I think that the place I went wrong is the clean target of my Makefile, but it could be something else entirely.

Here is what happens: after running make clean and then make few targets, which have their resulting files deleted during the clean don't rebuild. (In addition to my question I'd be interested in a way to cancel entirely all caching GNU/Make does, it has been a major pain since whenever I ever used it, and never had any positive consequences, not even once).

If I then run make again, some of the targets are rebuilt. If I run make one more time, the targets that depend on the targets built in the previous round are rebuilt and so on.

Here's the corresponding Makefile section:

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}

And here's the output:

First run

$ 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

Second run

$ 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

Third run

$ 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

As you can see, the $(INFO) isn't even entered on the first run, even though the directory where it outputs the file was just deleted and created anew. The exact same thing happens later when it (doesn't) rebuild the $(WIKI).

EDIT:

Here's the directory structure, text following # signs is comments.

|- 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

An update to the original Makefile, but the problem isn't solved

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' \
'{}' \;)

Trying to execute $(WIKI) in this way doesn't trigger the correspondent rule for some reason.

And if I change rename-wiki to look something like:

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

I get "no rule to build the target. Even though $(WIKIDIST)/%.wiki is the rule to build the target.


EDIT2:

Finally, I could achieve what I want in doing it like so:

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))))

Needless to mention how much I like the solution and the language that makes one devise one.

Upvotes: 0

Views: 184

Answers (1)

Beta
Beta

Reputation: 99104

There are several problems here. This may take a few iterations.

First, when you make clean you delete i-iterate/ and everything in it, including i-iterate/info/whatever.texi. Since there are no texi files, Make deduces that no info files need be made; $(INFO) is an empty list.

I gather that by some black magic the emacs command creates an info/ directory full of texi files out of the ether, which Make then copies into i-iterate/ (in the default rule). Is that correct? If it is correct, then we should do this before the $(INFO) step. I suspect that the same is true of the $(WIKI) step, but let's not get ahead of ourselves.

Upvotes: 1

Related Questions