X-Git-Url: http://git.tremily.us/?a=blobdiff_plain;f=doc%2FSConscript;h=7af3d33c90e68d3b608249c52bcf758f778f0f1a;hb=5b34a51c397b367bfa366df882bf1b2de82c154e;hp=d5fe171ba4af4588c6382c3a842e032e8a9a4239;hpb=c911a738519433c0d97ca8bdf44a3ad026fa050d;p=scons.git diff --git a/doc/SConscript b/doc/SConscript index d5fe171b..7af3d33c 100644 --- a/doc/SConscript +++ b/doc/SConscript @@ -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 @@ -24,44 +24,48 @@ # 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'', 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: # -# +# # # # @@ -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. """ % (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(''):] + 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'))