summaryrefslogtreecommitdiffstats
path: root/doc/SConscript
diff options
context:
space:
mode:
Diffstat (limited to 'doc/SConscript')
-rw-r--r--doc/SConscript547
1 files changed, 188 insertions, 359 deletions
diff --git a/doc/SConscript b/doc/SConscript
index 9f7dacd..7c888d2 100644
--- a/doc/SConscript
+++ b/doc/SConscript
@@ -26,103 +26,35 @@
import os.path
import re
+import sys
+import glob
+import SConsDoc
+import SConsExamples
-Import('build_dir', 'env', 'whereis')
+Import('build_dir', 'env', 'whereis', 'revaction')
env = env.Clone()
build = os.path.join(build_dir, 'doc')
+fop = whereis('fop')
+xep = whereis('xep')
+epydoc_cli = whereis('epydoc')
+
#
#
#
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_cli = whereis('epydoc')
-groff = whereis('groff')
-lynx = whereis('lynx')
-man2html = whereis('man2html')
-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 = []
-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 .xml files:
-#
-# <!entity bground SYSTEM "bground.xml">
-# <graphic fileref="file.jpg">
-# <imagedata fileref="file.jpg">
-#
-# This only finds one per line, and assumes that anything
-# defined as a SYSTEM entity is, in fact, a file included
-# somewhere in the document.
-#
-def scanxml(node, env, target):
- includes = []
-
- contents = node.get_text_contents()
-
- includes.extend(entity_re.findall(contents))
-
- matches = format_re.findall(contents)
- for m in matches:
- file, format = m
- if format and file[-len(format):] != format:
- file = file + '.' + format
- if not os.path.isabs(file):
- a = []
- f = file
- while f:
- f, tail = os.path.split(f)
- if tail == 'doc':
- break
- a = [tail] + a
- file = os.path.join(*a)
- includes.append(file)
-
- return includes
-
-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())
+env = orig_env.Clone(SCONS_PY = File('#src/script/scons.py').rfile())
-# Fetch the list of files in the build engine that contain
-# SCons documentation XML for processing.
-def chop(s): return s[:-1]
-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 "doc: jw not found, skipping building User Guide."
-else:
- #
- # 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')
- version_xml = File(os.path.join(build, "version.xml"))
- #version_xml = File("version.xml")
- verfile = str(version_xml)
+def writeVersionXml(verfile, date, ver, rev):
+ """ Helper function: Write a version.xml file. """
try:
os.unlink(verfile)
except OSError:
@@ -131,7 +63,7 @@ else:
try:
os.makedirs(dir)
except OSError:
- pass # okay if the directory already exists
+ pass # okay if the directory already exists
open(verfile, "w").write("""<!--
THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
-->
@@ -140,93 +72,121 @@ 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')
- functions_gen = os.path.join(build, 'user', 'functions.gen')
- functions_mod = os.path.join(build, 'user', 'functions.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,
- functions_gen, functions_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]} -f ${TARGETS[2]},${TARGETS[3]} -t ${TARGETS[4]},${TARGETS[5]} -v ${TARGETS[6]},${TARGETS[7]} $( $SOURCES $)")
- env.Depends(b, "$SCONS_PROC_PY")
-
- env.Local(b)
+#
+# Check whether we have all tools installed for
+# building the documentation.
+#
+skip_doc = False
+try:
+ import libxml2
+except:
+ try:
+ import lxml
+ except:
+ print "doc: Neither libxml2 nor lxml Python bindings found!"
+ print " Please install one of the packages python-libxml2 or python-lxml."
+ skip_doc = True
+
+if not fop and not xep:
+ print "doc: No PDF renderer found (fop|xep)!"
+ skip_doc = True
+
+if skip_doc:
+ print "doc: ...skipping building User Guide."
+else:
+ #
+ # 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')
+ version_xml = File(os.path.join(build, "version.xml"))
+ writeVersionXml(str(version_xml), date, ver, rev)
+
+ if not env.GetOption('clean'):
+ #
+ # Ensure that all XML files are valid against our XSD, and
+ # that all example names and example output suffixes are unique
+ #
+ print "Validating files against SCons XSD..."
+ if SConsDoc.validate_all_xml(['src'], xsdfile='xsd/scons.xsd'):
+ print "OK"
+ else:
+ print "Validation failed! Please correct the errors above and try again."
+ sys.exit(0)
+
+ print "Checking whether all example names are unique..."
+ if SConsExamples.exampleNamesAreUnique(os.path.join('doc','user')):
+ print "OK"
+ else:
+ print "Not all example names and suffixes are unique! Please correct the errors listed above and try again."
+ sys.exit(0)
+
+ #
+ # Copy generated files (.gen/.mod/.xml) to the build folder
+ #
+ env.Execute(Mkdir(os.path.join(build, 'generated')))
+ env.Execute(Mkdir(os.path.join(build, 'generated', 'examples')))
+ for g in glob.glob(os.path.join('generated', '*.gen')):
+ env.Execute(Copy(os.path.join(build, 'generated'), g))
+ for g in glob.glob(os.path.join('generated', '*.mod')):
+ env.Execute(Copy(os.path.join(build, 'generated'), g))
+ for g in glob.glob(os.path.join('generated', 'examples', '*')):
+ env.Execute(Copy(os.path.join(build, 'generated', 'examples'), g))
+
+ #
+ # Copy XSLT files (.xslt) to the build folder
+ #
+ env.Execute(Mkdir(os.path.join(build, 'xslt')))
+ for g in glob.glob(os.path.join('xslt','*.*')):
+ env.Execute(Copy(os.path.join(build, 'xslt'), g))
+
+ #
+ # Copy Docbook stylesheets and Tool to the build folder
+ #
+ dbtoolpath = ['src', 'engine', 'SCons', 'Tool', 'docbook']
+ env.Execute(Mkdir(os.path.join(build_dir, *dbtoolpath)))
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbtoolpath + ['utils']))))
+ env.Execute(Copy(os.path.join(build_dir, *dbtoolpath),
+ os.path.join('..', *(dbtoolpath + ['__init__.py']))))
+ env.Execute(Copy(os.path.join(build_dir, *(dbtoolpath + ['utils'])),
+ os.path.join('..', *(dbtoolpath + ['utils', 'xmldepend.xsl']))))
+ dbpath = dbtoolpath + ['docbook-xsl-1.76.1']
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['common']))))
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['lib']))))
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['html']))))
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['fo']))))
+ env.Execute(Mkdir(os.path.join(build_dir, *(dbpath + ['manpages']))))
+ env.Execute(Copy(os.path.join(build_dir, *dbpath),
+ os.path.join('..', *(dbpath + ['VERSION']))))
+ for g in glob.glob(os.path.join('..', *(dbpath + ['common', '*.*']))):
+ env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['common'])), g))
+ for g in glob.glob(os.path.join('..', *(dbpath + ['lib', '*.*']))):
+ env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['lib'])), g))
+ for g in glob.glob(os.path.join('..', *(dbpath + ['html', '*.*']))):
+ env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['html'])), g))
+ for g in glob.glob(os.path.join('..', *(dbpath + ['fo', '*.*']))):
+ env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['fo'])), g))
+ for g in glob.glob(os.path.join('..', *(dbpath + ['manpages', '*.*']))):
+ env.Execute(Copy(os.path.join(build_dir, *(dbpath + ['manpages'])), g))
#
# Each document will live in its own subdirectory. List them here
- # as hash keys, with a hash of the info to control its build.
+ # by their subfolder names. Note, how the specifiers for each subdir
+ # have nothing to do with which formats get created...but which
+ # of the outputs get installed to the build folder and added to
+ # the different source and binary packages in the end.
#
- docs = {
- 'design' : {
- 'htmlindex' : 'book1.html',
- 'ps' : 1,
- 'pdf' : 1,
- 'text' : 0,
- },
- # 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,
- 'ps' : 1,
- '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' : 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,
- },
- }
-
+ docs = {'design' : ['chtml','pdf'],
+ #'python10' : ['chtml','html','pdf'],
+ 'reference' : ['chtml','html','pdf'],
+ #'developer' : ['chtml','html','pdf'],
+ 'user' : ['chtml','html','pdf'],
+ 'man' : ['man']
+ }
+ # The names of the target files for the MAN pages
+ man_page_list = ['scons.1','scons-time.1','sconsign.1']
+
#
# We have to tell SCons to scan the top-level XML files which
# get included by the document XML files in the subdirectories.
@@ -234,227 +194,96 @@ THIS IS AN AUTOMATICALLY-GENERATED FILE. DO NOT EDIT.
manifest = File('MANIFEST').rstr()
src_files = [x[:-1] for x in open(manifest).readlines()]
for s in src_files:
+ if not s:
+ continue
base, ext = os.path.splitext(s)
if ext in ['.fig', '.jpg']:
- orig_env.Install(build, s)
+ env.Execute(Copy(build, s))
else:
- orig_env.SCons_revision(os.path.join(build, s), s)
- Local(os.path.join(build, s))
+ revaction([env.File(os.path.join(build, s))],
+ [env.File(s)], env)
#
- # For each document, build the document itself in HTML, Postscript,
+ # For each document, build the document itself in HTML,
# and PDF formats.
#
- for doc in docs.keys():
+ for doc in docs:
+
+ #
+ # Read MANIFEST file and copy the listed files to the
+ # build directory, while branding them with the
+ # SCons copyright and the current revision number...
+ #
+ env.Execute(Mkdir(os.path.join(build, doc)))
+ env.Execute(Mkdir(os.path.join(build, doc, 'titlepage')))
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:
+ if not s:
+ continue
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)
+ if ext in ['.fig', '.jpg', '.svg']:
+ env.Execute(Copy(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'
-
- # 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)
-
+ revaction([env.File(build_s)],
+ [env.File(doc_s)], env)
+
+ #
+ # Call SCons in each local doc folder directly, such that
+ # we can Glob for the created *.html files afterwards to
+ # get the dependencies for the install targets right.
+ #
+ cleanopt = ''
+ if env.GetOption('clean'):
+ cleanopt = ' -c'
+ cmd = env.subst("cd %s && $PYTHON ${SCONS_PY.abspath}" % os.path.join(build, doc))+cleanopt
+ os.system(cmd)
+
+ # Collect the output files for this subfolder
htmldir = os.path.join(build, 'HTML', 'scons-%s' % doc)
- htmlindex = os.path.join(htmldir, docs[doc]['htmlindex'])
+ htmlindex = os.path.join(htmldir, 'index.html')
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 = [
- Delete("${TARGET.dir}/*.html"),
- "jw -b html -o ${TARGET.dir} $SOURCES",
- ]
- if tidy:
- cmds.append("tidy -m -q $TARGET || true")
- cmds.append(Action(copy_index_html))
- env.Command(htmlindex, File(main), cmds)
+ if 'chtml' in docs[doc]:
+ env.Install(htmldir, Glob(os.path.join(build, doc,'scons-%s' % doc, '*.html')))
+ tar_deps.extend([htmlindex])
+ tar_list.extend([htmldir])
Local(htmlindex)
+ env.Ignore(htmlindex, version_xml)
- cmds = [
- Delete("${TARGET.dir}/main.html"),
- "jw -u -b html -o ${TARGET.dir} $SOURCES",
- Move("$TARGET", "${TARGET.dir}/main.html"),
- ]
- if tidy:
- cmds.append("tidy -m -q $TARGET || true")
- env.Command(html, File(main), cmds)
+ if 'html' in docs[doc]:
+ env.InstallAs(html, os.path.join(build, doc,'index.html'))
+ tar_deps.extend([html])
+ tar_list.extend([html])
Local(html)
-
- env.Ignore([html, htmlindex], version_xml)
-
- tar_deps.extend([html, htmlindex])
- 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, [
- Delete("${TARGET.dir}/%s" % out),
- "jw -b ps -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
- "mv ${TARGET.dir}/main.ps $TARGET",
- Delete("${TARGET.dir}/%s" % out),
- ])
- Local(ps)
-
- env.Ignore(ps, version_xml)
-
- tar_deps.append(ps)
- 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, [
- Delete("${TARGET.dir}/%s" % out),
- "jw -b pdf -o ${TARGET.dir} -p %s $SOURCES" % jade_original,
- "mv ${TARGET.dir}/main.pdf $TARGET",
- Delete("${TARGET.dir}/out"),
- ])
+ env.Ignore(html, version_xml)
+
+ if 'pdf' in docs[doc]:
+ env.InstallAs(pdf, os.path.join(build, doc,'scons-%s.pdf' % doc))
Local(pdf)
-
env.Ignore(pdf, version_xml)
tar_deps.append(pdf)
tar_list.append(pdf)
+
+ if 'man' in docs[doc]:
+ #
+ # Man page(s)
+ #
+ for m in man_page_list:
+ man, _1 = os.path.splitext(m)
+
+ pdf = os.path.join(build, 'PDF', '%s-man.pdf' % man)
+ html = os.path.join(build, 'HTML' , '%s-man.html' % man)
+
+ env.InstallAs(pdf, os.path.join(build, 'man','scons-%s.pdf' % man))
+ env.InstallAs(html, os.path.join(build, 'man','scons-%s.html' % man))
+
+ tar_deps.extend([pdf, html])
+ tar_list.extend([pdf, html])
- if docs[doc].get('text') and jade and lynx:
- env.Command(text, html, "lynx -dump ${SOURCE.abspath} > $TARGET")
- Local(text)
-
- env.Ignore(text, version_xml)
-
- tar_deps.append(text)
- tar_list.append(text)
-
-#
-# Man page(s), in good ol' troff format.
-#
-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', 'functions.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]} -f ${TARGETS[1]} -t ${TARGETS[2]} -v ${TARGETS[3]} $( $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])
- else:
- print "doc: WARNING: no groff, skipping text and PostScript versions of man pages"
-
- 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)
- else:
- print "doc: WARNING: no man2html, skipping HTML versions of man pages"
if not epydoc_cli:
try: