Using MSBuild to Build Multiple Configurations

后端 未结 3 1310
太阳男子
太阳男子 2020-12-05 05:01

I\'m trying to edit my project file to enable me to have a project that builds multiple build configs at once. I\'ve done this using a batching approach and using the MSBuil

相关标签:
3条回答
  • 2020-12-05 05:43

    Somthing is amiss in your project file. Consider this XML:

    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == '' ">
      <DebugType>pdbonly</DebugType>
      <Optimize>true</Optimize>
      <OutputPath>C:\Folder\Etc\Output\$(Configuration)\</OutputPath> 
      ...
    </PropertyGroup>
    

    Those properties can never be set, since even if $(Configuration) and $(Platform) are empty, they can never match the empty string when concatinated with the bar character; the minimal value for that condition is '|' and not ''. Even if corrected by making the condition compare with '|', you then go on to try to use $(Configuration) in the OutputPath in that PropertyGroup, but $(Configuration) will never have a value at the point it is used. Likewise, where you try to set $(Platform) to 'AnyCPU' it must already have that value. You probably meant to omit the condition on the first PropertyGroup altogether, and you may need to supply default values for $(Configuration) and $(Platform) in an early PropertyGroup with no conditions as well. Diff your whole project against a new project and see if there are any other oddities like this present.

    Also notice that on your override of the "Build" target, you have a redundant Condition on the MSBuild task; with the same condition is on the you don't need it on any of the tasks.

    0 讨论(0)
  • 2020-12-05 05:46

    I am not quite sure if I'd wanna go through such a convoluted configuration of the project's csproj file itself. I'd rather setup a separate MSBuild "BuildBoth.proj" file that has a specific target called "Both" that builds the solution in both configurations.

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Both">
    
        <!-- Calls twice for both configs -->
        <Target Name="Both">
            <MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Debug"
                             StopOnFirstFailure="true">
            </MSBuild>
    
            <MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Release"
                             StopOnFirstFailure="true">
            </MSBuild>
        </Target>
    
        <!-- single config targets
    
        <Target Name="Debug">
            <MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Debug"
                             StopOnFirstFailure="true">
            </MSBuild>
        </Target>
    
        <Target Name="Release">
            <MSBuild Projects="buildboth.sln" Targets="Rebuild" Properties="Configuration=Release"
                             StopOnFirstFailure="true">
            </MSBuild>
        </Target>
        -->
    
    </Project>
    

    Then I'd run the command (verbosity set Minimal) to target Both

    C:\Projects\experiments\BuildBoth>msbuild /v:m /target:Both BuildBoth.proj
    Microsoft (R) Build Engine Version 4.0.30319.1
    [Microsoft .NET Framework, Version 4.0.30319.225]
    Copyright (C) Microsoft Corporation 2007. All rights reserved.
    
      BothWpf -> C:\Projects\experiments\BuildBoth\BothWpf\bin\Debug\BothWpf.exe
      BothWpf -> C:\Projects\experiments\BuildBoth\BothWpf\bin\Release\BothWpf.exe
    
    0 讨论(0)
  • 2020-12-05 05:48

    It is important to realize that when you use a "MSBuild" task, a new child MSBuild process will be started. The implication of this is that any items and properties you define in the parent MSBuild process will not be automatically passed to/visible from the child MSBuild process unless you explicitely pass them via Properties attribute on MSBuild element (as in <MSbuild Properties="..." />).

    To answer your question, I wrote the following self-contained example that runs a child MSBuild project for all the specified configurations:

    1. First, create a directory for your MSBuild experiment (for example I used C:\temp\msbuildtest)

    2. In this directory, create the first file, main.proj:

      <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
          <ItemGroup>
              <ConfigList Condition=" '@(ConfigList)' == '' and $(Config) != '' " Include="$(Config.Split('+'))" /><!-- parse all requested configurations into a list -->
              <ConfigList Condition=" '@(ConfigList)' == '' " Include="Debug" /><!-- if no configurations were specified, default to Debug -->
          </ItemGroup>
          <!--
      
          Build the child project for each requested configuration. -->
          <Target Name="Build">
              <MSBuild Projects="$(MSBuildProjectDirectory)\child.proj" Properties="Configuration=%(ConfigList.Identity);OutputPath=$(MSBuildProjectDirectory)\bin\%(ConfigList.Identity)" Targets="Build" />
          </Target>
      </Project>
      
    3. In the same directory, create the second file, child.proj (in your case this would be the actual C# project you're trying to build, but because I'm trying to illustrate my point, I am using a simple child project that instead of running C# compiler just prints values of properties :-) )

      <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build" ToolsVersion="4.0">
          <Target Name="Build">
              <Message Text="Building configuration $(Configuration) with output path $(OutputPath)" Importance="High" />
          </Target>
      </Project>
      
    4. Now you can run the example. First the default, if you don't explicitly specify configurations to build:

      C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild main.proj
      > (cut the noise)
      > Build:
      >   Building configuration Debug with output path C:\temp_c\d\bin\Debug
      

      And then explicitly specified multiple configurations:

      C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\msbuild main.proj /property:Config=Debug+Release+Staging+Production
      > (cut the noise)
      > Build:
      >   Building configuration Debug with output path C:\temp_c\d\bin\Debug
      > Build:
      >   Building configuration Release with output path C:\temp_c\d\bin\Release
      > Build:
      >   Building configuration Staging with output path C:\temp_c\d\bin\Staging
      > Build:
      >   Building configuration Production with output path C:\temp_c\d\bin\Production
      

    You should be able to adapt this technique to your situation.

    0 讨论(0)
提交回复
热议问题