MSBuild C ++ Connection Time Dependencies

I would like to increase assembly parallelism using MSBuild in the following scenario:

There are three C ++ projects (goals). The first is a static library called A , the second is a dynamic library called B , which depends on A , and the third is the C executable, which depends on B All projects contain simple source code, without generating headers or other frauds.

There is nothing in this configuration that should exclude the possibility of compiling all translation blocks in parallel, since only real dependencies are in communication time. However, the standard way to configure links and dependencies in MSBuild forces everything to build A before it even starts creating anything in B , etc. This unnecessarily serializes some of the build processes.

Projects and a common solution should remain accessible to the β€œaverage” developer, which means that project support and build customization must be fully implemented in the Visual Studio user interface (new libraries and executables may depend on pre-existing property sheets, but this should not be required edit .vcxproj files of new projects manually or manually write MSBuild XML files).

My current thought is to move all the code from B and C to separate static libraries called B' and C' . Then B will depend on both A and B' , which allows them to compile in parallel. Similarly, since C ultimately depends on A , B' and C' , they can all be compiled in parallel. The only remaining sequential processes would be the linker steps, as expected. This is a little more cumbersome and non-idiomatic than we would like, although this is not the end of the world.

I would really like to be able to create dependencies for the project link step, which also do not act as dependencies for the compilation phase of the project. On most other build systems, I am familiar with this trivial, if not implied. Is this possible in MSBuild projects for C ++, given the requirements for ease of use of Visual Studio; if so, how?

+5
source share
2 answers

I did not find the perfect workaround, but it works and is simple. Within a few minutes after the implementation was able to completely rebuild from ~ 17 to 14 seconds, and we expect that it will be reduced. Will be updated when I use it more.

First remove the dependencies between the projects so that they are all built at the same time. This will cause race conditions that we will correct manually. At the bottom of vcxproj for project B (and similarly for CB) put:

 <Target Name="WaitForA" BeforeTargets="Link"> <Exec Command="$(SolutionDir)Build\A.bat $(OutputPath)A.lib"/> </Target> 

Goals are only triggered when it's good, but make sure the name is unique. WaitFor.bat is a bat that just launches powershell:

 param([string] $file) $sleeps = 0 while($true) { try { $lock = [System.IO.File]::Open($file,'Open','ReadWrite','None'); $lock.dispose(); break; } catch { $sleeps = $sleeps + 1 Start-Sleep -m 100 } } Write-Host ("Slept {0} times waiting for '{1}'" -f $sleeps,$file) 
+2
source

The easiest way to do this is to place your three projects in a visual studio solution file (i.e. * .sln). I know this is ugly and that the solution file is NOT a true msbuild file. For this to work, you also need to specify project dependencies using visual studio tools. (i.e. right click on the solution, select "Project Dependencies ...")

As soon as you do this, inside the visual studio, it should complete the compilation step in parallel for all projects, but then link them in the correct order.

On the command line, in order to achieve the same effect, you must go in -m to msbuild.exe, as well as the name of the solution file.

This also assumes that you specified -MP in all project files too.

+1
source

Source: https://habr.com/ru/post/1210644/


All Articles