summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2016-11-03 14:30:47 +1100
committerChris Johns <chrisj@rtems.org>2016-11-03 14:30:47 +1100
commit0bc9c6d3deb497b24debcaaefbab972c0ff2c6a8 (patch)
tree2e443277b0d549b7e5e4dd56cfa1b70c9869b417
parent3d055ece4e70f08f55ce40f49d0f022eac104bcd (diff)
downloadrtems-docs-0bc9c6d3deb497b24debcaaefbab972c0ff2c6a8.tar.bz2
waf: Have configure set building pdf and/or singlehtml.
Move selecting pdf and singlehtml to the configure stage so it is sticky for all builds. This means a top level build will always build all formats that have been configured. Do not complete the configure stage if tools are missing for the configured output. Add singlehtml support using the inliner tool. It is nice. Remove the groups as waf can track the dependences. This lets the manuals build in parallel.
-rw-r--r--common/waf.py453
1 files changed, 247 insertions, 206 deletions
diff --git a/common/waf.py b/common/waf.py
index 8782e16..2fda75c 100644
--- a/common/waf.py
+++ b/common/waf.py
@@ -1,240 +1,281 @@
import sys, os, re
from waflib.Build import BuildContext
-sphinx_min_version = (1,3)
-
+sphinx_min_version = (1, 3)
def cmd_spell(ctx):
- from waflib import Options
- from sys import argv
- from subprocess import call
-
- Options.commands = None # stop warnings about knowing commands.
+ from waflib import Options
+ from sys import argv
+ from subprocess import call
- if not ctx.env.BIN_ASPELL:
- ctx.fatal("'aspell' is required please add binary to your path and re-run configure.")
+ Options.commands = None # stop warnings about knowing commands.
- if len(argv) < 3:
- ctx.fatal("Please supply at least one file name")
+ if not ctx.env.BIN_ASPELL:
+ ctx.fatal("'aspell' is required please install and re-run configure.")
- files = argv[2:]
+ if len(argv) < 3:
+ ctx.fatal("Please supply at least one file name")
- path = ctx.path.parent.abspath()
+ files = argv[2:]
- # XXX: add error checking eg check if file exists.
- for file in files:
- cmd = ctx.env.BIN_ASPELL + ["-c", "--personal=%s/common/spell/dict/rtems" % path, "--extra-dicts=%s/common/spell/en_GB-ise-w_accents.multi" % path, file]
+ path = ctx.path.parent.abspath()
- print("running:", cmd)
- call(cmd)
+ # XXX: add error checking eg check if file exists.
+ for file in files:
+ cmd = ctx.env.BIN_ASPELL + \
+ ["-c",
+ "--personal=%s/common/spell/dict/rtems" % path,
+ "--extra-dicts=%s/common/spell/en_GB-ise-w_accents.multi" % path,
+ file]
+ print("running:", cmd)
+ call(cmd)
def cmd_linkcheck(ctx, conf_dir=".", source_dir="."):
- ctx(
- rule = "${BIN_SPHINX_BUILD} -b linkcheck -c %s -j %d -d build/doctrees %s build/linkcheck" % (conf_dir, ctx.options.jobs, source_dir),
- cwd = ctx.path.abspath(),
- source = ctx.path.ant_glob('**/*.rst'),
- target = "linkcheck/output.txt"
- )
-
+ ctx_rule = "${BIN_SPHINX_BUILD} -b linkcheck -c %s -j %d " + \
+ "-d build/doctrees %s build/linkcheck" % (conf_dir,
+ ctx.options.jobs,
+ source_dir)
+ ctx(
+ rule = ctx_rule,
+ cwd = ctx.path.abspath(),
+ source = ctx.path.ant_glob('**/*.rst'),
+ target = "linkcheck/output.txt"
+ )
class spell(BuildContext):
- __doc__ = "Check spelling. Supply a list of files or a glob (*.rst)"
- cmd = 'spell'
- fun = 'cmd_spell'
-
+ __doc__ = "Check spelling. Supply a list of files or a glob (*.rst)"
+ cmd = 'spell'
+ fun = 'cmd_spell'
class linkcheck(BuildContext):
- __doc__ = "Check all external URL references."
- cmd = 'linkcheck'
- fun = 'cmd_linkcheck'
-
+ __doc__ = "Check all external URL references."
+ cmd = 'linkcheck'
+ fun = 'cmd_linkcheck'
def check_sphinx_version(ctx, minver):
- version = ctx.cmd_and_log(ctx.env.BIN_SPHINX_BUILD + ['--version']).split(" ")[-1:][0].strip()
- try:
- ver = tuple(map(int, re.split('[\D]', version)))
- except:
- ctx.fatal("Sphinx version cannot be checked: %s" % version)
- if ver < minver:
- ctx.fatal("Sphinx version is too old: %s" % ".".join(map(str, ver)))
-
- return ver
+ version = ctx.cmd_and_log(ctx.env.BIN_SPHINX_BUILD +
+ ['--version']).split(" ")[-1:][0].strip()
+ try:
+ ver = tuple(map(int, re.split('[\D]', version)))
+ except:
+ ctx.fatal("Sphinx version cannot be checked: %s" % version)
+ if ver < minver:
+ ctx.fatal("Sphinx version is too old: %s" % ".".join(map(str, ver)))
+ return ver
def sphinx_verbose(ctx):
- return ' '.join(ctx.env.SPHINX_VERBOSE)
+ return ' '.join(ctx.env.SPHINX_VERBOSE)
+
+def is_top_build(ctx):
+ from_top = False
+ if ctx.env['BUILD_FROM_TOP'] and ctx.env['BUILD_FROM_TOP'] == 'yes':
+ from_top = True
+ return from_top
+
+def build_dir_setup(ctx, buildtype):
+ where = buildtype
+ if is_top_build(ctx):
+ where = os.path.join(ctx.path.name, where)
+ bnode = ctx.bldnode.find_node(where)
+ if bnode is None:
+ ctx.bldnode.make_node(where).mkdir()
+ build_dir = ctx.path.get_bld().relpath()
+ output_node = ctx.path.get_bld().make_node(buildtype)
+ output_dir = output_node.abspath()
+ return build_dir, output_node, output_dir
+
+def html_resources(ctx, buildtype):
+ for dir_name in ["_static", "_templates"]:
+ files = ctx.path.parent.find_node("common").ant_glob("%s/*" % dir_name)
+ fnode = ctx.path.get_bld().make_node(os.path.join(buildtype, dir_name))
+ fnode.mkdir() # dirs
+ ctx(
+ features = "subst",
+ is_copy = True,
+ source = files,
+ target = [fnode.make_node(x.name) for x in files]
+ )
+
+ # copy images
+# ctx.path.get_bld().make_node("images").mkdir()
+# files = ctx.path.parent.ant_glob("images/**")
+# ctx(
+# features = "subst",
+# is_copy = True,
+# source = files,
+# target = [x.srcpath().replace("../", "") for x in files]
+# )
def cmd_configure(ctx):
- ctx.load('tex')
-
- ctx.env.append_value('PDFLATEXFLAGS', '-shell-escape')
-
- ctx.find_program("sphinx-build", var="BIN_SPHINX_BUILD", mandatory=True)
- ctx.find_program("aspell", var="BIN_ASPELL", mandatory=False)
- ctx.find_program("inliner", var="BIN_INLINER", mandatory=False)
-
- ctx.start_msg("Checking if Sphinx is at least %s.%s" % sphinx_min_version)
- ver = check_sphinx_version(ctx, sphinx_min_version)
- ctx.end_msg("yes (%s)" % ".".join(map(str, ver)))
-
- ctx.start_msg("Sphinx Verbose: ")
- if 'SPHINX_VERBOSE' not in ctx.env:
- ctx.env.append_value('SPHINX_VERBOSE', ctx.options.sphinx_verbose)
- level = sphinx_verbose(ctx)
- if level == '-Q':
- level = 'quiet'
- ctx.end_msg(level)
-
-def html_resources(ctx):
- for dir_name in ["_static", "_templates"]:
- files = ctx.path.parent.find_node("common").ant_glob("%s/*" % dir_name)
- fnode = ctx.path.get_bld().make_node(os.path.join('html', dir_name))
- fnode.mkdir() # dirs
- ctx(
- features = "subst",
- is_copy = True,
- source = files,
- target = [fnode.make_node(x.name) for x in files]
- )
-
- # copy images
-# ctx.path.get_bld().make_node("images").mkdir()
-# files = ctx.path.parent.ant_glob("images/**")
-# ctx(
-# features = "subst",
-# is_copy = True,
-# source = files,
-# target = [x.srcpath().replace("../", "") for x in files]
-# )
+ ctx.find_program("sphinx-build", var="BIN_SPHINX_BUILD", mandatory = True)
+ ctx.find_program("aspell", var = "BIN_ASPELL", mandatory = False)
+
+ ctx.start_msg("Checking if Sphinx is at least %s.%s" % sphinx_min_version)
+ ver = check_sphinx_version(ctx, sphinx_min_version)
+ ctx.end_msg("yes (%s)" % ".".join(map(str, ver)))
+
+ ctx.start_msg("Sphinx Verbose: ")
+ if 'SPHINX_VERBOSE' not in ctx.env:
+ ctx.env.append_value('SPHINX_VERBOSE', ctx.options.sphinx_verbose)
+ level = sphinx_verbose(ctx)
+ if level == '-Q':
+ level = 'quiet'
+ ctx.end_msg(level)
+
+ #
+ # Optional builds.
+ #
+ ctx.env.BUILD_PDF = 'no'
+ if ctx.options.pdf:
+ ctx.env.BUILD_PDF = 'yes'
+ ctx.load('tex')
+ if not ctx.env.PDFLATEX or not ctx.env.MAKEINDEX:
+ ctx.fatal('The programs pdflatex and makeindex are required for PDF output')
+ if 'PDFLATEXFLAGS' not in ctx.env or \
+ '-shell-escape' not in ctx.env['PDFLATEXFLAGS']:
+ ctx.env.append_value('PDFLATEXFLAGS', '-shell-escape')
+
+ ctx.envBUILD_SINGLEHTML = 'no'
+ if ctx.options.singlehtml:
+ ctx.env.BUILD_SINGLEHTML = 'yes'
+ ctx.find_program("inliner", var = "BIN_INLINER", mandatory = False)
+ if not ctx.env.BIN_INLINER:
+ ctx.fatal("Node inliner is required install with 'npm install -g inliner' " +
+ "(https://github.com/remy/inliner)")
def doc_pdf(ctx, source_dir, conf_dir):
- if not ctx.env.PDFLATEX or not ctx.env.MAKEINDEX:
- ctx.fatal('The programs pdflatex and makeindex are required')
-
- build_dir = ctx.path.get_bld().relpath()
- output_node = ctx.path.get_bld().make_node('latex')
- output_dir = output_node.abspath()
-
- ctx(
- rule = "${BIN_SPHINX_BUILD} %s -b latex -c %s -d build/%s/doctrees %s %s" % (sphinx_verbose(ctx), conf_dir, build_dir, source_dir, output_dir),
- cwd = ctx.path,
- source = ctx.path.ant_glob('**/*.rst'),
- target = ctx.path.find_or_declare("latex/%s.tex" % (ctx.path.name))
- )
-
- ctx.add_group()
-
- ctx(
- features = 'tex',
- cwd = output_dir,
- type = 'pdflatex',
- source = "latex/%s.tex" % ctx.path.name,
- prompt = 0
- )
-
- ctx.install_files('${PREFIX}/%s' % (ctx.path.name),
- 'latex/%s.pdf' % (ctx.path.name),
- cwd = output_node,
- quiet = True)
+ buildtype = 'latex'
+ build_dir, output_node, output_dir = build_dir_setup(ctx, buildtype)
+ rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d build/%s/doctrees %s %s" % \
+ (sphinx_verbose(ctx), buildtype, conf_dir,
+ build_dir, source_dir, output_dir)
+ ctx(
+ rule = rule,
+ cwd = ctx.path,
+ source = ctx.path.ant_glob('**/*.rst'),
+ target = ctx.path.find_or_declare("%s/%s.tex" % (buildtype,
+ ctx.path.name))
+ )
+ ctx(
+ features = 'tex',
+ cwd = output_dir,
+ type = 'pdflatex',
+ source = "%s/%s.tex" % (buildtype, ctx.path.name),
+ prompt = 0
+ )
+ ctx.install_files('${PREFIX}',
+ '%s/%s.pdf' % (buildtype, ctx.path.name),
+ cwd = output_node,
+ quiet = True)
def doc_singlehtml(ctx, source_dir, conf_dir):
- if not ctx.env.BIN_INLINER:
- ctx.fatal("Node inliner is required install with 'npm install -g inliner' (https://github.com/remy/inliner)")
-
- html_resources(ctx)
-
- ctx(
- rule = "${BIN_SPHINX_BUILD} -b singlehtml -c %s -j %d -d build/doctrees %s build/singlehtml" % (conf_dir, ctx.options.jobs, source_dir),
- cwd = ctx.path.abspath(),
- source = ctx.path.ant_glob('**/*.rst'),
- target = "singlehtml/index.html",
- install_path = None
- )
-
- ctx.add_group()
- ctx(
- rule = "${BIN_INLINER} ${SRC} > ${TGT}",
- source = "singlehtml/index.html",
- target = "singlehtml/%s.html" % ctx.path.name,
- install_path = None
- )
+ #
+ # Use a run command to handle stdout and stderr output from inliner. Using
+ # a standard rule in the build context locks up.
+ #
+ def run(task):
+ src = task.inputs[0].abspath()
+ tgt = task.outputs[0].abspath()
+ cmd = '%s %s' % (task.env.BIN_INLINER[0], src)
+ so = open(tgt, 'w')
+ se = open(tgt + '.err', 'w')
+ r = task.exec_command(cmd, stdout = so, stderr = se)
+ so.close()
+ se.close()
+ #
+ # The inliner does not handle internal href's correctly and places the
+ # input's file name in the href. Strip these.
+ #
+ with open(tgt, 'r') as i:
+ before = i.read()
+ after = before.replace('index.html', '')
+ i.close()
+ with open(tgt, 'w') as o:
+ o.write(after)
+ o.close()
+ return r
+
+ buildtype = 'singlehtml'
+ build_dir, output_node, output_dir = build_dir_setup(ctx, buildtype)
+ html_resources(ctx, buildtype)
+ rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d build/%s/doctrees %s %s" % \
+ (sphinx_verbose(ctx), buildtype, conf_dir,
+ build_dir, source_dir, output_dir)
+ ctx(
+ rule = rule,
+ cwd = ctx.path,
+ source = ctx.path.ant_glob('**/*.rst'),
+ target = ctx.path.find_or_declare("%s/index.html" % (buildtype)),
+ install_path = None
+ )
+ ctx(
+ rule = run,
+ inliner = ctx.env.BIN_INLINER,
+ source = "%s/index.html" % buildtype,
+ target = "%s/%s.html" % (buildtype, ctx.path.name),
+ install_path = '${PREFIX}'
+ )
def doc_html(ctx, conf_dir, source_dir):
-
- html_resources(ctx)
-
- build_dir = ctx.path.get_bld().relpath()
- output_node = ctx.path.get_bld().make_node('html')
- output_dir = output_node.abspath()
-
- ctx(
- rule = "${BIN_SPHINX_BUILD} %s -b html -c %s -d build/%s/doctrees %s %s" % (sphinx_verbose(ctx), conf_dir, build_dir, source_dir, output_dir),
- cwd = ctx.path,
- source = ctx.path.ant_glob('**/*.rst'),# + ctx.path.ant_glob('conf.py'),
- target = ctx.path.find_or_declare('html/index.html'),
- install_path = None
- )
-
- ctx.install_files('${PREFIX}/%s' % (ctx.path.name),
- output_node.ant_glob('**/*'),
- cwd = output_node,
- relative_trick = True,
- quiet = True)
-
-def is_top_build(ctx):
- from_top = False
- if ctx.env['BUILD_FROM_TOP'] and ctx.env['BUILD_FROM_TOP'] == 'yes':
- from_top = True
- return from_top
-
-def build_type(ctx):
- build_type = 'html'
- if ctx.options.pdf:
- build_type = 'pdf'
- return build_type
-
-def build_dir_setup(ctx):
- btype = build_type(ctx)
- where = btype
- if is_top_build(ctx):
- where = os.path.join(ctx.path.name, where)
- bnode = ctx.bldnode.find_node(where)
- if bnode is None:
- ctx.bldnode.make_node(where).mkdir()
- return where
+ buildtype = 'html'
+ build_dir, output_node, output_dir = build_dir_setup(ctx, buildtype)
+ html_resources(ctx, buildtype)
+ rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d build/%s/doctrees %s %s" % \
+ (sphinx_verbose(ctx), buildtype, conf_dir,
+ build_dir, source_dir, output_dir)
+ ctx(
+ rule = rule,
+ cwd = ctx.path,
+ source = ctx.path.ant_glob('**/*.rst'),
+ target = ctx.path.find_or_declare('%s/index.html' % buildtype),
+ install_path = None
+ )
+ ctx.install_files('${PREFIX}/%s' % (ctx.path.name),
+ output_node.ant_glob('**/*', quiet = True),
+ cwd = output_node,
+ relative_trick = True,
+ quiet = True)
def cmd_build(ctx, conf_dir = ".", source_dir = "."):
- build_dir_setup(ctx)
+ srcnode = ctx.srcnode.abspath()
- srcnode = ctx.srcnode.abspath()
+ if ctx.env.BUILD_PDF == 'yes':
+ doc_pdf(ctx, source_dir, conf_dir)
- if ctx.options.pdf:
- doc_pdf(ctx, source_dir, conf_dir)
- elif ctx.options.singlehtml:
- html_resources(ctx)
- doc_singlehtml(ctx, source_dir, conf_dir)
- else:
- doc_html(ctx, source_dir, conf_dir)
+ if ctx.env.BUILD_SINGLEHTML == 'yes':
+ doc_singlehtml(ctx, source_dir, conf_dir)
-def cmd_options(ctx):
- ctx.add_option('--sphinx-verbose', action='store', default="-Q", help="Sphinx verbose.")
- ctx.add_option('--pdf', action='store_true', default=False, help="Build PDF.")
- ctx.add_option('--singlehtml', action='store_true', default=False, help="Build Single HTML file, requires Node Inliner")
+ doc_html(ctx, source_dir, conf_dir)
+def cmd_options(ctx):
+ ctx.add_option('--sphinx-verbose',
+ action = 'store',
+ default = "-Q",
+ help = "Sphinx verbose.")
+ ctx.add_option('--pdf',
+ action='store_true',
+ default = False,
+ help = "Build PDF.")
+ ctx.add_option('--singlehtml',
+ action='store_true',
+ default = False,
+ help = "Build Single HTML file, requires Node Inliner")
def cmd_options_path(ctx):
- cmd_options(ctx)
- ctx.add_option('--rtems-path-py', type='string', help="Full path to py/ in RTEMS source repository.")
-
+ cmd_options(ctx)
+ ctx.add_option('--rtems-path-py',
+ type = 'string',
+ help = "Full path to py/ in RTEMS source repository.")
def cmd_configure_path(ctx):
- if not ctx.options.rtems_path_py:
- ctx.fatal("--rtems-path-py is required")
+ if not ctx.options.rtems_path_py:
+ ctx.fatal("--rtems-path-py is required")
- ctx.env.RTEMS_PATH = ctx.options.rtems_path_py
+ ctx.env.RTEMS_PATH = ctx.options.rtems_path_py
- cmd_configure(ctx)
+ cmd_configure(ctx)
CONF_FRAG = """
@@ -244,22 +285,22 @@ templates_path = ['_templates']
html_static_path = ['_static']
"""
-
# XXX: fix this ugly hack. No time to waste on it.
def cmd_build_path(ctx):
- def run(task):
+ def run(task):
- with open("conf.py") as fp:
- conf = "import sys, os\nsys.path.append(os.path.abspath('../../common/'))\n"
- conf += fp.read()
+ with open("conf.py") as fp:
+ conf = "import sys, os\nsys.path.append(os.path.abspath('../../common/'))\n"
+ conf += fp.read()
- task.inputs[0].abspath()
- task.outputs[0].write(conf + (CONF_FRAG % ctx.env.RTEMS_PATH))
+ task.inputs[0].abspath()
+ task.outputs[0].write(conf + (CONF_FRAG % ctx.env.RTEMS_PATH))
- ctx(
- rule = run,
- source = [ctx.path.parent.find_node("common/conf.py"), ctx.path.find_node("./conf.py")],
- target = ctx.path.get_bld().make_node('conf.py')
+ ctx(
+ rule = run,
+ source = [ctx.path.parent.find_node("common/conf.py"),
+ ctx.path.find_node("./conf.py")],
+ target = ctx.path.get_bld().make_node('conf.py')
)
- cmd_build(ctx, conf_dir="build", source_dir="build")
+ cmd_build(ctx, conf_dir = "build", source_dir = "build")