Skip to content

Module Header Auto-Generation

Versión en español de esta publicación.
Lastly I’ve been working on a library for fdtd simulations. I wanted to design the library so the end user can just include one header file which will provide all the library functionality but it should also keep the modularity architecture and interfaces.

I like to have control over the way that the code gets build by having custom makefiles so providing such a global header file and having to do manual maintenance on it will just don’t work for me, so I made some googling on the subject but I didn’t found anything relevant so I decided to make a small script that will work for me in the maintenance task of the header file in each module.

I thought it could be helpful for someone with the same problem so here it is!

GenerateModuleHeaders.sh

#!/bin/bash
 
moduleName="${1}"
moduleNameUpper=${moduleName^^}  # Module name in uppercase
 
# Run as user, -e allows to interpret new line \n
echo -e "\n \
********************************************************** \n \
** Automatic header generation for module ${moduleName} \n \
**********************************************************"
 
incDir="${2}"
outFile="${3}"
 
# "ls -l $incDir"         = get a directory listing
# --time-style="long-iso" = makes sure that the same format for the date-time string is the same in all environments.
# "| egrep '^d'"          = pipe to egrep and select only the directories
# "awk '{print $8}'"      = pipe the result from egrep to awk and print only the 8th field
incDirs=`ls -l --time-style="long-iso" $incDir | egrep '^d' | awk '{print $8}'`
 
cat <<EOF >"${outFile}"
/*
 * ${moduleName}.hpp
 *
 * Auto-Generated module header file, do not modify directly
 * to prevent changes loss, to modify please change GenHeaders.sh
 * 
 *  Created on: 2014
 *      Author: nano
 */
 
#ifndef ${moduleNameUpper}_HPP_
#define ${moduleNameUpper}_HPP_
 
// Include all headers that are part of the ${moduleName} module
EOF
 
# Loop through the directories
for dir in ${incDirs}; do
    echo -e "\n${dir}";  
    currDir=${incDir}/${dir}
    fileCnt=$( find ${currDir} -name "*.h*" | wc -l )
    if [ ${fileCnt} -gt 0 ]; then  # check  if we have headers in dir
        for file in ${currDir}/*.h*; do # Loop through files and add includes
            echo "#include \"${file}\"" >> ${outFile};
            echo "${file}";
        done       
    fi
done
echo -e "\n";
 
# Add closing ifdef    
echo "" >> ${outFile}
echo "#endif /* ${moduleNameUpper}_HPP_ */" >> ${outFile}

And here is a sample output

Nems_Data.hpp

/*
 * Nems_Data.hpp
 *
 * Auto-Generated module header file, do not modify directly
 * to prevent changes loss, to modify please change GenHeaders.sh
 * 
 *  Created on: 2014
 *      Author: nano
 */
 
#ifndef NEMS_DATA_HPP_
#define NEMS_DATA_HPP_
 
// Include all headers that are part of the Nems_Data module
#include "./include/common/Programs.hpp"
#include "./include/common/Visualizers.hpp"
#include "./include/config/EmConstants.hpp"
#include "./include/config/SimulationConfig.hpp"
#include "./include/gnuplot/GnuplotConfig.hpp"
#include "./include/gnuplot/GnuplotItem1D.hpp"
#include "./include/gnuplot/GnuplotItem2D.hpp"
#include "./include/gnuplot/GnuplotShapes.hpp"
 
#endif /* NEMS_DATA_HPP_ */

And finally you can add a makefile target so the header module gets generated on each build like this

target

# This target generates a global header file for this module, this header
# file includes all the headers of the module and is a convenient way to
# use the API from the client code using only one header file, the shell script
# will be maintaining the list of header files automatically on each build :). 
genheaders:
    @echo Generate headers file for module.
    sh ../GenerateModuleHeaders.sh Nems_Data ./include ./Nems_Data.hpp

That’s it!

Enjoy! 🙂
-Yohan

Leave a Reply

Your email address will not be published. Required fields are marked *