fsprojects / Paket

A dependency manager for .NET with support for NuGet packages and Git repositories.
https://fsprojects.github.io/Paket/
MIT License
2.02k stars 525 forks source link

Package ... contains libraries, but not for the selected TargetFramework net452 in project ... #1693

Closed Thorium closed 8 years ago

Thorium commented 8 years ago

When I run paket.exe install, I got these warnings:

Package ... contains libraries, but not for the selected TargetFramework net452 in project ...

  1. If 452 is not available will this fallback to net451 and net45?
  2. It seems that packages xunit.assert and xunit.core are using dnxcore50 (.Net Core) and referencing all these libraries as Nuget-packages. So of course I use System.Collections and System.Linq in my other projects, but they are not using dnxcore. I don't have direct reference to core libraries via nuget.
Package Microsoft.Bcl contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\backend\myproj.fsproj.
Package Microsoft.Net.Http contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\backend\myproj.fsproj.
Package Zlib.Portable contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\backend\myproj.fsproj.
Package Zlib.Portable contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\backendcalc\backendcalc.fsproj.
Package Zlib.Portable contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Collections contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Diagnostics.Contracts contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Diagnostics.Debug contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Globalization contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.IO contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Linq.Expressions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Private.Uri contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Reflection contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Reflection.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Reflection.Primitives contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Reflection.TypeExtensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Resources.ResourceManager contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Runtime contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Runtime.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Text.Encoding contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Text.Encoding.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Threading contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Threading.Tasks contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\integrationtests\integrationtests.fsproj.
Package System.Collections contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Diagnostics.Contracts contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Diagnostics.Debug contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Globalization contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.IO contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Linq.Expressions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Private.Uri contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Reflection contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Reflection.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Reflection.Primitives contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Reflection.TypeExtensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Resources.ResourceManager contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Runtime contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Runtime.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Text.Encoding contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Text.Encoding.Extensions contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Threading contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Package System.Threading.Tasks contains libraries, but not for the selected TargetFramework net452 in project C:\git\myproj\unittests\unittests.fsproj.
Thorium commented 8 years ago

Adding limit framework >= 4.0 will significantly lower the amount of warnings.

Rcomian commented 8 years ago

We're getting this issue as well and it's causing a bit of confusion. Basically, if we install a package that supports .netcore but we don't use the .netcore support we get these warnings.

It's a weird situation really. I've made a reproduction here:

https://github.com/Rcomian/paket3dotnetcoreissue

It's a very simple repro.

We had a secondary issue which was warned correctly and we could resolve it, but was harder to see since the initial reaction is always, oh there's a hundred pointless warnings, ignore all.

Adding in framework: >= 4.0 does quiet the warnings. I'm really not sure if that's the thing to do or if it's just hiding the problem in paket.

forki commented 8 years ago

that framework limit is fine since you don't use coreclr

Rcomian commented 8 years ago

@forki thanks. Buuuuuut I can't help feel that paket might be able to work this out itself. As I say, we have had legitimate warnings in this area that we don't want to quiet.

forki commented 8 years ago

there is framework: auto-detect

Rcomian commented 8 years ago

There is and it works, but doing so means that now my .net core packages have been removed.

If I then switched to .netcore as a build target, we would have to re-run paket install, or maybe just restore.

But paket has this wonderful structure of conditionals everywhere so that we've not had to do that before - all packages were available and we could just build for different targets without having to recalculate packages in between.

The framework is fine as a workaround, I'm just not sure it's a solution.

Rcomian commented 8 years ago

I think this is an underlying issue that's causing other bugs, I've got 2 further build problems based on the same dependency issues:

  1. I'm building from msbuild to single output folder for the solution. I'm getting "Could not find a part of the path 'bin\Release\System.Collections.dll'" for my non-dotnetcore build.
  2. I'm trying to build projects with wixproj. But it's no longer including the wix targets because somehow the dotnetframework checks aren't working and the wix target import name isn't being set. This results in either trying to pull wix from the installed location (legacy wix upgrade) or trying to import with an empty path.
forki commented 8 years ago

I'm not sure I can follow

Rcomian commented 8 years ago

I'll try for a reproduction on that repository

Rcomian commented 8 years ago

I've updated

https://github.com/Rcomian/paket3dotnetcoreissue

Double click paket.update.cmd for the warnings, Double click build.cmd for the first build failure.

forki commented 8 years ago

what do you expect it to do differently?

Rcomian commented 8 years ago

The paket.update.cmd I would expect to complete without warnings. It does the right thing to the files as far as I can tell, but the warnings are spurious, unnecessary.

The build.cmd - there's no reason for that to fail. If you remove the /p:OutDir flag from the command, it does work. But it's failing when looking for dependencies that it doesn't need.

forki commented 8 years ago

so if the files are ok, then only thing for me to do is to look at the additional warnings and see if we get rid of those!?

Rcomian commented 8 years ago

warnings is step 1, for sure.

Step 2 would be to get the build.cmd working when we specify an output directory through msbuild. This might be a separate issue, looking at it.

forki commented 8 years ago

still don't understand why you think the message is not correct?

It has libs for netcore, but not for net45!?

Rcomian commented 8 years ago

Ah, ok, no problem. Ok this is really long, I'm sorry, but I'm trying to supply as much detail as I can. This might be 3 or 4 different issues or 1 root issue, I'm not sure.

The message is a warning based on the currently selected framework. Basically, one of the packages in the tree doesn't have libs for the currently selected framework.

That's fine as stands - but there's a problem. That package (lets use System.Collections as an example). is not being depended on directly. It's indirect.

The direct dependency is AutoMapper. With full .net 4.5.2, AutoMapper has no dependencies. So for the selected framework, we're good.

Now AutoMapper can depend on System.Collections, if the framework is .netCore. I think it's correct that System.Collections should be downloaded and installed in the packges folder for this reason. It's also correct to add System.Collections to the list of references behind the guard conditionals that say "If the currently selected framework is .netcore, then reference this assembly".

Paket has had this behaviour since day 1 and I love it. It's really powerful and correct to not have to re-install your nuget packages every time you switch frameworks.

So all that works.

But then paket looks at System.Collections, sees it only has assemblies for .netcore and not .net452 as currently selected, and prints the warning.

I come down hard on warnings in general, warning fatigue hides real problems. So I don't want spurious warnings.

But System.Collections isn't even going to be brought in as a dependency when we're building for .net452.

So the build would work - because we don't need System.Collections with this configuration, but the warning implies it won't.

So that's the warning issue. If that makes sense. I can try to explain another way if you like. You can stop there for a moment, but there's an additional thing on the back of this:

Paket now creates an "AfterBuild" build step that copies dependencies to the output. This step is copying System.Collections to the output folder even tho it's not required in the current build. That is, a build that is being built for .net4.5.2 that depends on AutoMapper which has no dependencies when used with .net4.5.2 is getting its additional dependencies from .netcore added to the output during build.

More than that, if you then specify the output folder using /p:OutDir on the msbuild commandline, it fails to copy System.Collections. It looks like the build step builds the path of where it expects the output to be, but because we specify it directly, the build step gets the wrong path and can't find what it's after. So the build fails trying to copy something from the wrong location when it doesn't need it in the first place.

Which is messing our builds up :P

Now there is a workaround of sorts. Putting in Framework: >4.0

This helps for now. But we would like to target .netcore in the future as well as .net4.5.2 (or 4.6 or 4.7 or whatever). So although this workaround appears to solve the issue, it's kind of sidestepping it, rather than getting to the root of the problems.

There's another workaround: framework: auto. This only installs the dependencies for the currently selected framework. But if we want to target .netcore and .net452, we can't just change the msbuild commandline like we can now:

http://stackoverflow.com/questions/12003475/override-target-framework-from-command-line

The commandline version works normally because of the wonderful conditionals that paket adds to the csproj file that ensures that the right assemblies are referenced in the right situations.

But if you use framework: auto, those conditionals are cut down to only the framework that was selected when paket install was run.

So if you change the framework, suddenly there's no assemblies being referenced. We'd need to run paket-install with the newly selected framework and change all the .csproj files.

There is an additional problem with the .wixproj files which I'm trying to pin down with a reproduction. Effectively it's looking like there are some conditionals being used that are always false, but right now I'm not sure.

To sum up. I think there's an issue with paket bringing in dependencies it doesn't need. In particular, .netcore dependencies when the currently selected framework is .net452, or .net46

(I've just noticed the latest version of paket doesn't fail the build as I discuss here, it successfully copies the unnecessary dependent assemblies into the wrong folder).

forki commented 8 years ago

thanks for clarification. that message should be gone in latest alpha. Please test and if it works I will release it properly

Rcomian commented 8 years ago

Sorry for the delay. Yes the warning is gone, but is it right to get rid of the warning entirely? I still think it's valid to warn if, for example, I depend on AutoMapper with .net 452 and AutoMapper only supports .netcore ...

forki commented 8 years ago

the warning is not gone entirely

Rcomian commented 8 years ago

Ok cool :D works then

Rcomian commented 8 years ago

Thank you!