DoxyPress and Visual Studio

Last week I wrote about integrating Doxygen with Visual Studio. In one of the comments about that post, legalize suggested that I use its modern C++ replacement DoxyPress instead. DoxyPress is a fork of Doxygen so you should be able to migrate very easily from Doxygen to DoxyPress; there is functionality included to convert an existing Doxygen configuration file to a DoxyPress project file.

Installing DoxyPress

Here are the instructions for using DoxyPress with Visual Studio 2015 and 2017.

  1. Download the 32-bit or 64-bit Windows installer for DoxyPress as appropriate.
  2. Use Run as Administrator to execute the installer. If you do not run the installer as administrator, the installer will not be able to install the files into Program Files (or Program Files (x86) as appropriate). If you execute the installer on a computer running Windows 8/8.1 or 10, you will probably see the following messagebox. If you do not see this messagebox, you may skip forward to step 5.
    SmartScreen
    This is displayed because Microsoft is being cautious and warning you about applications and websites it does not recognize. It does not mean that the installer contains malware, just that it is not in Microsoft’s list of high use applications.
  3. To proceed, click on More info:
    SmartScreen-moreinfo
  4. Either heed the warning and click on the Don’t run button, in which case you cannot install DoxyPress, or click on the Run anyway button to continue.
    Note: I cannot and will not guarantee that the installer for any version of DoxyPress does not contain any malware. As with every application you install, you ultimately take responsibility for that.
  5. The DoxyPress installer dialog will be displayed:
    DoxyPressLanguage
    Choose your preferred language and click Next>.
  6. Continue clicking the Next> button until the installer installs DoxyPress. If the following messagebox is not displayed, proceed to step 7. If the messagebox is displayed, you did not use Run as Administrator.
    DoxyPressNoInstall
    Click the OK button to go back to the installer dialog and click Cancel, then go back to step 2 to rerun the installer using Run as Administrator.
  7. When the installation completes, click on the Finish button to close the installer.

Integrating DoxyPress With Visual Studio

  1. To integrate DoxyPress with Visual Studio, open Visual Studio and select the Tools -> External Tools… menu button. This will open the External Tools dialog:
    ExternalTools
  2. Click on the Add button. The dialog changes to:
    AddExternalTool
  3. Set the Title to DoxyPress, the Command to the executable for DoxyPress (e.g. C:\Program Files\DoxyPress\doxypress.exe), the Arguments to $(ProjectDir)DoxyPress.json, and the Initial directory to $(ProjectDir). Note that there is no ‘\’ character in the Arguments value. Check the Use Output window checkbox. The bottom portion of the dialog box should look similar to this:
    AddDoxyPress
  4. Click the Apply button to add DoxyPress as a menu item.
  5. Again click the Add button.
  6. Set the Title to DoxyPressApp, the Command to the executable for DoxyPressApp (e.g. C:\Program Files\DoxyPress\DoxyPressApp.exe), leave the Arguments blank, and set the Initial directory to $(ProjectDir). Do not check any checkboxes that are not already checked.
  7. Click the OK button to add the DoxyPressApp menu item and close the dialog box.

Generating Documentation the First Time

These instructions assume you have added the appropriate DoxyPress comments to your source code. To use DoxyPress to generate documentation:

  1. In Visual Studio, select the project you are documenting in the Solution Explorer.
  2. If this is the first time you will be generating the documenation for this project, select the Tools -> DoxyPressApp menu item. If this is first time you have ever run DoxyPressApp, the following messagebox will be displayed:DoxyPressAppSetupFileMissingThe setup file contains the location and size of the DoxyPressApp window, a list of the most recently opened DoxyPress project files, and the path to the directory that the last DoxyPress.json file was saved in.
  3. Click on the Default Location button. This saves the settings in C:\Users\<yourusername>\AppData\Local\CS\DoxyPressApp\DoxyPressApp.json. The DoxyPressApp dialog will now open:DoxyPressApp
  4. Select each of the topics in the Setup, Build Settings, and Output Formats tabs to configure the output that will be generated by DoxyPress. The various settings are described in the DoxyPress Project File web page.
  5. When done, select the Run tab:DoxyPressAppRun
  6. Click on the Options for DoxyPress button. This opens the Passed Parameters dialog:NamedParameters
  7. Enter the values you want, then click the Ok button to close the dialog.
  8. Click the Run DoxyPress button. The first time you click on Run DoxyPress, the Save File dialog will open so you can save the DoxyPress project file. Navigate to the project directory (the directory containing the Visual Studio project file (vcxproj file) and enter the file name DoxyPress.json. This file name must match the name specified in the Arguments in step 3 in the section Integrating DoxyPress With Visual Studio, above. Click the Save button to save the file and close the Save File dialog.
  9.  Your documentation will now be generated. If you selected HTML output in the Output Formats tab, click the Display HTML button to view the generated documentation; otherwise, open the generated documentation to ensure that it is created as you would like it.
  10. If you wish to make changes to how the documentation is generated, repeat steps 4 – 9 until you are satisfied. Once you are satisfied with the generated output, close DoxyPressApp.

Regenerating Documentation

When you want to regenerate your documentation, select the project in Visual Studio’s Solution Explorer and then select the Tools -> DoxyPress menu item. It will use the DoxyPress.json file you saved in the instructions above so it is not necessary to run DoxyPressApp again for the selected project.

Doxygen and Visual Studio

Doxygen is a tool for generating documentation from annotated source code. Originally created specifically for C++, it now also supports C, Objective-C, C#, PHP, Java, Python, IDL, Fortran, VHDL, Tcl, and D. Output formats include HTML, Latex, RTF (MS-Word), PostScript, hyperlinked PDF, compressed HTML, and Unix man pages. Although developed in OS X and Linux, there is also an MS Windows executable.

This post will not discuss how to document your source code for use with Doxygen, nor will it list the advantages and disadvantages of using Doxygen. You will have to decide if Doxygen is the right tool for you. You should see the Doxygen website for that. This post will simply show how to use Doxygen with Visual Studio.

There are no extensions for integrating Doxygen with Visual Studio. However, Doxygen, and Doxywizard, a wizard-based executable for creating the configuration file for use with Doxygen, are command line executables which can easily be run from the Visual Studio Tools menu. Adding Doxygen and Doxywizard to the Tools menu is done as follows. The instructions work for both Visual Studio 2015 and Visual Studio 2017.

  1. Download and install the latest Doxygen Windows binary.
  2. Open the Visual Studio Tools dropdown menu and select External Tools…
  3. This opens the External Tools dialog:
    ExternalTools
    Click the Add button. The dialog changes to this:
    AddExternalTool
  4. Change the Title to Doxygen, the command to point to the Doxygen executable (C:\Program Files\doxygen\bin\doxygen.exe on my computer), the arguments to $(ProjectDir)\Doxyfile, and initial directory to $(ProjectDir). Check the Use Output window checkbox. The lower portion of the dialog box will look like this:
    AddDoxygen
    $(ProjectDir) is the macro in Visual Studio that points to the project directory (the directory that contains the project’s vcxproj file).
  5. Click the Apply button to add the Doxygen menu item to the Tools menu.
  6. Click the Add button.
  7. Enter DoxyWizard as the Title, the location of the doxywizard executable  as the Command (e.g. C:\Program Files\doxygen\bin\doxywizard.exe), leave Arguments blank, and $(ProjectDir) as initial directory. Leave all checkboxes unchecked.
  8. Click the OK button to add the DoxyWizard menu item and close the dialog box.

The first time you use Doxygen with a project, select the Tools -> DoxyWizard menu item to open the DoxyWizard dialog, shown here:
DoxyWizardDialog

  1. Step 1: Set the working directory to be the $(ProjectDir) directory. That is the directory containing the project’s vcxproj file.
  2. Step2: Use the Wizard and/or Expert tabs to set the configuration values.
  3. Select the Run tab and then Run doxygen.
  4. If you wish, go back and change the various configuration values.
  5. Once you are satisfied with the values you have set, close the dialog. This will display the Unsaved changes message box. Click Save to save the configuration. Select the directory that contains the project’s vcxproj file. This will ensure that the configuration file is found when you run Doxygen.

You should only run DoxyWizard once for each project that you are documenting. For each subsequent document generation, use Tools -> Doxygen. Provided you saved the configuration file in the correct location, Doxygen will run correctly, saving its generated documentation to the specified directory, and sending its output to the Visual Studio Output window.

 

Generating enum class Documentation with Doxygen

Doxygen is the defacto standard for generating API documentation in C++. Documentation on how to comment code to produce your API documentation is generally good, but there are places where the Doxygen documentation is somewhat lacking. I recently ran across one of these cases: documenting enum class enumerations. There is no mention whatsoever in the Doxygen documentation of how to document enum class. enum is documented, but following the methods shown for it may cause problems.

To illustrate the problems, look at the following code. Note that Enum2, Enum2, and Enum3 all have a value called e2.

namespace ns {
    struct A
    {
        enum class Enum1 {
            e1,
            e2
        };

        enum class Enum2 {
            e3,
            e2
        };

        enum class Enum3 {
            e2
        }
    };
}

Trying the following:

/// This is Enum1
/// \var e1
/// This is Enum1::e1
/// \var e2
/// This is Enum1::e2
enum class Enum1 {
    e1,
    e2
};

and so forth, produces this output:

enum1

You should note three things:

  1. The documentation for  Enum1::e2, Enum2::e2, and Enum3::e2 are all placed together in the documentation for Enum1::e2.
  2. There is no documentation for Enum3. This is because there is only one enumeration value, Enum3::e2, which is included in the documentation for Enum1::e2.
  3. The descriptions for Enum1, Enum2, and Enum3 are not placed as descriptions for the enumerations, but rather as part of the documentation for the values.

The only correct way to document enumeration class values is to not use the special \var command, but to place the documentation inline as follows:

enum class Enum2 {
    e3,     ///< This is Enum2::e3
    e2      ///< This is Enum2::e2
}

If you need multiple lines to describe a value, start the documentation on the line below the value, not on the same line. If you start on the same line as the value, that line will be placed last in the description for the value. This will be shown in the final example.

The special command, \enum, should only be used if the description of the enum class is placed after the enum class is defined. To switch back to placing the description before the next enum class, you must use the \enum special command before that description as well.

Here is an example that shows each of these changes. Firstly, note that there is a description for each enumeration. Secondly, each value is correctly described, except Enum2::e3, where the second line of the description in the header file is placed first in the documentation. This is because the first line of the description was placed on the same line as the enumeration value.

namespace ns {
    /// Description of struct A
    struct A
    {
        /// This is enumeration Enum1
        enum class Enum1 {
            e1,     ///< This is Enum1::e1
            e2      ///< This is Enum1::e2
        };

        enum class Enum2 {
            e3,     ///< This is Enum2::e3.
            ///< Second line of Enum2::e3
            e2
            ///< First line of Enum2::e2 description.
            ///< Second line of Enum2::e2 description
            ///<
            ///< Third line of Enum2::e2 description
        };
        /// \enum Enum2
        /// This is enumeration Enum2

        /// \enum Enum3
        /// This is enumeration Enum3
.        enum class Enum3 {
            e2      ///< This is Enum3::e2
        };
    };
}

enum2