mrward / monodevelop-nuget-addin

NuGet addin for MonoDevelop and Xamarin Studio
MIT License
264 stars 38 forks source link

How to use appropriate configurations of library from package for different project configurations? #62

Closed ArsenShnurkov closed 8 years ago

ArsenShnurkov commented 8 years ago

I am creating a package for some library. Package have files bin/net35/Debug/mylib.dll bin/net35/Release/mylib.dll bin/net45/Debug/mylib.dll bin/net45/Release/mylib.dll

My main project have 2 configurations (Debug, Release). How monodevelop knows which dll's to reference from package in which configuration of main project?

mrward commented 8 years ago

NuGet does not have a concept of debug or release. If you want to do that you would need to create two separate NuGet packages or use a custom MSBuild targets file so the correct assemblies are used at compile time.

ArsenShnurkov commented 8 years ago

Ok, but monodevelop somehow knows, that some .dll-s are at path "bin/net45" (don't important for now - debug or release). Is this path hardcoded in monodevelop addin ?

Monodevelop shows dll under "References/From packages" node of Solution pad. Will it show 2 libraries (both Debug and Release)?

mrward commented 8 years ago

In a NuGet package you can have assemblies that target different frameworks. Taking Json.NET as an example it has the following directories with assemblies:

The last two are portable class assemblies (PCLs).

NuGet looks at the NuGet package and finds the best match based on your project's target framework. You do not have to create assemblies for all target frameworks. For example you could compile just for NET 2.0 and NuGet would use that in a .NET 4.5 project. The logic is inside NuGet itself not the addin.

MonoDevelop will not show two libraries in the References/From Packages node in the solution pad. It shows the assemblies referenced from the packages directory.

ArsenShnurkov commented 8 years ago

i found a link which says the same as you say:

https://docs.nuget.org/create/enforced-package-conventions#framework-version-folder-structure "selects the correct version of the assembly in the package by selecting the correct subfolder within the lib folder"

"nuget add assembly references" (also https://github.com/NuGet/Home/issues/2008)

"NuGet also supports targeting a specific framework profile by appending a dash and the profile name to the end of the folder."

But I still don't understood how many references nuget will add if several configurations are present in the same framework folder

mrward commented 8 years ago

Not sure what you mean by several configurations present. Taking the lib/net45 directory for Json.NET it contains two files:

If you install Json.NET into a .NET 4.5 project then lib/net45/Newtonsoft.Json.dll will be referenced. If there were other .dll files in the lib/net45 directory they would all be referenced.

NuGet does not support having configuration directories inside a lib directory. It only supports target frameworks. If you create a lib directory like:

lib/net45/Release/Foo.dll
lib/net45/Debug/FooBar.dll
lib/net45/Abc.dll

Foo.dll, FooBar.dll and Abc.dll will all be referenced by a .NET 4.5 project. NuGet just takes all the .dll files from inside the target framework directory and references them.

ArsenShnurkov commented 8 years ago

i mean, that for

lib/net45/Debug/Foo.dll
lib/net45/Release/Foo.dll

nuget should insert

... ...

As I understood, a patch is required for that

ArsenShnurkov commented 8 years ago

http://stackoverflow.com/a/30172491/1709408

"NuGet allows you to include an MSBuild targets file"

ok, but probably it is not called automatically from .csproj ?

https://docs.nuget.org/release-notes/nuget-2.5#automatic-import-of-msbuild-targets-and-props-files

"When NuGet installs a package with \build files, it will add an MSBuild element in the project file pointing to the .targets and .props files. The .props file is added at the top, whereas the .targets file is added to the bottom."

mrward commented 8 years ago

Correct. If you want to references like the following to be added:

 <Reference Condition="'$(Configuration)' == 'Debug'" Include="Debug/Foo.dll">...</Reference>
 <Reference Condition="'$(Configuration)' == 'Release'" Include="Release/Foo.dll">...</Reference>

Then you would need either to patch NuGet or use a custom MSBuild targets file and define the references yourself in the .targets file.