Search code examples
visual-studioqtvisual-studio-2013qmakemoc

Why is my MOC_DIR ignored when generating Visual Studio projects with qmake


I'm generating Visual Studio 2013 projects with Qt 5.3 qmake. In my .pro file, I've got the following line:

MOC_DIR = $$BUILD_DIR/<DEBUG OR RELEASE>/moc

If I message($$MOC_DIR), the path is correctly formed. However, when I build in VS, the moc_<CLASS>.cpp files are not generated in that location, but instead end up in the same directory as the .pro. I get the following warning during compilation:

Two or more files with the name of moc_<CLASS>.cpp will produce outputs to the same location

That's not surprising, because if I look at the contents of the generated .vcxproj, I see the following (irrelevant tags/text elided ...):

<CustomBuild Include="..\include\Class.hpp">
    ...
    <Outputs Condition="...Release...">moc_Class.cpp;%(Outputs)</Outputs>
    ...
    <Outputs Condition="...Debug...">moc_Class.cpp;%(Outputs)</Outputs>
    ...
</CustomBuild>

Why does is my custom MOC_DIR being ignored?


Solution

  • Other VS2013 projects generated with Qt5 qmake were placing the moc_<CLASS>.cpp files in the specified location, as expected, so my suspicion was that something else in the .pro was interfering.

    I'm using Boost (1.55) and while adding Boost to the project, I came across the issue described in this SO question: link.

    I added the following lines to the top of my .pro:

    load(moc)
    QMAKE_MOC += -DBOOST_MPL_IF_HPP_INCLUDED
    

    ... and that sorted out my macro argument mismatch bug. It also caused the bug described here. Calling load(moc) before setting MOC_DIR for some reason causes qmake to ignore the custom MOC_DIR. If you reorder load(moc) to be after MOC_DIR is set, everything works as expected.

    My .vcxproj now looks as it should, my moc_<CLASS>.cpp files now placed into the correct <BUILD>/debug/moc or <BUILD>/release/moc directories.

    However: I still get the same MSB8027 build warnings. This appears to be a known bug in Visual Studio. It confuses the situation, though, as I only broke the moc locations when I added load(moc), but I got the warning before the problem was introduced, while it existed, and now even after it's fixed! For now I'm disabling the warning; see Felix Huang's answer here.