Skip to content

Commit ba34638

Browse files
committed
meson: Add xmllint/xsltproc wrapper script to handle dependencies automatically
1 parent e2c068a commit ba34638

File tree

2 files changed

+88
-10
lines changed

2 files changed

+88
-10
lines changed

doc/src/sgml/meson.build

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ docs = []
22
alldocs = []
33
doc_generated = []
44

5-
xmllint = find_program(get_option('XMLLINT'), native: true, required: false)
5+
xmllint_bin = find_program(get_option('XMLLINT'), native: true, required: false)
66

77

88
version_sgml = configure_file(
@@ -60,21 +60,31 @@ doc_generated += custom_target('keywords-table.sgml',
6060
)
6161

6262
# For everything else we need at least xmllint
63-
if not xmllint.found()
63+
if not xmllint_bin.found()
6464
subdir_done()
6565
endif
6666

6767
pandoc = find_program('pandoc', native: true, required: false)
68-
xsltproc = find_program(get_option('XSLTPROC'), native: true, required: false)
68+
xsltproc_bin = find_program(get_option('XSLTPROC'), native: true, required: false)
6969
fop = find_program('fop', native: true, required: false)
7070

71+
xmltools_wrapper = [
72+
python, files('xmltools_dep_wrapper'),
73+
'--targetname', '@OUTPUT@', '--depfile', '@DEPFILE@'
74+
]
75+
76+
xmllint = xmltools_wrapper + [
77+
'--tool', xmllint_bin, '--',
78+
]
79+
7180
# Run validation only once, common to all subsequent targets. While
7281
# we're at it, also resolve all entities (that is, copy all included
7382
# files into one big file). This helps tools that don't understand
7483
# vpath builds (such as dbtoepub).
7584
postgres_full_xml = custom_target('postgres-full.xml',
7685
input: 'postgres.sgml',
7786
output: 'postgres-full.xml',
87+
depfile: 'postgres-full.xml.d',
7888
command: [xmllint, '--noent', '--valid', '--path', '@OUTDIR@', '-o', '@OUTPUT@', '@INPUT@'],
7989
depends: doc_generated,
8090
build_by_default: false,
@@ -86,18 +96,20 @@ alldocs += postgres_full_xml
8696
#
8797
# Full documentation as html, text
8898
#
89-
if xsltproc.found()
99+
if xsltproc_bin.found()
90100
xsltproc_flags = [
91101
'--stringparam', 'pg.version', pg_version,
92102
'--param', 'website.stylesheet', '1'
93103
]
94104

105+
xsltproc = xmltools_wrapper + [
106+
'--tool', xsltproc_bin, '--',
107+
]
95108

96-
# FIXME: Should use a wrapper around xsltproc --load-trace to compute a
97-
# depfile
98109
html = custom_target('html',
99110
input: ['stylesheet.xsl', postgres_full_xml],
100111
output: 'html',
112+
depfile: 'html.d',
101113
depends: doc_generated,
102114
command: [xsltproc, '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
103115
build_by_default: false,
@@ -110,6 +122,7 @@ if xsltproc.found()
110122
html_help = custom_target('html_help',
111123
input: ['stylesheet-hh.xsl', postgres_full_xml],
112124
output: 'htmlhelp',
125+
depfile: 'htmlhelp.d',
113126
depends: doc_generated,
114127
command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
115128
build_by_default: false,
@@ -121,6 +134,7 @@ if xsltproc.found()
121134
postgres_html = custom_target('postgres.html',
122135
input: ['stylesheet-html-nochunk.xsl', postgres_full_xml],
123136
output: 'postgres.html',
137+
depfile: 'postgres.html.d',
124138
depends: doc_generated,
125139
command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '@INPUT@'],
126140
build_by_default: false,
@@ -144,17 +158,19 @@ endif
144158
#
145159
# INSTALL in html, text
146160
#
147-
if xsltproc.found()
161+
if xsltproc_bin.found()
148162
install_xml = custom_target('INSTALL.xml',
149163
input: ['standalone-profile.xsl', 'standalone-install.xml'],
150164
output: 'INSTALL.xml',
165+
depfile: 'INSTALL.xml.d',
151166
depends: doc_generated + [postgres_full_xml],
152167
command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '--xinclude', '@INPUT@'],
153168
build_by_default: false,
154169
)
155170
install_html = custom_target('INSTALL.html',
156171
input: ['stylesheet-text.xsl', install_xml],
157172
output: 'INSTALL.html',
173+
depfile: 'INSTALL.html.d',
158174
command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTPUT@', xsltproc_flags, '@INPUT@'],
159175
build_by_default: false,
160176
)
@@ -177,11 +193,12 @@ endif
177193
#
178194
# Man pages
179195
#
180-
if xsltproc.found()
196+
if xsltproc_bin.found()
181197
# FIXME: implement / consider sqlmansectnum logic
182198
man = custom_target('man',
183199
input: ['stylesheet-man.xsl', postgres_full_xml],
184200
output: ['man1', 'man3', 'man7'],
201+
depfile: 'man.d',
185202
depends: doc_generated,
186203
command: [xsltproc, '--path', '@OUTDIR@', '-o', '@OUTDIR@/', xsltproc_flags, '@INPUT@'],
187204
build_by_default: false,
@@ -195,7 +212,7 @@ endif
195212
#
196213
# Full documentation as PDF
197214
#
198-
if fop.found() and xsltproc.found()
215+
if fop.found() and xsltproc_bin.found()
199216
xsltproc_fo_flags = xsltproc_flags + ['--stringparam', 'img.src.path', meson.current_source_dir() + '/']
200217

201218
foreach format, detail: {'A4': 'A4', 'US': 'USletter'}
@@ -206,6 +223,7 @@ if fop.found() and xsltproc.found()
206223
input: ['stylesheet-fo.xsl', postgres_full_xml],
207224
output: [postgres_x_fo_f],
208225
depends: doc_generated,
226+
depfile: postgres_x_fo_f + '.d',
209227
command: [xsltproc, '--path', '@OUTDIR@/', xsltproc_fo_flags,
210228
'--stringparam', 'paper.type', detail,
211229
'-o', '@OUTPUT@', '@INPUT@'],
@@ -230,7 +248,7 @@ endif
230248
# This was previously implemented using dbtoepub - but that doesn't seem to
231249
# support running in build != source directory (i.e. VPATH builds already
232250
# weren't supported).
233-
if pandoc.found() and xsltproc.found()
251+
if pandoc.found() and xsltproc_bin.found()
234252
postgres_epub = custom_target('postgres.epub',
235253
input: postgres_full_xml,
236254
output: 'postgres.epub',

doc/src/sgml/xmltools_dep_wrapper

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import re
5+
import subprocess
6+
import sys
7+
8+
parser = argparse.ArgumentParser(
9+
description='generate dependency file for docs')
10+
11+
parser.add_argument('--targetname', type=str, required=False, nargs='+')
12+
parser.add_argument('--depfile', type=str, required=False)
13+
parser.add_argument('--tool', type=str, required=True)
14+
15+
parser.add_argument('flags', nargs='*')
16+
17+
args = parser.parse_args()
18+
19+
if args.depfile:
20+
depfile_result_list = []
21+
22+
command = [args.tool, '--load-trace'] + args.flags
23+
# --load-trace flag displays all the documents
24+
# loaded during the processing to stderr
25+
res = subprocess.run(command, stderr=subprocess.PIPE,
26+
universal_newlines=True)
27+
# if exit code is different than 0, exit
28+
if res.returncode:
29+
exit(res.returncode)
30+
31+
# get line start from targetname
32+
line_start = ''
33+
for name in args.targetname:
34+
line_start = line_start + name + ' '
35+
line_start = line_start.strip() + ': '
36+
37+
# collect only file paths
38+
line_re = re.compile('^Loaded URL="([^"]+)"')
39+
with open(args.depfile, 'w') as f:
40+
for line in res.stderr.split('\n'):
41+
if line == '':
42+
continue
43+
m = re.match(line_re, line)
44+
45+
# continue to show errors
46+
if m is None:
47+
print(line, file=sys.stderr)
48+
continue
49+
50+
fname = m.group(1)
51+
if fname.startswith('http:'):
52+
continue
53+
if fname.startswith('file://'):
54+
fname = fname.split('file://')[1]
55+
f.write(line_start + fname + '\n')
56+
57+
else:
58+
command = [args.tool] + args.flags
59+
res = subprocess.run(command)
60+
exit(res.returncode)

0 commit comments

Comments
 (0)