Can you do parallel incremental building of a list of projects?

Is it possible to take a list of projects and create them in parallel only if they are not updated?

<Target Name="DependenciesLevel7" DependsOnTargets="DependenciesLevel6"> <Message Text="5 items to build" /> <MSBuild Projects="C:\Projects\ApplicationManager.csproj;C:\Projects\Metrics.csproj" Properties="$(CustomAllProperties)" BuildInParallel="true"> <Output TaskParameter="TargetOutputs" ItemName="built_DependenciesLevel7" /> </MSBuild> 

This is an example of a format that I create, I was hoping that I could only create elements that are not relevant here in parallel? Perhaps msbuild internal task calls are automatically parallel? If so, how would you configure this to grow based on the previous build task? (Target DependenciesLevel6) I figured that for incremental building you should use Inputs / Outputs for your purpose.

Summary of the issue:

  • Is the list of projects transferred to the msbuild task automatically incremental (construction is skipped if the assembly is already updated)?
    • If not, is it possible to make an incremental list of projects in parallel?
  • Can you do between target incremental, where each target is a parallel assembly?
+2
source share
3 answers

what you describe "parallel incremental building" is already built (sort of), but what you really need is partially built in part.

Let me explain the concepts first, and then I will look at how this works in your scenario. You need to know two things; incremental construction and partial construction. I just wrote a blog post discussing this at http://sedodream.com/2010/09/23/MSBuildYouveHeardOfIncrementalBuildingButHaveYouHeardOfPartialBuilding.aspx , but here I will insert the relevant parts.

An incremental building is a concept that you should only build what is obsolete. To support this MSBuild, there are attributes, inputs and outputs in the Target element. Using these attributes, you can specify the files that hit the target (through the input attribute) and the files that you expect to exit the target (through the outputs attribute). Once you do this, MSBuild will compare the timestamp of the inputs with the outputs, and if all the outputs are updated (i.e., the inputs are older), then the target will be skipped. Take a look at the simple project file below.

 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <Files Include="src\01.txt;src\02.txt;src\03.txt;src\04.txt;src\05.txt;"/> </ItemGroup> <PropertyGroup> <Dest>dest\</Dest> </PropertyGroup> <Target Name="CopyFiles" Inputs="@(Files)" Outputs="@(Files->'$(Dest)%(Filename)%(Extension)')"> <Message Text="CopyFiles" /> <Copy SourceFiles="@(Files)" DestinationFiles="@(Files->'$(Dest)%(Filename)%(Extension)')"/> </Target> <Target Name="DeleteTwoFiles"> <Message Text="DeleteTwoFiles" /> <Delete Files="$(dest)01.txt;$(dest)02.txt"/> </Target> </Project> 

In this project file, we have two goals; CopyFiles and DeleteTwoFiles. Ignore DeleteTwoFiles. Also note that the directory in which Im executing this assembly has an src folder with the files specified in the Files element. For the purpose of CopyFiles, I defined the inputs and outputs. Inputs are just @ (files), these are files that the target acts on. The outputs contain the expression @ (Files β†’ '$ (Dest)% (Filename)% (Extension)'). This is the same expression from the Copy statement. If the "Dest" folder is empty and I run the CopyFiles target, the result will be shown below.

alt text

So, as expected, the files were copied, so all this is good. Now, what happens if I make money again? The result is shown below.

alt text

Since you can see that the target was skipped, the "CopyFiles" message statement was not executed and was not a copy as a result. Thus, in a nutshell, this is an incremental building. Now that the dest folder contains all the files that you think will happen, I execute the command msbuild.exe PartialBuilding01.proj / t: DeleteTwoFiles; CopyFiles? This command will first remove two files from the output directory and then call the CopyFiles target again. Let's look at the result below.

alt text

When the CopyFiles target has been completed, you see this expression "Creating the CopyFiles target partially, ...". When it came time to execute the target MSBuild, examined the inputs and outputs, he determined that the 01.txt and 02.txt files were out of date (because they did not exist on the target), but 03.txt, 04.txt and 05.txt were updated. Thus, MSBuild passes CopyFiles for the value for the Files element, which contains only the 01.txt and 02.txt files and allows it to do this.

Now this concerns your problem in many ways, and not as direct as you might hope. Firstly, MSBuild will gradually build up your project, so if your project is updated, it will not be built again. The fact is that in order for MSBuild to determine that your project is up to date, it must load a project that launches the default target (usually Build), and then the goals themselves will realize that there is no work. This material alone takes time. Therefore, if you have a huge number of projects or a huge number of files inside a project, you can take matters into your own hands. What you need is a way to determine whether your projects are relevant or not, and correctly express what is inside your attributes of inputs and outputs. When you do this, you can skip creating projects that are being updated.

The core of the problem is how you make the correct inputs / outputs. If you can figure out how to do this, then you will get what you want. . How you do this will depend on your scenario, but I might see something like this:

  • After each assembly of the project displays a file in a known place specific to this project
  • Before you build a project, scan its directory, find the latest file, and then update the project file’s timestamp with this value
  • You can then put the project files as Inputs and the marker files as Outputs
  • Then challenge your target

In this case, you assume that all the dependencies are completely contained in the files in the project directory (which may be incorrect). I am not saying that this is an ideal solution, but a solution.

================================================

Edit: update based on the quests below.

You will need to put the projects in an element (although not required), for example, ProjectFiles, and then use @ (ProjectFiles) for input. For the exits I talked about, this is the hard part. You need to figure out a way to find out (or tell you through your own process) that the projects are relevant. There is nothing for this. Concern on progressive assembly versus clean assembly. In an ideal world, incremental and clean assemblies are the same. But sometimes this is not so. This is true for many projects. If you start adding a bunch of goals to the build process, and you configure them to incrementally build, but you don't implement it correctly, then you can MSBuild skip the goals when they are really out of date. A good example of this would be to create a target using Inputs set to a list of files and then Outputs set to a list of created files. If you do not prolong the clean process for deleting these created files, then the next recovery (provided that you did not modify the files) will skip the goal when it should have been cleared on the previous recovery.

+9
source

You may be looking for IncrediBuild .

-1
source

I'm not sure about the incremental part, but I read that it checks the inputs / outputs.

I am doing parallel builds with MsBuild with a configuration similar to yours, do not forget to run msbuild with the / m option.

You can try a simple project and check the logs to see if it is incremental or not.

-1
source

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


All Articles