[PATCH wayland v3 3/4] meson: Run Doxygen on the Meson build
Daniel Stone
daniels at collabora.com
Sat Jul 21 15:31:23 UTC 2018
From: Emmanuele Bassi <ebassi at gnome.org>
Add a script which generates the desired Doxygen configuration for our
various output formats and executes it using that configuration.
This is currently broken as clean fails:
ninja: error: remove(doc/doxygen/man): Directory not empty
Cleaning... 92 files.
[daniels: Properly install into mandir/man3 via some gross
paramaterisation, generate real stamp files.]
Reviewed-by: Daniel Stone <daniels at collabora.com>
---
doc/doxygen/.gitignore | 1 +
doc/doxygen/gen-doxygen.py | 105 ++++++++++++++++++++++++++++++++
doc/doxygen/meson.build | 115 ++++++++++++++++++++++++++++++++++++
doc/doxygen/xml/meson.build | 18 ++++++
doc/meson.build | 6 +-
5 files changed, 240 insertions(+), 5 deletions(-)
create mode 100755 doc/doxygen/gen-doxygen.py
create mode 100644 doc/doxygen/meson.build
create mode 100644 doc/doxygen/xml/meson.build
diff --git a/doc/doxygen/.gitignore b/doc/doxygen/.gitignore
index a85e6c0d..5c544d6c 100644
--- a/doc/doxygen/.gitignore
+++ b/doc/doxygen/.gitignore
@@ -2,3 +2,4 @@ doxygen_sqlite3.db
html/
wayland.doxygen
xml/
+!xml/meson.build
diff --git a/doc/doxygen/gen-doxygen.py b/doc/doxygen/gen-doxygen.py
new file mode 100755
index 00000000..1bb07e57
--- /dev/null
+++ b/doc/doxygen/gen-doxygen.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+import argparse
+import datetime
+import errno
+import os
+import subprocess
+import sys
+
+# Custom configuration for each documentation format
+doxygen_templates = {
+ 'xml': [
+ 'GENERATE_XML=YES\n',
+ 'XML_OUTPUT={format}/{section}\n',
+ 'INPUT= {files}\n',
+ ],
+ 'html': [
+ 'GENERATE_HTML=YES\n',
+ 'HTML_OUTPUT={format}/{section}\n',
+ 'PROJECT_NAME=\"Wayland {section} API\"\n',
+ 'INPUT= {files}\n',
+ ],
+ 'man': [
+ 'GENERATE_MAN=YES\n',
+ 'MAN_OUTPUT={format}\n',
+ 'MAN_SUBDIR=.\n',
+ 'JAVADOC_AUTOBRIEF=NO\n',
+ 'INPUT= {files}\n',
+ ],
+}
+
+def load_doxygen_file(doxyfile):
+ with open(doxyfile, 'r') as f:
+ res = f.readlines()
+ return res
+
+def get_template(outformat):
+ for (k,v) in doxygen_templates.items():
+ if outformat.startswith(k):
+ return v
+
+def gen_doxygen_file(data, outformat, section, files):
+ for l in get_template(outformat):
+ data.append(l.format(format=outformat, section=section, files=' '.join(files)))
+ return data
+
+parser = argparse.ArgumentParser(description='Generate docs with Doxygen')
+parser.add_argument('doxygen_file',
+ help='The doxygen file to use')
+parser.add_argument('files',
+ help='The list of files to parse',
+ metavar='FILES',
+ nargs='+')
+parser.add_argument('--builddir',
+ help='The build directory',
+ metavar='DIR',
+ default='.')
+parser.add_argument('--section',
+ help='The section to build',
+ metavar='NAME',
+ default='Client')
+parser.add_argument('--output-format',
+ help='The output format: xml, html, man',
+ metavar='FORMAT',
+ default='xml')
+parser.add_argument('--stamp',
+ help='Stamp file to output',
+ metavar='STAMP_FILE',
+ nargs='?',
+ type=argparse.FileType('w'))
+
+args = parser.parse_args()
+
+# Merge the doxyfile with our custom templates
+conf = load_doxygen_file(args.doxygen_file)
+conf = gen_doxygen_file(conf, args.output_format, args.section, args.files)
+
+# Doxygen is not clever enough to create the directories it
+# needs beforehand
+try:
+ os.makedirs(os.path.join(args.builddir, args.output_format))
+except OSError as e:
+ if e.errno != errno.EEXIST:
+ raise e
+
+# Run Doxygen with the generated doxyfile
+cmd = subprocess.Popen(['doxygen', '-'], stdin=subprocess.PIPE)
+cmd.stdin.write(''.join(conf).encode('utf-8'))
+cmd.stdin.close()
+if cmd.wait() != 0:
+ sys.exit(1)
+
+# This is a bit of a hack; Doxygen will generate way more files than we
+# want to install, but there's no way to know how many at configuration
+# time. Since we want to install only the wl_* man pages anyway, we can
+# delete the other files and let Meson install the whole man3 subdirectory
+if args.output_format.startswith('man'):
+ manpath = os.path.join(args.builddir, args.output_format)
+ for filename in os.listdir(manpath):
+ full_path = os.path.join(manpath, filename)
+ if not filename.startswith('wl_'):
+ os.remove(full_path)
+
+if args.stamp:
+ args.stamp.write(str(datetime.datetime.now()))
diff --git a/doc/doxygen/meson.build b/doc/doxygen/meson.build
new file mode 100644
index 00000000..d5ec6dc0
--- /dev/null
+++ b/doc/doxygen/meson.build
@@ -0,0 +1,115 @@
+# Here be dragons
+doxygen = find_program('doxygen')
+
+dot = find_program('dot')
+dot_gv = [
+ [ 'wayland-architecture', files('dot/wayland-architecture.gv') ],
+ [ 'x-architecture', files('dot/x-architecture.gv') ],
+]
+
+# This is a workaround for Meson's custom_target() directive, which
+# currently does not support outputs pointing to a sub-directory
+dot_png = []
+dot_map = []
+subdir('xml')
+
+doxygen = configuration_data()
+doxygen.set('VERSION', meson.project_version())
+doxygen.set('top_builddir', meson.build_root())
+wayland_doxygen = configure_file(
+ input: 'wayland.doxygen.in',
+ output: 'wayland.doxygen',
+ configuration: doxygen,
+)
+
+shared_files = files([
+ '../../src/wayland-util.h',
+])
+
+client_files = files([
+ '../../src/wayland-client.c',
+ '../../src/wayland-client.h',
+ '../../src/wayland-client-core.h',
+])
+
+server_files = files([
+ '../../src/event-loop.c',
+ '../../src/wayland-server.c',
+ '../../src/wayland-server.h',
+ '../../src/wayland-server-core.h',
+ '../../src/wayland-shm.c',
+])
+
+extra_client_files = [
+ 'mainpage.dox',
+ get_variable('wayland_client_protocol_h'),
+]
+
+extra_server_files = [
+ 'mainpage.dox',
+ get_variable('wayland_server_protocol_h'),
+]
+
+# formats = [ format_name, [ [ section_name, files ] ] ]
+formats = [
+ [
+ 'xml', [
+ [ 'Client', shared_files + client_files, ],
+ [ 'Server', shared_files + server_files, ],
+ ]
+ ],
+ [
+ 'html', [
+ [ 'Client', shared_files + client_files + extra_client_files, ],
+ [ 'Server', shared_files + server_files + extra_server_files, ],
+ ]
+ ],
+]
+
+gen_doxygen = find_program('gen-doxygen.py')
+foreach f: formats
+ f_name = f[0]
+ sections = f[1]
+
+ foreach s: sections
+ s_name = s[0]
+ s_files = s[1]
+ t_name = '@0 at -@1 at -doc'.format(f_name, s_name)
+
+ # We do not really need an output file, but Meson
+ # will complain if one is not set, so we use a
+ # dummy 'stamp' file
+ custom_target(t_name,
+ command: [
+ gen_doxygen,
+ '--builddir=@OUTDIR@',
+ '--section=@0@'.format(s_name),
+ '--output-format=@0@'.format(f_name),
+ '--stamp=doc/doxygen/@0 at .stamp'.format(t_name),
+ wayland_doxygen,
+ '@INPUT@',
+ ],
+ input: s_files,
+ output: '@0 at .stamp'.format(t_name),
+ depends: [dot_png, dot_map],
+ build_by_default: true,
+ )
+ endforeach
+endforeach
+
+man_files = shared_files + client_files + server_files
+custom_target('man-pages-3',
+ command: [
+ gen_doxygen,
+ '--builddir=@OUTDIR@',
+ '--output-format=man3',
+ '--stamp=doc/doxygen/man3.stamp',
+ wayland_doxygen,
+ '@INPUT@',
+ ],
+ input: man_files,
+ output: 'man3',
+ build_by_default: true,
+ install: true,
+ install_dir: join_paths(get_option('prefix'), get_option('mandir')),
+)
diff --git a/doc/doxygen/xml/meson.build b/doc/doxygen/xml/meson.build
new file mode 100644
index 00000000..58826c51
--- /dev/null
+++ b/doc/doxygen/xml/meson.build
@@ -0,0 +1,18 @@
+# dot_png: list of PNG targets
+# dot_map: list of MAP targets
+foreach gv: dot_gv
+ name = gv[0]
+ infile = gv[1]
+
+ dot_png += custom_target(name + '.png',
+ command: [ dot, '-Tpng', '-o at OUTPUT@', '@INPUT@' ],
+ input: infile,
+ output: name + '.png',
+ )
+
+ dot_map += custom_target(name + '.map',
+ command: [ dot, '-Tcmapx_np', '-o at OUTPUT@', '@INPUT@' ],
+ input: infile,
+ output: name + '.map',
+ )
+endforeach
diff --git a/doc/meson.build b/doc/meson.build
index 8c743fe9..f05c57b3 100644
--- a/doc/meson.build
+++ b/doc/meson.build
@@ -1,5 +1 @@
-xsltproc = find_program('xsltproc', required: false)
-doxygen = find_program('doxygen')
-xmlto = find_program('xmlto')
-dot = find_program('dot')
-
+subdir('doxygen')
--
2.17.1
More information about the wayland-devel
mailing list