0
votes

Brief

I use doxygen (Version 1.8.16) to document some python project. One of the main processes calls some subprocesses as threads. Unfortunately this is not recognised in the call graphs in doxygen. I suppose it is because these functions are passed as arguments (without the "()").

# functionA / functionB are not recognised as called functions by doxygen
t1 = Thread(target = functionA, args=(argA,argB))
t2 = Thread(target = functionB, args=(argC,argD))

t1.start()
t2.start()

t1.join()
t2.join()

Has anybody a best practice or hack or filter for doxygen to take care of such cases, when functions are called indirectly?

Full example

The example python file to document

## @file 
#@brief This is a simple doxygen test document.

## @brief A test function
# This is a simple test function for doxygen.
# It calls two functions, <em> functionA, functionB </em> by spawning threads, which is not recognised by doxygen.
def test():        
    t1 = Thread(target = functionA, args=(argA,argB))
    t2 = Thread(target = functionB, args=(argC,argD))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

## @brief Another test function
# This is a simple test function for doxygen.
# It calls two functions, <em> <functionA, functionB> directly, which is recognised by doxygen and reflected in the callgraph.
def test_serial():        
    functionA()
    functionB()    

## @brief One test function
# @param testParA \b =1 A test constant
# @return \b str A test return
def functionA():
    testParA = 1
    testVarA = "test"
    return testVarA

## @brief Another test function
# @param testParB \b ="test" A test constant
# @return \b int Another test return
def functionB():
    testParB = "test"
    testVarB = 1
    return testVarB

The doxygen config is to long to add here. You may use the default and just add. Note that graphviz with dot needs to be installed and findable (i.e. added to PATH environment)

OPTIMIZE_OUTPUT_JAVA   = YES
EXTRACT_LOCAL_METHODS  = YES

REFERENCED_BY_RELATION = YES
REFERENCES_RELATION    = YES

HAVE_DOT               = YES
UML_LOOK               = YES

CALL_GRAPH             = YES
CALLER_GRAPH           = YES
1
Which version of doxygen are you using? Can you make an example out of your snippet where also the missing functions are shown (also the difference between the default doxygen configuration file and the one you use)? - albert
I added a full example. - Frederik
A small side note / word about the usage of e and the <functionA, functionB>, looks like you misunderstood the meaning of the < / > sign here, they are just in the documentation of the doxygen commands to signal that just one word is taken as argument, so in this case the word is terminated after of the <functionA,, I think you either wanted: <em><functionA, functionB></em> or <em> functionA, functionB </em>. - albert
I tried to reproduce the problem,. but I don't even see the call graph in the test_serial function, which I would expect as well. Do you have any other parameters set? as you use doxygen 1.8.16 you can gibe doxygen -x Doxyfile to see the differences between the default and used Doxyfile. - albert
Sorry for the delayed answer. One hack solution I used now is to add an if False: block that calls the functions directly, so doxygen does recognise it. I will check the code later today again @albert - Frederik

1 Answers

0
votes

Until someone finds a better answer, here is a small hack that worked for me. Simply include standard function calls alongside the threaded version in a falsified if block.

def test():
  if False: #include in documentation, as doxygen does't recognise the threaded calls.
    functionA()
    functionB()        
  t1 = Thread(target = functionA, args=(argA,argB))
  t2 = Thread(target = functionB, args=(argC,argD))
  t1.start()
  t2.start()
  t1.join()
  t2.join()