conf.py 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
  1. # -*- coding: utf-8 -*-
  2. #
  3. # waf documentation build configuration file, created by
  4. # sphinx-quickstart on Sat Nov 6 20:46:09 2010.
  5. #
  6. # This file is execfile()d with the current directory set to its containing dir.
  7. #
  8. # Note that not all possible configuration values are present in this
  9. # autogenerated file.
  10. #
  11. # All configuration values have a default; values that are commented out
  12. # serve to show the default.
  13. import sys, os, re
  14. # If extensions (or modules to document with autodoc) are in another directory,
  15. # add these directories to sys.path here. If the directory is relative to the
  16. # documentation root, use os.path.abspath to make it absolute, like shown here.
  17. sys.path.insert(0, os.path.abspath(os.path.join('..', "..")))
  18. sys.path.append(os.path.abspath('.'))
  19. graphviz_output_format = 'svg'
  20. # monkey patch a few waf classes for documentation purposes!
  21. #-----------------------------------------------------------
  22. from waflib import TaskGen
  23. from waflib.TaskGen import task_gen, feats
  24. exclude_taskgen = []
  25. def taskgen_method(func):
  26. exclude_taskgen.append(func.__name__)
  27. setattr(task_gen, func.__name__, func)
  28. fix_fun_doc(func)
  29. return func
  30. taskgen_method.__doc__ = TaskGen.taskgen_method.__doc__
  31. TaskGen.taskgen_method = taskgen_method
  32. def extension(*k):
  33. def deco(func):
  34. exclude_taskgen.append(func.__name__)
  35. setattr(task_gen, func.__name__, func)
  36. for x in k:
  37. task_gen.mappings[x] = func
  38. return func
  39. return deco
  40. extension.__doc__ = TaskGen.extension.__doc__
  41. TaskGen.extension = extension
  42. def fix_fun_doc(fun):
  43. try:
  44. if not fun.__doc__.startswith('\tTask generator method'):
  45. fun.__doc__ = '\tTask generator method\n\t\n' + (fun.__doc__ or '')
  46. except Exception as e:
  47. print("Undocumented function %r (%r)" % (fun.__name__, e))
  48. fun.__doc__ = ""
  49. def fixmeth(x):
  50. if x == 'process_source':
  51. return ":py:func:`waflib.TaskGen.process_source`"
  52. if x == 'process_rule':
  53. return ":py:func:`waflib.TaskGen.process_rule`"
  54. return ":py:func:`%s`" % x
  55. def fixfeat(x):
  56. app = '../'
  57. if x in ('*', 'subst'):
  58. app = ''
  59. return "`%s <%sfeaturemap.html#feature%s>`_" % (x=='*' and 'all' or x, app, x!='*' and '-'+x or '')
  60. def append_doc(fun, keyword, meths):
  61. if keyword == "feature":
  62. meths = [fixfeat(x) for x in meths]
  63. else:
  64. meths = [fixmeth(x) for x in meths]
  65. dc = ", ".join(meths)
  66. fun.__doc__ += '\n\t:%s: %s' % (keyword, dc)
  67. def feature(*k):
  68. def deco(func):
  69. exclude_taskgen.append(func.__name__)
  70. setattr(task_gen, func.__name__, func)
  71. for name in k:
  72. feats[name].update([func.__name__])
  73. fix_fun_doc(func)
  74. append_doc(func, 'feature', k)
  75. #print "feature", name, k
  76. return func
  77. return deco
  78. feature.__doc__ = TaskGen.feature.__doc__
  79. TaskGen.feature = feature
  80. def before(*k):
  81. def deco(func):
  82. exclude_taskgen.append(func.__name__)
  83. setattr(task_gen, func.__name__, func)
  84. for fun_name in k:
  85. task_gen.prec[func.__name__].add(fun_name)
  86. fix_fun_doc(func)
  87. append_doc(func, 'before', k)
  88. return func
  89. return deco
  90. before.__doc__ = TaskGen.before.__doc__
  91. TaskGen.before = before
  92. def after(*k):
  93. def deco(func):
  94. exclude_taskgen.append(func.__name__)
  95. setattr(task_gen, func.__name__, func)
  96. for fun_name in k:
  97. task_gen.prec[fun_name].add(func.__name__)
  98. fix_fun_doc(func)
  99. append_doc(func, 'after', k)
  100. return func
  101. return deco
  102. after.__doc__ = TaskGen.after.__doc__
  103. TaskGen.after = after
  104. # replay existing methods
  105. TaskGen.taskgen_method(TaskGen.to_nodes)
  106. TaskGen.feature('*')(TaskGen.process_source)
  107. TaskGen.feature('*')(TaskGen.process_rule)
  108. TaskGen.before('process_source')(TaskGen.process_rule)
  109. TaskGen.feature('seq')(TaskGen.sequence_order)
  110. TaskGen.extension('.pc.in')(TaskGen.add_pcfile)
  111. TaskGen.feature('subst')(TaskGen.process_subst)
  112. TaskGen.before('process_source','process_rule')(TaskGen.process_subst)
  113. from waflib.Task import Task
  114. Task.__dict__['post_run'].__doc__ = "Update the cache files (executed by threads). Override in subclasses."
  115. from waflib import Configure, Build, Errors
  116. confmeths = []
  117. def conf(f):
  118. def fun(*k, **kw):
  119. mandatory = True
  120. if 'mandatory' in kw:
  121. mandatory = kw['mandatory']
  122. del kw['mandatory']
  123. try:
  124. return f(*k, **kw)
  125. except Errors.ConfigurationError as e:
  126. if mandatory:
  127. raise e
  128. confmeths.append(f.__name__)
  129. f.__doc__ = "\tConfiguration Method bound to :py:class:`waflib.Configure.ConfigurationContext`\n" + (f.__doc__ or '')
  130. setattr(Configure.ConfigurationContext, f.__name__, fun)
  131. setattr(Build.BuildContext, f.__name__, fun)
  132. return f
  133. conf.__doc__ = Configure.conf.__doc__
  134. Configure.conf = conf
  135. Configure.ConfigurationContext.__doc__ = """
  136. Configure the project.
  137. Waf tools may bind new methods to this class::
  138. from waflib.Configure import conf
  139. @conf
  140. def myhelper(self):
  141. print("myhelper")
  142. def configure(ctx):
  143. ctx.myhelper()
  144. """
  145. # Import all tools and build tool->feature map
  146. tool_to_features = {}
  147. import os
  148. lst = [x.replace('.py', '') for x in os.listdir('../../waflib/Tools/') if x.endswith('.py')]
  149. for x in lst:
  150. if x == '__init__':
  151. continue
  152. tool = __import__('waflib.Tools.%s' % x)
  153. mod = tool.__dict__['Tools'].__dict__[x]
  154. dc = mod.__all__ = list(mod.__dict__.keys())
  155. excl = ['before', 'after', 'feature', 'taskgen_method', 'extension']
  156. if x != 'ccroot':
  157. excl += ['link_task', 'stlink_task']
  158. for k in excl:
  159. try:
  160. dc.remove(k)
  161. except:
  162. pass
  163. thetool = getattr(tool.Tools, x)
  164. funcs = dir(thetool)
  165. for func_name in funcs:
  166. thefunc = getattr(TaskGen.task_gen, func_name, None)
  167. if getattr(thefunc, "__name__", None) is None: continue
  168. for feat in TaskGen.feats:
  169. funcs = list(TaskGen.feats[feat])
  170. if func_name in funcs:
  171. if x not in tool_to_features:
  172. tool_to_features[x] = []
  173. tool_to_features[x].append(feat)
  174. txt = ""
  175. txt += "%s\n%s\n\n.. automodule:: waflib.Tools.%s\n\n" % (x, "="*len(x), x)
  176. if x in tool_to_features:
  177. txt += "Features defined in this module:"
  178. for feat in sorted(list(set(tool_to_features[x]))):
  179. link = "../featuremap.html#feature-%s" % feat
  180. txt += "\n\n* `%s <%s>`_" % (feat, link)
  181. try: old = open("tools/%s.rst" % x, "r").read()
  182. except: old = None
  183. if old != txt:
  184. with open("tools/%s.rst" % x, "w") as f:
  185. f.write(txt)
  186. lst = list(TaskGen.feats.keys())
  187. lst.sort()
  188. accu = []
  189. for z in lst:
  190. meths = TaskGen.feats[z]
  191. links = []
  192. allmeths = set(TaskGen.feats[z])
  193. for x, lst in TaskGen.task_gen.prec.items():
  194. if x in meths:
  195. for y in lst:
  196. links.append((x, y))
  197. allmeths.add(y)
  198. else:
  199. for y in lst:
  200. if y in meths:
  201. links.append((x, y))
  202. allmeths.add(x)
  203. color = ',fillcolor="#fffea6",style=filled'
  204. ms = []
  205. for x in allmeths:
  206. try:
  207. m = TaskGen.task_gen.__dict__[x]
  208. except KeyError:
  209. raise ValueError("undefined method %r" % x)
  210. k = "%s.html#%s.%s" % (m.__module__.split('.')[-1], m.__module__, m.__name__)
  211. if str(m.__module__).find('.Tools') > 0:
  212. k = 'tools/' + k
  213. k = '../' + k
  214. ms.append('\t\t"%s" [style="setlinewidth(0.5)",URL="%s",target="_top",fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",height=0.25,shape="rectangle",fontsize=10%s];' % (x, k, x in TaskGen.feats[z] and color or ''))
  215. for x, y in links:
  216. ms.append('\t\t"%s" -> "%s" [arrowsize=0.5,style="setlinewidth(0.5)"];' % (x, y))
  217. rs = '\tdigraph feature_%s {\n\t\tsize="8.0, 12.0";\n%s\n\t}\n' % (z == '*' and 'all' or z, '\n'.join(ms))
  218. title = "Feature %s" % (z == '*' and '\\*' or z)
  219. title += "\n" + len(title) * '='
  220. accu.append("%s\n\n.. graphviz::\n\n%s\n\n" % (title, rs))
  221. f = open('featuremap.rst', 'w')
  222. f.write(""".. _featuremap:
  223. Feature reference
  224. =================
  225. .. include:: featuremap_example.txt
  226. """)
  227. f.write("\n".join(accu))
  228. f.close()
  229. # now for the configuration methods
  230. confmeths.extend('find_program find_file find_perl_program cmd_to_list add_os_flags check_waf_version'.split())
  231. confmeths.sort()
  232. confmeths_dict = {}
  233. accu = []
  234. lst = [x.replace('.py', '') for x in os.listdir('../../waflib/Tools/') if x.endswith('.py')]
  235. for x in lst:
  236. if x == '__init__':
  237. continue
  238. tool = __import__('waflib.Tools.%s' % x)
  239. mod = tool.__dict__['Tools'].__dict__[x]
  240. dc = mod.__all__ = list(mod.__dict__.keys())
  241. thetool = getattr(tool.Tools, x)
  242. funcs = dir(thetool)
  243. for func_name in funcs:
  244. thefunc = getattr(Configure.ConfigurationContext, func_name, None)
  245. if getattr(thefunc, "__name__", None) is None: continue
  246. if thefunc:
  247. confmeths_dict[func_name] = x
  248. for x in confmeths:
  249. modname = confmeths_dict.get(x, '')
  250. if modname:
  251. d = 'tools/%s.html' % modname
  252. modname = 'Tools.' + modname
  253. else:
  254. modname = 'Configure'
  255. d = '%s.html' % modname
  256. accu.append('.. _%s: %s#waflib.%s.%s\n' % (x, d, modname, x))
  257. accu.append('* %s_\n' % x)
  258. f = open('confmap.rst', 'w')
  259. f.write(""".. _confmap:
  260. Configuration methods
  261. =====================
  262. .. include:: confmap_example.txt
  263. """)
  264. f.write("\n".join(accu))
  265. f.close()
  266. #print("Path: %s" % sys.path)
  267. # -- General configuration -----------------------------------------------------
  268. # If your documentation needs a minimal Sphinx version, state it here.
  269. #needs_sphinx = '1.0'
  270. # Add any Sphinx extension module names here, as strings. They can be extensions
  271. # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
  272. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.imgmath', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.graphviz', 'sphinx.ext.viewcode']
  273. # Add any paths that contain templates here, relative to this directory.
  274. templates_path = ['_templates']
  275. # The suffix of source filenames.
  276. source_suffix = '.rst'
  277. # The encoding of source files.
  278. #source_encoding = 'utf-8-sig'
  279. # The master toctree document.
  280. master_doc = 'index'
  281. # General information about the project.
  282. project = u'Waf'
  283. copyright = u'2005-2018, Thomas Nagy'
  284. # The version info for the project you're documenting, acts as replacement for
  285. # |version| and |release|, also used in various other places throughout the
  286. # built documents.
  287. #
  288. # The short X.Y version.
  289. #version = '1.8.10'
  290. # The full version, including alpha/beta/rc tags.
  291. #release = version
  292. #
  293. with open('../../waflib/Context.py', 'r') as f:
  294. txt = f.read()
  295. m = re.compile('WAFVERSION=[\'"]([^\'"]+)', re.M).search(txt)
  296. version = release = m.group(1)
  297. # The language for content autogenerated by Sphinx. Refer to documentation
  298. # for a list of supported languages.
  299. #language = None
  300. # There are two options for replacing |today|: either, you set today to some
  301. # non-false value, then it is used:
  302. #today = ''
  303. # Else, today_fmt is used as the format for a strftime call.
  304. #today_fmt = '%B %d, %Y'
  305. # List of patterns, relative to source directory, that match files and
  306. # directories to ignore when looking for source files.
  307. exclude_patterns = []
  308. # The reST default role (used for this markup: `text`) to use for all documents.
  309. #default_role = None
  310. # If true, '()' will be appended to :func: etc. cross-reference text.
  311. #add_function_parentheses = True
  312. # If true, the current module name will be prepended to all description
  313. # unit titles (such as .. function::).
  314. #add_module_names = True
  315. # If true, sectionauthor and moduleauthor directives will be shown in the
  316. # output. They are ignored by default.
  317. #show_authors = False
  318. # The name of the Pygments (syntax highlighting) style to use.
  319. pygments_style = 'sphinx'
  320. # A list of ignored prefixes for module index sorting.
  321. #modindex_common_prefix = []
  322. # -- Options for HTML output ---------------------------------------------------
  323. # The theme to use for HTML and HTML Help pages. See the documentation for
  324. # a list of builtin themes.
  325. try:
  326. from sphinx import version_info
  327. except ImportError:
  328. version_info = None
  329. if version_info and (1, 3) <= version_info:
  330. html_theme = 'classic'
  331. else:
  332. html_theme = 'default'
  333. # Theme options are theme-specific and customize the look and feel of a theme
  334. # further. For a list of options available for each theme, see the
  335. # documentation.
  336. #html_theme_options = {}
  337. # Add any paths that contain custom themes here, relative to this directory.
  338. #html_theme_path = []
  339. # The name for this set of Sphinx documents. If None, it defaults to
  340. # "<project> v<release> API documentation".
  341. #html_title = None
  342. # A shorter title for the navigation bar. Default is the same as html_title.
  343. #html_short_title = None
  344. # The name of an image file (relative to this directory) to place at the top
  345. # of the sidebar.
  346. html_logo = '_images/waf-64x64.png'
  347. # The name of an image file (within the static path) to use as favicon of the
  348. # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
  349. # pixels large.
  350. #html_favicon = None
  351. # Add any paths that contain custom static files (such as style sheets) here,
  352. # relative to this directory. They are copied after the builtin static files,
  353. # so a file named "default.css" will overwrite the builtin "default.css".
  354. html_static_path = ['_static']
  355. # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
  356. # using the given strftime format.
  357. #html_last_updated_fmt = '%b %d, %Y'
  358. # If true, SmartyPants will be used to convert quotes and dashes to
  359. # typographically correct entities.
  360. #html_use_smartypants = True
  361. # Custom sidebar templates, maps document names to template names.
  362. #html_sidebars = {}
  363. # Additional templates that should be rendered to pages, maps page names to
  364. # template names.
  365. html_additional_pages = {'index':'indexcontent.html'}
  366. # If false, no module index is generated.
  367. #html_domain_indices = True
  368. # If false, no index is generated.
  369. #html_use_index = True
  370. # If true, the index is split into individual pages for each letter.
  371. #html_split_index = False
  372. # If true, links to the reST sources are added to the pages.
  373. #html_show_sourcelink = True
  374. # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
  375. html_show_sphinx = False
  376. # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
  377. #html_show_copyright = True
  378. # If true, an OpenSearch description file will be output, and all pages will
  379. # contain a <link> tag referring to it. The value of this option must be the
  380. # base URL from which the finished HTML is served.
  381. #html_use_opensearch = ''
  382. # This is the file name suffix for HTML files (e.g. ".xhtml").
  383. #html_file_suffix = None
  384. # Output file base name for HTML help builder.
  385. htmlhelp_basename = 'wafdoc'
  386. # -- Options for LaTeX output --------------------------------------------------
  387. latex_elements = {
  388. 'papersize':'a4paper',
  389. }
  390. # Grouping the document tree into LaTeX files. List of tuples
  391. # (source start file, target name, title, author, documentclass [howto/manual]).
  392. latex_documents = [
  393. ('index', 'waf.tex', u'waf Documentation',
  394. u'Thomas Nagy', 'manual'),
  395. ]
  396. # The name of an image file (relative to this directory) to place at the top of
  397. # the title page.
  398. #latex_logo = None
  399. # For "manual" documents, if this is true, then toplevel headings are parts,
  400. # not chapters.
  401. #latex_use_parts = False
  402. # If true, show page references after internal links.
  403. #latex_show_pagerefs = False
  404. # If true, show URL addresses after external links.
  405. #latex_show_urls = False
  406. # Additional stuff for the LaTeX preamble.
  407. #latex_preamble = ''
  408. # Documents to append as an appendix to all manuals.
  409. #latex_appendices = []
  410. # If false, no module index is generated.
  411. #latex_domain_indices = True
  412. # -- Options for manual page output --------------------------------------------
  413. # One entry per manual page. List of tuples
  414. # (source start file, name, description, authors, manual section).
  415. man_pages = [
  416. ('index', 'waf', u'waf Documentation',
  417. [u'Thomas Nagy'], 1)
  418. ]
  419. #autodoc_default_flags = ['members', 'no-undoc-members', 'show-inheritance']
  420. autodoc_default_flags = ['members', 'show-inheritance']
  421. autodoc_member_order = 'bysource'
  422. def maybe_skip_member(app, what, name, obj, skip, options):
  423. # from http://sphinx.pocoo.org/ext/autodoc.html#event-autodoc-skip-member
  424. # param name: the fully qualified name of the object <- it is not, the name does not contain the module path
  425. if name in ('__doc__', '__module__', 'Nod3', '__weakref__'):
  426. return True
  427. global exclude_taskgen
  428. if what == 'class' and name in exclude_taskgen:
  429. return True
  430. if obj.__doc__:
  431. return False
  432. def setup(app):
  433. app.connect('autodoc-skip-member', maybe_skip_member)