generate-gtkdoc 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #!/usr/bin/env python
  2. # Copyright (C) 2011 Igalia S.L.
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. import common
  18. import glob
  19. import gtkdoc
  20. import logging
  21. import os.path
  22. import sys
  23. def configure_logging():
  24. level = logging.DEBUG if '-v' in sys.argv else logging.INFO
  25. logger = logging.getLogger('gtkdoc')
  26. logger.setLevel(level)
  27. handler = logging.StreamHandler()
  28. handler.setLevel(level)
  29. logger.addHandler(handler)
  30. if level == logging.DEBUG:
  31. handler.setFormatter(logging.Formatter('[%(asctime)s] %(message)s'))
  32. else:
  33. handler.setFormatter(logging.Formatter('%(message)s'))
  34. def get_gtkdoc_module_paths(xref_dep_packages):
  35. deps = []
  36. html_dir = os.path.join('share', 'gtk-doc', 'html')
  37. for package in xref_dep_packages:
  38. prefix = common.prefix_of_pkg_config_file(package)
  39. if prefix is None:
  40. continue
  41. for module in xref_dep_packages[package]:
  42. deps.append(os.path.join(prefix, html_dir, module))
  43. return deps
  44. def get_common_options():
  45. # TODO: We should consider using an arguments parsing library if
  46. # we need more of these complex ones.
  47. virtual_root = ''
  48. for argument in sys.argv:
  49. if argument.startswith('--virtual-root='):
  50. virtual_root = argument.split('=')[1]
  51. break
  52. return {
  53. 'decorator': 'WEBKIT_API',
  54. 'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
  55. 'library_path' : common.build_path('.libs'),
  56. 'virtual_root' : virtual_root,
  57. }
  58. def get_common_xref_deps():
  59. return {
  60. 'glib-2.0' : ['glib', 'gobject', 'gio'],
  61. 'libsoup-2.4' : ['libsoup-2.4'],
  62. 'gdk-pixbuf-2.0': ['gdk-pixbuf']
  63. }
  64. def get_webkit2_options():
  65. def derived_sources_path(*args):
  66. return common.build_path(*(('DerivedSources', 'WebKit2') + args))
  67. def src_path(*args):
  68. return common.top_level_path(*(('Source', 'WebKit2', 'UIProcess', 'API', 'gtk') + args))
  69. def injected_bundle_src_path(*args):
  70. return common.top_level_path(*(('Source', 'WebKit2', 'WebProcess', 'InjectedBundle', 'API', 'gtk') + args))
  71. xref_deps = get_common_xref_deps().copy()
  72. xref_deps.update({
  73. 'gtk+-3.0' : ['gtk3', 'gdk3']
  74. })
  75. options = get_common_options().copy()
  76. options.update({
  77. 'module_name' : 'webkit2gtk',
  78. 'doc_dir' : src_path('docs'),
  79. 'output_dir' : common.build_path('Documentation', 'webkit2gtk'),
  80. 'source_dirs' : [src_path(), derived_sources_path('webkit2gtk', 'webkit2'), injected_bundle_src_path()],
  81. 'cflags' : ' -I' + derived_sources_path('webkit2gtk', 'include') + \
  82. ' -I' + derived_sources_path('webkit2gtk') + \
  83. ' -I' + derived_sources_path('include') + \
  84. ' -I' + common.top_level_path('Source') + \
  85. ' -I' + src_path(),
  86. 'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
  87. 'ignored_files': glob.glob(src_path('*Private.h')) + \
  88. glob.glob(injected_bundle_src_path('*Private.h')) + \
  89. glob.glob(src_path('*Client*')) + \
  90. glob.glob(src_path('WebKitGeolocationProvider.*')) + \
  91. glob.glob(src_path('WebKitTextChecker.*')) + \
  92. glob.glob(src_path('WebKitAuthenticationDialog.*')) + \
  93. glob.glob(src_path('WebKitWebViewBaseAccessible.*')) + \
  94. glob.glob(src_path('WebViewBaseInputMethodFilter.*')) + \
  95. glob.glob(derived_sources_path('webkit2gtk', 'webkit2', 'WebKitMarshal.*')) + \
  96. glob.glob(derived_sources_path('webkit2gtk', 'webkit2', 'WebKitEnumTypes.*')) + \
  97. glob.glob(src_path('tests/*.h'))
  98. })
  99. return options
  100. def get_webkit1_options(gtk_version):
  101. def src_path(*args):
  102. return common.top_level_path(*(('Source', 'WebKit', 'gtk') + args))
  103. xref_deps = get_common_xref_deps().copy()
  104. if gtk_version == 3:
  105. xref_deps.update({
  106. 'gtk+-3.0' : ['gtk3', 'gdk3']
  107. })
  108. else:
  109. xref_deps.update({
  110. 'gtk+-2.0' : ['gtk', 'gdk']
  111. })
  112. options = get_common_options().copy()
  113. options.update({
  114. 'module_name' : 'webkitgtk',
  115. 'doc_dir' : src_path('docs'),
  116. 'output_dir' : common.build_path('Documentation', 'webkitgtk'),
  117. 'source_dirs' : [src_path('webkit'), common.build_path('Source', 'WebKit', 'gtk', 'webkit')],
  118. 'cflags' : ' -I' + common.build_path('WebKit', 'gtk') + \
  119. ' -I' + common.build_path('DerivedSources') + \
  120. ' -I' + src_path() + \
  121. ' -I' + common.top_level_path('Source') + \
  122. ' -I' + common.top_level_path('Source', 'JavaScriptCore', 'ForwardingHeaders'),
  123. 'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
  124. 'ignored_files': glob.glob(src_path('webkit', '*private.*')) + \
  125. glob.glob(src_path('webkit', 'webkitauthenticationdialog.*')) + \
  126. glob.glob(src_path('webkit', 'webkitspellcheckerenchant.*'))
  127. })
  128. return options
  129. def print_missing_api(generator):
  130. missing_api = generator.api_missing_documentation()
  131. if not missing_api:
  132. return
  133. print("\nThe following API are missing documentation:")
  134. for api in missing_api:
  135. print("\t%s" % api)
  136. def generate_doc(generator):
  137. generator.generate(html='--skip-html' not in sys.argv)
  138. if generator.saw_warnings:
  139. print_missing_api(generator)
  140. return generator.saw_warnings
  141. configure_logging()
  142. # We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
  143. # so that pkgconfig can properly resolve the libjavascriptcore dependency.
  144. pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
  145. os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
  146. if pkg_config_path:
  147. os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path
  148. # Newer versions of glib have deprecated g_type_init, so we need to disable
  149. # that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
  150. # to compile it.
  151. cflags = os.environ.get('CFLAGS', '')
  152. cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'
  153. os.environ['CFLAGS'] = cflags
  154. # Clang can be noisy, throwing unnecessary warnings for unused arguments.
  155. if os.environ.get('CC') == "clang":
  156. os.environ['CFLAGS'] += ' -Qunused-arguments'
  157. saw_webkit1_warnings = saw_webkit2_warnings = False
  158. pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkitgtk-3.0.pc')
  159. if not os.path.exists(pkg_config_path):
  160. pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkit-1.0.pc')
  161. if os.path.exists(pkg_config_path):
  162. options = get_webkit1_options(common.gtk_version_of_pkg_config_file(pkg_config_path))
  163. generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, options)
  164. if '--rebase' not in sys.argv:
  165. print("Generating WebKit1 documentation...")
  166. saw_webkit1_warnings = generate_doc(generator)
  167. else:
  168. print("Rebasing WebKit1 documentation...")
  169. try:
  170. generator.rebase_installed_docs()
  171. except Exception:
  172. print("Rebase did not happen, likely no documentation is present.")
  173. # WebKit2 might not be enabled, so check for the pkg-config file before building documentation.
  174. pkg_config_path = common.build_path('Source', 'WebKit2', 'webkit2gtk-3.0.pc')
  175. if os.path.exists(pkg_config_path):
  176. generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkit2_options())
  177. if '--rebase' not in sys.argv:
  178. print("\nGenerating WebKit2 documentation...")
  179. saw_webkit2_warnings = generate_doc(generator)
  180. else:
  181. print("\nRebasing WebKit2 documentation...")
  182. try:
  183. generator.rebase_installed_docs()
  184. except Exception:
  185. print("Rebase did not happen, likely no documentation is present.")
  186. sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)