dotnet / sdk

Core functionality needed to create .NET Core projects, that is shared between Visual Studio and CLI
https://dot.net/core
MIT License
2.75k stars 1.07k forks source link

PublishSingleFile=true and PackAsTool=true in csproj do not play well with dotnet pack #10402

Open alexrp opened 5 years ago

alexrp commented 5 years ago

Steps to reproduce

Expected behavior

As I understand it, .NET Core tool packages are RID-agnostic, so PublishSingleFile should be ignored by dotnet pack and only be observed by dotnet publish. I am not sure what the behavior should be for PackAsTool=false.

Actual behavior

$ dotnet publish -r linux-x64 # Works as expected.
Microsoft (R) Build Engine version 16.3.0-preview-19329-01+d31fdbf01 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 77.09 ms for /home/alexrp/tests/netcore/test.csproj.
  You are using a preview version of .NET Core. See: https://aka.ms/dotnet-core-preview
  test -> /home/alexrp/tests/netcore/bin/Debug/netcoreapp3.0/linux-x64/test.dll
  test -> /home/alexrp/tests/netcore/bin/Debug/netcoreapp3.0/linux-x64/publish/
$ ls bin/Debug/netcoreapp3.0/linux-x64/publish
test  test.pdb
$ dotnet pack # Fails unexpectedly.
Microsoft (R) Build Engine version 16.3.0-preview-19329-01+d31fdbf01 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 57.33 ms for /home/alexrp/tests/netcore/test.csproj.
/home/alexrp/.dotnet/sdk/3.0.100-preview7-012821/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.RuntimeIdentifierInference.targets(134,5): error NETSDK1097: It is not supported to publish an application to a single-file without specifying a RuntimeIdentifier. Please either specify a RuntimeIdentifier or set PublishSingleFile to false. [/home/alexrp/tests/netcore/test.csproj]

(Incidentally, passing --runtime linux-x64 to dotnet pack makes no difference.)

Environment data

$ dotnet --info
.NET Core SDK (reflecting any global.json):
 Version:   3.0.100-preview7-012821
 Commit:    6348f1068a

Runtime Environment:
 OS Name:     ubuntu
 OS Version:  18.10
 OS Platform: Linux
 RID:         ubuntu.18.10-x64
 Base Path:   /home/alexrp/.dotnet/sdk/3.0.100-preview7-012821/

Host (useful for support):
  Version: 3.0.0-preview7-27912-14
  Commit:  4da6ee6450

.NET Core SDKs installed:
  2.1.604 [/home/alexrp/.dotnet/sdk]
  2.2.204 [/home/alexrp/.dotnet/sdk]
  3.0.100-preview6-012264 [/home/alexrp/.dotnet/sdk]
  3.0.100-preview7-012821 [/home/alexrp/.dotnet/sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.11 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.All 2.2.5 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.11 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 2.2.5 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-preview6.19307.2 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.0.0-preview7.19365.7 [/home/alexrp/.dotnet/shared/Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.11 [/home/alexrp/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 2.2.5 [/home/alexrp/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview6-27804-01 [/home/alexrp/.dotnet/shared/Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.0.0-preview7-27912-14 [/home/alexrp/.dotnet/shared/Microsoft.NETCore.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
alexrp commented 5 years ago

On a perhaps related note, if you replace the PublishSingleFile=true with PublishTrimmed=true, you get a similar issue:

$ dotnet pack
Microsoft (R) Build Engine version 16.3.0-preview-19329-01+d31fdbf01 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 16.17 ms for /home/alexrp/tests/netcore/test.csproj.
  You are using a preview version of .NET Core. See: https://aka.ms/dotnet-core-preview
  test -> /home/alexrp/tests/netcore/bin/Debug/netcoreapp3.0/test.dll
  test -> /home/alexrp/tests/netcore/bin/Debug/netcoreapp3.0/test.dll
/home/alexrp/.dotnet/sdk/3.0.100-preview7-012821/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.ILLink.targets(113,5): error NETSDK1102: Optimizing assemblies for size is not supported for the selected publish configuration. Please ensure that you are publishing a self-contained app. [/home/alexrp/tests/netcore/test.csproj]

Again, it seems like dotnet pack should ignore this property if it's not relevant.

livarcocc commented 5 years ago

I am not sure silently ignoring an option is the right choice here, as it will cause confusion when the thing the user wanted to happen does not happen.

The issue here is that trimming is only supported for self-contained apps while packastool is support for framework dependent apps. If you are trying to use packastool, I would say for you to follow the error message recommendation and remove trimming or turn it off.

alexrp commented 5 years ago

That's the thing though, I don't want trimming or self-contained packaging to happen when doing dotnet pack, only when doing dotnet publish. As part of my build process, this project is published both as a tool package for NuGet and as a self-contained app to be released on GitHub.

Of course, I could just remove PublishSingleFile and PublishTrimmed from the project file and specify them manually to dotnet publish (this is what I do right now), but I really do not like this. It means that a user who just types dotnet publish -r linux-x64 (as opposed to the much longer and less obvious dotnet publish -r linux-x64 -p:PublishSingleFile=true -p:PublishTrimmed=true) will get a result that is different from the build configuration that I actually support and test.

IMO, the obvious command the user is going to type should do the obvious and supported thing for the project.

livarcocc commented 5 years ago

But the issue is that a user specifying these properties and then running pack might spec that these properties will work for pack, unless something happens, which is what we are doing. This is the last surprising behavior: I set some configuration, if it does not work with the command I am running, tell me, don't silently ignore said configurations and let me scratching my head to understand which ones are honored by which commands.

alexrp commented 5 years ago

Well, I'm not saying they should necessarily be silently ignored. A simple warning would suffice, I'd think. There's precedent for that too with e.g. the ApplicationIcon property:

$ dotnet publish win-x64
Microsoft (R) Build Engine version 16.3.0-preview-19329-01+d31fdbf01 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 111.73 ms for /home/alexrp/flare/flare/src/cli/cli.csproj.
  Restore completed in 111.74 ms for /home/alexrp/flare/flare/src/lib/lib.csproj.
  You are using a preview version of .NET Core. See: https://aka.ms/dotnet-core-preview
  lib -> /home/alexrp/flare/flare/src/lib/bin/Debug/libflare.dll
/home/alexrp/.dotnet/sdk/3.0.100-preview7-012821/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.Sdk.targets(358,5): warning NETSDK1074: The application host executable will not be customized because adding resources requires that the build be performed on Windows (excluding Nano Server). [/home/alexrp/flare/flare/src/cli/cli.csproj]
  cli -> /home/alexrp/flare/flare/src/cli/bin/Debug/win-x64/flare.dll
  cli -> /home/alexrp/flare/flare/src/cli/bin/Debug/win-x64/publish/

Alternatively, if there was a way to set these properties in the project file based on which publish command is being executed, that would be fine too.

alexrp commented 5 years ago

In any case, I would have to say that, for me, the most surprising behavior here is the fact that these properties (whose names start with Publish) are being observed by the dotnet pack command at all. From my perspective as a user, packing and publishing have nothing whatsoever to do with each other. This is further backed up by the existence of the distinct IsPackable and IsPublishable properties. It may be the case that they share some MSBuild logic under the hood, but I don't think that's obvious to a user at all unless they go digging through the MSBuild files and/or try these properties and discover that they apply to dotnet pack for some reason.

TclasenITVT commented 5 years ago

I have also been bitten by this I though that PublishSingleFile, PublishTrimmed and PublishReadyToRun would only effect the dotnet publish command otherwise I would have expected them to be called just SingleFile, Trimmed and ReadyToRun... I think this behavior is more unexpected than expected.

alexrp commented 3 years ago

I keep running into this, even 2 years later. My options seem to be:

Both of these options are really quite bad.

Is there any interest in addressing this at all?

dscheg commented 9 months ago

As a workaround trick, it seems that there are some "private" properties _IsPacking and _IsPublishing, and it is possible (with some caveats) to use specific PropertyGroup under the Condition

https://github.com/dotnet/sdk/issues/26324