[v3] doc: build manpages as well as html output

Message ID 20230803164400.98873-1-bruce.richardson@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series [v3] doc: build manpages as well as html output |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS
ci/Intel-compilation success Compilation OK
ci/intel-Testing success Testing PASS
ci/intel-Functional success Functional PASS
ci/github-robot: build success github build: passed
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-x86_64-compile-testing success Testing PASS
ci/iol-unit-testing success Testing PASS
ci/iol-testing success Testing PASS
ci/iol-x86_64-unit-testing success Testing PASS
ci/iol-aarch-unit-testing success Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-aarch64-compile-testing success Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS

Commit Message

Bruce Richardson Aug. 3, 2023, 4:44 p.m. UTC
  Doxygen can produce manpage output as well as html output for the DPDK
APIs. However, we need to do this as a separate task as the manpage
output needs to be placed in a different location post-install to the
html output (/usr/local/share/man vs /usr/local/share/doc/).

Changes required are:
* Add configurable options for manpage output and html output to the
  doxygen config template. (Remove option for html output path as it's
  always "html")
* Modify API meson.build file to configure two separate doxygen config
  files, for HTML and manpages respectively.
* Change doxygen wrapper script to have separate output log files for
  the manpage and HTML jobs, to avoid conflicts
* Add "custom_targets" to meson.build file to build the HTML pages and
  the manpages, with individual install locations for each.
* Where supported by meson version, call "mandb" post-install to update
  the man database to ensure the new manpages can be found.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Reviewed-by: David Marchand <david.marchand@redhat.com>

---

V3: don't use full file paths when generating manpages

V2: add doc update about building or using the manpages
---
 doc/api/doxy-api.conf.in                  |  8 ++--
 doc/api/generate_doxygen.py               |  2 +-
 doc/api/meson.build                       | 54 +++++++++++++++++++----
 doc/guides/contributing/documentation.rst | 12 ++++-
 4 files changed, 63 insertions(+), 13 deletions(-)
  

Comments

David Marchand Aug. 4, 2023, 12:12 p.m. UTC | #1
On Thu, Aug 3, 2023 at 6:44 PM Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> Doxygen can produce manpage output as well as html output for the DPDK
> APIs. However, we need to do this as a separate task as the manpage
> output needs to be placed in a different location post-install to the
> html output (/usr/local/share/man vs /usr/local/share/doc/).
>
> Changes required are:
> * Add configurable options for manpage output and html output to the
>   doxygen config template. (Remove option for html output path as it's
>   always "html")
> * Modify API meson.build file to configure two separate doxygen config
>   files, for HTML and manpages respectively.
> * Change doxygen wrapper script to have separate output log files for
>   the manpage and HTML jobs, to avoid conflicts
> * Add "custom_targets" to meson.build file to build the HTML pages and
>   the manpages, with individual install locations for each.
> * Where supported by meson version, call "mandb" post-install to update
>   the man database to ensure the new manpages can be found.
>
> Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
> Reviewed-by: David Marchand <david.marchand@redhat.com>
>
> ---
>
> V3: don't use full file paths when generating manpages

Nice!
Thank you Bruce.
  
Thomas Monjalon Aug. 29, 2023, 9:28 a.m. UTC | #2
3/08/2023, Bruce Richardson:
> +#set up common doxygen configuration

A space is missing here

> +man_cdata.set('FULL_PATH_NAMES', 'NO')

Why it has to be disabled? Maybe add a comment?

> +    meson.add_install_script(mandb)

When is it executed exactly?
Will it update the database in case we install in a staging directory,
when preparing a package for later deploying on another machine?

> +.. code-block:: console
> +
> +    export MANPATH=:/path/to/build/doc/api/man

Styling consideration: I think we should indent with 3 spaces
so it is aligned with "code-block".
  
Bruce Richardson Aug. 29, 2023, 10:10 a.m. UTC | #3
On Tue, Aug 29, 2023 at 11:28:01AM +0200, Thomas Monjalon wrote:
> 3/08/2023, Bruce Richardson:
> > +#set up common doxygen configuration
> 
> A space is missing here
> 
Ack

> > +man_cdata.set('FULL_PATH_NAMES', 'NO')
> 
> Why it has to be disabled? Maybe add a comment?
> 

Sure, will add comment. It's so that the man pages don't include
full paths to the headers, but are just e.g. "rte_eal.h".

> > +    meson.add_install_script(mandb)
> 
> When is it executed exactly?
> Will it update the database in case we install in a staging directory,
> when preparing a package for later deploying on another machine?

Yes, it will. Unfortunately, I can't find any way to just call mandb if we
are installing in a system manpage location on the local machine. Therefore,
I had two options:
1. don't update the manpage database. In this case, the user won't be able to
actually get the newly install manpages
2. always update the local manpage database. In this case, the user
installing the docs will find them, but anyone installing to staging will
experience a slight delay while their local mandb is updated.

I went for #2 on the basis that the delay in the staging case is pretty
harmless, while not actually finding the manpages is more serious.

However, I'm open to other suggestions on how to work this?

> 
> > +.. code-block:: console
> > +
> > +    export MANPATH=:/path/to/build/doc/api/man
> 
> Styling consideration: I think we should indent with 3 spaces
> so it is aligned with "code-block".
> 
Ack.
  
Thomas Monjalon Aug. 30, 2023, 9:47 a.m. UTC | #4
29/08/2023 12:10, Bruce Richardson:
> On Tue, Aug 29, 2023 at 11:28:01AM +0200, Thomas Monjalon wrote:
> > 3/08/2023, Bruce Richardson:
> > > +    meson.add_install_script(mandb)
> > 
> > When is it executed exactly?
> > Will it update the database in case we install in a staging directory,
> > when preparing a package for later deploying on another machine?
> 
> Yes, it will. Unfortunately, I can't find any way to just call mandb if we
> are installing in a system manpage location on the local machine. Therefore,
> I had two options:
> 1. don't update the manpage database. In this case, the user won't be able to
> actually get the newly install manpages

The user can update the manpage database himself.
And if installing from a package, it should have been done automatically.

> 2. always update the local manpage database. In this case, the user
> installing the docs will find them, but anyone installing to staging will
> experience a slight delay while their local mandb is updated.
> 
> I went for #2 on the basis that the delay in the staging case is pretty
> harmless, while not actually finding the manpages is more serious.
> 
> However, I'm open to other suggestions on how to work this?

My concern is polluting the machine of the packager.
What happens when the staging directory is removed?
Is it an error when opening a manpage later?
  
Bruce Richardson Aug. 30, 2023, 10:20 a.m. UTC | #5
On Wed, Aug 30, 2023 at 11:47:00AM +0200, Thomas Monjalon wrote:
> 29/08/2023 12:10, Bruce Richardson:
> > On Tue, Aug 29, 2023 at 11:28:01AM +0200, Thomas Monjalon wrote:
> > > 3/08/2023, Bruce Richardson:
> > > > +    meson.add_install_script(mandb)
> > > 
> > > When is it executed exactly?  Will it update the database in case we
> > > install in a staging directory, when preparing a package for later
> > > deploying on another machine?
> > 
> > Yes, it will. Unfortunately, I can't find any way to just call mandb if
> > we are installing in a system manpage location on the local machine.
> > Therefore, I had two options: 1. don't update the manpage database. In
> > this case, the user won't be able to actually get the newly install
> > manpages
> 
> The user can update the manpage database himself.  And if installing from
> a package, it should have been done automatically.
> 
> > 2. always update the local manpage database. In this case, the user
> > installing the docs will find them, but anyone installing to staging
> > will experience a slight delay while their local mandb is updated.
> > 
> > I went for #2 on the basis that the delay in the staging case is pretty
> > harmless, while not actually finding the manpages is more serious.
> > 
> > However, I'm open to other suggestions on how to work this?
> 
> My concern is polluting the machine of the packager.  What happens when
> the staging directory is removed?  Is it an error when opening a manpage
> later?
> 
Running mandb doesn't add the manpages from the staging directory to the
database, it simply triggers a scan of the registered manpage directories
on the system, adding new pages found there. It's the man equivalent of
doing an "ldconfig".

/Bruce
  
Thomas Monjalon Aug. 30, 2023, 11:23 a.m. UTC | #6
30/08/2023 12:20, Bruce Richardson:
> On Wed, Aug 30, 2023 at 11:47:00AM +0200, Thomas Monjalon wrote:
> > 29/08/2023 12:10, Bruce Richardson:
> > > On Tue, Aug 29, 2023 at 11:28:01AM +0200, Thomas Monjalon wrote:
> > > > 3/08/2023, Bruce Richardson:
> > > > > +    meson.add_install_script(mandb)
> > > > 
> > > > When is it executed exactly?  Will it update the database in case we
> > > > install in a staging directory, when preparing a package for later
> > > > deploying on another machine?
> > > 
> > > Yes, it will. Unfortunately, I can't find any way to just call mandb if
> > > we are installing in a system manpage location on the local machine.
> > > Therefore, I had two options: 1. don't update the manpage database. In
> > > this case, the user won't be able to actually get the newly install
> > > manpages
> > 
> > The user can update the manpage database himself.  And if installing from
> > a package, it should have been done automatically.
> > 
> > > 2. always update the local manpage database. In this case, the user
> > > installing the docs will find them, but anyone installing to staging
> > > will experience a slight delay while their local mandb is updated.
> > > 
> > > I went for #2 on the basis that the delay in the staging case is pretty
> > > harmless, while not actually finding the manpages is more serious.
> > > 
> > > However, I'm open to other suggestions on how to work this?
> > 
> > My concern is polluting the machine of the packager.  What happens when
> > the staging directory is removed?  Is it an error when opening a manpage
> > later?
> > 
> Running mandb doesn't add the manpages from the staging directory to the
> database, it simply triggers a scan of the registered manpage directories
> on the system, adding new pages found there. It's the man equivalent of
> doing an "ldconfig".

Ah OK
So there is no more concern, thanks.
  

Patch

diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 1a4210b948..c77bdb328b 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -124,11 +124,13 @@  EXAMPLE_PATTERNS        = *.c
 EXAMPLE_RECURSIVE       = YES
 
 OUTPUT_DIRECTORY        = @OUTPUT@
+FULL_PATH_NAMES         = @FULL_PATH_NAMES@
 STRIP_FROM_PATH         = @STRIP_FROM_PATH@
-GENERATE_HTML           = YES
-HTML_OUTPUT             = @HTML_OUTPUT@
+GENERATE_HTML           = @GENERATE_HTML@
+HTML_OUTPUT             = html
 GENERATE_LATEX          = NO
-GENERATE_MAN            = NO
+GENERATE_MAN            = @GENERATE_MAN@
+MAN_LINKS               = YES
 
 HAVE_DOT                = NO
 
diff --git a/doc/api/generate_doxygen.py b/doc/api/generate_doxygen.py
index d3a22869f6..c704f13018 100755
--- a/doc/api/generate_doxygen.py
+++ b/doc/api/generate_doxygen.py
@@ -7,7 +7,7 @@ 
 
 pattern = re.compile('^Preprocessing (.*)...$')
 out_dir, *doxygen_command = sys.argv[1:]
-out_file = os.path.join(os.path.dirname(out_dir), 'doxygen.out')
+out_file = os.path.join(out_dir + '.out')
 dep_file = f'{out_dir}.d'
 with open(out_file, 'w') as out:
     subprocess.run(doxygen_command, check=True, stdout=out)
diff --git a/doc/api/meson.build b/doc/api/meson.build
index 2876a78a7e..9f83b34bb3 100644
--- a/doc/api/meson.build
+++ b/doc/api/meson.build
@@ -29,11 +29,11 @@  example = custom_target('examples.dox',
         install_dir: htmldir,
         build_by_default: get_option('enable_docs'))
 
+#set up common doxygen configuration
 cdata = configuration_data()
 cdata.set('VERSION', meson.project_version())
 cdata.set('API_EXAMPLES', join_paths(dpdk_build_root, 'doc', 'api', 'examples.dox'))
 cdata.set('OUTPUT', join_paths(dpdk_build_root, 'doc', 'api'))
-cdata.set('HTML_OUTPUT', 'html')
 cdata.set('TOPDIR', dpdk_source_root)
 cdata.set('STRIP_FROM_PATH', ' '.join([dpdk_source_root, join_paths(dpdk_build_root, 'doc', 'api')]))
 cdata.set('WARN_AS_ERROR', 'NO')
@@ -41,14 +41,33 @@  if get_option('werror')
     cdata.set('WARN_AS_ERROR', 'YES')
 endif
 
-doxy_conf = configure_file(input: 'doxy-api.conf.in',
-        output: 'doxy-api.conf',
-        configuration: cdata)
+# configure HTML doxygen run
+html_cdata = configuration_data()
+html_cdata.merge_from(cdata)
+html_cdata.set('GENERATE_HTML', 'YES')
+html_cdata.set('GENERATE_MAN', 'NO')
+html_cdata.set('FULL_PATH_NAMES', 'YES')
 
-doxy_build = custom_target('doxygen',
+doxy_html_conf = configure_file(input: 'doxy-api.conf.in',
+        output: 'doxy-api-html.conf',
+        configuration: html_cdata)
+
+# configure manpage doxygen run
+man_cdata = configuration_data()
+man_cdata.merge_from(cdata)
+man_cdata.set('GENERATE_HTML', 'NO')
+man_cdata.set('GENERATE_MAN', 'YES')
+man_cdata.set('FULL_PATH_NAMES', 'NO')
+
+doxy_man_conf = configure_file(input: 'doxy-api.conf.in',
+        output: 'doxy-api-man.conf',
+        configuration: man_cdata)
+
+# do doxygen runs
+doxy_html_build = custom_target('doxygen-html',
         depends: example,
         depend_files: 'doxy-api-index.md',
-        input: doxy_conf,
+        input: doxy_html_conf,
         output: 'html',
         depfile: 'html.d',
         command: [generate_doxygen, '@OUTPUT@', doxygen, '@INPUT@'],
@@ -56,5 +75,24 @@  doxy_build = custom_target('doxygen',
         install_dir: htmldir,
         build_by_default: get_option('enable_docs'))
 
-doc_targets += doxy_build
-doc_target_names += 'Doxygen_API'
+doc_targets += doxy_html_build
+doc_target_names += 'Doxygen_API(HTML)'
+
+doxy_man_build = custom_target('doxygen-man',
+        depends: example,
+        depend_files: 'doxy-api-index.md',
+        input: doxy_man_conf,
+        output: 'man',
+        depfile: 'man.d',
+        command: [generate_doxygen, '@OUTPUT@', doxygen, '@INPUT@'],
+        install: get_option('enable_docs'),
+        install_dir: get_option('datadir'),
+        build_by_default: get_option('enable_docs'))
+
+doc_targets += doxy_man_build
+doc_target_names += 'Doxygen_API(Manpage)'
+
+mandb = find_program('mandb', required: false)
+if mandb.found() and get_option('enable_docs') and meson.version().version_compare('>=0.55.0')
+    meson.add_install_script(mandb)
+endif
diff --git a/doc/guides/contributing/documentation.rst b/doc/guides/contributing/documentation.rst
index 7fcbb7fc43..e0b672ffbb 100644
--- a/doc/guides/contributing/documentation.rst
+++ b/doc/guides/contributing/documentation.rst
@@ -182,7 +182,17 @@  To build the documentation::
 
 See :doc:`../linux_gsg/build_dpdk` for more detail on compiling DPDK with meson.
 
-The output is generated in the directories ``build/doc/html/{api,guides}``.
+The output is generated in the directory ``build/doc/``, with:
+
+* HTML versions of the guide docs, e.g. Getting Started Guides, Programmers Guide, in ``build/doc/guides/html``
+* HTML version of the API documentation in ``build/doc/api/html``
+* Man-page version of the API documentation in ``build/doc/api/man``.
+  If not installing DPDK system-wise, these pages can be accessed by adding this directory to the ``MANPATH`` environment variable.
+  For example:
+
+.. code-block:: console
+
+    export MANPATH=:/path/to/build/doc/api/man
 
 .. Note::