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)" 
          Name="Moc" 
          BeforeTargets="ClCompile" 
          Outputs="@(QtIncludes->'$(GenDir)/moc_%(Filename).cpp')">
    <Exec Command = "$(Moc) %(QtIncludes.identity) -nw -o $(GenDir)/moc_%(Filename).cpp $(MocFlags)"/>
  </Target>

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

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

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

  <PropertyGroup>
    <SourceDir>src/</SourceDir>
    <CppDir>$(SourceDir)main</CppDir>
    <GenDir>$(SourceDir)gen/cpp</GenDir>
  </PropertyGroup>

  <PropertyGroup>
    <QtDir>c:\qt\4.8.0\</QtDir>
    <MocExt>hpp</MocExt>
    <Moc>$(QtDir)/bin/moc.exe</Moc>
  </PropertyGroup>

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">
    <MakeDir
        Directories="$(GenDir)"/>
  </Target>

  <Target Inputs="@(CopyToOutput)"
          Name="CopytoOut"
          Outputs="@(CopyToOutput->'%(DestinationFolder)/%(RecursiveDir)%(Filename)%(Extension)')"
          AfterTargets="Link">
  </Target>

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" />
</ImportGroup>

2 thoughts on “Automatic moc’ing in Visual Studio

  1. Pretty old, but I found this – thank you very much, this is nearly what I was looking for…
    Although in my case I really need to make the distinction from the Q_OBJECT-macro. My project has gotten too large to rename Qt-headers to .hpp for a distinction…

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s