使用不依赖sln文件的MSBuild项目进行不同构建配置的构建

11

相关

我的VS解决方案中有两个项目,BookApp.WebBookApp.Domain

BookApp.Web引用BookApp.Domain

BookApp.Web有以下构建配置:debugstagingprod-euprod-usprod-as。我们有三个用于生产的数据中心和一个暂存环境。

到目前为止,BookApp.Domain仅有两个构建配置:debug

当在Visual Studio中构建解决方案时,我可以使用构建配置器来确保无论Web项目选择哪种构建配置,Domain项目始终使用debug配置。

但是,在我的持续集成服务器上使用MSBuild构建时,出现了问题。我在我的rollout.msbuild文件中使用这个命令:

<MSBuild Projects="BookApp.Web\BookApp.Web.csproj" Properties="Configuration=Prod-us" />
当我运行它时,MSBuild 期望所有相关的项目具有相同的构建配置。由于这不是事实(在我看来也不应该是),所以它会失败并显示此错误消息:
The OutputPath property is not set for project 'BookApp.Domain.csproj'.  Please check to make sure that you have specified a valid combination of Configuration and Platform for this project.  Configuration='Prod-us'  Platform='AnyCPU'.

相关问题的答案建议为每个构建配置创建单独的.sln解决方案,并使用MSBuild运行。对我来说,这听起来不是一个好主意。

将所有构建配置复制到域项目中也不理想。

有没有更好的方法告诉MSBuild使用不同的构建配置?

1个回答

2
请看这个答案,它解释了如何通过MSBuild任务和使用配置的元数据将配置从项目传递到项目,并使用配置的元数据来传递目标项目所需的配置。 这里 更新:
我创建了一个包含类库(Sample.Domain)和控制台应用程序(SampleApp.Console)的解决方案。我在SamplApp.Console中添加了两个更多的配置:prod-us;prod-eu,Sample.Domain保持debug;release。
然后我修改了ConsoleApplication的csproj文件,如下所示:
ProjectReferences
  <!--<ItemGroup>
    <ProjectReference Include="..\Sample.Domain\Sample.Domain.csproj">
      <Project>{73e8a7fd-0a24-47c5-a527-7601550d4b92}</Project>
      <Name>Sample.Domain</Name>
    </ProjectReference>
  </ItemGroup>-->

  <ItemGroup>
    <ProjectReference Include="..\Sample.Domain\Sample.Domain.csproj" >
      <Targets>Build</Targets>
    </ProjectReference>
  </ItemGroup>

在传递给MSBuild的配置中添加了一个switch case,用于配置输出文件和引用文件的一些属性:

  <Choose>
    <When Condition="'$(Configuration)' != 'Debug'">
      <PropertyGroup>
        <OutputProperty>$(OutputPath)\$(Configuration)</OutputProperty>
        <FileCopy>$(OutputProperty)</FileCopy>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup>
        <OutputProperty>$(OutputPath)</OutputProperty>
        <FileCopy>$(OutputProperty)</FileCopy>
      </PropertyGroup>
    </Otherwise>
  </Choose>

创建了一个目标来切换传递给MSBuild的配置,这样Debug会将Debug传递给Sample.Domain,其他所有情况都会传递Release。
  <Target Name="MultiConfiguration" >
    <CreateProperty Value="Debug">
      <Output TaskParameter="Value" PropertyName="LibConfiguration" Condition="'$(Configuration)' == 'Debug'"/>
    </CreateProperty>

    <CreateProperty Value="Release">
      <Output TaskParameter="Value" PropertyName="LibConfiguration" Condition="'$(Configuration)' != 'Debug' "/>
    </CreateProperty>
  </Target>

构建目标使用我们添加的属性,因此输出和引用文件的复制将根据配置值具有正确的值。

  <!--Build Process-->
  <Target Name="Build" DependsOnTargets="Clean;MultiConfiguration;ComputeProjectReference" >
    <Csc Sources="@(Compile)" References="@(NewAssemblies)" TargetType="exe" OutputAssembly="$(OutputProperty)\$(AssemblyName).exe"/>
  </Target>

  <Target Name="ComputeProjectReference" Inputs="@(ProjectReference)" Outputs="%(ProjectReference.Identity)__Forced">
    <MSBuild Projects="@(ProjectReference)" Targets="%(ProjectReference.Targets)" Properties="Configuration=$(LibConfiguration);Platform=AnyCPU;OutputPath=bin\$(LibConfiguration)">
      <Output TaskParameter="TargetOutputs" ItemName="ResolvedProjectReferences"/>
    </MSBuild>
  </Target>

  <Target Name="AfterProjectReference"  AfterTargets="ComputeProjectReference">
    <CreateItem Include="@(ResolvedProjectReferences)">
      <Output TaskParameter="Include" ItemName="CopyFiles" />
    </CreateItem>

    <Copy SourceFiles="@(CopyFiles)" DestinationFolder="$(FileCopy)" SkipUnchangedFiles="false"  />

    <ItemGroup>
      <NewAssemblies Include="$(OutputProperty)\%(CopyFiles.FileName)%(CopyFiles.Extension)" />
    </ItemGroup>
  </Target>

调用 Debug 配置的方法如下: msbuild SampleApp.Console.csproj

调用(Release;prod-us;prod-eu;...)的方法如下: msbuild SampleApp.Console.csproj /p:Configuration="prod-us" /p:OutputPath="bin"

我相信这种方法可以进行优化,可能还有更简单的方法,但它是可行的。


据我所知,那个问题和答案涉及到使用一个步骤构建一个项目的多个构建配置。我正在尝试理解如何在我的情况下使用它。你能详细说明一下吗? - lasseschou
@Iasseschou,你有没有找到更简单的解决方法?我也遇到了完全相同的问题,这种优秀的方法有点让人不知所措。 - Tiger Galo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接