Sdk: Cannot publish core console app + core app library tests

Created on 30 Dec 2017  Â·  13Comments  Â·  Source: dotnet/sdk

The solution is here: https://github.com/orloffm/failingpublish

The first project is a netcoreapp2.0 exe, the second is a test netcoreapp2.0 project for it. The solution dotnet builds, but when I do

dotnet publish -c Release --self-contained -r win-x64

I get the following:

Microsoft (R) Build Engine version 15.5.179.9764 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 43.37 ms for C:\dev\failing_build\a\a.csproj.
  Restore completed in 75.49 ms for C:\dev\failing_build\a.tests\a.tests.csproj.
C:\Program Files\dotnet\sdk\2.1.3\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.RuntimeIdentifierInference.targets(116,5): error : It is not supported to build or publish a self-contained application without specifying a RuntimeIdentifier.  Please either specify a RuntimeIdentifier or set SelfContained to false. [C:\dev\failing_build\a\a.csproj]
  a -> C:\dev\failing_build\a\bin\Release\netcoreapp2.0\win-x64\a.dll
  a -> C:\dev\failing_build\a\bin\Release\netcoreapp2.0\win-x64\publish\

If I remove the test project from the solution, it works fine:

Microsoft (R) Build Engine version 15.5.179.9764 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  Restore completed in 43.62 ms for C:\dev\failing_build\a\a.csproj.
  a -> C:\dev\failing_build\a\bin\Release\netcoreapp2.0\win-x64\a.dll
  a -> C:\dev\failing_build\a\bin\Release\netcoreapp2.0\win-x64\publish\

I expect it to work, as this is almost a copy of a https://github.com/dotnet/docs/tree/master/samples/core/getting-started/unit-testing-using-dotnet-test, but with the main project switched to netcoreapp2.0.

Most helpful comment

@alexzaytsev-newsroomly @orloffm sry forgot to post the workaround half a year ago:

The workaround is to change the project reference to exclude the property:

<ItemGroup>
  <ProjectReference Include="..\other\app.csproj"
                    GlobalPropertiesToRemove="SelfContained" />
</ItemGroup>

At the moment, you may also get an "was restored using 2.1.1 but … 2.1.0 … used insead" error.
To work around this one, add this to the referenced(!) project(s):

<PropertyGroup>
  <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>

All 13 comments

Are you using dotnet publish on the solution or a single project?
I'm not sure if it is supposed to work on a solution..

As a workaround, you could try to omit the --self-contained parameter, since it is on by default.
However, I believe the underlying issue would also affect any self-contained app that references another application since the build of a project reference will remove a global RuntimeIdentifier but not a SelfConained property..

I just do it in the solution folder. Yes, I understand I can specify the project, but the message is at least misleading if it depends on the presence of test projects.

As suspected, the issue also occurs when an app references another app.
selfcontainedrepro.zip also fails in the same way when the testmainapp is published with dotnet publish -r osx-x64 --self-contained.

This likely needs a change to MSBuild similar to https://github.com/Microsoft/msbuild/pull/1674 to remove the SelfContained global property for RID-agnostic P2Ps. (Or maybe for even for RID-specific ones?). cc @nguerrera @livarcocc

This seems to still affect the 2.1 SDK

@peterhuene @dsplaisted could you make a change similar to https://github.com/Microsoft/msbuild/pull/1674 to remove SelfContained as well as the new app host property as global properties for building P2P references?
If no one is actively working on it (@peterhuene is assigned) I can give it a go myself..

@alexzaytsev-newsroomly @orloffm sry forgot to post the workaround half a year ago:

The workaround is to change the project reference to exclude the property:

<ItemGroup>
  <ProjectReference Include="..\other\app.csproj"
                    GlobalPropertiesToRemove="SelfContained" />
</ItemGroup>

At the moment, you may also get an "was restored using 2.1.1 but … 2.1.0 … used insead" error.
To work around this one, add this to the referenced(!) project(s):

<PropertyGroup>
  <TargetLatestRuntimePatch>true</TargetLatestRuntimePatch>
</PropertyGroup>

Thanks @dasMulli. I'm going to try to get this resolved for 2.1.4xx this week.

I'm wondering if there can be a way to do these kind of things without hardcoding these properties in msbuild..
like a target that modifies the GlobalPropertiesToRemove before msbuild's PrepareProjectReferences or a variable in msbuild that the sdk could set. or an additional ItemDefinitionGroup etc.

That's definitely something that I can bring up with the MSBuild team. I'd certainly prefer not to have to modify their targets for SDK properties.

@peterhuene @dasMulli, +@rainersigwald

We discussed this back in https://github.com/dotnet/sdk/pull/993/files/6eaa5f97e01d3ac55a1a15961c20f61d90b035bd#diff-e1389449b5e96849141625fcaa2713d6 and I forget why it was abandoned now. :(

Things changed quite a bit since, mostly for the double evaluation fix. Unfortunately, this stuff gets quite complicated.

Unfortunately, this is not so simple a fix as to not propagate a global SelfContained property to referenced projects. Even if we fix it such that the property isn't propagated, a larger issue is exposed: what we restore for referenced netcoreapp* targeted Exe projects differs from how they build or publish due to the new "target latest runtime patch level" feature.

The TargetLatestRuntimePatch property is keyed off of SelfContained, which itself is keyed off of RuntimeIdentifier. RuntimeIdentifier does not propagate to the referenced projects by (current) design. As a result, if SelfContained is propagated, we get the expected error originally mentioned in this issue.

However, if SelfContained is not propagated as a global property, then TargetLatestRuntimePatch defaults to false (because RuntimeIdentifier did not propagate, and hence SelfContained defaults to false) and the build fails because the restore was against the latest runtime patch level, but the build operation was not (the NuGet error mentioned above by @dasMulli).

I don't know if we want to fix SelfContained propagation without having a fix for restoring / building for the appropriate patch level since the two are very much related. There are currently several issues tracking problems related to the patch level feature, as well.

For now, there are workarounds such as what's listed here and in https://github.com/dotnet/sdk/issues/2364. I'm going to move this to 2.2.1xx to see if we an make an appropriate, all-encompassing fix.

Making NuGet and MSBuild use the same properties for P2Ps would be great, I remember seeing this in https://github.com/dotnet/cli/issues/9544#issuecomment-399674198

NuGet does <GetRestoreProjectReferencesTask …ProjectReferences="@(ProjectReference)"> while MSBuild has logic to carefully unset some global properties (PrepareProjectReferences> @(AnnotatedProjects)), including RuntimeIdentifier.
I believe that NuGet and MSBuild evaluation will then see a different list of global properties. Is that correct?

For -r RID this always worked since NuGet always creates a non-RID dependency graph in addition to the RID-specific one.
But evaluation-wise, this will now become interesting with the plural RuntimeIdentifiers property which will need additional properties being set to restore only once for multiple RIDs and then publish for them. Maybe this will need some doc changes - https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli#simpleSelf

we are experiencing the same issue when trying to publish a project that is used to execute tests:
image

Was this page helpful?
0 / 5 - 0 ratings