Eliminate / replace remaining cPickle references in test scripts.
[scons.git] / doc / SConscript
index d5fe171ba4af4588c6382c3a842e032e8a9a4239..7af3d33c90e68d3b608249c52bcf758f778f0f1a 100644 (file)
@@ -3,7 +3,7 @@
 #
 
 #
-# Copyright (c) 2001, 2002, 2003 Steven Knight
+# __COPYRIGHT__
 #
 # Permission is hereby granted, free of charge, to any person obtaining
 # a copy of this software and associated documentation files (the
 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
+from __future__ import generators  ### KEEP FOR COMPATIBILITY FIXERS
 
 import os.path
 import re
-import string
 
-Import('env', 'whereis')
+Import('build_dir', 'env', 'whereis')
+
+env = env.Clone()
+
+build = os.path.join(build_dir, 'doc')
 
 #
 #
 #
-doc_tar_gz = os.path.join('#build',
-                          'dist',
-                          'scons-doc-%s.tar.gz' % env.Dictionary('VERSION'))
+dist_doc_tar_gz = '$DISTDIR/scons-doc-${VERSION}.tar.gz'
 
 #
 # We'll only try to build text files (for some documents)
 # if lynx is available to do the dump.
 #
 fig2dev = whereis('fig2dev')
+epydoc = whereis('epydoc')
 groff = whereis('groff')
 lynx = whereis('lynx')
 man2html = whereis('man2html')
-jade = whereis('jade')
+jade_original = whereis('jade')
+jade = whereis('openjade') or jade_original
 jadetex = whereis('jadetex')
 pdfjadetex = whereis('pdfjadetex')
 jw = whereis('jw')
 tidy = whereis('tidy')
 
 tar_deps = []
-tar_list = ""
+tar_list = []
 
 entity_re = re.compile(r'<!entity\s+(?:%\s+)?(?:\S+)\s+SYSTEM\s+"([^"]*)">', re.I)
 format_re = re.compile(r'<(?:graphic|imagedata)\s+fileref="([^"]*)"(?:\s+format="([^"]*)")?')
 
 #
-# Find internal dependencies in .sgml files:
+# Find internal dependencies in .xml files:
 #
-#   <!entity bground SYSTEM "bground.sgml">
+#   <!entity bground SYSTEM "bground.xml">
 #   <graphic fileref="file.jpg">
 #   <imagedata fileref="file.jpg">
 #
@@ -69,10 +73,10 @@ format_re = re.compile(r'<(?:graphic|imagedata)\s+fileref="([^"]*)"(?:\s+format=
 # defined as a SYSTEM entity is, in fact, a file included
 # somewhere in the document.
 #
-def scansgml(node, env, target):
+def scanxml(node, env, target):
     includes = []
 
-    contents = node.get_contents()
+    contents = node.get_text_contents()
 
     includes.extend(entity_re.findall(contents))
 
@@ -80,31 +84,56 @@ def scansgml(node, env, target):
     for m in matches:
         file, format = m
         if format and file[-len(format):] != format:
-            file = file + format
+            file = file + '.' + format
         if not os.path.isabs(file):
             a = []
             f = file
-            while 1:
+            while f:
                 f, tail = os.path.split(f)
                 if tail == 'doc':
                     break
                 a = [tail] + a
-            file = apply(os.path.join, a, {})
+            file = os.path.join(*a)
         includes.append(file)
 
     return includes
 
-s = Scanner(name = 'sgml', function = scansgml, skeys = ['.sgml', '.mod'])
-env = env.Copy(SCANNERS = [s])
-
-if jw:
+s = Scanner(name = 'xml', function = scanxml, skeys = ['.xml', '.mod'])
+
+orig_env = env
+env = orig_env.Clone(SCANNERS = [s],
+                     SCONS_DOC_PY = File('#bin/scons-doc.py').rfile(),
+                     SCONS_PROC_PY = File('#bin/scons-proc.py').rfile())
+
+# Fetch the list of files in the build engine that contain
+# SCons documentation XML for processing.
+def chop(s): return s[:-1]
+
+# If we ever read doc from __scons_doc__ strings in *.py files again,
+# here's how it's done:
+#manifest_in = File('#src/engine/MANIFEST.in').rstr()
+#manifest_xml_in = File('#src/engine/MANIFEST-xml.in').rstr()
+#scons_doc_files = map(chop, open(manifest_in).readlines() +\
+#                            open(manifest_xml_in).readlines())
+#scons_doc_files = map(lambda x: '#src/engine/'+x, scons_doc_files)
+#manifest_in = File('#src/engine/MANIFEST.in').rstr()
+
+manifest_xml_in = File('#src/engine/MANIFEST-xml.in').rstr()
+scons_doc_files = list(map(chop, open(manifest_xml_in).readlines()))
+scons_doc_files = [File('#src/engine/'+x).rstr() for x in scons_doc_files]
+
+if not jw:
+    print "jw not found, skipping building User Guide."
+else:
     #
-    # Always create a version.sgml file containing the version information
+    # Always create a version.xml file containing the version information
     # for this run.  Ignore it for dependency purposes so we don't
     # rebuild all the docs every time just because the date changes.
     #
     date, ver, rev = env.Dictionary('DATE', 'VERSION', 'REVISION')
-    verfile = str(File("version.sgml"))
+    version_xml = File(os.path.join(build, "version.xml"))
+    #version_xml = File("version.xml")
+    verfile = str(version_xml)
     try:
         os.unlink(verfile)
     except OSError:
@@ -122,6 +151,29 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
 <!ENTITY buildrevision "%s">
 """ % (date, ver, rev))
 
+    builders_gen = os.path.join(build, 'user', 'builders.gen')
+    builders_mod = os.path.join(build, 'user', 'builders.mod')
+    tools_gen = os.path.join(build, 'user', 'tools.gen')
+    tools_mod = os.path.join(build, 'user', 'tools.mod')
+    variables_gen = os.path.join(build, 'user', 'variables.gen')
+    variables_mod = os.path.join(build, 'user', 'variables.mod')
+
+    # We put $( - $) around $SOURCES in the command line below because
+    # the path names will change when a given input file is found in
+    # a repository one run and locally the next, and we don't want
+    # to rebuild documentation just because it's found in one location
+    # vs. the other.  The *.gen and *.mod targets will still be dependent
+    # on the list of the files themselves.
+    doc_output_files = [builders_gen, builders_mod,
+                        tools_gen, tools_mod,
+                        variables_gen, variables_mod]
+    b = env.Command(doc_output_files,
+                    scons_doc_files,
+                    "$PYTHON $SCONS_PROC_PY --xml -b ${TARGETS[0]},${TARGETS[1]} -t ${TARGETS[2]},${TARGETS[3]} -v ${TARGETS[4]},${TARGETS[5]} $( $SOURCES $)")
+    env.Depends(b, "$SCONS_PROC_PY")
+
+    env.Local(b)
+
     #
     # Each document will live in its own subdirectory.  List them here
     # as hash keys, with a hash of the info to control its build.
@@ -133,14 +185,24 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
                 'pdf'       : 1,
                 'text'      : 0,
         },
-        'python10' : {
-                'htmlindex' : 't1.html',
-                'html'      : 1,
-                'ps'        : 1,
-                'pdf'       : 0,
-                'text'      : 0,
-                'graphics'  : [ 'arch', 'builder', 'job-task', 'node', 'scanner', 'sig' ],
-        },
+        # This doesn't build on all systems, and the document is old
+        # enough that there's reallyno need to build it every time any
+        # more, so just comment it out for now.
+        #'python10' : {
+        #        'htmlindex' : 't1.html',
+        #        'html'      : 1,
+        #        'ps'        : 1,
+        #        'pdf'       : 0,
+        #        'text'      : 0,
+        #        'graphics'  : [
+        #                        'arch.fig',
+        #                        'builder.fig',
+        #                        'job-task.fig',
+        #                        'node.fig',
+        #                        'scanner.fig',
+        #                        'sig.fig'
+        #                      ],
+        #},
         'reference' : {
                 'htmlindex' : 'book1.html',
                 'html'      : 1,
@@ -148,149 +210,318 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE.  DO NOT EDIT.
                 'pdf'       : 1,
                 'text'      : 0,
         },
+        # For whenever (if ever?) we start putting developer guide
+        # information in a printable document instead of the wiki.
+        #'developer' : {
+        #        'htmlindex' : 'book1.html',
+        #        'html'      : 1,
+        #        'ps'        : 1,
+        #        'pdf'       : 1,
+        #        'text'      : 0,
+        #},
         'user' : {
                 'htmlindex' : 'book1.html',
                 'html'      : 1,
                 'ps'        : 1,
                 'pdf'       : 1,
-                'text'      : 0,
+                'text'      : 1,
+                'graphics'  : [
+                                'SCons-win32-install-1.jpg',
+                                'SCons-win32-install-2.jpg',
+                                'SCons-win32-install-3.jpg',
+                                'SCons-win32-install-4.jpg',
+                              ],
+                'scons-doc' : 1,
         },
     }
 
     #
-    # We have to tell SCons to scan the top-level SGML files which
-    # get included by the document SGML files in the subdirectories.
+    # We have to tell SCons to scan the top-level XML files which
+    # get included by the document XML files in the subdirectories.
     #
-    included_sgml = [
-        'scons.mod',
-        'copyright.sgml',
-    ]
+    manifest = File('MANIFEST').rstr()
+    src_files = [x[:-1] for x in open(manifest).readlines()]
+    for s in src_files:
+        base, ext = os.path.splitext(s)
+        if ext in ['.fig', '.jpg']:
+            orig_env.Install(build, s)
+        else:
+            orig_env.SCons_revision(os.path.join(build, s), s)
+        Local(os.path.join(build, s))
 
     #
     # For each document, build the document itself in HTML, Postscript,
     # and PDF formats.
     #
     for doc in docs.keys():
-        main = os.path.join(doc, 'main.sgml')
+        manifest = File(os.path.join(doc, 'MANIFEST')).rstr()
+        src_files = [x[:-1] for x in open(manifest).readlines()]
+        build_doc = docs[doc].get('scons-doc') and int(ARGUMENTS.get('BUILDDOC', 0))
+        for s in src_files:
+            doc_s = os.path.join(doc, s)
+            build_s = os.path.join(build, doc, s)
+            base, ext = os.path.splitext(doc_s)
+            if ext in ['.fig', '.jpg']:
+                orig_env.InstallAs(build_s, doc_s)
+            else:
+                if build_doc and ext == '.xml':
+                    env.Command(doc_s,
+                                base + '.in',
+                                "$PYTHON $SCONS_DOC_PY $SOURCE > $TARGET")
+                orig_env.SCons_revision(build_s, doc_s)
+            Local(build_s)
+
+        main = os.path.join(build, doc, 'main.xml')
         out = 'main.out'
 
-        htmldir = os.path.join('HTML', 'scons-%s' % doc)
+        # Hard-coding the scons-src path is a bit of a hack.  This can
+        # be reworked when a better solution presents itself.
+        scons_src_main = os.path.join(build_dir, 'scons-src', 'doc', main)
+        env.Ignore(scons_src_main, version_xml)
+
+        htmldir = os.path.join(build, 'HTML', 'scons-%s' % doc)
         htmlindex = os.path.join(htmldir, docs[doc]['htmlindex'])
-        html = os.path.join('HTML', 'scons-%s.html' % doc)
-        ps = os.path.join('PS', 'scons-%s.ps' % doc)
-        pdf = os.path.join('PDF', 'scons-%s.pdf' % doc)
-        text = os.path.join('TEXT', 'scons-%s.txt' % doc)
+        html = os.path.join(build, 'HTML', 'scons-%s.html' % doc)
+        ps = os.path.join(build, 'PS', 'scons-%s.ps' % doc)
+        pdf = os.path.join(build, 'PDF', 'scons-%s.pdf' % doc)
+        text = os.path.join(build, 'TEXT', 'scons-%s.txt' % doc)
 
         if docs[doc].get('html') and jade:
+            def copy_index_html(target, source, env):
+                # Older versions of DocBook|jw|jade|whatever would
+                # create a book1.html file, while newer versions create
+                # an index.html file (logically enough).  The scons.org
+                # web site links expect book1.html, so we're going to
+                # leave the target as is, and run this post-processing
+                # action function to check that the target really did
+                # get created, and if it didn't, copy it from index.html.
+                t = str(target[0])
+                if not os.path.exists(t):
+                    i = os.path.join(os.path.split(t)[0], 'index.html')
+                    open(t, 'w').write(open(i, 'r').read())
+                return None
+
             cmds = [
-                "rm -f ${TARGET.dir}/*.html",
+                Delete("${TARGET.dir}/*.html"),
                 "jw -b html -o ${TARGET.dir} $SOURCES",
-                "mv -v ${TARGET.dir}/index.html $TARGET || true",
             ]
             if tidy:
                 cmds.append("tidy -m -q $TARGET || true")
-            env.Command(htmlindex, main, cmds)
+            cmds.append(Action(copy_index_html))
+            env.Command(htmlindex, File(main), cmds)
             Local(htmlindex)
 
             cmds = [
-                "rm -f ${TARGET.dir}/main.html",
+                Delete("${TARGET.dir}/main.html"),
                 "jw -u -b html -o ${TARGET.dir} $SOURCES",
-                "mv -v ${TARGET.dir}/main.html $TARGET || true",
+                Move("$TARGET", "${TARGET.dir}/main.html"),
             ]
             if tidy:
                 cmds.append("tidy -m -q $TARGET || true")
-            env.Command(html, main, cmds)
+            env.Command(html, File(main), cmds)
             Local(html)
 
-            env.Ignore([html, htmlindex], "version.sgml")
+            env.Ignore([html, htmlindex], version_xml)
 
             tar_deps.extend([html, htmlindex])
-            tar_list = string.join([tar_list, html, htmldir], " ")
-
-            if fig2dev:
-                for g in docs[doc].get('graphics', []):
-                    fig = os.path.join(doc, '%s.fig' % g)
-                    jpg = os.path.join(htmldir, '%s.jpg' % g)
-                    env.Command(jpg, fig,
-                                "%s -L jpeg -q 100 $SOURCES $TARGET" % fig2dev)
-                    env.Depends(html, jpg)
-                    Local(jpg)
-
-        if docs[doc].get('ps') and jadetex:
+            tar_list.extend([html, htmldir])
+
+            for g in docs[doc].get('graphics', []):
+                base, ext = os.path.splitext(g)
+                if ext == '.fig':
+                    jpg = base + '.jpg'
+                    htmldir_jpg = os.path.join(htmldir, jpg)
+                    if fig2dev:
+                        fig = os.path.join(build, doc, g)
+                        env.Command(htmldir_jpg, fig,
+                                    "%s -L jpeg -q 100 $SOURCES $TARGET" % fig2dev)
+                    else:
+                        env.InstallAs(htmldir_jpg, jpg)
+                    env.Depends(html, htmldir_jpg)
+                    Local(htmldir_jpg)
+                else:
+                    src = os.path.join(build, doc, g)
+                    Local(env.Install(htmldir, src))
+
+        if docs[doc].get('ps') and jadetex and jade_original:
             env.Command(ps, main, [
-                "rm -f ${TARGET.dir}/%s" % out,
-                "jw -b ps -o ${TARGET.dir} $SOURCES",
+                Delete("${TARGET.dir}/%s" % out),
+                "jw -b ps -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
                 "mv ${TARGET.dir}/main.ps $TARGET",
-                "rm -f ${TARGET.dir}/%s" % out,
+                Delete("${TARGET.dir}/%s" % out),
             ])
             Local(ps)
 
-            env.Ignore(ps, "version.sgml")
+            env.Ignore(ps, version_xml)
 
             tar_deps.append(ps)
-            tar_list = tar_list + " " + ps
-
-            if fig2dev:
-                for g in docs[doc].get('graphics', []):
-                    fig = os.path.join(doc, '%s.fig' % g)
-                    eps = os.path.join('PS', '%s.eps' % g)
-                    env.Command(eps, fig, "%s -L eps $SOURCES $TARGET" % fig2dev)
-                    env.Depends(ps, eps)
-                    Local(eps)
-
-        if docs[doc].get('pdf') and pdfjadetex:
+            tar_list.append(ps)
+
+            for g in docs[doc].get('graphics', []):
+                base, ext = os.path.splitext(g)
+                if ext == '.fig':
+                    eps = base + '.eps'
+                    build_eps = os.path.join(build, 'PS', eps)
+                    if fig2dev:
+                        fig = os.path.join(build, doc, g)
+                        env.Command(build_eps, fig, "%s -L eps $SOURCES $TARGET" % fig2dev)
+                    else:
+                        env.InstallAs(build_eps, eps)
+                    env.Depends(ps, build_eps)
+                    Local(build_eps)
+                else:
+                    src = os.path.join(build, doc, g)
+                    Local(env.Install(htmldir, src))
+
+        if docs[doc].get('pdf') and pdfjadetex and jade_original:
             env.Command(pdf, main, [
-                "rm -f ${TARGET.dir}/%s" % out,
-                "jw -b pdf -o ${TARGET.dir} $SOURCES",
+                Delete("${TARGET.dir}/%s" % out),
+                "jw -b pdf -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
                 "mv ${TARGET.dir}/main.pdf $TARGET",
-                "rm -f ${TARGET.dir}/out",
+                Delete("${TARGET.dir}/out"),
             ])
             Local(pdf)
 
-            env.Ignore(pdf, "version.sgml")
+            env.Ignore(pdf, version_xml)
 
             tar_deps.append(pdf)
-            tar_list = tar_list + " " + pdf
+            tar_list.append(pdf)
 
         if docs[doc].get('text') and jade and lynx:
             env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
+            Local(text)
 
-            env.Ignore(text, "version.sgml")
+            env.Ignore(text, version_xml)
 
             tar_deps.append(text)
-            tar_list = tar_list + " " + text
+            tar_list.append(text)
 
 #
 # Man page(s), in good ol' troff format.
 #
-scons_1 = os.path.join('man', 'scons.1')
-
-if groff:
-    ps = os.path.join('PS', 'scons-man.ps')
-    text = os.path.join('TEXT', 'scons-man.txt')
-
-    env.Command(ps, scons_1, "groff -man -Tps $SOURCES > $TARGET")
-
-    env.Command(text, scons_1, "groff -man -Tascii $SOURCES > $TARGET")
-
-    tar_deps.extend([ps, text])
-    tar_list = string.join([tar_list, ps, text], " ")
-
-if man2html:
-    html = os.path.join('HTML' , 'scons-man.html')
-
-    cmds = [ "man2html $SOURCES > $TARGET" ]
-    if tidy:
-        cmds.append("tidy -m -q $TARGET || true")
-    env.Command(html, scons_1, cmds)
+man_page_list = ['scons.1', 'sconsign.1', 'scons-time.1']
+
+for m in man_page_list:
+    x = orig_env.SCons_revision(os.path.join(build, 'man', m),
+                            os.path.join('man', m))
+
+man_i_files = ['builders.man', 'tools.man', 'variables.man']
+
+man_intermediate_files = [os.path.join(build, 'man', x) for x in man_i_files]
+
+cmd = "$PYTHON $SCONS_PROC_PY --man -b ${TARGETS[0]} -t ${TARGETS[1]} -v ${TARGETS[2]} $( $SOURCES $)"
+man_intermediate_files = env.Command(man_intermediate_files,
+                                     scons_doc_files,
+                                     cmd)
+env.Depends(man_intermediate_files, "$SCONS_PROC_PY")
+Local(man_intermediate_files)
+
+for man_1 in man_page_list:
+    man, _1 = os.path.splitext(man_1)
+
+    man_1 = os.path.join(build, 'man', man_1)
+
+    if groff:
+        ps = os.path.join(build, 'PS', '%s-man.ps' % man)
+        text = os.path.join(build, 'TEXT', '%s-man.txt' % man)
+
+        b = env.Command(ps, man_1, "( cd ${SOURCES.dir} && groff -man -Tps ${SOURCES.file} ) > $TARGET")
+        Local(ps)
+        env.Depends(b, man_intermediate_files)
+
+        b = env.Command(text, man_1, "( cd ${SOURCES.dir} && groff -man -Tascii ${SOURCES.file} ) > $TARGET")
+        Local(text)
+        env.Depends(b, man_intermediate_files)
+
+        tar_deps.extend([ps, text])
+        tar_list.extend([ps, text])
+
+    if man2html:
+        html = os.path.join(build, 'HTML' , '%s-man.html' % man)
+
+        def strip_to_first_html_tag(target, source, env):
+            t = str(target[0])
+            contents = open(t).read()
+            contents = contents[contents.find('<HTML>'):]
+            open(t, 'w').write(contents)
+            return 0
+
+        cmds = [
+            "( cd %s/man && cp %s .. )" % (build, ' '.join(man_i_files)),
+            "( cd ${SOURCE.dir} && man2html ${SOURCE.file} ) > $TARGET",
+            Action(strip_to_first_html_tag),
+        ]
+        if tidy:
+            cmds.append("tidy -m -q $TARGET || true")
+        b = env.Command(html, man_1, cmds)
+        Local(html)
+        env.Depends(b, man_intermediate_files)
+
+        tar_deps.append(html)
+        tar_list.append(html)
+
+if not epydoc:
+    print "epydoc not found, skipping building API documentation."
+else:
+    # XXX Should be in common with reading the same thing in
+    # the SConstruct file.
+    e = os.path.join('#src', 'engine')
+    manifest_in = File(os.path.join(e, 'MANIFEST.in')).rstr()
+    sources = [x[:-1] for x in open(manifest_in).readlines()]
+    sources = [x for x in sources if x.find('Optik') == -1]
+    sources = [x for x in sources if x.find('Platform') == -1]
+    sources = [x for x in sources if x.find('Tool') == -1]
+    # XXX
+    sources = [x for x in sources if x.find('Options') == -1]
+
+    e = os.path.join(build, '..', 'scons', 'engine')
+    sources = [os.path.join(e, x) for x in sources]
+
+    epydoc_commands = [
+        Delete('$OUTDIR'),
+        '$EPYDOC $EPYDOCFLAGS --debug --output $OUTDIR --docformat=restructuredText --name SCons --url http://www.scons.org/ $SOURCES',
+        Touch('$TARGET'),
+    ]
 
-    tar_deps.append(html)
-    tar_list = tar_list + " " + html
+    htmldir = os.path.join(build, 'HTML', 'scons-api')
+    env.Command('${OUTDIR}/index.html', sources, epydoc_commands,
+                EPYDOC=epydoc, EPYDOCFLAGS='--html', OUTDIR=htmldir)
+    tar_deps.append(htmldir)
+    tar_list.append(htmldir)
+
+    # PDF and PostScript and TeX are built from the
+    # same invocation.
+    api_dir = os.path.join(build, 'scons-api')
+    api_pdf = os.path.join(api_dir, 'api.pdf')
+    api_ps = os.path.join(api_dir, 'api.ps')
+    api_tex = os.path.join(api_dir, 'api.tex')
+    api_targets = [api_pdf, api_ps, api_tex]
+    env.Command(api_targets, sources, epydoc_commands,
+                EPYDOC=epydoc, EPYDOCFLAGS='--pdf', OUTDIR=api_dir)
+    Local(api_targets)
+
+    pdf_install = os.path.join(build, 'PDF', 'scons-api.pdf')
+    env.InstallAs(pdf_install, api_pdf)
+    tar_deps.append(pdf_install)
+    tar_list.append(pdf_install)
+    Local(pdf_install)
+
+    ps_install = os.path.join(build, 'PS', 'scons-api.ps')
+    env.InstallAs(ps_install, api_ps)
+    tar_deps.append(ps_install)
+    tar_list.append(ps_install)
+    Local(ps_install)
 
 #
 # Now actually create the tar file of the documentation,
 # for easy distribution to the web site.
 #
 if tar_deps:
-    env.Command(doc_tar_gz, tar_deps,
-                "tar cf${TAR_HFLAG} - -C build/doc %s | gzip > $TARGET" % tar_list)
+    tar_list = ' '.join([x.replace(build+'/', '') for x in tar_list])
+    t = env.Command(dist_doc_tar_gz, tar_deps,
+                "tar cf${TAR_HFLAG} - -C %s %s | gzip > $TARGET" % (build, tar_list))
+    AddPostAction(dist_doc_tar_gz, Chmod(dist_doc_tar_gz, 0644))
+    Local(t)
+    Alias('doc', t)
+else:
+    Alias('doc', os.path.join(build_dir, 'doc'))