blob: f538977dd12d4e9926333b67f2162a736d7123d1 [file] [log] [blame]
Alexander Afanasyev1160baa2014-04-10 18:50:29 -07001# inspired by code by Hans-Martin von Gaudecker, 2012
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -08002
Davide Pesaventoac537892024-03-11 20:30:08 -04003"""Support for Sphinx documentation"""
4
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -08005import os
Davide Pesaventob62f9522024-03-11 17:50:53 -04006from waflib import Node, Task, TaskGen, Utils
7
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -08008
Alexander Afanasyev1160baa2014-04-10 18:50:29 -07009class sphinx_build(Task.Task):
10 color = 'BLUE'
Alexander Afanasyeva06fdda2014-04-29 19:15:00 -070011 run_str = '${SPHINX_BUILD} -D ${VERSION} -D ${RELEASE} -q -b ${BUILDERNAME} -d ${DOCTREEDIR} ${SRCDIR} ${OUTDIR}'
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080012
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070013 def __str__(self):
14 env = self.env
Alexander Afanasyev8b1674a2014-05-15 00:58:43 -070015 src_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.inputs])
16 tgt_str = ' '.join([a.path_from(a.ctx.launch_node()) for a in self.outputs])
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070017 if self.outputs: sep = ' -> '
18 else: sep = ''
19 return'%s [%s]: %s%s%s\n'%(self.__class__.__name__.replace('_task',''),
20 self.env['BUILDERNAME'], src_str, sep, tgt_str)
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080021
Davide Pesaventob62f9522024-03-11 17:50:53 -040022
23# from https://docs.python.org/3.12/whatsnew/3.12.html#imp
24def load_source(modname, filename):
25 import importlib.util
26 from importlib.machinery import SourceFileLoader
27 loader = SourceFileLoader(modname, filename)
28 spec = importlib.util.spec_from_file_location(modname, filename, loader=loader)
29 module = importlib.util.module_from_spec(spec)
30 loader.exec_module(module)
31 return module
32
33
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070034@TaskGen.extension('.py', '.rst')
35def sig_hook(self, node):
36 node.sig=Utils.h_file(node.abspath())
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080037
Davide Pesaventob62f9522024-03-11 17:50:53 -040038
Davide Pesaventoac537892024-03-11 20:30:08 -040039@TaskGen.feature('sphinx')
40@TaskGen.before_method('process_source')
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070041def apply_sphinx(self):
42 """Set up the task generator with a Sphinx instance and create a task."""
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080043
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070044 inputs = []
45 for i in Utils.to_list(self.source):
46 if not isinstance(i, Node.Node):
47 node = self.path.find_node(node)
48 else:
49 node = i
50 if not node:
51 raise ValueError('[%s] file not found' % i)
52 inputs.append(node)
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080053
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070054 task = self.create_task('sphinx_build', inputs)
Alexander Afanasyev5e1288e2014-03-28 11:11:48 -070055
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070056 conf = self.path.find_node(self.config)
57 task.inputs.append(conf)
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080058
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070059 confdir = conf.parent.abspath()
Davide Pesaventob310efb2019-04-11 22:10:24 -040060 buildername = getattr(self, 'builder', 'html')
61 srcdir = getattr(self, 'srcdir', confdir)
62 outdir = self.path.find_or_declare(getattr(self, 'outdir', buildername)).get_bld()
63 doctreedir = getattr(self, 'doctreedir', os.path.join(outdir.abspath(), '.doctrees'))
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080064
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070065 task.env['BUILDERNAME'] = buildername
66 task.env['SRCDIR'] = srcdir
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070067 task.env['OUTDIR'] = outdir.abspath()
Davide Pesaventob62f9522024-03-11 17:50:53 -040068 task.env['DOCTREEDIR'] = doctreedir
Davide Pesaventob310efb2019-04-11 22:10:24 -040069 task.env['VERSION'] = 'version=%s' % self.version
70 task.env['RELEASE'] = 'release=%s' % getattr(self, 'release', self.version)
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080071
Davide Pesaventob310efb2019-04-11 22:10:24 -040072 if buildername == 'man':
Davide Pesaventob62f9522024-03-11 17:50:53 -040073 confdata = load_source('sphinx_conf', conf.abspath())
74 for i in confdata.man_pages:
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070075 target = outdir.find_or_declare('%s.%d' % (i[1], i[4]))
76 task.outputs.append(target)
Alexander Afanasyeva1ae0a12014-01-28 15:21:02 -080077
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070078 if self.install_path:
Davide Pesaventob310efb2019-04-11 22:10:24 -040079 self.bld.install_files('%s/man%d/' % (self.install_path, i[4]), target)
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070080 else:
81 task.outputs.append(outdir)
82
Davide Pesaventob62f9522024-03-11 17:50:53 -040083
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070084def configure(conf):
Davide Pesaventoac537892024-03-11 20:30:08 -040085 """Check if sphinx-build program is available."""
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070086 conf.find_program('sphinx-build', var='SPHINX_BUILD', mandatory=False)
Alexander Afanasyev5e1288e2014-03-28 11:11:48 -070087
Davide Pesaventob62f9522024-03-11 17:50:53 -040088
Davide Pesaventoac537892024-03-11 20:30:08 -040089# sphinx command
Alexander Afanasyev5e1288e2014-03-28 11:11:48 -070090from waflib.Build import BuildContext
Alexander Afanasyev1160baa2014-04-10 18:50:29 -070091class sphinx(BuildContext):
Davide Pesaventoac537892024-03-11 20:30:08 -040092 cmd = 'sphinx'
93 fun = 'sphinx'