Unreviewed, rolling out r163530.
[WebKit-https.git] / Tools / gtk / generate-gtkdoc
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
18 import common
19 import glob
20 import gtkdoc
21 import logging
22 import os.path
23 import sys
24
25 def configure_logging():
26     level = logging.DEBUG if '-v' in sys.argv else logging.INFO
27     logger = logging.getLogger('gtkdoc')
28     logger.setLevel(level)
29     handler = logging.StreamHandler()
30     handler.setLevel(level)
31     logger.addHandler(handler)
32     if level == logging.DEBUG:
33         handler.setFormatter(logging.Formatter('[%(asctime)s]  %(message)s'))
34     else:
35         handler.setFormatter(logging.Formatter('%(message)s'))
36
37
38 def get_gtkdoc_module_paths(xref_dep_packages):
39     deps = []
40     html_dir = os.path.join('share', 'gtk-doc', 'html')
41
42     for package in xref_dep_packages:
43         prefix = common.prefix_of_pkg_config_file(package)
44         if prefix is None:
45             continue
46         for module in xref_dep_packages[package]:
47             deps.append(os.path.join(prefix, html_dir, module))
48
49     return deps
50
51
52 def get_common_options():
53     # TODO: We should consider using an arguments parsing library if
54     # we need more of these complex ones.
55     virtual_root = ''
56     for argument in sys.argv:
57         if argument.startswith('--virtual-root='):
58             virtual_root = argument.split('=')[1]
59             break
60
61     return {
62         'decorator': 'WEBKIT_API|WEBKIT_DEPRECATED|WEBKIT_DEPRECATED_FOR\(.+\)',
63         'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
64         'library_path' : common.library_build_path(),
65         'virtual_root' : virtual_root,
66     }
67
68 def get_common_xref_deps():
69     return {
70         'glib-2.0' : ['glib', 'gobject', 'gio'],
71         'libsoup-2.4' : ['libsoup-2.4'],
72         'gdk-pixbuf-2.0': ['gdk-pixbuf']
73     }
74
75 def webkitdom_docs_html_path():
76     return common.build_path('Documentation', 'webkitdomgtk', 'html')
77
78 def get_webkit2_options():
79     api_path = common.top_level_path('Source', 'WebKit2', 'UIProcess', 'API', 'gtk')
80     injected_bundle_api_path = common.top_level_path('Source', 'WebKit2', 'WebProcess', 'InjectedBundle', 'API', 'gtk')
81
82     if common.is_cmake_build():
83         generated_api_path = common.build_path('DerivedSources', 'webkit2gtk', 'webkit2')
84     else:
85         generated_api_path = common.build_path('DerivedSources', 'WebKit2', 'webkit2gtk', 'webkit2')
86
87     xref_deps = get_common_xref_deps().copy()
88     xref_deps.update({
89         'gtk+-3.0' : ['gtk3', 'gdk3']
90     })
91
92     def src_path(*args):
93         return os.path.join(api_path, *args)
94
95     options = get_common_options().copy()
96     options.update({
97         'module_name' : 'webkit2gtk',
98         'namespace' : 'webkit',
99         'doc_dir' : src_path('docs'),
100         'output_dir' : common.build_path('Documentation', 'webkit2gtk'),
101         'source_dirs' : [src_path(), generated_api_path, injected_bundle_api_path],
102         'cflags' :
103             # Common paths
104             ' -I' + common.top_level_path('Source') + \
105             ' -I' + api_path + \
106             # Autotools paths
107             ' -I' + common.build_path('DerivedSources', 'webkit2gtk', 'include') + \
108             ' -I' + common.build_path('DerivedSources', 'WebKit2', 'webkit2gtk') + \
109             # CMake paths
110             ' -I' + common.build_path('DerivedSources', 'ForwardingHeaders', 'webkit2gtk') + \
111             ' -I' + common.build_path('DerivedSources', 'webkit2gtk'),
112         'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps) + [webkitdom_docs_html_path()],
113         'ignored_files': glob.glob(src_path('*Private.h')) + \
114                          glob.glob(os.path.join(injected_bundle_api_path, '*Private.h')) + \
115                          glob.glob(src_path('*Client*')) + \
116                          glob.glob(src_path('WebKitAuthenticationDialog.*')) + \
117                          glob.glob(src_path('WebKitBatteryProvider.*')) + \
118                          glob.glob(src_path('WebKitGeolocationProvider.*')) + \
119                          glob.glob(src_path('WebKitTextChecker.*')) + \
120                          glob.glob(src_path('WebKitWebViewBaseAccessible.*')) + \
121                          glob.glob(src_path('WebViewBaseInputMethodFilter.*')) + \
122                          glob.glob(os.path.join(generated_api_path, 'WebKitMarshal.*')) + \
123                          glob.glob(os.path.join(generated_api_path, 'WebKitEnumTypes.*')) + \
124                          glob.glob(src_path('tests/*.h'))
125     })
126     return options
127
128 def get_webkit1_options(gtk_version):
129     def src_path(*args):
130         return common.top_level_path(*(('Source', 'WebKit', 'gtk') + args))
131
132     def webkitversionh_path():
133         if common.is_cmake_build():
134             return common.build_path('DerivedSources', 'webkitgtk')
135         else:
136             return common.build_path('Source', 'WebKit', 'gtk', 'webkit')
137
138     xref_deps = get_common_xref_deps().copy()
139     if gtk_version == 3:
140         xref_deps.update({
141                 'gtk+-3.0' : ['gtk3', 'gdk3']
142         })
143     else:
144         xref_deps.update({
145                 'gtk+-2.0' : ['gtk', 'gdk']
146         })
147
148     options = get_common_options().copy()
149     options.update({
150         'module_name' : 'webkitgtk',
151         'namespace' : 'webkit',
152         'doc_dir' : src_path('docs'),
153         'output_dir' : common.build_path('Documentation', 'webkitgtk'),
154         'source_dirs' : [src_path('webkit'), webkitversionh_path()],
155         'cflags' : ' -I' + common.build_path('WebKit', 'gtk') + \
156                    ' -I' + common.build_path('DerivedSources') + \
157                    ' -I' + src_path() + \
158                    ' -I' + common.top_level_path('Source') + \
159                    ' -I' + common.top_level_path('Source', 'JavaScriptCore', 'ForwardingHeaders'),
160         'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps) + [webkitdom_docs_html_path()],
161         'ignored_files': glob.glob(src_path('webkit', '*private.*')) + \
162                          glob.glob(src_path('webkit', 'webkitauthenticationdialog.*')) + \
163                          glob.glob(src_path('webkit', 'webkitspellcheckerenchant.*'))
164     })
165     return options
166
167 def get_webkitdom_options():
168     def derived_sources_path(*args):
169         return common.build_path(*(('DerivedSources', 'webkitdom') + args))
170     def src_path(*args):
171         return common.top_level_path(*(('Source', 'WebCore', 'bindings', 'gobject') + args))
172
173     xref_deps = { 'glib-2.0' : ['glib', 'gobject', 'gio'] }
174
175     options = get_common_options().copy()
176     options.update({
177         'module_name' : 'webkitdomgtk',
178         'namespace' : 'webkit_dom',
179         'doc_dir' : derived_sources_path('docs'),
180         'output_dir' : common.build_path('Documentation', 'webkitdomgtk'),
181         'source_dirs' : [derived_sources_path()],
182         'cflags' : ' -I' + derived_sources_path() + \
183                    ' -I' + src_path() + \
184                    ' -I' + common.top_level_path('Source'),
185         'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
186         'ignored_files': glob.glob(derived_sources_path('*Private.h'))
187     })
188     return options
189
190 def print_missing_api(generator):
191     missing_api = generator.api_missing_documentation()
192     if not missing_api:
193         return
194     print("\nThe following API are missing documentation:")
195     for api in missing_api:
196         print("\t%s" % api)
197
198 def generate_doc(generator):
199     generator.generate(html='--skip-html' not in sys.argv)
200     if generator.saw_warnings:
201         print_missing_api(generator)
202     return generator.saw_warnings
203
204 configure_logging()
205
206 # We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
207 # so that pkgconfig can properly resolve the libjavascriptcore dependency.
208 pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
209 os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
210 if pkg_config_path:
211     os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path
212
213 # Newer versions of glib have deprecated g_type_init, so we need to disable
214 # that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
215 # to compile it.
216 cflags = os.environ.get('CFLAGS', '')
217 cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'
218 os.environ['CFLAGS'] = cflags
219
220 # Clang can be noisy, throwing unnecessary warnings for unused arguments.
221 if os.environ.get('CC') == "clang":
222     os.environ['CFLAGS'] += ' -Qunused-arguments'
223
224 saw_webkit1_warnings = saw_webkit2_warnings = False
225 wk2_pkg_config_path = common.build_path('Source', 'WebKit2', 'webkit2gtk-3.0.pc')
226 wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkitgtk-3.0.pc')
227 if not os.path.exists(wk1_pkg_config_path):
228     wk1_pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkit-1.0.pc')
229
230 if os.path.exists(wk2_pkg_config_path):
231     pkg_config_path = wk2_pkg_config_path
232 elif os.path.exists(wk1_pkg_config_path):
233     pkg_config_path = wk1_pkg_config_path
234
235 webkitdom_docs_path = common.build_path('DerivedSources', 'webkitdom', 'docs')
236 if not common.is_cmake_build():
237     generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkitdom_options())
238     if '--rebase' not in sys.argv:
239         print("\nGenerating WebKitDOM documentation...")
240         saw_webkitdom_warnings = generate_doc(generator)
241     else:
242         print("\nRebasing WebKitDOM documentation...")
243         try:
244             generator.rebase_installed_docs()
245         except Exception:
246             print("Rebase did not happen, likely no documentation is present.")
247
248 pkg_config_path = wk1_pkg_config_path
249 if os.path.exists(pkg_config_path):
250     options = get_webkit1_options(common.gtk_version_of_pkg_config_file(pkg_config_path))
251     generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, options)
252     if '--rebase' not in sys.argv:
253         print("Generating WebKit1 documentation...")
254         saw_webkit1_warnings = generate_doc(generator)
255     else:
256         print("Rebasing WebKit1 documentation...")
257         try:
258             generator.rebase_installed_docs()
259         except Exception:
260             print("Rebase did not happen, likely no documentation is present.")
261
262 # WebKit2 might not be enabled, so check for the pkg-config file before building documentation.
263 pkg_config_path = wk2_pkg_config_path
264 if os.path.exists(pkg_config_path):
265     generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkit2_options())
266     if '--rebase' not in sys.argv:
267         print("\nGenerating WebKit2 documentation...")
268         saw_webkit2_warnings = generate_doc(generator)
269     else:
270         print("\nRebasing WebKit2 documentation...")
271         try:
272             generator.rebase_installed_docs()
273         except Exception:
274             print("Rebase did not happen, likely no documentation is present.")
275
276 # For CMake we are still generating warnings because we lack DOM bindings docs,
277 # so do not cause the build to fail for now.
278 if not common.is_cmake_build():
279     sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)