sdk: SDK doesnt publish exes correctly when used as a project reference
Often a group of exes need to be built and deployed together. This is common in applications like Roslyn where we ship several exes as a single unit: csc, vbc and VBCSCompiler.
Rather than building each project separately and then copying the outputs together we create deployment projects. Essentially dummy exes projects that just reference all of the exes that we need via project reference elements
<ProjectReference Include="..\..\src\Compilers\CSharp\csc\csc.csproj" />
<ProjectReference Include="..\..\src\Compilers\VisualBasic\vbc\vbc.csproj" />
<ProjectReference Include="..\..\src\Compilers\Server\VBCSCompiler\VBCSCompiler.csproj" />
This approach works fine in desktop MSBuild as it will correctly deploy all of the runtime assets. The same approach does not work on SDK projects though as the publish step fails to include critical files like deps.json and runtimeconfig.json. That completely breaks this approach.
If this isn’t meant to be supported by SDK that would be unfortunate but understandable. I would expect an error though positively asserting that this case is not supported. Today everything builds and publishes without error but the output is completely unusable.
Repo:
Clone https://github.com/jaredpar/roslyn and checkout the branch repro/group-exe. Then run the following commands:
> dotnet restore build/ToolsetPackages/BaseToolset.csproj
> dotnet restore build/ToolsetPackages/CoreToolset.csproj
> dotnet restore build/Toolset/CoreToolset.csproj
> dotnet publish -o ${HOME}/temp/test --framework netcoreapp2.0 build/Toolset/CoreToolset.csproj
The directory ${HOME}/temp/test should contain the deps.json / runtimeconfig.json for csc, vbc and VBCSCompiler but it does not. That means the output of publish is unusable.
CC @khyperia
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 25
- Comments: 35 (22 by maintainers)
Links to this issue
Commits related to this issue
- Ensure that publish workaround runs after runtime files exist The workaround for https://github.com/dotnet/sdk/issues/1675 must run after GenerateBuildDependencyFile and GenerateBuildRuntimeConfigura... — committed to sbomer/linker by sbomer 5 years ago
- Run illink out of process (#477) * Run illink out-of-process by implementing ToolTask * Publish illink with runtimeconfig.json and deps.json * Ensure that publish workaround runs after runtime ... — committed to dotnet/linker by sbomer 5 years ago
- Add first test case for referencing and running Exe project See #1675 — committed to dsplaisted/sdk by dsplaisted 4 years ago
- Copy deps.json and runtimeconfig.json files from referenced Exe projects Fix #1675 — committed to dsplaisted/sdk by dsplaisted 4 years ago
- Make dotnet-new-UnitTests compile and execute Changes file by file: -`dotnet-new3.UnitTests.csproj`: Add "Microsoft.DotNet.Cli.Utils" nuget because `Command` and `CommandResult` are all defined there... — committed to dotnet/templating by DavidKarlas 4 years ago
- Make dotnet-new-UnitTests compile and execute Changes file by file: -`dotnet-new3.UnitTests.csproj`: Add "Microsoft.DotNet.Cli.Utils" nuget because `Command` and `CommandResult` are all defined there... — committed to DavidKarlas/templating by DavidKarlas 4 years ago
- Make dotnet-new-UnitTests compile and execute Changes file by file: -`dotnet-new3.UnitTests.csproj`: Add "Microsoft.DotNet.Cli.Utils" nuget because `Command` and `CommandResult` are all defined there... — committed to dotnet/templating by DavidKarlas 4 years ago
- Make dotnet-new-UnitTests compile and execute Changes file by file: -`dotnet-new3.UnitTests.csproj`: Add "Microsoft.DotNet.Cli.Utils" nuget because `Command` and `CommandResult` are all defined there... — committed to GangWang01/sdk by DavidKarlas 4 years ago
- Make dotnet-new-UnitTests compile and execute Changes file by file: -`dotnet-new3.UnitTests.csproj`: Add "Microsoft.DotNet.Cli.Utils" nuget because `Command` and `CommandResult` are all defined there... — committed to GangWang01/sdk by DavidKarlas 4 years ago
- Run illink out of process (dotnet/linker#477) * Run illink out-of-process by implementing ToolTask * Publish illink with runtimeconfig.json and deps.json * Ensure that publish workaround runs a... — committed to tkapin/runtime by sbomer 5 years ago
OK the reason why the proposed workaround doesn’t work in your repro is because you don’t have any other content items in the lib that are copied over. Please try this one:
Here’s a potential workaround that includes the deps.json and runtimeconfig.json in the files that referenced projects will copy.
It should be in .NET SDK 5.0.200, which will ship with VS 16.9
Fixed by https://github.com/dotnet/sdk/pull/14488
VS 16.9.0 is out and it works! Thanks for the fix.
@MartyIX
$(TargetFrameworkIdentifier)is still.NETCoreAppin .NET 5.Note that the workaround doesn’t handle a self-contained publish correctly: the dependency won’t be published in self-contained mode.
To reproduce:
Paste the workaround to ConsoleAppB, then:
Now diff the two
.deps.jsonfiles inConsoleAppA\bin\Debug\netcoreapp3.1\win-x64\publish:runtimeTargetofConsoleAppAis.NETCoreApp,Version=v3.1/win-x64and it has all the runtime dependencies includedruntimeTargetofConsoleAppBis.NETCoreApp,Version=v3.1and the runtime dependencies are not listedThis can be fixed by setting the
RuntimeIdentifierorRuntimeIdentifiersproperty inConsoleAppB.I’m currently using a… less subtle workaround though as I haven’t seen this issue before, and I don’t really want to set the
RuntimeIdentifierproperty in the project. I’m posting it here in case it may help someone else:In
ConsoleAppA, add this:The drawback of this approach is that the project gets built twice.
I suppose you can combine both workarounds this way:
Condition="'$(RuntimeIdentifier)' == ''"on theAddRuntimeDependenciesToContenttargetAddExeDependencyForBuildtarget (only keepAddExeDependencyForPublish)Here’s yet another fix I tried, it’s to be used with the original one. Add this to
ConsoleAppA:This is not great either, as it depends on and modifies “internal” data (targets and items whose names start with an underscore).
Anyway, nothing I posted here is particularly pleasant… I’d be grateful if the SDK was fixed to be able to handle exe references correctly. 😉
The same approach does not work on SDK projects though as the publish step fails to include critical files like deps.json and runtimeconfig.json.Just to note, that the problem appear not only on publish step, but on simple build too, see #11207.
That doesn’t quite get the behavior we want though. Part of the advantage to using the
<ProjectReference>route is that MSBuild hepls ensure we have consistent dependencies across the projects. If any dependencies are wrong the standard warnings around conflicts will come into play.This is important because the versions need to be consistent in order to ensure the exes will run correctly when all their dependencies are dumped into a single directory.
In that case why do the app.config files get deployed at all? Thats only relevant when running the application. I would assume, possibly wrong, that app.config, runtimeconfig.json and deps.json would all be deployed or none.
We’re running into challenges because of this too. It would be really nice if this could get resolved.
Dependencies shouldn’t be copied. Dependencies should be allowed to flow transitively into the referenced project. That’s what @jaredpar was specifically calling out as something he wanted to accomplish with this strategy here https://github.com/dotnet/sdk/issues/1675#issuecomment-338283234.
In this case System.Security.Permissions wasn’t copied because your referencing project is an ASPNetCore project and AspNetCore’s shared framework includes System.Security.Permissions.dll. You’d run into the same problem when referencing any package which is in the AspNetCore.App shared framework and not NetCore.App shared framework.