Monday, October 02, 2006

[Tutorial] Good Documentation with Doxygen

Well today's tutorial isn't specific to Cocoa, but it's a good tool Mac Developers should use. Doxygen is a simple tool that goes through your source code and auto generates documentation which you can browse through in several formats. If you've browsed through Xcodes menu's you'll have noticed in the Script menu there is a category for HeaderDoc which Xcode provides the ability to insert predefined HeaderDoc comments for generating HeaderDoc documentation. After some experience with HeaderDoc I can tell you it's no where near up to par with Doxygen. Doxygen's documentation is much easier to browse through and much nicer on the eyes as well so I'll show you how to use Doxygen. Step #1 - Download Doxygen Download Doxygen from here: Step #2 - Create your Projects Doxyfile The thing about Doxygen is that you don't need to actually distribute the documentation, you can just distribute the Doxyfile for your project which is a configuration file that tells Doxygen how you want it to create the documentation. When someone wants the documentation all they need to do is load the Doxyfile into Doxygen and tell it to go and generate all documentation. So now lets launch Doxygen, you'll get a window like this Before we continue I reccomend (though it's not necessary) that you create a folder called "Documentation" in the root level of your project directory (the same one that has the *.xcodeproj file.) Now click on the Wizard button... Here you fill out the basic info about the project like the name, version, etc. The source code directory is where you have placed all your source code files you want Doxygen to create documentation for. Really you should have a "Source" folder at your root level of your project for all source code (not auto generated by Xcode) in your project, either way point the source directory at the root level of your project directory and tell it to scan recursively. Then point the destination directory at your newly created Documentation directory. Switch over to the "Mode" tab... Here is where you may want to change settings to what you personally (or your team) want. Personally I reccommend that you tell Doxygen to generate documentation for all entities and include corresponding source code so you know everything that is and isn't documented as well as see what was in the source code at the time the documentation was generated. Leave it optimized for C++ output and switch over to the "Output" tab. Here again you can chose what you like, but really the easiest to navigate around in (IMHO) is to generate with frames and a navigation tree. The search function requires PHP and since Xcode can search your methods and text pretty well i'd leave that alone as it's really unecessary. You'll also want to uncheck the LaTeX option and if you like you can also generate a nice RTF file containing your documentation as well. After that switch over to the Diagram tab and tell it to not generate any Diagrams as Xcode can do this much better than Doxygen can. Click ok and you'll be brought back to the Window though Step 2 will say it's not saved. Click the save button and save the Doxygen file in your Documentation folder. Step 3 - Generate the Documentation Now by Step 3 on the Doxygen window click the Select button and point it at your Documentation folder. Then go down to Step 4 and click the Start button and Doxygen will go through and start generating your documentation. When you look at your Documentation folder again you'll see a html folder and (if you selected it) a rtf folder for each type of Documentation respectively. You can browse through all your classes now... the only thing is theres no documentation just a listing right now. Step 4 - Write Documentation So lets write some documentation! Ok well it's not that painful, trust me it'll help a lot of people. Everytime I think about documentation I remember this quote from a KDE mailing list

Documentation is like sex, when it's good it's really really good and when it's bad it's better than nothing at all.
So here's how you write Doxygen documentation For instance items in your header (*.h) file you would create documentation like so...
NSButton *saveButton; /**< On main window to save all data */ NSArrayController *objectsArrayController; /**< Main table columns are binded to this array */ NSWindow *mainWindow; /**< Window visible at launch for loading views into */
The next type of documentation can be done on your header file as well as your *.m implementation file for method documentation
/** Generates a number of categories from the number specified in n @param n number of categories to generate */ - (void)generateCategoriesWithCount:(int)n;
the "@param" is used to tell Doxygen about the method parameters you want it to document. Lastly you can provide a description of the classes themselves in the Documentation. This I would place before the #import in your header file of the class your documenting...
//! ATXAboutBoxController. /*! ATXAboutBoxController is a class based on Adium's LNAboutBoxController with some tweaks and is designed to display the aboute box in a scrolling credits text box with some simple version information on other text labels, setting options in Interface Builder whenever possible. */
Once you do that to all the source code you can and rerun Doxygen, you get something beutiful... Questions? Comments? Write a comment below to let me know what you think!


Anonymous said...

The only thing I don't like about Doxygen is its partial support for Objective-C, esp. the use C++ naming conventions like "Public Member Function".

Colin Wheeler said...

true it doesn't really support Objective-C, however it's pages are easier to browse than other functions out there and look better which makes it a better documentation system in my book.

Maybe if enough people ask the Doxygen people nicely enough we might get Objective-C support :)

Anonymous said...

Is there any way by which Doxygen can resolve dependencies across frameworks? Thats is: If i have a Project X, in which there is a class dependent on another class of a framework FX (A framework written by me).
Let's say I include the framework file in my project file like this: #import "FX/FXHeader.h". I feel this dependency is ignored by doxygen. May be i'm doing something wrong or missing some settings.
If you have the solution to my problem and if it's not much of a trouble, it would be great if you can drop me a mail at Thanks.

Unknown said...

You should update this for Xcode 4

Unknown said...

Is there a way to document methods in .m files? nice tutorial BTW