summaryrefslogtreecommitdiffstats
path: root/Tools/gtk/generate-gtkdoc
blob: 7b981723f2245f38cffdf9f916239b24d660288d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#!/usr/bin/env python
# Copyright (C) 2011 Igalia S.L.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

import common
import glob
import gtkdoc
import logging
import os.path
import sys

def configure_logging():
    level = logging.DEBUG if '-v' in sys.argv else logging.INFO
    logger = logging.getLogger('gtkdoc')
    logger.setLevel(level)
    handler = logging.StreamHandler()
    handler.setLevel(level)
    logger.addHandler(handler)
    if level == logging.DEBUG:
        handler.setFormatter(logging.Formatter('[%(asctime)s]  %(message)s'))
    else:
        handler.setFormatter(logging.Formatter('%(message)s'))


def get_gtkdoc_module_paths(xref_dep_packages):
    deps = []
    html_dir = os.path.join('share', 'gtk-doc', 'html')

    for package in xref_dep_packages:
        prefix = common.prefix_of_pkg_config_file(package)
        if prefix is None:
            continue
        for module in xref_dep_packages[package]:
            deps.append(os.path.join(prefix, html_dir, module))

    return deps


def get_common_options():
    # TODO: We should consider using an arguments parsing library if
    # we need more of these complex ones.
    virtual_root = ''
    for argument in sys.argv:
        if argument.startswith('--virtual-root='):
            virtual_root = argument.split('=')[1]
            break

    return {
        'decorator': 'WEBKIT_API',
        'deprecation_guard': 'WEBKIT_DISABLE_DEPRECATED',
        'library_path' : common.build_path('.libs'),
        'virtual_root' : virtual_root,
    }

def get_common_xref_deps():
    return {
        'glib-2.0' : ['glib', 'gobject', 'gio'],
        'libsoup-2.4' : ['libsoup-2.4'],
        'gdk-pixbuf-2.0': ['gdk-pixbuf']
    }

def get_webkit2_options():
    def derived_sources_path(*args):
        return common.build_path(*(('DerivedSources', 'WebKit2') + args))
    def src_path(*args):
        return common.top_level_path(*(('Source', 'WebKit2', 'UIProcess', 'API', 'gtk') + args))
    def injected_bundle_src_path(*args):
        return common.top_level_path(*(('Source', 'WebKit2', 'WebProcess', 'InjectedBundle', 'API', 'gtk') + args))

    xref_deps = get_common_xref_deps().copy()
    xref_deps.update({
        'gtk+-3.0' : ['gtk3', 'gdk3']
    })

    options = get_common_options().copy()
    options.update({
        'module_name' : 'webkit2gtk',
        'doc_dir' : src_path('docs'),
        'output_dir' : common.build_path('Documentation', 'webkit2gtk'),
        'source_dirs' : [src_path(), derived_sources_path('webkit2gtk', 'webkit2'), injected_bundle_src_path()],
        'cflags' : ' -I' + derived_sources_path('webkit2gtk', 'include') + \
                   ' -I' + derived_sources_path('webkit2gtk') + \
                   ' -I' + derived_sources_path('include') + \
                   ' -I' + common.top_level_path('Source') + \
                   ' -I' + src_path(),
        'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
        'ignored_files': glob.glob(src_path('*Private.h')) + \
                         glob.glob(injected_bundle_src_path('*Private.h')) + \
                         glob.glob(src_path('*Client*')) + \
                         glob.glob(src_path('WebKitGeolocationProvider.*')) + \
                         glob.glob(src_path('WebKitTextChecker.*')) + \
                         glob.glob(src_path('WebKitAuthenticationDialog.*')) + \
                         glob.glob(src_path('WebKitWebViewBaseAccessible.*')) + \
                         glob.glob(src_path('WebViewBaseInputMethodFilter.*')) + \
                         glob.glob(derived_sources_path('webkit2gtk', 'webkit2', 'WebKitMarshal.*')) + \
                         glob.glob(derived_sources_path('webkit2gtk', 'webkit2', 'WebKitEnumTypes.*')) + \
                         glob.glob(src_path('tests/*.h'))
    })
    return options

def get_webkit1_options(gtk_version):
    def src_path(*args):
        return common.top_level_path(*(('Source', 'WebKit', 'gtk') + args))

    xref_deps = get_common_xref_deps().copy()
    if gtk_version == 3:
        xref_deps.update({
                'gtk+-3.0' : ['gtk3', 'gdk3']
        })
    else:
        xref_deps.update({
                'gtk+-2.0' : ['gtk', 'gdk']
        })

    options = get_common_options().copy()
    options.update({
        'module_name' : 'webkitgtk',
        'doc_dir' : src_path('docs'),
        'output_dir' : common.build_path('Documentation', 'webkitgtk'),
        'source_dirs' : [src_path('webkit'), common.build_path('Source', 'WebKit', 'gtk', 'webkit')],
        'cflags' : ' -I' + common.build_path('WebKit', 'gtk') + \
                   ' -I' + common.build_path('DerivedSources') + \
                   ' -I' + src_path() + \
                   ' -I' + common.top_level_path('Source') + \
                   ' -I' + common.top_level_path('Source', 'JavaScriptCore', 'ForwardingHeaders'),
        'cross_reference_deps' : get_gtkdoc_module_paths(xref_deps),
        'ignored_files': glob.glob(src_path('webkit', '*private.*')) + \
                         glob.glob(src_path('webkit', 'webkitauthenticationdialog.*')) + \
                         glob.glob(src_path('webkit', 'webkitspellcheckerenchant.*'))
    })
    return options

def print_missing_api(generator):
    missing_api = generator.api_missing_documentation()
    if not missing_api:
        return
    print("\nThe following API are missing documentation:")
    for api in missing_api:
        print("\t%s" % api)

def generate_doc(generator):
    generator.generate(html='--skip-html' not in sys.argv)
    if generator.saw_warnings:
        print_missing_api(generator)
    return generator.saw_warnings

configure_logging()

# We need to add the JavaScriptCore build directory to the PKG_CONFIG_PATH
# so that pkgconfig can properly resolve the libjavascriptcore dependency.
pkg_config_path = os.environ.get("PKG_CONFIG_PATH")
os.environ['PKG_CONFIG_PATH'] = common.build_path('Source', 'JavaScriptCore')
if pkg_config_path:
    os.environ['PKG_CONFIG_PATH'] += ':' + pkg_config_path

# Newer versions of glib have deprecated g_type_init, so we need to disable
# that warning when running gtkdoc-scanobj by overriding the CFLAGS we use
# to compile it.
cflags = os.environ.get('CFLAGS', '')
cflags += ' -DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_32'
os.environ['CFLAGS'] = cflags

# Clang can be noisy, throwing unnecessary warnings for unused arguments.
if os.environ.get('CC') == "clang":
    os.environ['CFLAGS'] += ' -Qunused-arguments'

saw_webkit1_warnings = saw_webkit2_warnings = False

pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkitgtk-3.0.pc')
if not os.path.exists(pkg_config_path):
    pkg_config_path = common.build_path('Source', 'WebKit', 'gtk', 'webkit-1.0.pc')
if os.path.exists(pkg_config_path):
    options = get_webkit1_options(common.gtk_version_of_pkg_config_file(pkg_config_path))
    generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, options)
    if '--rebase' not in sys.argv:
        print("Generating WebKit1 documentation...")
        saw_webkit1_warnings = generate_doc(generator)
    else:
        print("Rebasing WebKit1 documentation...")
        try:
            generator.rebase_installed_docs()
        except Exception:
            print("Rebase did not happen, likely no documentation is present.")

# WebKit2 might not be enabled, so check for the pkg-config file before building documentation.
pkg_config_path = common.build_path('Source', 'WebKit2', 'webkit2gtk-3.0.pc')
if os.path.exists(pkg_config_path):
    generator = gtkdoc.PkgConfigGTKDoc(pkg_config_path, get_webkit2_options())
    if '--rebase' not in sys.argv:
        print("\nGenerating WebKit2 documentation...")
        saw_webkit2_warnings = generate_doc(generator)
    else:
        print("\nRebasing WebKit2 documentation...")
        try:
            generator.rebase_installed_docs()
        except Exception:
            print("Rebase did not happen, likely no documentation is present.")

sys.exit(saw_webkit1_warnings or saw_webkit2_warnings)