source: rtems-docs/common/waf.py @ 9024cfb

4.115
Last change on this file since 9024cfb was 9024cfb, checked in by Chris Johns <chrisj@…>, on 11/03/16 at 21:44:37

waf: Fix the bnode issue when building in a manual directory.

  • Property mode set to 100644
File size: 10.3 KB
Line 
1import sys, os, re
2from waflib.Build import BuildContext
3
4sphinx_min_version = (1, 3)
5
6def cmd_spell(ctx):
7    from waflib import Options
8    from sys import argv
9    from subprocess import call
10
11    Options.commands = None # stop warnings about knowing commands.
12
13    if not ctx.env.BIN_ASPELL:
14        ctx.fatal("'aspell' is required please install and re-run configure.")
15
16    if len(argv) < 3:
17        ctx.fatal("Please supply at least one file name")
18
19    files = argv[2:]
20
21    path = ctx.path.parent.abspath()
22
23    # XXX: add error checking eg check if file exists.
24    for file in files:
25        cmd = ctx.env.BIN_ASPELL + \
26              ["-c",
27               "--personal=%s/common/spell/dict/rtems" % path,
28               "--extra-dicts=%s/common/spell/en_GB-ise-w_accents.multi" % path,
29               file]
30        print("running:", cmd)
31        call(cmd)
32
33
34def cmd_linkcheck(ctx, conf_dir=".", source_dir="."):
35    ctx_rule = "${BIN_SPHINX_BUILD} -b linkcheck -c %s -j %d " + \
36               "-d build/doctrees %s build/linkcheck" % (conf_dir,
37                                                         ctx.options.jobs,
38                                                             source_dir)
39    ctx(
40        rule   = ctx_rule,
41        cwd    = ctx.path.abspath(),
42        source = ctx.path.ant_glob('**/*.rst'),
43        target = "linkcheck/output.txt"
44    )
45
46class spell(BuildContext):
47    __doc__ = "Check spelling.  Supply a list of files or a glob (*.rst)"
48    cmd = 'spell'
49    fun = 'cmd_spell'
50
51class linkcheck(BuildContext):
52    __doc__ = "Check all external URL references."
53    cmd = 'linkcheck'
54    fun = 'cmd_linkcheck'
55
56def check_sphinx_version(ctx, minver):
57    version = ctx.cmd_and_log(ctx.env.BIN_SPHINX_BUILD +
58                              ['--version']).split(" ")[-1:][0].strip()
59    try:
60        ver = tuple(map(int, re.split('[\D]', version)))
61    except:
62        ctx.fatal("Sphinx version cannot be checked: %s" % version)
63    if ver < minver:
64        ctx.fatal("Sphinx version is too old: %s" % ".".join(map(str, ver)))
65    return ver
66
67def sphinx_verbose(ctx):
68    return ' '.join(ctx.env.SPHINX_VERBOSE)
69
70def is_top_build(ctx):
71    from_top = False
72    if ctx.env['BUILD_FROM_TOP'] and ctx.env['BUILD_FROM_TOP'] == 'yes':
73        from_top = True
74    return from_top
75
76def build_dir_setup(ctx, buildtype):
77    where = buildtype
78    if is_top_build(ctx):
79        where = os.path.join(ctx.path.name, where)
80    bnode = ctx.bldnode.find_node(where)
81    if bnode is None:
82        ctx.bldnode.make_node(where).mkdir()
83    build_dir = ctx.path.get_bld().relpath()
84    output_node = ctx.path.get_bld().make_node(buildtype)
85    output_dir = output_node.abspath()
86    doctrees = os.path.join(os.path.dirname(output_dir), 'doctrees', buildtype)
87    return build_dir, output_node, output_dir, doctrees
88
89def html_resources(ctx, buildtype):
90    for dir_name in ["_static", "_templates"]:
91        files = ctx.path.parent.find_node("common").ant_glob("%s/*" % dir_name)
92        fnode = ctx.path.get_bld().make_node(os.path.join(buildtype, dir_name))
93        fnode.mkdir() # dirs
94        ctx(
95            features = "subst",
96            is_copy  = True,
97            source   = files,
98            target   = [fnode.make_node(x.name) for x in files]
99        )
100
101    # copy images
102#    ctx.path.get_bld().make_node("images").mkdir()
103#    files = ctx.path.parent.ant_glob("images/**")
104#    ctx(
105#        features    = "subst",
106#        is_copy     = True,
107#        source      = files,
108#        target      = [x.srcpath().replace("../", "") for x in files]
109#    )
110
111def cmd_configure(ctx):
112    ctx.find_program("sphinx-build", var="BIN_SPHINX_BUILD", mandatory = True)
113    ctx.find_program("aspell", var = "BIN_ASPELL", mandatory = False)
114
115    ctx.start_msg("Checking if Sphinx is at least %s.%s" % sphinx_min_version)
116    ver = check_sphinx_version(ctx, sphinx_min_version)
117    ctx.end_msg("yes (%s)" % ".".join(map(str, ver)))
118
119    ctx.start_msg("Sphinx Verbose: ")
120    if 'SPHINX_VERBOSE' not in ctx.env:
121        ctx.env.append_value('SPHINX_VERBOSE', ctx.options.sphinx_verbose)
122    level = sphinx_verbose(ctx)
123    if level == '-Q':
124        level = 'quiet'
125    ctx.end_msg(level)
126
127    #
128    # Optional builds.
129    #
130    ctx.env.BUILD_PDF = 'no'
131    if ctx.options.pdf:
132        ctx.env.BUILD_PDF = 'yes'
133        ctx.load('tex')
134        if not ctx.env.PDFLATEX or not ctx.env.MAKEINDEX:
135            ctx.fatal('The programs pdflatex and makeindex are required for PDF output')
136        if 'PDFLATEXFLAGS' not in ctx.env or \
137           '-shell-escape' not in ctx.env['PDFLATEXFLAGS']:
138            ctx.env.append_value('PDFLATEXFLAGS', '-shell-escape')
139
140    ctx.envBUILD_SINGLEHTML = 'no'
141    if ctx.options.singlehtml:
142        ctx.env.BUILD_SINGLEHTML = 'yes'
143        ctx.find_program("inliner", var = "BIN_INLINER", mandatory = False)
144        if not ctx.env.BIN_INLINER:
145            ctx.fatal("Node inliner is required install with 'npm install -g inliner' " +
146                      "(https://github.com/remy/inliner)")
147
148def doc_pdf(ctx, source_dir, conf_dir):
149    buildtype = 'latex'
150    build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
151    rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
152           (sphinx_verbose(ctx), buildtype, conf_dir,
153            doctrees, source_dir, output_dir)
154    ctx(
155        rule         = rule,
156        cwd          = ctx.path,
157        source       = ctx.path.ant_glob('**/*.rst'),
158        target       = ctx.path.find_or_declare("%s/%s.tex" % (buildtype,
159                                                               ctx.path.name))
160    )
161    ctx(
162        features     = 'tex',
163        cwd          = output_dir,
164        type         = 'pdflatex',
165        source       = "%s/%s.tex" % (buildtype, ctx.path.name),
166        prompt       = 0
167    )
168    ctx.install_files('${PREFIX}',
169                      '%s/%s.pdf' % (buildtype, ctx.path.name),
170                      cwd = output_node,
171                      quiet = True)
172
173def doc_singlehtml(ctx, source_dir, conf_dir):
174
175    #
176    # Use a run command to handle stdout and stderr output from inliner. Using
177    # a standard rule in the build context locks up.
178    #
179    def run(task):
180        src = task.inputs[0].abspath()
181        tgt = task.outputs[0].abspath()
182        cmd = '%s %s' % (task.env.BIN_INLINER[0], src)
183        so = open(tgt, 'w')
184        se = open(tgt + '.err', 'w')
185        r = task.exec_command(cmd, stdout = so, stderr = se)
186        so.close()
187        se.close()
188        #
189        # The inliner does not handle internal href's correctly and places the
190        # input's file name in the href. Strip these.
191        #
192        with open(tgt, 'r') as i:
193            before = i.read()
194            after = before.replace('index.html', '')
195        i.close()
196        with open(tgt, 'w') as o:
197            o.write(after)
198        o.close()
199        return r
200
201    buildtype = 'singlehtml'
202    build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
203    html_resources(ctx, buildtype)
204    rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
205           (sphinx_verbose(ctx), buildtype, conf_dir,
206            doctrees, source_dir, output_dir)
207    ctx(
208        rule         = rule,
209        cwd          = ctx.path,
210        source       = ctx.path.ant_glob('**/*.rst'),
211        target       = ctx.path.find_or_declare("%s/index.html" % (buildtype)),
212        install_path = None
213    )
214    ctx(
215        rule         = run,
216        inliner      = ctx.env.BIN_INLINER,
217        source       = "%s/index.html" % buildtype,
218        target       = "%s/%s.html" % (buildtype, ctx.path.name),
219        install_path = '${PREFIX}'
220    )
221
222def doc_html(ctx, conf_dir, source_dir):
223    buildtype = 'html'
224    build_dir, output_node, output_dir, doctrees = build_dir_setup(ctx, buildtype)
225    html_resources(ctx, buildtype)
226    rule = "${BIN_SPHINX_BUILD} %s -b %s -c %s -d %s %s %s" % \
227           (sphinx_verbose(ctx), buildtype, conf_dir,
228            doctrees, source_dir, output_dir)
229    ctx(
230        rule         = rule,
231        cwd          = ctx.path,
232        source       = ctx.path.ant_glob('**/*.rst'),
233        target       = ctx.path.find_or_declare('%s/index.html' % buildtype),
234        install_path = None
235    )
236    ctx.install_files('${PREFIX}/%s' % (ctx.path.name),
237                      output_node.ant_glob('**/*', quiet = True),
238                      cwd = output_node,
239                      relative_trick = True,
240                      quiet = True)
241
242def cmd_build(ctx, conf_dir = ".", source_dir = "."):
243    srcnode = ctx.srcnode.abspath()
244
245    if ctx.env.BUILD_PDF == 'yes':
246        doc_pdf(ctx, source_dir, conf_dir)
247
248    if ctx.env.BUILD_SINGLEHTML == 'yes':
249        doc_singlehtml(ctx, source_dir, conf_dir)
250
251    doc_html(ctx, source_dir, conf_dir)
252
253def cmd_options(ctx):
254    ctx.add_option('--sphinx-verbose',
255                   action = 'store',
256                   default = "-Q",
257                   help = "Sphinx verbose.")
258    ctx.add_option('--pdf',
259                   action='store_true',
260                   default = False,
261                   help = "Build PDF.")
262    ctx.add_option('--singlehtml',
263                   action='store_true',
264                   default = False,
265                   help = "Build Single HTML file, requires Node Inliner")
266
267def cmd_options_path(ctx):
268    cmd_options(ctx)
269    ctx.add_option('--rtems-path-py',
270                   type = 'string',
271                   help = "Full path to py/ in RTEMS source repository.")
272
273def cmd_configure_path(ctx):
274    if not ctx.options.rtems_path_py:
275        ctx.fatal("--rtems-path-py is required")
276
277    ctx.env.RTEMS_PATH = ctx.options.rtems_path_py
278
279    cmd_configure(ctx)
280
281
282CONF_FRAG = """
283sys.path.append(os.path.abspath('../../common/'))
284sys.path.append('%s')
285templates_path = ['_templates']
286html_static_path = ['_static']
287"""
288
289# XXX: fix this ugly hack.  No time to waste on it.
290def cmd_build_path(ctx):
291    def run(task):
292
293        with open("conf.py") as fp:
294            conf = "import sys, os\nsys.path.append(os.path.abspath('../../common/'))\n"
295            conf += fp.read()
296
297        task.inputs[0].abspath()
298        task.outputs[0].write(conf + (CONF_FRAG % ctx.env.RTEMS_PATH))
299
300    ctx(
301        rule   = run,
302        source = [ctx.path.parent.find_node("common/conf.py"),
303                  ctx.path.find_node("./conf.py")],
304        target = ctx.path.get_bld().make_node('conf.py')
305    )
306
307    cmd_build(ctx, conf_dir = "build", source_dir = "build")
Note: See TracBrowser for help on using the repository browser.