Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt MOC multiple files in parallel with MSBuild

Good morning!

I know there is already this question here: Qt Moc'ing multiple files in parallel under msbuild but I would not show up this old question.

I work under Visual Studio 2010 and I've got to speed up the compilation time of my app. I use all flags like /MP with MSBuild -j with Make etc... The last step of the optimization is to parallelize MOC'ing steps. They are painfully slow and I googled a lot and I didn't find a solution.

I know that jom exists but it uses nmake and I've got to use MSBuild.

If someone has already heard a solution, it should be really cool!

Have a nice day!

like image 872
CloudCompany Avatar asked Apr 15 '14 08:04

CloudCompany


1 Answers

If you generate VC project file with qmake from qt *.pro , it generates it in a way that mocables are compiled in one thread. The only way I know to workaround this behavior is to explicitly call jom for moc pre-processing.

I have only VS2012 (win32-msvc2012), but I used to do the similar thing for VS2010 (win32-msvc2010 in your case)

To do so you should automate the following steps:

Create VC project from pro file through qmake:

qmake -spec win32-msvc2012 -tp vc -o ${path-to-target}/${your-project}.vcxproj ${path-to-source}/${your-qt-pro}.pro

Create makefile from pro file through qmake:

qmake -spec win32-msvc2012 CONFIG+=release -o ${path-to-target}/Makefile', ${path-to-source}/${your-qt-pro}.pro

Create the following .bat file next to vcproj file (put %VS100COMNTOOLS% for vc2010 and x86/x64 for arch):

call "%VS110COMNTOOLS%\..\..\VC\vcvarsall.bat" ${arch}
md build\release\generated 
${environment.dir}\bin\jom.exe -j 16 /F Makefile.release mocables

To do debug build change 'release' to 'debug' (or introduce a variable)

Now it is necessary to edit VC project file. Here is what you need to find/replace (using regular expressions):

1) For all includes (tags Project->ItemGroup->CustomBuild Include that contains *.h files:

  • find: </CustomBuild>
  • replace to: <ExcludedFromBuild>true</ExcludedFromBuild> </CustomBuild>

2) for Project->ItemDefinitionGroup:

  • find: </Link>
  • replace to: </Link> <PreBuildEvent> <Command>build_moc.bat</Command> </PreBuildEvent>

3) for Project->ItemDefinitionGroup: - find: <ItemDefinitionGroup> - replace to: <Target Name="BeforeClean"> <Message Text="Cleaning moc generated files"/> <Exec Command="del \$\(ProjectDir\)..\\\$(Platform\)\\build\\${arch}\\generated\\moc_*.* /F /Q" /> </Target> <ItemDefinitionGroup>

I automate it with Maven, so here is the code snippet for the reference:

build_moc.bat:

cd %1
md build\%2\generated 
c:\\develop\\buildenv\bin\jom.exe -j 16 /F Makefile.%2 mocables

maven script that does replacements (maven-replacer-plugin config):

<!-- Disabling moc preprocessor steps, since we do it with jom -->                                        
<replacement>
    <xpath>//Project/ItemGroup/CustomBuild[contains(@Include,'.h')]</xpath>
    <token><![CDATA[</CustomBuild>]]></token>
    <value><![CDATA[
      <ExcludedFromBuild>true</ExcludedFromBuild>
    </CustomBuild>
                                            ]]></value>
</replacement>

<!-- Adding moc preprocessor steps with jom -->
<replacement>
    <xpath>//Project/ItemDefinitionGroup[not(@*)]</xpath>
    <token><![CDATA[</Link>]]></token>
    <value><![CDATA[
    </Link>
    <PreBuildEvent>
      <Command>\$\(ProjectDir\)../${arch}/build_moc.bat \$\(ProjectDir\)../${arch} \$\(Configuration\)</Command>
    </PreBuildEvent>
                                            ]]></value>
</replacement>

<!-- Cleaning moc files -->
<replacement>
<token><![CDATA[<ItemDefinitionGroup>]]></token>
<value><![CDATA[
    <Target Name="BeforeClean">
    <Message Text="Cleaning moc generated files"/>
    <Exec Command="del \$\(ProjectDir\)..\\\$\(Platform\)\\build\\${arch}\\generated\\moc_*.* /F /Q" />
    </Target>
    <ItemDefinitionGroup>
                                            ]]></value>
</replacement>

I hope this helps

like image 170
Boris Biryuchkov Avatar answered Sep 22 '22 02:09

Boris Biryuchkov