【问题标题】:How to give a different OutputPath per project per build configuration with MSBuild?如何使用 MSBuild 为每个项目的每个构建配置提供不同的 OutputPath?
【发布时间】:2012-01-06 12:46:25
【问题描述】:

必须使用一种或多种配置(调试/发布/...)构建多个项目。

需要将构建的输出复制到一个文件夹 (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

我得到了这么远的 atm,但不知道如何覆盖每个项目的 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 项目文件中完成此操作?

【问题讨论】:

    标签: msbuild msbuild-4.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>
    

    【讨论】:

      【解决方案2】:

      尝试使用项目元数据来实现

      <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)" />
      

      【讨论】:

      • 我试过了,但是当我将项目元数据放入 MSBuild 属性时,%ConfigList.Identity 被忽略了。
      猜你喜欢
      • 2014-08-31
      • 1970-01-01
      • 2012-06-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 2012-01-14
      • 2010-12-03
      • 2015-03-28
      相关资源
      最近更新 更多