【问题标题】:MSBuild projects with different build-configs, without using sln具有不同构建配置的 MSBuild 项目,不使用 sln
【发布时间】:2015-03-28 17:45:18
【问题描述】:

Related

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

BookApp.Web 引用 BookApp.Domain

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

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

在 Visual Studio 中构建解决方案时,我可以使用构建配置器来确保无论为 Web 项目选择什么构建配置,调试配置始终用于域项目。

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

<MSBuild Projects="BookApp.Web\BookApp.Web.csproj" Properties="Configuration=Prod-us" />

当我运行它时,MSBuild 期望所有依赖项目都具有相同的构建配置。由于情况并非如此(也不应该是 IMO),因此它会失败并显示以下错误消息:

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'.

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

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

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

【问题讨论】:

    标签: visual-studio msbuild


    【解决方案1】:

    看看这个答案,它解释了如何通过 MSBuild 任务将配置从项目传递到项目,并使用配置的元数据传递目标项目所需的配置

    here

    更新

    我使用类库 (Sample.Domain) 和 ConsoleApplication(SampleApp.Console) 创建了一个解决方案。我在 SamplApp.Console 中添加了另外两个配置:prod-us;prod-eu,Sample.Domain 保留在 debug;release 中。

    然后我更改了 ConsoleApplication 的 csproj 文件,如下所示:

    项目参考

      <!--<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>
    

    创建了一个Target来切换传递给MSBuild的Configuration,这样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>
    

    调用调试配置是这样完成的 msbuild SampleApp.Console.csproj

    调用 (Release;prod-us;prod-eu;...) 是这样完成的 msbuild SampleApp.Console.csproj /p:Configuration="prod-us" /p:OutputPath="bin"

    我确信它可以优化,并且可能更容易一些,但它确实有效。

    【讨论】:

    • 据我了解,该问题和答案涉及构建 one 项目的多个构建配置,只需一步。我试图了解如何在我的情况下使用它。你能详细说明一下吗?
    • @Iasseschou,你有没有找到更简单的方法来解决你的问题?我有完全相同的问题,这种好方法有点压倒性。
    猜你喜欢
    • 2018-09-07
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多