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.71k stars 1.06k forks source link

Runtime identifier is not forwarded when publishing exe project references (self-contained mode) #16184

Open ltrzesniewski opened 3 years ago

ltrzesniewski commented 3 years ago

This is a follow-up to #1675 and #14488. Tested with the SDK v5.0.200.

If you have a project A that references a project B, and both are of the exe output type, then publishing A with a runtime identifier will generate a self-contained A, but a framework-dependent B.

Here's a simple repro:

dotnet new console -o A
dotnet new console -o B
dotnet add A reference B
dotnet publish A -r win-x64

A.deps.json will have the .NETCoreApp,Version=v5.0/win-x64 runtime target, and B.deps.json will have .NETCoreApp,Version=v5.0.

Workaround:

If you change the project reference to the following:

<ProjectReference Include="..\B\B.csproj" SkipGetTargetFrameworkProperties="true" />

Then B will be published in self-contained mode as expected.

/cc @dsplaisted

dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

deng0 commented 3 years ago

I've noticed the same problem.

It seems instead of specifying SkipGetTargetFrameworkProperties in A.csproj another workaround is to specify RuntimeIdentifiers in B.csproj. Something like this <RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>. I don't really understand why, but when RuntimeIdentifiers is specified the runtime identifier is forwarded to B.csproj when doing a publish on A.csproj.

It would be nice if someone with a better understanding could elaborate on this.

CCRcmcpe commented 3 years ago

Same, it caused inconvenience when publishing a project that references many other projects. If you don't want to modify project files like @deng0 mentions, you need to build all the depended projects manually with -r before publishing with --no-build.

ltrzesniewski commented 3 years ago

I noticed that the SkipGetTargetFrameworkProperties workaround doesn't work with projects that need to generate a publish-specific deps.json file, as of the SDK 5.0.400-preview.21277.10.

In my case, this situation happened because of a PackageReference with PrivateAssets="all".

Here's a different workaround, in case it helps anyone:

<Target Name="AddReferencedExeProjectForPublish" BeforeTargets="CopyFilesToPublishDirectory">
  <MSBuild Projects="..\B\B.csproj" Targets="Publish" Properties="PublishDir=$([System.IO.Path]::GetFullPath($(PublishDir)))" BuildInParallel="$(BuildInParallel)" />
</Target>

It essentially publishes B to the same output path when you want to publish A. Not pretty, but it works.

dsplaisted commented 2 years ago

This may be the same as or related to #21677