MSBuild Conditions Not Evaluating

1.1k Views Asked by At

I have an app which can come in one of 3 "flavors", the flavor depends only on the NuGet packages that are referenced in the project. In order to simplify the build, I want to use a custom property to define the flavor and then use conditions on the package references. It should be possible to build the app using Visual Studio or using MSBuild CommandLine. I added this to the PropertyGroup:

<Flavor Condition= "'$(Flavor)'==''">Flavor1</Flavor>

I can see the custom property is being set correctly, simply the conditions are being ignored This is what I tried:

  1. Setting the condition on the PackageReference itself as described here: https://learn.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#adding-a-packagereference-condition
  2. Placing the conditioned packages in separate ItemGroup and setting the condition there
  3. Same as #2 but with Choose+When

Only #3 works and only in Visual Studio I need a solution that will work in both Visual Studio and MSBuild command line

#1 looks like this:

<PackageReference Include="Falvor1Package" Condition="'$(Flavor)'=='Flavor1'">
    <Version>1.1.1.1</Version>
</PackageReference>
<PackageReference Include="Falvor2Package" Condition="'$(Flavor)'=='Flavor2'">
    <Version>1.1.1.1</Version>
</PackageReference>

#2 looks like this:

<ItemGroup Condition="'$(Flavor)'=='Flavor1'">
    <PackageReference Include="Falvor1Package">
        <Version>1.1.1.1</Version>
    </PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(Flavor)'=='Flavor2'">
    <PackageReference Include="Falvor2Package">
        <Version>1.1.1.1</Version>
    </PackageReference>
</ItemGroup>

#3 looks like this:

<Choose>
    <When Condition="'$(Flavor)'=='Flavor1'">
        <ItemGroup>
            <PackageReference Include="Falvor1Package">
                <Version>1.1.1.1</Version>
            </PackageReference>
        </ItemGroup>
    </When>
</Choose>
<Choose>
    <When Condition="'$(Flavor)'=='Flavor2'">
        <ItemGroup>
            <PackageReference Include="Falvor2Package">
                <Version>1.1.1.1</Version>
            </PackageReference>
        </ItemGroup>
    </When>
</Choose>

I am using VS2019 and MSBuild 16 What am I missing?

3

There are 3 best solutions below

3
On BEST ANSWER

AFAIK, that doesn't work. You cannot use arbitrary conditions (properties) on PackageReference. Also see this:

You can use a condition to control whether a package is included, where conditions can use any MSBuild variable or a variable defined in the targets or props file. However, at presently, only the TargetFramework variable is supported.

In other words, you could do something like this, but not use your custom property:

<ItemGroup>
    <PackageReference Include="..." Version="..." Condition="'$(TargetFramework)' == '...'" />
</ItemGroup>

Where the value of TargetFramework must be a valid TFM.

The same applies when adding the condition to the/a enclosing ItemGroup element.

Guesswork: I guess that the reason is, that when supporting arbitrary conditions here that wouldn't play well with Visual Studio. Because in the end, it has know which nuget packages (assemblies in the end), are referenced. The TargetFramework value is changed by changing the respective setting inside Visual Studio, so it can cope with that (manually), adjusting the referenced packages accordingly. It would be hard to do that for arbitrary stuff. But that all is just a guess and might be totally wrong.

1
On

I think it is an issue on VS IDE nuget Restore. And the issue is for the PackageReference nuget management format of the non-sdk net framework project. However, the issue is not for new-sdk project.

I have tested the issue multiple times and the condition will be ignored by VS IDE nuget restore. And it is an issue no doubt.

So I suggest you could report the issue to the Team.

I have raised the issue on Github.

However, nuget restore and msbuild restore can specify the condition on non-sdk project. So the issue is a difference between msbuild restore, nuget restore and VS IDE Restore.

So as a suggestion, you could do some changes on the project of VS2019:

Right-click on the Project Properties-->Build Event--> add this on the Pre-build event command line:

"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" -t:restore $(ProjectDir)

And then you can build your project on VS2019 without any problems.

0
On

This is how I accomplish it:

<Choose>
    <When Condition=" '$(Configuration)'=='Release' ">
        <ItemGroup>
            <PackageReference Include="Volo.Abp.Autofac" Version="7.3.2" />
            <PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" Version="7.3.2" />
        </ItemGroup>
    </When>
    <When Condition=" '$(Configuration)'=='Debug' ">
        <ItemGroup>
            <ProjectReference Include="..\..\abp\framework\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
            <ProjectReference Include="..\..\abp\framework\src\Volo.Abp.Caching.StackExchangeRedis\Volo.Abp.Caching.StackExchangeRedis.csproj" />
        </ItemGroup>
    </When>
</Choose>