From: Otto Moerbeek Date: Tue, 18 Feb 2025 13:20:16 +0000 (+0100) Subject: Fix dependencies for docs, using a Sphinx extension to generate a dep file, as sugges... X-Git-Tag: dnsdist-2.0.0-alpha1~48^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ffce917e77c43efceb89c4435fcdc15a382f198;p=thirdparty%2Fpdns.git Fix dependencies for docs, using a Sphinx extension to generate a dep file, as suggested by @eli-schwart in https://github.com/PowerDNS/pdns/pull/15169#discussion_r1959138532 Actually, the depfile (sphinx.d) is removed by ninja after generating it as shown by a trace. I do not know why, but touching an .rst file has the correct behaviour. So I suspect it is an optimization. --- diff --git a/docs/conf.py b/docs/conf.py index 2457532b83..b8cbbc8bbb 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -19,8 +19,8 @@ # # import os import glob -# import sys -# sys.path.insert(0, os.path.abspath('.')) +import sys +from pathlib import Path import guzzle_sphinx_theme import datetime @@ -30,13 +30,15 @@ import datetime # # needs_sphinx = '1.0' +sys.path.append(str(Path('.').resolve())) + # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. #extensions = [] #extensions = ['redjack.sphinx.lua', 'sphinxcontrib.httpdomain', 'sphinxjsondomain'] extensions = ['sphinxcontrib.openapi', - 'sphinxcontrib.fulltoc', 'changelog'] + 'sphinxcontrib.fulltoc', 'changelog', 'depfile'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -237,3 +239,6 @@ epub_copyright = copyright # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] + +depfile = 'sphinx.d' +depfile_stamp = 'sphinx.stamp' diff --git a/docs/depfile.py b/docs/depfile.py new file mode 100644 index 0000000000..fda8ba8340 --- /dev/null +++ b/docs/depfile.py @@ -0,0 +1,69 @@ +# coding=utf-8 +# +# QEMU depfile generation extension +# +# Copyright (c) 2020 Red Hat, Inc. +# +# This work is licensed under the terms of the GNU GPLv2 or later. +# See the COPYING file in the top-level directory. + +"""depfile is a Sphinx extension that writes a dependency file for + an external build system""" + +import os +import sphinx +import sys +from pathlib import Path + +__version__ = '1.0' + +def get_infiles(env): + for x in env.found_docs: + yield str(env.doc2path(x)) + yield from ((os.path.join(env.srcdir, dep) + for dep in env.dependencies[x])) + for mod in sys.modules.values(): + if hasattr(mod, '__file__'): + if mod.__file__: + yield mod.__file__ + # this is perhaps going to include unused files: + for static_path in env.config.html_static_path + env.config.templates_path: + for path in Path(static_path).rglob('*'): + yield str(path) + + # also include kdoc script + #yield str(env.config.kerneldoc_bin[1]) + + +def write_depfile(app, exception): + if exception: + return + + env = app.env + if not env.config.depfile: + return + + # Using a directory as the output file does not work great because + # its timestamp does not necessarily change when the contents change. + # So create a timestamp file. + if env.config.depfile_stamp: + with open(env.config.depfile_stamp, 'w') as f: + print('depfile.py: Writing ' + env.config.depfile_stamp) + + with open(env.config.depfile, 'w') as f: + print('depfile.py: Writing ' + env.config.depfile) + print((env.config.depfile_stamp or app.outdir) + ": \\", file=f) + print(*get_infiles(env), file=f) + for x in get_infiles(env): + print(x + ":", file=f) + +def setup(app): + app.add_config_value('depfile', None, 'env') + app.add_config_value('depfile_stamp', None, 'env') + app.connect('build-finished', write_depfile) + + return dict( + version = __version__, + parallel_read_safe = True, + parallel_write_safe = True + ) diff --git a/meson.build b/meson.build index e4d946e8db..89560ba961 100644 --- a/meson.build +++ b/meson.build @@ -1125,9 +1125,6 @@ if get_option('unit-tests-backends') endif if python.found() - find_rst_files = run_command(['find', docs_dir, '-name', '*.rst']) - rst_files = find_rst_files.stdout().strip().split('\n') - html_docs = custom_target( 'html-docs', command: [ @@ -1140,9 +1137,9 @@ if python.found() '--source-directory', docs_dir, '--target-directory', '@BUILD_ROOT@' / 'html-docs', ], - output: 'html-docs', + output: 'sphinx.stamp', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', ) docs_tarball = custom_target( @@ -1165,7 +1162,7 @@ if python.found() ], output: 'PowerDNS-Authoritative.pdf', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', ) run_target( diff --git a/pdns/dnsdistdist/docs/conf.py b/pdns/dnsdistdist/docs/conf.py index 9708c85cd3..a137e14707 100644 --- a/pdns/dnsdistdist/docs/conf.py +++ b/pdns/dnsdistdist/docs/conf.py @@ -20,6 +20,8 @@ # import os # import sys # sys.path.insert(0, os.path.abspath('.')) +import sys +from pathlib import Path import datetime # -- General configuration ------------------------------------------------ @@ -28,11 +30,13 @@ import datetime # # needs_sphinx = '1.0' +sys.path.append(str(Path('.').resolve())) + # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['redjack.sphinx.lua', 'sphinxcontrib.httpdomain', 'sphinxjsondomain', - 'sphinxcontrib.fulltoc', 'changelog'] + 'sphinxcontrib.fulltoc', 'changelog', 'depfile'] primary_domain = 'lua' # Add any paths that contain templates here, relative to this directory. @@ -200,4 +204,5 @@ epub_copyright = copyright # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] - +depfile = 'sphinx.d' +depfile_stamp = 'sphinx.stamp' diff --git a/pdns/dnsdistdist/docs/depfile.py b/pdns/dnsdistdist/docs/depfile.py new file mode 120000 index 0000000000..0decaf3523 --- /dev/null +++ b/pdns/dnsdistdist/docs/depfile.py @@ -0,0 +1 @@ +../../../docs/depfile.py \ No newline at end of file diff --git a/pdns/dnsdistdist/meson.build b/pdns/dnsdistdist/meson.build index c13ef069d0..e06cfc02a8 100644 --- a/pdns/dnsdistdist/meson.build +++ b/pdns/dnsdistdist/meson.build @@ -691,8 +691,6 @@ install_data( ) if python.found() - find_rst_files = run_command(['find', docs_dir, '-name', '*.rst']) - rst_files = find_rst_files.stdout().strip().split('\n') html_docs = custom_target( 'html-docs', @@ -706,9 +704,9 @@ if python.found() '--source-directory', docs_dir, '--target-directory', '@BUILD_ROOT@' / 'html-docs', ], - output: 'html-docs', + output: 'sphinx.stamp', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', ) docs_tarball = custom_target( @@ -731,7 +729,7 @@ if python.found() ], output: 'dnsdist.pdf', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', ) run_target( diff --git a/pdns/recursordist/docs/conf.py b/pdns/recursordist/docs/conf.py index f07504db32..d0188e72f0 100644 --- a/pdns/recursordist/docs/conf.py +++ b/pdns/recursordist/docs/conf.py @@ -18,8 +18,8 @@ # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) +import sys +from pathlib import Path import guzzle_sphinx_theme import datetime @@ -29,13 +29,15 @@ import datetime # # needs_sphinx = '1.0' +sys.path.append(str(Path('.').resolve())) + # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. #extensions = [] #extensions = ['redjack.sphinx.lua', 'sphinxcontrib.httpdomain', 'sphinxjsondomain'] extensions = ['redjack.sphinx.lua', 'sphinxcontrib.httpdomain', 'sphinxjsondomain', - 'sphinxcontrib.fulltoc', 'changelog'] + 'sphinxcontrib.fulltoc', 'changelog', 'depfile'] primary_domain = 'lua' # Add any paths that contain templates here, relative to this directory. @@ -208,3 +210,6 @@ epub_copyright = copyright # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] + +depfile = 'sphinx.d' +depfile_stamp = 'sphinx.stamp' diff --git a/pdns/recursordist/docs/depfile.py b/pdns/recursordist/docs/depfile.py new file mode 120000 index 0000000000..0decaf3523 --- /dev/null +++ b/pdns/recursordist/docs/depfile.py @@ -0,0 +1 @@ +../../../docs/depfile.py \ No newline at end of file diff --git a/pdns/recursordist/meson.build b/pdns/recursordist/meson.build index c6c4e7a6b5..5d8a970d7b 100644 --- a/pdns/recursordist/meson.build +++ b/pdns/recursordist/meson.build @@ -735,8 +735,6 @@ dep_conf_distfile = custom_target( ) if python.found() - find_rst_files = run_command(['find', docs_dir, '-name', '*.rst']) - rst_files = find_rst_files.stdout().strip().split('\n') html_docs = custom_target( 'html-docs', @@ -750,9 +748,10 @@ if python.found() '--source-directory', docs_dir, '--target-directory', '@BUILD_ROOT@' / 'html-docs', ], - output: 'html-docs', + output: 'sphinx.stamp', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', + depends: [ metricfiles, recrust ], # for generated .rst files ) docs_tarball = custom_target( @@ -775,7 +774,8 @@ if python.found() ], output: 'PowerDNS-Recursor.pdf', console: true, - depend_files: rst_files, + depfile: 'sphinx.d', + depends: [ metricfiles, recrust ], # for generated .rst files ) run_target(