sdk icon indicating copy to clipboard operation
sdk copied to clipboard

ContentFiles not included with multiple TargetFrameworks and --no-incremental after upgrading to 6.0.300

Open mattjohnsonpint opened this issue 3 years ago • 11 comments
trafficstars

Describe the bug

After installing the 6.0.300 SDK, running dotnet build --no-incremental fails when using <TargetFrameworks> (plural) and including a nuget package that bundles source files as contentFiles (as described in docs here).

Specifically, multi-targeted projects using the popular Nullable library by @manuelroemer started failing non-incremental builds after upgrading to 6.0.300. This library provides a shim for nullability annotations on older targets, and does so by including several .cs.pp source files under contentFiles in its nuget package. The problem isn't with this library, but that the files it provides are being excluded from the build.

It does work when passing a specific framework (such as -f net48), or when only specifying a single <TargetFramework>. So I believe the problem is with content files not being included when dispatching to each framework's build.

Everything does work when the .NET SDK is pinned to 6.0.203 in a global.json file, so this is new for 6.0.300.

I tried on both Windows 11 21H2 and macOS 12.4 with the same results.

To Reproduce

See minimal repro in issue here: https://github.com/manuelroemer/Nullable/issues/24

Failed build output:

C:\Users\mattj\Code\MyApp>dotnet build --no-incremental                                          
Microsoft (R) Build Engine version 17.2.0+41abc5629 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
C:\Users\mattj\Code\MyApp\Program.cs(16,35): error CS0246: The type or namespace name 'NotNullWhenAttribute' could not be found (are you m
issing a using directive or an assembly reference?) [C:\Users\mattj\Code\MyApp\MyApp.csproj]
C:\Users\mattj\Code\MyApp\Program.cs(16,35): error CS0246: The type or namespace name 'NotNullWhen' could not be found (are you missing a 
using directive or an assembly reference?) [C:\Users\mattj\Code\MyApp\MyApp.csproj]
  MyApp -> C:\Users\mattj\Code\MyApp\bin\Debug\net6.0\MyApp.dll

Build FAILED.

C:\Users\mattj\Code\MyApp\Program.cs(16,35): error CS0246: The type or namespace name 'NotNullWhenAttribute' could not be found (are you m 
issing a using directive or an assembly reference?) [C:\Users\mattj\Code\MyApp\MyApp.csproj]
C:\Users\mattj\Code\MyApp\Program.cs(16,35): error CS0246: The type or namespace name 'NotNullWhen' could not be found (are you missing a  
using directive or an assembly reference?) [C:\Users\mattj\Code\MyApp\MyApp.csproj]
    0 Warning(s)
    2 Error(s)

Time Elapsed 00:00:01.01

Working build output (without --no-incremental):

C:\Users\mattj\Code\MyApp>dotnet build                 
Microsoft (R) Build Engine version 17.2.0+41abc5629 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  MyApp -> C:\Users\mattj\Code\MyApp\bin\Debug\net48\MyApp.exe
  MyApp -> C:\Users\mattj\Code\MyApp\bin\Debug\net6.0\MyApp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.94

Further technical details

  • Include the output of dotnet --info
C:\Users\mattj>dotnet --info
.NET SDK (reflecting any global.json):
 Version:   6.0.300
 Commit:    8473146e7d

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.22000
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\6.0.300\

Host (useful for support):
  Version: 6.0.5
  Commit:  70ae3df4a6

.NET SDKs installed:
  2.1.818 [C:\Program Files\dotnet\sdk]
  3.1.419 [C:\Program Files\dotnet\sdk]
  5.0.408 [C:\Program Files\dotnet\sdk]
  6.0.202 [C:\Program Files\dotnet\sdk]
  6.0.203 [C:\Program Files\dotnet\sdk]
  6.0.300 [C:\Program Files\dotnet\sdk]

.NET runtimes installed:
  Microsoft.AspNetCore.All 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.30 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.25 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 5.0.17 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 6.0.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  • The IDE (VS / VS Code/ VS4Mac) you're running on, and its version N/A - occurs on command line

  • Here are binlogs that may be useful: binlogs.zip

Thanks

mattjohnsonpint avatar Jun 01 '22 17:06 mattjohnsonpint

I observed the error also with only one TFM. It is not limited to projects that are multi-targeting. I confirm the observation that it breaks on 6.0.300.

shuebner avatar Jun 01 '22 17:06 shuebner

@shuebner - Same here, but only with the plural form of the tag. The problem doesn't appear to be the number of TFMs, but which tag is used to specify. In other words, <TargetFrameworks>net6.0;net48</TargetFrameworks> or <TargetFrameworks>net48</TargetFrameworks> fail, but <TargetFramework>net48</TargetFramework> works. Is that your experience as well?

mattjohnsonpint avatar Jun 01 '22 17:06 mattjohnsonpint

@mattjohnsonpint No, my experience is build failure when using <TargetFramework> (singular).

shuebner avatar Jun 01 '22 17:06 shuebner

@shuebner - possibly that's another separate but related issue then. Not sure, really. If you can make a minimal repro, that would help, but I don't want the .NET SDK team to lose site of the main issue since it seems like an obvious bug introduced in the latest SDK.

mattjohnsonpint avatar Jun 01 '22 17:06 mattjohnsonpint

@mattjohnsonpint

If you can make a minimal repro, that would help

I was going to, don't worry.

This is the repro for the same errors (with one error each for both IsExternalInit and Nullable) without multitargeting: https://github.com/shuebner/repro-dotnet-sdk-25758 Building the Parent project fails when using SDK 6.0.300 and --no-incremental. Note that only the Consumers project references the IsExternalInit and Nullable packages.

shuebner avatar Jun 02 '22 04:06 shuebner

I don't have a full analysis of this yet, but after looking into the scenario described in https://github.com/manuelroemer/Nullable/issues/24 I have the mechanism of the problem well understood:

  • The outer build runs a Clean
    • Each inner build performs a Clean
      • The content items from the nuget package are resolved successfully during ResolvePackageAssets during this clean
      • RunProduceContentAssets (which would normally generate the content files) doesn't run because the Clean target has set _CleaningWithoutRebuilding to true.
  • The outer build runs a Build
    • Each inner build performs a Build, which fails

The Build doesn't seem to be doing a restore, which is when these content assets would be produced from what I can tell. More research needs to be done as to why that is, I don't have all of the context.

For what it's work, --no-incremental just sets the build target to Rebuild instead of Build.

baronfel avatar Jun 02 '22 04:06 baronfel

FYI, it appear that the issue also appears in Visual Studio when doing a "Rebuild" - which makes sense as I believe it uses the same mechanism. https://github.com/manuelroemer/IsExternalInit/issues/13

mattjohnsonpint avatar Jun 02 '22 15:06 mattjohnsonpint

I can confirm the bug being introduced in 6.0.300.

Build command is

dotnet build --no-incremental

The following fails in 6.0.300

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>netcoreapp3.1</TargetFrameworks>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="LightInject.Source" Version="6.4.1" />
  </ItemGroup>
</Project>

Changing from TargetFrameworks to TargetFramework fixes the issue

When downgrading to 6.0.203 there is no problem 👍

seesharper avatar Jun 09 '22 13:06 seesharper

The issue appears to be related to the use of .pp as the file extension to hide the file in Visual Studio. I believe this is fixed with https://github.com/manuelroemer/IsExternalInit/pull/14 and https://github.com/manuelroemer/Nullable/pull/26. I couldn't find any official info about the .pp file extension so I'm not sure if it was just a hack nor why this would only be a problem with the Rebuild target and TargetFrameworks property.

@seesharper I see that LightInject.Source is also using this strategy so it might benefit from the same change as an alternative to waiting for this to be fixed here.

gtbuchanan avatar Jul 08 '22 21:07 gtbuchanan

On .pp files: https://docs.microsoft.com/en-us/nuget/create-packages/source-and-config-file-transformations#specifying-source-code-transformations

It may have been a workaround in Nullable, but in other libraries (like LibLog), it's a legitimate way to include transformable source code files in a NuGet package.

asherber avatar Jul 08 '22 22:07 asherber

Worth noting that I couldn't reproduce this in 7.0.100 RC 1 so far. I also note that NuGet-scaffolded generated files don't seem to be added to the list of files to Clean.

baronfel avatar Aug 04 '22 18:08 baronfel

I'm still able to reproduce this with solutions that use LibLog, using dotnet 7.0.100.

asherber avatar Nov 28 '22 18:11 asherber

Removed myself so that the @dotnet/domestic-cat can take a look as available.

baronfel avatar Nov 28 '22 18:11 baronfel

Well, interestingly, the specific repro given above now works for me, but my actual project that uses LibLog is still seeing the error. I'll try to come up with a new repro.

asherber avatar Nov 28 '22 18:11 asherber