doxygen as new target

504 views
Skip to first unread message

Rob

unread,
Aug 10, 2015, 5:06:32 PM8/10/15
to The Meson Build System
Hi,

I'm trying to get a top level build target working with doxygen.

I want to type: 'ninja docs' and have doxygen execute in several subdirectories (one or more).

In the top level meson.build, I did:

doxygen = find_program('doxygen')

then in a subdir I want to setup the custom build target that uses doxygen but I'm failing.

run_target('docs',
    [doxygen, 'Doxyfile'],
)

'run_target' seems to be what I want but it only allows strings. Can I tell the doxygen object to output a string. I've tried 'doxygen.get_command()' but it doesn't work.

What should I be doing in this case?

Thanks!

Jussi Pakkanen

unread,
Aug 10, 2015, 5:29:39 PM8/10/15
to Rob, The Meson Build System
On Mon, Aug 10, 2015 at 11:06 PM, Rob <rdool...@gmail.com> wrote:
 
then in a subdir I want to setup the custom build target that uses doxygen but I'm failing.

run_target('docs',
    [doxygen, 'Doxyfile'],
)

'run_target' seems to be what I want but it only allows strings. Can I tell the doxygen object to output a string. I've tried 'doxygen.get_command()' but it doesn't work.

What should I be doing in this case?

Just put the command name in the target like this:

run_target('docs', ['doxygen', 'Doxyfile'])

Note that the reference documentation says that the directory where the command is executed is undefined so this command invocation will most likely not work. You should create a script that does all the steps you need. Scripts can be in any language you wish, as an example you could create a script create_docs.sh that looks like this:

#!/bin/sh

cd $MESON_SOURCE_ROOT
cd dir1
doxygen commands
cd ..
cd dir2
doxygen commands
cd ..
# etc

Then you can create a run target like this:

run_target('docs', 'create_docs.sh')

Rob

unread,
Aug 12, 2015, 2:14:28 PM8/12/15
to The Meson Build System, rdool...@gmail.com
Hi Jussi


On Monday, August 10, 2015 at 2:29:39 PM UTC-7, Jussi Pakkanen wrote:
run_target('docs', ['doxygen', 'Doxyfile'])

Note that the reference documentation says that the directory where the command is executed is undefined so this command invocation will most likely not work. You should create a script that does all the steps you need. Scripts can be in any language you wish, as an example you could create a script create_docs.sh that looks like this:

run_target('docs', 'create_docs.sh')

Does this means that any top level target will require a script? Which means different scripts for windows vs Linux?

Would it be possible to allow run_target() to accept a list of run_commands() or something? 

This is the first instance where I have felt meson was more difficult then cmake. Our CMakeLists.txt file looks like this (not maintained by me):
add_custom_target( docs COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
   SOURCES ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile )

This works in Linux and in windows.

Anyway, as always, thanks for the prompt response.

Jussi Pakkanen

unread,
Aug 13, 2015, 10:11:19 AM8/13/15
to Rob, The Meson Build System
On Wed, Aug 12, 2015 at 8:14 PM, Rob <rdool...@gmail.com> wrote:
 
Does this means that any top level target will require a script? Which means different scripts for windows vs Linux?

You are not required to have a script, you just need to specify input and output files with full paths (as you can't know beforehand the cwd of your project. As an example..
  
This is the first instance where I have felt meson was more difficult then cmake. Our CMakeLists.txt file looks like this (not maintained by me):
add_custom_target( docs COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile 
   SOURCES ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile )

You can achieve this with the following:

run_target('docs', 'doxygen', meson.current_build_dir() + '/Doxyfile')

You just have to set up your Doxyfile to output things in the correct directory.

Rob

unread,
Aug 17, 2015, 8:33:53 PM8/17/15
to The Meson Build System, rdool...@gmail.com
Ok, thanks.

Do you think meson run_target will ever be as capable as cmake's 'add custom target'?

It supports everything one might expect from a custom target - multiple commands, dependencies, etc.  

It seems like 'custom_target' is close, but it requires the output be specified and it runs automatically.

custom_target('docs2',
    input : 'Doxyfile',
    output : 'foo',
    command : ['doxygen', '@INPUT@']
)

Also, I was surprised by this:
$ ninja docs2
ninja: error: unknown target 'docs2'

'custom_target' doesn't actually add a target?

Thanks for your hard work on this!

Jussi Pakkanen

unread,
Aug 18, 2015, 3:52:52 AM8/18/15
to Rob, The Meson Build System
On Tue, Aug 18, 2015 at 3:33 AM, Rob <rdool...@gmail.com> wrote:
 
Ok, thanks.

Do you think meson run_target will ever be as capable as cmake's 'add custom target'?

It supports everything one might expect from a custom target - multiple commands, dependencies, etc.  

It seems like 'custom_target' is close, but it requires the output be specified and it runs automatically.

There are many issues at work here.

First, dependencies should already work. If you specify files in the command line (as declared with the files() command), then dependency info is generated automatically.

Second, multiple commands is not supported by design. If you have a build step that is more complicated than just one command, you are better off writing it into a script. It has many benefits. For example, this makes your standalone step testable in isolation, you can just run it on its own to debug any issue. Secondly that makes your custom step easy to find. Hunting for embedded build steps in multi-hundred lines of build definition is extremely unpleasant (speaking from experience). You also improve portability because if you write shell commands in your build definition it might fail mysteriously on Windows where the shell is different. You can even write your custom steps in Python, Lua, or anything you like.

Thirdly, if you do not want the target to be built automatically but instead only when you explicitly call it, you might want to look into a run_target instead. As an example see what the gtk-doc test case in unit tests does (test cases/frameworks/10 gtk-doc). In this case you probably don't care about dependencies either, just regenerate all docs on invocation.
 
Finally, when you have your commands in a script file rather than embedded, your editor's syntax highlighter will display correct output.

custom_target('docs2',
    input : 'Doxyfile',
    output : 'foo',
    command : ['doxygen', '@INPUT@']
)

Also, I was surprised by this:
$ ninja docs2
ninja: error: unknown target 'docs2'

'custom_target' doesn't actually add a target?

This is due to the way Ninja works. It deals primarily with output files. To run this target manually you would say "ninja subdir/foo". In the VS backend things are slightly different as it works only on target level so you could do that.

Note that run_target does set up a phony top level target so you could do just "ninja docs2".

Rob

unread,
Aug 18, 2015, 9:04:10 PM8/18/15
to The Meson Build System, rdool...@gmail.com


On Tuesday, August 18, 2015 at 12:52:52 AM UTC-7, Jussi Pakkanen wrote:
On Tue, Aug 18, 2015 at 3:33 AM, Rob <rdool...@gmail.com> wrote:
 
Ok, thanks.

Do you think meson run_target will ever be as capable as cmake's 'add custom target'?

It supports everything one might expect from a custom target - multiple commands, dependencies, etc.  

It seems like 'custom_target' is close, but it requires the output be specified and it runs automatically.

There are many issues at work here.

First, dependencies should already work. If you specify files in the command line (as declared with the files() command), then dependency info is generated automatically.

Second, multiple commands is not supported by design. If you have a build step that is more complicated than just one command, you are better off writing it into a script. It has many benefits. For example, this makes your standalone step testable in isolation, you can just run it on its own to debug any issue. Secondly that makes your custom step easy to find. Hunting for embedded build steps in multi-hundred lines of build definition is extremely unpleasant (speaking from experience). You also improve portability because if you write shell commands in your build definition it might fail mysteriously on Windows where the shell is different. You can even write your custom steps in Python, Lua, or anything you like.

Thirdly, if you do not want the target to be built automatically but instead only when you explicitly call it, you might want to look into a run_target instead. As an example see what the gtk-doc test case in unit tests does (test cases/frameworks/10 gtk-doc). In this case you probably don't care about dependencies either, just regenerate all docs on invocation.
 
Finally, when you have your commands in a script file rather than embedded, your editor's syntax highlighter will display correct output.

Thanks for being so patient and informative! I think I am starting to get it regarding these custom targets :) 
Reply all
Reply to author
Forward
0 new messages