Automatic moc’ing in Visual Studio

A key step in Qt’s build pipeline is running the toolkit’s Meta Object Compiler to enable C++ extensions.  moc.exe runs on Qt  derived headers which generates an additional .cpp file that enable Qt extensions such as reflection, signals, etc.

For Qt projects on Windows, I prefer Visual Studio’s IDE and msbuild over Qt’s qmake. Although Qt provides a VS addin to create and manage Qt projects from within VS,  the default workflow can be rather cumbersome and I find myself editing .vcxproj files for each new header.

To automate the process, I use a VS properties (.props) file to batch moc commands. It includes a target that runs before the ClCompile target.

  <Target Inputs="@(QtIncludes)" 
    <Exec Command = "$(Moc) %(QtIncludes.identity) -nw -o $(GenDir)/moc_%(Filename).cpp $(MocFlags)"/>

For my projects, QtIncludes is any header with the .hpp extension, which I use only for Qt specific headers

    <QtIncludes Include="$(CppDir)/**/*.$(MocExt)"/>

My project sources are located in src/main/cpp. Moc outputs are located in src/gen/cpp.



The props file contains  additional housekeeping targets that create the generated files directory and copy moc outputs to src/gen/cpp

<Target Name="CreateDirectories" BeforeTargets="Moc">

  <Target Inputs="@(CopyToOutput)"

The full props file an be found here. Include the contents in Microsoft.Cpp.Win32.user.props for global use. For a single project, add a reference in the project’s .vcxproj

<ImportGroup Condition="'$(Configuration)|$(Platform)'=='xxx|yyy'" Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
    <Import Project="Moc.props" />