NuGet / Home

Repo for NuGet Client issues
Other
1.49k stars 252 forks source link

Dependencies specified by RID as not usable as project's references (but shown as) #3397

Closed xlegalles closed 4 years ago

xlegalles commented 8 years ago

Hi, We try to use project.json to describe dependencies to a package containing C++ managed libraries. Its content is something like that:

1.0.0.0
  |__ runtimes
    |__win-x64/lib/net452/*.dll
    |__win-x86/lib/net452/*.dll

The project.json is very simple:

{
  "runtimes": {
    "win-x86": { },
    "win-x64": { }
  },
  "dependencies": {
    "MyPackage": "1.0.0.0"
  },
  "frameworks": {
    "net452": {}
  }
}

The result is 1) the package is well displayed in VS under references and 2) the right dll from the package is well copied in the output folder depending on the platform x86/x64. BUT the referenced dll is not usable in the project i.e. it does not compile if you try to use it in the source code, no intellisense, etc.

Actually the dll is not listed in the project references during the compilation. So, I dig into the Microsoft.NuGet.Build.Tasks project and found the issue: in the GetReferences method, you always list targets without any runtime identifier: var target = GetTargetOrAttemptFallback(lockFile, needsRuntimeIdentifier: false);

Why don't you list targets without and with RID?

Thank you.

jasonmalinowski commented 8 years ago

I'm not sure if there's better docs out there than these (@rrelyea can probably comment on that) but you'll probably want to read that if you haven't already. The NuGet model here explicitly splits up the concept of build time (i.e. passed to the compiler) vs. run time (needed to be deployed with the app). The runtimes folder is explicitly the latter only; we won't pass those to the compiler because it might not make sense to.

Assuming for a moment that your "public interface" is the same for different platforms (i.e you don't have different types, method signatures, etc.) then what you probably want to do is also put an assembly in the 'ref' folder, which will get passed to the compiler. That's a platform-independent binary that's picked up for all builds, but isn't copied anywhere.

If your public interface is different, then I'm not sure what the right package spec is here. I'm still not sure if we have platform-specific ref, partly because that's explicitly what we didn't want when we originally designed this. @ericstj might know if that changed. The reason the build task doesn't look at the RID-specific target was because supposedly that's equivalent to the RID-less target, because of the lack of support here.

ericstj commented 8 years ago

RID assets have always been only for "runtime" not "compile" time. There is a feature request to allow NuGet to support RID-specific compile time but it's on the backlog: https://github.com/NuGet/Home/issues/1660.

That means for any package today that needs RID-specific implementations, it must also expose a assembly in either ref or lib to be used at compile time. If in 'ref' it can be a reference assembly and will never be used at runtime. If in lib it should be a RID-agnostic implementation since it will be used at runtime if the project does not specify a RID in it's project.json.

xlegalles commented 8 years ago

Thank you for your explanation. The doc that you reference is simple and clear enough but this is not the case for everything I read about project.json! And my mistake was that I tried to understand the problem and make it work from the json definition :( For instance I found that I should do a clear distinction in the runtime folder between native dlls (in a native folder) and .NET ones (in a lib/netxxx folder). That's why I could not understand why .NET libraries were only copied and not referenced. But now I know from Microsoft.NuGet.Build.Tasks, that you take everything from the runtime folder, or nothing. And with your explanation, everything makes sense. To conclude, I agree that it should be possible to extract a common interface and put it in the 'ref' folder. And it would be interesting if you could add something in docs about it. Thank you.

ericstj commented 8 years ago

@harikmenon didn't you have some docs you were working on around this?

nkolev92 commented 4 years ago

At this point this is a stale issue.

The docs for packing runtime specific assets is in https://docs.microsoft.com/en-us/nuget/create-packages/supporting-multiple-target-frameworks#architecture-specific-folders.