可以颠倒ItemGroup元素的顺序吗?

时间:2010-06-14 11:18:51

标签: msbuild

在MSBuild 3.5中,是否可以反转ItemGroup中的order元素?

示例

我有2个项目。一个可以独立构建,另一个依赖于第一个。每个项目都在.targets文件中引用其特定项目。

project_A.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_A.dll">
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>

    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_A.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

project_B.targets

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_B.dll">
            <ApplicationName>App_B</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>

    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_B.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_B</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

project_A.proj

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="project_A.targets" />

    <Import Project="Common.targets" />
</Project>

project_B.proj

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Import Project="project_A.targets" />

    <Import Project="project_B.targets" />

    <Import Project="Common.targets" />
</Project>

问题

在这种情况下,问题出现在任务处理@(AssembliesToDeploy)期间,因为需要在Assembly_A.dll之前部署Assembly_B.dll。

处理@(AssembliesToRemove)工作正常,因为这里的程序集顺序正确(在Assembly_B.dll之前删除Assembly_A.dll)。

我尝试做什么

<击> 我尝试通过修改project_B.targets来影响@(AssembliesToDeploy)的顺序:

<ItemGroup>
    <AssembliesToDeploy Include="Assembly_B.dll">
        <AssemblyType>SomeType</AssemblyType>
        <ApplicationName>App_B</ApplicationName>
    </AssembliesToDeploy>
    <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
</ItemGroup>

但是当在project_B.proj中使用project_B.targets时,@(AssembliesToDeploy)内的顺序仍然是Assembly_A.dll; Assembly_B.dll。

修改

MadGnome指出这不起作用,因为我最终会在@(AssembliesToDeploy)

中找到重复的内容

是否有一个解决方案允许重用我的.targets,即不将所有ItemGroup元素复制到所有.targets文件?

2 个答案:

答案 0 :(得分:1)

您必须先包含project_B.targets project_A

<Project DefaultTargets="Start" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="project_B.targets" />
  <Import Project="project_A.targets" />    

  <Import Project="Common.targets" />
</Project>

我认为此代码中存在错误:

<ItemGroup>
  <!-- Generates duplicates if used with Import -->
  <AssembliesToDeploy Include="@(AssembliesToDeploy)" />

  <AssembliesToDeploy Include="Assembly_B.dll">
    <AssemblyType>SomeType</AssemblyType>
    <ApplicationName>App_B</ApplicationName>
  </AssembliesToDeploy>
</ItemGroup>

您使用的是Import,因此,如果您使用上述代码,则AssembliesToDeploy中会有重复

答案 1 :(得分:0)

采用 MadGnomes回答我决定将ItemGroup拆分为单独的.target文件。

<强> project_A_REMOVE.targets

<Project xmlns="...">
    <ItemGroup>
        <AssembliesToRemove Include="@(AssembliesToRemove)" />
        <AssembliesToRemove Include="Assembly_A.dll">
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToRemove>
    </ItemGroup>
</Project>

<强> project_A_DEPLOY.targets

<Project xmlns="...">
    <ItemGroup>
        <AssembliesToDeploy Include="@(AssembliesToDeploy)" />
        <AssembliesToDeploy Include="Assembly_A.dll">
            <AssemblyType>SomeType</AssemblyType>
            <ApplicationName>App_A</ApplicationName>
        </AssembliesToDeploy>
    </ItemGroup>
</Project>

和project_B.targets相同。

project_B.proj 现在看起来像这样

<Project DefaultTargets="Start" xmlns="...">
    <Import Project="project_A_REMOVE.targets" />
    <Import Project="project_B_REMOVE.targets" />

    <Import Project="project_B_DEPLOY.targets" />
    <Import Project="project_A_DEPLOY.targets" />

    <Import Project="Common.targets" />
</Project>

由于我的真实解决方案包含大约58个项目,因此会产生大量的.targets。更是如此,因为我必须为每个项目保留一个共同的.targets。