Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Choose position of ItemGroup files generated in a Target via a Task

I've got the following set up (uninteresting XML removed for brevity):

MyProject.fsproj

<Project ...>
  <Import Project="MyTask.props" />
  ...
  <ItemGroup>
    <Compile Include="Program.fs" />
  </ItemGroup>
</Project>

MyTask.props

<Project ...>
  <UsingTask XXX.UpdateAssemblyInfo />
  <Target Name="UpdateAssemblyInfo"
          BeforeTargets="CoreCompile">
    <UpdateAssemblyInfo ...>
      <Output
        TaskParameter="AssemblyInfoTempFilePath"
        PropertyName="AssemblyInfoTempFilePath" />
    </UpdateAssemblyInfo>

    <ItemGroup>
      <Compile Include="$(AssemblyInfoTempFilePath)" />
    </ItemGroup>
  </Target>
</Project>

The problem is that the ItemGroup added by MyTask.props is added last, despite being imported right at the very start of the project. I assume that this is because the ItemGroup is not actually imported then - it's added by when the task is run.

This isn't a good thing in F#, as file order is important - including the file at the end of the build list means it's impossible to build an EXE, for example (as the entrypoint must be in the last file).

Hence my question - is there a way for me to output an ItemGroup as part of a Target and have that generated ItemGroup be first?

like image 213
Alex Hardwicke Avatar asked Sep 21 '15 18:09

Alex Hardwicke


1 Answers

A bit late, but this may help someone in the future, I'm not using the import tag on this sample, but it will work the same way, the important part is the "UpdateAssemblyInfo" target, the main idea is to clear and regenerate the Compile ItemGroup using the appropriate sort order.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <Compile Include="Program.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
  </ItemGroup>

  <Target Name="Build" DependsOnTargets="UpdateAssemblyInfo">

  </Target>

  <Target Name="UpdateAssemblyInfo">
    <!-- Generate your property -->
    <PropertyGroup>
      <AssemblyInfoTempFilePath>ABC.xyz</AssemblyInfoTempFilePath>
    </PropertyGroup>

    <!-- Copy current Compile ItemGroup to TempCompile -->
    <ItemGroup>
      <TempCompile Include="@(Compile)"></TempCompile>
    </ItemGroup>

    <!-- Clear the Compile ItemGroup-->
    <ItemGroup>
      <Compile Remove="@(Compile)"/>
    </ItemGroup>

    <!-- Create the new Compile ItemGroup using the required order -->    
    <ItemGroup>
      <Compile Include="$(AssemblyInfoTempFilePath)"/>
      <Compile Include="@(TempCompile)"/>
    </ItemGroup>

    <!-- Display the Compile ItemGroup ordered -->
    <Message Text="Compile %(Compile.Identity)"/>
  </Target>
</Project>
like image 115
Rolo Avatar answered Sep 17 '22 13:09

Rolo