Makefile: Streamline directory creation
authorMichael Hanselmann <hansmi@google.com>
Thu, 28 Oct 2010 15:06:21 +0000 (17:06 +0200)
committerMichael Hanselmann <hansmi@google.com>
Fri, 29 Oct 2010 12:43:04 +0000 (14:43 +0200)
Some directories don't exist in the repository, but are required at build time
(e.g. doc/html). Until now some were created explicitly, some through the
target “stamp-directories” and other target simply relied on a previous target
to create the directory.

This patch tries to clean this up by getting rid of “stamp-directories” and
instead use rules to recreate any missing directory. As described in a comment
in the code, a file inside each directory is necessary, named “.dir”.

Order-only dependencies are used for directory creation to avoid rebuilding
where only the “.dir” file is missing (see “info make”, section “4.3 Types of
Prerequisites”).

The target for building the documentation is also changed to use “…/index.html”
instead of a hidden file. Some style changes are also made.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
Reviewed-by: René Nussbaumer <rn@google.com>

.gitignore
Makefile.am

index dd3fe68..1948d14 100644 (file)
@@ -8,6 +8,7 @@
 *.py[co]
 *.swp
 *~
+.dir
 
 # /
 /Makefile
@@ -24,7 +25,6 @@
 /config.status
 /configure
 /ganeti
-/stamp-directories
 /stamp-srclinks
 /vcs-version
 /*.patch
index 39c0d60..bce35f0 100644 (file)
@@ -49,12 +49,12 @@ DIRS = \
        lib/rapi \
        man \
        qa \
-       scripts \
        test \
        test/data \
        tools
 
 BUILDTIME_DIRS = \
+       scripts \
        doc/api \
        doc/coverage \
        doc/html
@@ -64,6 +64,8 @@ DIRCHECK_EXCLUDE = \
        ganeti-[0-9]*.[0-9]*.[0-9]* \
        doc/html/_*
 
+all_dirfiles = $(addsuffix /.dir,$(DIRS) $(BUILDTIME_DIRS))
+
 MAINTAINERCLEANFILES = \
        $(docpng) \
        $(maninput) \
@@ -76,6 +78,7 @@ maintainer-clean-local:
 
 CLEANFILES = \
        $(addsuffix /*.py[co],$(DIRS)) \
+       $(all_dirfiles) \
        $(PYTHON_BOOTSTRAP) \
        autotools/replace_vars.sed \
        daemons/daemon-util \
@@ -89,19 +92,18 @@ CLEANFILES = \
        doc/examples/hooks/ipsec \
        $(man_MANS) \
        $(manhtml) \
-       stamp-directories \
        stamp-srclinks \
        $(nodist_pkgpython_PYTHON)
 
+# BUILT_SOURCES should only be used as a dependency on phony targets. Otherwise
+# it'll cause the target to rebuild every time.
 BUILT_SOURCES = \
        ganeti \
        stamp-srclinks \
-       stamp-directories \
        lib/_autoconf.py \
+       $(all_dirfiles) \
        $(PYTHON_BOOTSTRAP)
 
-$(RUN_IN_TEMPDIR): $(BUILT_SOURCES)
-
 nodist_pkgpython_PYTHON = \
        lib/_autoconf.py
 
@@ -207,7 +209,10 @@ docrst = \
        doc/security.rst \
        doc/walkthrough.rst
 
-doc/html/.stamp: $(docrst) $(docpng) doc/conf.py configure.ac $(RUN_IN_TEMPDIR)
+$(RUN_IN_TEMPDIR): | $(all_dirfiles)
+
+doc/html/index.html: $(docrst) $(docpng) doc/conf.py configure.ac \
+       $(RUN_IN_TEMPDIR) | doc/html/.dir
        @test -n "$(SPHINX)" || \
            { echo 'sphinx-build' not found during configure; exit 1; }
        PYTHONPATH=. $(RUN_IN_TEMPDIR) $(SPHINX) -q -W -b html \
@@ -218,7 +223,7 @@ doc/html/.stamp: $(docrst) $(docpng) doc/conf.py configure.ac $(RUN_IN_TEMPDIR)
        rm -f doc/html/.buildinfo doc/html/objects.inv
        touch $@
 
-doc/html: doc/html/.stamp
+doc/html: doc/html/index.html
 
 doc/news.rst: NEWS
        set -e; \
@@ -493,17 +498,14 @@ devel/upload: devel/upload.in $(REPLACE_VARS_SED)
        sed -f $(REPLACE_VARS_SED) < $< > $@
        chmod u+x $@
 
-daemons/%: daemons/%.in \
-               $(REPLACE_VARS_SED)
+daemons/%: daemons/%.in $(REPLACE_VARS_SED)
        sed -f $(REPLACE_VARS_SED) < $< > $@
        chmod +x $@
 
-doc/examples/%: doc/examples/%.in \
-               $(REPLACE_VARS_SED)
+doc/examples/%: doc/examples/%.in $(REPLACE_VARS_SED)
        sed -f $(REPLACE_VARS_SED) < $< > $@
 
-doc/examples/hooks/%: doc/examples/hooks/%.in \
-               $(REPLACE_VARS_SED)
+doc/examples/hooks/%: doc/examples/hooks/%.in $(REPLACE_VARS_SED)
        sed -f $(REPLACE_VARS_SED) < $< > $@
 
 doc/examples/bash_completion: $(BUILD_BASH_COMPLETION) $(RUN_IN_TEMPDIR) \
@@ -550,7 +552,7 @@ regen-vcs-version:
          $(MAKE) vcs-version; \
        fi
 
-lib/_autoconf.py: Makefile stamp-directories vcs-version
+lib/_autoconf.py: Makefile vcs-version | lib/.dir
        set -e; \
        VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
        { echo '# This file is automatically generated, do not edit!'; \
@@ -631,9 +633,8 @@ $(REPLACE_VARS_SED): Makefile
          echo 's#@GNTDAEMONSGROUP@#$(DAEMONS_GROUP)#g'; \
        } > $@
 
-$(PYTHON_BOOTSTRAP): Makefile
+$(PYTHON_BOOTSTRAP): Makefile | $(all_dirfiles)
        set -e; \
-       test -e $(dir $@) || mkdir $(dir $@); \
        module='$(subst -,_,$(notdir $@))'; \
        { echo '#!/usr/bin/python'; \
          echo '# This file is automatically generated, do not edit!'; \
@@ -659,7 +660,7 @@ $(PYTHON_BOOTSTRAP): Makefile
 
 # We need to create symlinks because "make distcheck" will not install Python
 # files when building.
-stamp-srclinks: Makefile stamp-directories
+stamp-srclinks: Makefile | $(all_dirfiles)
        set -e; \
        for i in $(srclink_files); do \
                if test ! -f $$i -a -f $(abs_top_srcdir)/$$i; then \
@@ -699,7 +700,7 @@ check-local: check-dirs
        $(CHECK_PYTHON_CODE) $(check_python_code)
 
 .PHONY: lint
-lint: ganeti $(BUILT_SOURCES)
+lint: $(BUILT_SOURCES)
        @test -n "$(PYLINT)" || { echo 'pylint' not found during configure; exit 1; }
        $(PYLINT) $(LINT_OPTS) $(lint_python_code)
 
@@ -730,13 +731,13 @@ install-exec-local:
          "$(DESTDIR)${localstatedir}/log/ganeti" \
          "$(DESTDIR)${localstatedir}/run/ganeti"
 
-stamp-directories: Makefile
-       @mkdir_p@ $(DIRS)
-       touch $@
+# To avoid conflicts between directory names and other targets, a file inside
+# the directory is used to ensure its existence.
+%.dir:
+       @mkdir_p@ $* && touch $@
 
 .PHONY: apidoc
 apidoc: epydoc.conf $(RUN_IN_TEMPDIR) $(BUILT_SOURCES)
-       test -e doc/api || mkdir doc/api
        $(RUN_IN_TEMPDIR) epydoc -v \
                --conf $(CURDIR)/epydoc.conf \
                --output $(CURDIR)/doc/api
@@ -752,7 +753,6 @@ TAGS: $(BUILT_SOURCES)
 .PHONY: coverage
 coverage: $(BUILT_SOURCES) $(python_tests)
        set -e; \
-       @mkdir_p@ doc/coverage; \
        COVERAGE_FILE=$(CURDIR)/doc/coverage/data \
        TEXT_COVERAGE=$(CURDIR)/doc/coverage/report.txt \
        HTML_COVERAGE=$(CURDIR)/doc/coverage \