如何使用MSBuild为每个构建配置为每个项目提供不同的OutputPath?

时间:2012-01-06 12:46:25

标签: msbuild msbuild-4.0

必须使用一个或多个配置构建多个项目(debug / release /...)。

需要将构建的输出复制到文件夹(BuildOutputPath)。 有一个默认的BuildOutputFolder,但对于某些项目,您可以指示输出需要放在一个额外的子文件夹中。

例如:

配置是:   - 调试   - 发布

项目是:

  • Project1(BuildOutputFolder)
  • Project2(BuildOutputFolder)
  • Project3(BuildOutputFolder \ Child)

最终结果应如下所示:

\\BuildOutput\
     debug\
         project1.dll
         project2.dll
         Child\
               Project3.dll
     release\
         project1.dll
         project2.dll
         Child\
              Project3.dll

我到目前为止,但无法弄清楚如何覆盖每个项目的OutputPath。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0" DefaultTargets="Build" >
  <ItemGroup>
    <ConfigList Include="Debug" />
    <ConfigList Include="Release" />
   </ItemGroup>  

  <PropertyGroup>
    <BuildOutputPath>$(MSBuildProjectDirectory)\BuildOutput\</BuildOutputPath>
  </PropertyGroup>

  <ItemGroup>
    <Projects Include="project1.csproj" />
    <Projects Include="project2.csproj" />
    <Projects Include="project3.csproj" />
  </ItemGroup>

  <Target Name="Build">
    <MSBuild Projects="@(Projects)"
             BuildInParallel="true"
             Properties="Configuration=%(ConfigList.Identity);OutputPath=$(BuildOutputPath)%(ConfigList.Identity)" />

  </Target>
</Project>

如何在MSBuild项目文件中完成此操作?

2 个答案:

答案 0 :(得分:1)

你试图在两个不同的上下文中递归调用一个任务。 2个配置和3个项目需要6次调用构建任务。您需要以这样的方式布置项目:ConfigList中的每个项目都会调用Projects中的每个项目。

还可以使用ItemDefinitionGroup设置默认共享属性:     

  <ItemGroup>
    <ConfigList Include="Debug" />
    <ConfigList Include="Release" />
  </ItemGroup>

   <ItemDefinitionGroup>
    <Projects>
      <BuildOutputPath>$(MSBuildProjectDirectory)\BuildOutput\</BuildOutputPath>
    </Projects>
  </ItemDefinitionGroup>

  <ItemGroup>
    <Projects Include="project1.csproj" />
    <Projects Include="project2.csproj" />
    <Projects Include="project3.csproj" >
      <Subfolder>Child</Subfolder>
    </Projects>
  </ItemGroup>

  <Target Name="Build">

    <MSBuild Projects="$(MSBuildProjectFullPath)"
             Targets="_BuildSingleConfiguration"
             Properties="Configuration=%(ConfigList.Identity)" />

  </Target>

  <Target Name="_BuildSingleConfiguration">

    <MSBuild Projects="@(Projects)"
             BuildInParallel="true"
             Properties="Configuration=$(Configuration);OutputPath=%(Projects.BuildOutputPath)$(Configuration)\%(Projects.Subfolder)" />
  </Target>

</Project>

答案 1 :(得分:0)

尝试使用项目元数据

来完成
<ItemGroup>
    <Projects Include="project1.csproj">
       <ChildFolder/>
    </Project>
    <Projects Include="project2.csproj">
       <ChildFolder/>
    </Project>
    <Projects Include="project3.csproj">
       <ChildFolder>Child</ChildFolder>
    </Project>
  </ItemGroup>

  <Target Name="Build">
    <MSBuild Projects="@(Projects)"
         BuildInParallel="true"
         Properties="Configuration=%(ConfigList.Identity);OutputPath=$(BuildOutputPath)%(ConfigList.Identity)%(Project.ChildFolder)" />