Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project references with ReferenceOutputAssembly=false should be ignored during VS restore #4992

Closed
livarcocc opened this issue Apr 6, 2017 · 10 comments

Comments

@livarcocc
Copy link

From @hach-que on April 6, 2017 11:15

Steps to reproduce

  • Create a solution with two .NET Standard projects
  • In the solution file, specify dependencies e.g.:
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMP.Test.Framework", "HiveMP.Test.Framework\HiveMP.Test.Framework.csproj", "{ED0EB86B-502C-4523-B24F-564620359721}"
	ProjectSection(ProjectDependencies) = postProject
		{F6D6B937-3689-443F-BD20-FE4F7C5E9FCD} = {F6D6B937-3689-443F-BD20-FE4F7C5E9FCD}
		{0F934DF0-7B27-4192-96C5-BE4F81594175} = {0F934DF0-7B27-4192-96C5-BE4F81594175}
	EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HiveMP.ClientGenerator", "HiveMP.ClientGenerator\HiveMP.ClientGenerator.csproj", "{0F934DF0-7B27-4192-96C5-BE4F81594175}"
EndProject
  • Run dotnet restore.

Expected behavior

  • dotnet restore should restore packages for HiveMP.Test.Framework.
  • The obj folder inside HiveMP.Test.Framework with project.assets.json should exist.

Actual behavior

  • dotnet restore doesn't process HiveMP.Test.Framework, packages aren't restored.

Environment data

dotnet --info output:

.NET Command Line Tools (1.0.1)

Product Information:
 Version:            1.0.1
 Commit SHA-1 hash:  005db40cd1

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

Copied from original issue: dotnet/cli#6258

@livarcocc
Copy link
Author

From @hach-que on April 6, 2017 11:17

To clarify, we specify dependencies here because HiveMP.Test.Framework has a Prebuild step which runs HiveMP.ClientGenerator to create C# source files.

Both package restore and build for both these projects works fine in Visual Studio 2017, but doesn't work on the dotnet CLI (under either Windows or Linux).

@livarcocc
Copy link
Author

From @hach-que on April 6, 2017 11:31

For some reason, removing and re-adding the project dependencies in Visual Studio changed all the project type guids in the solution from FAE04EC0-301F-11D3-BF4B-00C04F79EFBC to 9A19103F-16F7-4668-BE54-9A1E7A4F7556. However, dotnet restore still doesn't work in this case. The only way to make dotnet restore is to remove the ProjectDependencies section from the solution.

@livarcocc
Copy link
Author

From @hach-que on April 6, 2017 14:28

So I tried using ProjectReferences in the HiveMP.Test.Framework project instead of ProjectDependencies in the solution, like so:

  <ItemGroup>
    <ProjectReferenceWithConfiguration Include="..\hivemp\HiveMP.csproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReferenceWithConfiguration>
    <ProjectReferenceWithConfiguration Include="..\HiveMP.ClientGenerator\HiveMP.ClientGenerator.csproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReferenceWithConfiguration>
  </ItemGroup>

(I also tried ProjectReference instead of ProjectReferenceWithConfiguration). This is the recommended way of doing build-time (but not runtime) dependencies as per this MSDN article: https://blogs.msdn.microsoft.com/kirillosenkov/2015/04/04/how-to-have-a-project-reference-without-referencing-the-actual-binary/

However, in .NET Core this doesn't due to the GetNearestTargetFramework in Microsoft.NET.Sdk.Common.targets, which causes this error:

       "C:\Users\June\Documents\Projects\hivemp\hivemp.build.sln" (Publish target) (1) ->
       "C:\Users\June\Documents\Projects\hivemp\HiveMP.Test.Framework\HiveMP.Test.Framework.csproj" (Publish target) (17) ->
       "C:\Users\June\Documents\Projects\hivemp\hivemp\HiveMP.csproj" (GetTargetFrameworkProperties target) (2:2) ->
       (GetTargetFrameworkProperties target) ->
         C:\Program Files\dotnet\sdk\1.0.1\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.Common.targets(73,5): error : Project 'C:\Users\June\Documents\Projects\hivemp\hivemp\HiveMP.csproj' targets '.NETCoreApp,Version=v1.1'. It cannot be referenced by a project that targets '.NETStandard,Version=v1.6'. [C:\Users\June\Documents\Projects\hivemp\hivemp\HiveMP.csproj]

Even though this kind of check isn't required because it isn't referencing the output assembly.

The workaround is to make the library a .NET Core library instead of .NET Standard so that this check passes, but preferrably that should not be required.

@livarcocc
Copy link
Author

From @hach-que on April 6, 2017 15:4

So for anyone else running into this issue, this is what I ended up with.

This allows you to have a .NET Core project whose source code files are generated from another .NET Core project in the same solution.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>

  <Target Name="PreBuild" BeforeTargets="PreBuildEvent" DependsOnTargets="ResolveProjectReferences">
    <Exec Command="dotnet &quot;$(SolutionDir)HiveMP.ClientGenerator/bin/$(Configuration)/netcoreapp1.1/HiveMP.ClientGenerator.dll&quot; self-generate $(Configuration)" />

    <ItemGroup>
      <Compile Include="GeneratedClientApis\*" />
    </ItemGroup>
  </Target>

  <ItemGroup>
    <ProjectReferenceWithConfiguration Include="..\hivemp\HiveMP.csproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReferenceWithConfiguration>
    <ProjectReferenceWithConfiguration Include="..\HiveMP.ClientGenerator\HiveMP.ClientGenerator.csproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReferenceWithConfiguration>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="10.0.2" />
  </ItemGroup>

</Project>

Important points are:

  • The project references must be a compatible framework (i.e. you can't have a .NET Standard library reference a .NET Core project, even with ReferenceOutputAssembly set to false).
  • The prebuild target must have the signature of Target Name="PreBuild" BeforeTargets="PreBuildEvent" DependsOnTargets="ResolveProjectReferences". This ensures the prebuild step runs after project references have built (which we want to so that we can actually run the program that's going to generate code).
  • The generated files then need to be manually included with <Compile> in an ItemGroup as part of that target, as whatever mechanism scans the project directory to auto-include files runs before this point and thus otherwise the generated files won't be included in the Csc compiler task.

Hopefully this helps someone else in the same situation.

@emgarten
Copy link
Member

emgarten commented Apr 6, 2017

@hach-que are you setting project build order dependencies in the solution? Are you hitting this issue: #4578 or this unrelated?

ReferenceOutputAssembly=false projects are currently skipped, this is tracked here: #4700

To workaround this you will need to restore these projects directly.

@hach-que
Copy link

hach-que commented Apr 6, 2017

Yeah, that's the one. Though that doesn't address the build-time issues I was having around framework checks (even if NuGet currently doesn't support ReferenceOutputAssembly=false, the MSBuild targets that happen as part of publish should).

@emgarten
Copy link
Member

emgarten commented Apr 7, 2017

What issues are you seeing with framework checks?

@hach-que
Copy link

hach-que commented Apr 7, 2017

When ReferenceOutputAssembly=false for a ProjectReference, the MSBuild targets still check if the frameworks are compatible, even though no assembly reference will be made.

It means that you can't have a ProjectReference to a .NET Core console project from a .NET Standard project with ReferenceOutputAssembly=false because it says you can't reference .NET Core from .NET Standard due to framework compatibility.

@emgarten
Copy link
Member

emgarten commented Apr 7, 2017

@hach-que thanks for explaining it, I was able to repro this.

From Visual Studio 2017 ReferenceOutputAssembly=false is ignored and these are treated as normal project references.
From the command the property is checked and those projects are not checked for compatibility.

I verified when debugging this that ReferenceOutputAssembly=false is sent as part of nominations. NuGet should exclude these projects here: https:/NuGet/NuGet.Client/blob/dev/src/NuGet.Clients/NuGet.SolutionRestoreManager/VsSolutionRestoreService.cs#L340-L343

I'm going to update the issue title to use this as tracking for the VS restore issue. Let me know if there is anything else that hasn't been covered yet by another issue.

The build issue is covered here: dotnet/sdk#1096

//cc @alpaix

@emgarten emgarten changed the title dotnet restore does not restore packages of projects with dependencies in .sln file Project references with ReferenceOutputAssembly=false should be ignored during VS restore Apr 7, 2017
@emgarten emgarten self-assigned this Apr 30, 2017
@emgarten emgarten added this to the 4.3 milestone Apr 30, 2017
emgarten added a commit to NuGet/NuGet.Client that referenced this issue May 1, 2017
…sual Studio restore

Projects with ReferenceOutputAssembly=false should be ignored during restore in Visual Studio. Transitive dependencies should not flow from these projects to the parent project.

Fixes NuGet/Home#4992
@emgarten emgarten modified the milestones: 4.3 - 4/17 thru 5/6, 4.3 May 1, 2017
emgarten added a commit to NuGet/NuGet.Client that referenced this issue May 2, 2017
…sual Studio restore

Projects with ReferenceOutputAssembly=false should be ignored during restore in Visual Studio. Transitive dependencies should not flow from these projects to the parent project.

Fixes NuGet/Home#4992
@aelij
Copy link

aelij commented Feb 20, 2019

We're still seeing this issue in a UWP project referencing a .NET Framework project with ReferenceOutputAssembly=false (getting a NU1201). #6079 also seems related.

NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299). Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-arm. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-arm-aot. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-arm64-aot. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-x64. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-x64-aot. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-x86. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)
NU1201: Project Foo.DesktopBridge is not compatible with uap10.0.16299 (UAP,Version=v10.0.16299) / win10-x86-aot. Project Foo.DesktopBridge supports: net47 (.NETFramework,Version=v4.7)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants