Search code examples
pythondoxygenwaf

Use different configuration sources as input to waf's doxygen feature


Based on the question I asked here, where I wanted to use different sources based on the build variant specified, it now appears that I have the same problem for building the doxygen documentation, as I need different configurations based on the build variant.

The example stays quite the same, but gets a little longer:


The directory structure looks like this:

  • doc
    • a.conf # config of doxygen sources for source a
    • b.conf # config of doxygen sources for source b
    • stylesheetfile # the same for both
  • src
    • a.c
    • b.c
  • doxygen.py
  • wscript

The waf doxygen.py implementation is the same as on repository on GitHub of the waf project doxygen.py.


The waf script is extend to accept the doxygen option. But inside the definition of doxygen it is not possible to check against the build variant (here bld.variant) and this leads to an error as there seems no build variant defined in the doxygen feature.

The part where I check for the build variant is marked in the example with arrows.

What, where and how do I have to implement changes, that the doxygen feature works and uses the correct configuration based on the build variant.

MWE:

def options(opt):
    opt.load(['doxygen'], tooldir=os.path.join('doxygen.py'))

def configure(ctx):
    load('compiler_c')

def build(bld):
    if not bld.variant:
        bld.fatal('call 'waf build_a' or 'waf build_b', and try 'waf --help'')

    if bld.variant == 'a':
        bld.program(source='a.c', target='app', includes='.',  features=['doxygen'])
    elif bld.variant == 'b':
        bld.program(source='b.c', target='app', includes='.', features=['doxygen'])
    else:
        bld.fatal('err')

# create build and clean commands for each build context
from waflib.Build import BuildContext, CleanContext

for x in 'a b'.split():
    for y in (BuildContext, CleanContext):
        name = y.__name__.replace('Context','').lower()
        class tmp(y):
            __doc__ = '''executes the {} of {}'''.format(name, x)
            cmd = name + '_' + x
            variant = x

def doxygen(bld):
    import sys
    import logging
    from waflib import Logs

    if bld.env.DOXYGEN:
        if bld.variant == 'a':    # <=================
            _conf = 'src/a.conf'  # <=================
        elif bld.variant == 'b':  # <=================
            _conf = 'src/b.conf'  # <=================
        else:                     # <=================
            bld.fatal('err')      # <=================

        bld.logger = Logs.make_logger('doxy.log', out)
        hdlr = logging.StreamHandler(sys.stdout)
        formatter = logging.Formatter('%(message)s')
        hdlr.setFormatter(formatter)
        bld.logger.addHandler(hdlr)

        bld(features='doxygen', doxyfile=_conf)

Solution

  • Your problem is that you have not defined your variants for the doxygen command. You should add something like:

    variants = ['a', 'b']
    
    for variant in variants:
        dox = "doxygen"
        class tmp(BuildContext):
            __doc__ = '''executes the {} of {}'''.format(dox, variant)
            cmd = dox + '_' + variant
            fun = dox
            variant = variant
    

    A minimal working example:

    def configure(conf):
        pass
    
    def doxygen(bld):
        print "variant =", bld.variant
    
    # Create build commands with variants
    
    from waflib.Build import BuildContext
    
    variants = ['a', 'b']
    for variant in variants:
        dox = "doxygen"
        class tmp(BuildContext):
            __doc__ = '''executes the {} of {}'''.format(dox, variant)
            cmd = dox + '_' + variant
            fun = dox
            variant = variant