diff --git a/NuGet.Docs/Create/nuget3-packages-walkthrough.md b/NuGet.Docs/Create/nuget3-packages-walkthrough.md index c50a517d..3594447b 100644 --- a/NuGet.Docs/Create/nuget3-packages-walkthrough.md +++ b/NuGet.Docs/Create/nuget3-packages-walkthrough.md @@ -1,74 +1,63 @@ # NuGet 3 Package Authoring # +## 1 .NET library ## +### 1.1 Portable library targeting `dotnet` ### +This is the simplest type of package. You wish to ship a portable class library in package that you intend to be consumed only in projects supporting nuget v3 and project.json. The `dotnet` target moniker represents all platforms who's .NET surface area can be represented entirely by package dependencies. For many projects using this target moniker will eliminate the need to ever list specific platforms in a package. -## .NET library ## -### pure portable on dotnet ### -This is the simplest type of package. You wish to ship a portable class library in package that you intend to be consumed only in projects supporting nuget v3 and project.json. - +The below sample illustrates the dependencies of a project.json based PCL targeting .NET Framework 4.6, Windows Universal 10.0, and ASP.NET Core 5.0. The dependency section can be generated using the third party [NuSpec.ReferenceGenerator](https://www.nuget.org/packages/NuSpec.ReferenceGenerator/) package. ``` - - - - - - - + + lib/dotnet/System.Banana.dll - ``` +### 1.2 Support packages.config with `dotnet` ### +Now lets suppose that we want to target older platforms that don't yet support project.json. The below example changes the PCL to target .NET Framework 4.5, Windows 8, Windows Phone 8.1 and Windows Phone Silverlight 8. -### supporting nuget v2 and project types that don't yet support project.json ### -NuGet v2 and packages.config in Nuget v3 will promote any indirect references to direct references. This creates a problem for the example we have so far since the dependencies of the library cannot always be updated on platforms like .NET desktop or Windows Phone where the packages just represent the surface area in the platform. +Nuget using packages.config will promote any indirect references to direct references. Nuget will also offer upgrade of any packages directly referenced. This creates a problem for the example we have so far since the dependencies of the library cannot always be updated on platforms like .NET desktop or Windows Phone where the packages just represent the surface area inbox in the platform. -To avoid this problem we can add empty dependency groups for all of the platforms where our dependencies are included in box. This should **not** be done for platforms that rely on packages for implementation (like DNXCore, NETCore version >= 5.0, and UAP). This should also **not** be done if the version of the dependency is higher than the one inbox. +To avoid this problem we can add empty dependency groups for all of the platforms where our dependencies are included in box. This should **not** be done for platforms that rely on packages for implementation (Windows Universal 10.0 and ASP.NET Core 5.0). This should only be done for platforms which you've specifically targeted in the project. + +In order to also support installation into packages.config based portable projects NuGet requires `portable-` folder and dependency group. The dependency group is needed for the same reason as above, the file is needed because NuGet does not treat any `portable-` targets as compatible with `dotnet`. ``` - - - - + - - - + - - - - + - - + + +lib/portable-netcore45+net45+wp8+wpa8/System.Banana.dll lib/dotnet/System.Banana.dll ``` +The .NET and NuGet team hope to eliminate the need to create these additional dependency groups in future releases. -The .NET and NuGet team hope to eliminate the need to do this in future releases. - -### native library ### +### 1.3 Native library ### Some libraries can benefit from using a native component within their package. This can help to provide a performance optimized native implementation of an algorithm or directly consume some other native SDK (eg: statically link it or compile against its headers). -Add native runtime entries. +To represent the native component we will use 'runtime/{rid}/native' folders. The '{rid}' used during package restore is determined by the runtimes section of the project.json. The '{rid}' used at package resolve time is determined by the NuGet client and should match one of the {rid}s in the project.json. In the case of the MSBuild client in Visual Studio, this is based on the project's properties like Platform and TargetFramework. ``` lib/dotnet/System.Banana.dll -runtimes/win7-x86/native/cherry.dll -runtimes/win7-x64/native/cherry.dll +runtimes/win-x86/native/cherry.dll +runtimes/win-x64/native/cherry.dll runtimes/win10-arm/native/cherry.dll ``` Note that we still use `lib` for the managed assembly. This is behaving as both the compile time and runtime asset for the managed assembly. The presense of `runtime/{rid}/native` folders does not replace lib. @@ -78,35 +67,105 @@ The .NET assembly is likely now runtime specific since it depends on the runtime TODO: tooling to produce reference assembly. ``` ref/dotnet/System.Banana.dll -runtimes/win7/lib/dotnet/System.Banana.dll -runtimes/win7-x86/native/cherry.dll -runtimes/win7-x64/native/cherry.dll +runtimes/win/lib/dotnet/System.Banana.dll +runtimes/win-x86/native/cherry.dll +runtimes/win-x64/native/cherry.dll runtimes/win10-arm/native/cherry.dll ``` Note that we now need a `ref` folder. This is because the `runtimes/{rid}/lib/dotnet` folder replaces `lib/dotnet` since it is more specific. Since the `runtimes` folder is only used at runtime we need a seperate definition of the compile time asset. This will give folks the right error when they try to install the package on a new runtime (eg: Linux) instead of permitting the package to install and failing to find the DLL at runtime. -### architecture specific implementation ### +To help produce a reference assembly you can use the Microsoft.DotNet.BuildTools.GenAPI package. TODO: sample. + +### 1.4 Architecture specific .NET library ### It may be necessary to include architecture specific managed code in your package. If this is the case the implementation assembly will need to be placed in architecture specific folders. These folders are only used for the runtime asset from your package, so we'll need to provide a compile time asset. For that we use `ref`. This has the added benefit of making your architecture specific library consumable by AnyCPU projects. -TODO: tooling to produce reference assembly. +To help produce a reference assembly you can use the Microsoft.DotNet.BuildTools.GenAPI package. TODO: sample. ``` ref/dotnet/System.Banana.dll runtimes/win7-x86/lib/dotnet/System.Banana.dll runtimes/win7-x64/lib/dotnet/System.Banana.dll -runtimes/win10-arm/native/System.Banana.dll +runtimes/win10-arm/lib/dotnet/System.Banana.dll +runtimes/win7-x86/native/cherry.dll +runtimes/win7-x64/native/cherry.dll +runtimes/win10-arm/native/cherry.dll +``` + +### 1.5 Support packages.config with `runtimes` ### +Both of the previous examples used the NuGet v3 project.json feature of `runtimes` to provide OS/architecture specific assets. To do the same for packages.config based projects we'll need to approximate this feature using msbuild targets. We'll add the targets to the 'build/dotnet' folder, matching the target moniker used by our assets and give it the same name as our package. +``` +build/dotnet/System.Banana.targets +ref/dotnet/System.Banana.dll +runtimes/win7-x86/lib/dotnet/System.Banana.dll +runtimes/win7-x64/lib/dotnet/System.Banana.dll +runtimes/win10-arm/lib/dotnet/System.Banana.dll +runtimes/win7-x86/native/cherry.dll +runtimes/win7-x64/native/cherry.dll +runtimes/win10-arm/native/cherry.dll ``` -### cross compiling for additional platforms ### +``` + + + + + + false + + + + + + +``` +Note that this assumes only one `{rid}` per architecture. If a package uses multiple `{rid}`s per architcture these targets will be more involved than just `win*`. + +### 1.6 Cross compiling for additional platforms ### +Expanding on the previous example, suppose that a single build of a library cannot provide the full functionality on all platforms. For example: you'd like to use the System.IO.MemoryStream.TryGetBuffer. This API is available in System.IO version 4.0.10 which is supported on .NET Framework 4.6, Windows Universal 10.0, and ASP.NET Core 5.0. The API can return the underlying byte array used by the MemoryStream without copying it. On older platforms the API is not available but a similar API ToArray() can be used which does a copy of the byte array. + +The package will contain two different PCLs. +Build A targeting .NET Framework 4.5, Windows 8, Windows Phone 8.1 and Windows Phone Silverlight 8, using MemoryStream.ToArray(); +Build B targeting .NET Framework 4.6, Windows Universal 10.0, and ASP.NET Core 5.0, using MemoryStream.TryGetBuffer(). + +``` + + + + + + + + + + + + + + + + + + + +lib/portable-netcore45+net45+wp8+wpa8/System.Banana.dll (build A) +lib/netcore45/System.Banana.dll (build A, required since dotnet would take precedence over portable-*) +lib/netcore50/System.Banana.dll (build B, required since netcore45 would take precedence over dotnet) +lib/net45/System.Banana.dll (build A, required since dotnet would take precedence over portable-*) +lib/net46/System.Banana.dll (build B, required since net45 would take precedence over dotnet) +lib/wp8/System.Banana.dll (build A, required since dotnet would take precedence over portable-*) +lib/wpa8/System.Banana.dll (build A, required since dotnet would take precedence over portable-*) +lib/dotnet/System.Banana.dll (build B) +``` -## WinMD library ## -### with managed implementation ### -### with native implementation ### -### with resources ### -### supporting c++ ### -### supporting javascript ### -cannot include managed dll in packages that intend to support JS because JS does not handle dll references. +## 2 WinMD library ## +### 2.1 .NET implementation ### +### 2.2 Native implementation ### +### 2.3 With resources ### +### 2.4 Supporting c++ ### +### 2.5 Supporting javascript ### +note: cannot include managed dll in packages that intend to support JS because JS does not handle dll references. diff --git a/NuGet.Docs/Create/uwp-create.md b/NuGet.Docs/Create/uwp-create.md index 5f3b61f8..227a7af2 100644 --- a/NuGet.Docs/Create/uwp-create.md +++ b/NuGet.Docs/Create/uwp-create.md @@ -13,23 +13,6 @@ If you target netcore45 already, and you don’t need to take advantage of anyth In this case you need to add the uap10.0 TxM to your package. Create a new directory in your package and add the assembly that has been compiled to work with Windows 10 to that directory. -## I don’t need Windows 10 specific APIs, but want new .NET features or don’t have netcore45 already ## - -In this case you would add the new dotnet TxM to your package. Unlike other TxMs dotnet doesn’t imply a surface area or platform. It is stating that your package will work on any platform that your dependencies work on. When building a package with the dotnet TxM you are likely to have many more TxM specific dependencies in your NuSpec, as you will need to define the BCL packages you depend on, such System.Text, System.Xml, etc. The locations that those dependencies work on define where your package will work. - -### How do I find out my dependencies? - -There are two ways to figure out which dependencies to list: - -1. Use `ILDasm` to look at your dll to see what assemblies are actually needed at runtime. Then determine which NuGet package they each come from. This is the hard way. -2. Use the [NuSpec Dependency Generator](https://github.com/onovotny/ReferenceGenerator) **3rd party** tool. The tool automates the process and updates your .nuspec file with the depependant packages on build. It is available via a NuGet package, [NuSpec.ReferenceGenerator](https://www.nuget.org/packages/NuSpec.ReferenceGenerator/). - -See the project.json document for details on supports and includes features that both help in the creation of a package that support the dotnet TxM. - -**If your package is intended to work with the new PCL project, we highly recommend to create a dotnet folder, to avoid warnings and potential compatibility issues.** - - - ## Directory Structure ## NuGet packages using the new format have the following well-known directories and behaviors: @@ -66,7 +49,7 @@ MSBuild knows to look for these two files and automatically imports them near th ## Lib and Ref ## -The behavior of the Lib directory hasn't changed significantly in NuGet v3. However, all assemblies must be within sub-folders named after a TxM, and can no longer be placed directly under the lib folder. A TxM is the name of a platform that a given asset in a package is supposed to work for. Logically these are an extension of the Target Framework Monikers (TFM) e.g. *net45*, *net46*, *netcore50*, and *dnxcore50* are all examples of TxMs. We use a new term TxM because a TxM can refer to a framework (TFM) as well as other platform specific surface area. For example the UWP TxM (UAP10.0) represents the .NET surface area as well as the Windows surface area for UWP applications. +The behavior of the Lib directory hasn't changed significantly in NuGet v3. However, all assemblies must be within sub-folders named after a TxM, and can no longer be placed directly under the lib folder. A TxM is the name of a platform that a given asset in a package is supposed to work for. Logically these are an extension of the Target Framework Monikers (TFM) e.g. *net45*, *net46*, *netcore50*, *uap10.0* and *dnxcore50* are all examples of TxMs. We use a new term TxM because a TxM can refer to a framework (TFM) as well as other platform specific surface area. For example the UWP TxM (UAP10.0) represents the .NET surface area as well as the Windows surface area for UWP applications. An example lib structure: @@ -75,7 +58,10 @@ An example lib structure: │ MyLibrary.dll │ └───wp81 - MyLibrary.dll + | MyLibrary.dll + | + └───uap10.0 + MyLibrary.dll The lib folder contains assemblies that will be used at runtime. For most packages a directory under lib for each of the target TxMs is all that is required.