I am trying to generate Doxygen documentation for the very first time in a simple C project. Unfortunately, I am only having limited success. I have tried reading the documentation that Doxygen provides (https://www.doxygen.nl/manual/starting.html) on getting started. However, it is not very clear to me.
I can generate some Doxygen documentation from my small C project. The Doxygen documentation that I do generate is limited to a struct I created in Michaels_Criterion_tests.c
called structOfSignals
. For structOfSignals
, I see my brief statement in "Class Lists/Class Index" along with there being no parameters or returns (I basically copied this from how I document my functions).
For all other documentation in my header files or functions in my .c files, I do not see my brief comments (though Doxygen clearly does acknowledge my header files since it has put them under "File List").
I believe my issue stems from one of three possibilities:
Doxyfile
are incorrect.CmakeLists.txt
is incorrect (a strong likelihood).I have kept my Doxyfile
with mostly the defaults. The few exceptions are:
PROJECT_NAME
, PROJECT_NUMBER
, and PROJECT_BRIEF
.OUTPUT_DIRECTORY = "output"
(output files are being created in my output
directory).JAVADOC_BANNER
from NO
to YES
. I knew this would be a problem with my style of comments if I did not change this value.Here are the contents of my several files:
The Doxyfile
file is too large to post but hopefully the above list of changes make it clear it is mostly the defualt values. I am using version 1.9.1 of Doxygen.
CmakeLists.txt:
NOTE: I comment out the c and header files of Michaels_Criterion_tests
and fibonacci
because that is only code I care about when I unit test. A future goal is to have a conditional statement which will toggle to include or exclude those files based on wether or not I am trying to unit test. But for right now, I just want to have things work with a smaller unber of files.
#Minimum version of CMake required
cmake_minimum_required(VERSION 3.20)
project(mainProject) #name this to whatever you'd like
# Set C standard
set(CMAKE_C_STANDARD 11)
# Locate Doxygen
find_package(Doxygen REQUIRED)
# Locate Criterion
#find_package(criterion REQUIRED)
# Set input directory
set(DOXYGEN_INPUT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
#set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/docs)
# Set source and header files
set(SOURCES
${DOXYGEN_INPUT_DIR}/main.c
${DOXYGEN_INPUT_DIR}/timer.c
#${DOXYGEN_INPUT_DIR}/Michaels_Criterion_tests.c
${DOXYGEN_INPUT_DIR}/signalHandler.c
#${DOXYGEN_INPUT_DIR}/fibonacci.c
)
set(HEADERS
${DOXYGEN_INPUT_DIR}/timer.h
#${DOXYGEN_INPUT_DIR}/Michaels_Criterion_tests.h
${DOXYGEN_INPUT_DIR}/signalHandler.h
#${DOXYGEN_INPUT_DIR}/fibonacci.h
)
# Configure Doxygen
set(DOXYGEN_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/output/Doxyfile)
configure_file(${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOXYGEN_CONFIG} @ONLY)
# Add executable target
add_executable(mainProject ${SOURCES} ${HEADERS})
# Link with Criterion
#target_link_libraries(mainProject criterion)
# Add a target to generate API documentation with Doxygen
add_custom_target(
doc ALL DEPENDS mainProject
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_CONFIG}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
main.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h> //for clock() and CLOCKS_PER_SEC
#include "signalHandler.h"
#include "timer.h"
//@file main.c
int main(int argc, char *argv[]) {
int raiseResult;
void (*prev_handler)(int);
sig_atomic_t signaled = 0; //Debug testing only. Remove later.
printf("Hello, World!\n");
//Register the signal handler
prev_handler = signal(TEST_SIGNAL_51, sigHandler);
//call the timey function
raiseResult = timey(1, TEST_SIGNAL_51);
//debug
printf("raiseResult =%d.\n",raiseResult );
return 0;
}
sigHandler.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "signalHandler.h"
//sig_atomic_t signaled = 0; //Debug testing only. Remove later.
/************************************************************************************************************
The function is a signal handler.
Parameters:
int sig - The signal's number
Returns:
N/A
************************************************************************************************************/
void sigHandler(int sig)
{
//signaled = 1;
//Switch statement to handle all signals
switch(sig) {
case TEST_SIGNAL_50:
printf("Case 50 has been matched.\n");
//LOG AND DO STUFF...
break;
case TEST_SIGNAL_51:
printf("Case 51 has been matched.\n");
//LOG AND DO STUFF...
break;
case TEST_SIGNAL_52:
printf("Case 52 has been matched.\n");
//LOG AND DO STUFF...
break;
case SIGINT:
printf("SIGINT Case has been matched.\n");
//LOG AND DO STUFF...
break;
default: //Raised signal is not a match
printf("Raised signal %d is not a match.\n", sig);
//Probably just log an error and hope we can ignore without blowing up??
break;
}
}
sigHandler.h
#ifndef SIGNAL_HANDLER_H
#define SIGNAL_HANDLER_H
#define TEST_SIGNAL_50 50 //PLACEHOLDER
#define TEST_SIGNAL_51 51 //PLACEHOLDER
#define TEST_SIGNAL_52 52 //PLACEHOLDER
//Function declarations
void sigHandler(int sig);
#endif /* SIGNAL_HANDLER_H */
timer.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h> //for clock() and CLOCKS_PER_SEC
#include <signal.h>
#include "timer.h"
#include "signalHandler.h"
//@file timer.c
int timer(int trigger){
clock_t start = clock(), difference;
int msec = 0;
int raiseResult; //Holds return value of raise(). raise() returns zero if successful and a nonzero value if unsuccessful.
do{
//printf("This is a message\n"); //Debug only
difference = clock() - start; //The difference between the start of the clock and "now".
msec = difference * 1000 / CLOCKS_PER_SEC; //CLOCKS_PER_SEC is defined in time.h. Clock ticks per second (system dependent)
} while(msec < trigger);
printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);
//raiseResult = raise(SIGINT);
//raiseResult = raise(SIGUSR1);
raiseResult = raise(TEST_SIGNAL_51);
return raiseResult;
}
/***********************************************************************************************************
* This function is a timer which raises the signal after trigger milliseconds have elapsed
* Parameters:
* @param int trigger - The time, in milliseconds, in which this timer should trigger an alarm.
* @param int signalToRaise - The signal that will be raised once this timer raises its alarm.
* Returns:
* @return int - This is the return result of raise(); zero if successful and a nonzero value if unsuccessful.
************************************************************************************************************/
int timey(int trigger, int signalToRaise){
clock_t start = clock(), difference;
int msec = 0;
int raiseResult; //Holds return value of raise(). raise() returns zero if successful and a nonzero value if unsuccessful.
do{
//printf("This is a message\n"); //Debug only
difference = clock() - start; //The difference between the start of the clock and "now".
msec = difference * 1000 / CLOCKS_PER_SEC; //CLOCKS_PER_SEC is defined in time.h. Clock ticks per second (system dependent)
} while(msec < trigger);
printf("Time taken %d seconds %d milliseconds\n", msec/1000, msec%1000);
printf("About to raise signal %d\n", signalToRaise);
raiseResult = raise(signalToRaise);
return raiseResult;
}
timer.h
#ifndef TIMER_H
#define TIMER_H
//@file CASCTimer.c
//Function declarations
int timer(int trigger);
/***********************************************************************************************************
* @brief This function is a timer which raises the signal after trigger milliseconds have elapsed
* Parameters:
* @param int trigger - The time, in milliseconds, in which this timer should trigger an alarm.
* @param int signalToRaise - The signal that will be raised once this timer raises its alarm.
* Returns:
* @return int - This is the return result of raise(); zero if successful and a nonzero value if unsuccessful.
************************************************************************************************************/
int timey(int trigger, int signalToRaise);
#endif /* TIMER_H */
Does anyone see what I am doing wrong?
Noteworthy Doxyfile configurations:
OPTIMIZE_OUTPUT_FOR_C
EXTRACT
in the section "Build related configuration options". If you set the relevant options to YES
, doxygen will generate documentation for each and every statement/declaration in your header and source files, even if they are undocumented.