Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding x86 and x64 libraries to NuGet package

Tags:

I have made a library which depends on CefSharp which requires to build the library for specific platforms. So no AnyCPU support.

Now I want to pack this into a NuGet. As far as I understand, you have to put these files into the build folder and have a .targets file which picks the correct dll to reference. So I ended up with a NuGet package looking like this:

lib     monodroid         MyLib.dll     xamarin.ios10         MyLib.dll     net45         MyLib.dll (x86) build     net45         x86             MyLib.dll (x86)         x64             MyLib.dll (x64)         MyLib.targets 

I put the following inside of the .targets file:

<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">   <Target Name="PlatformCheck" BeforeTargets="InjectReference"     Condition="(('$(Platform)' != 'x86') AND  ('$(Platform)' != 'x64'))">     <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' platform. You need to specify platform (x86 or x64)." />   </Target>      <Target Name="InjectReference" BeforeTargets="ResolveAssemblyReferences">     <ItemGroup Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'x64'">       <Reference Include="MyLib">         <HintPath>$(MSBuildThisFileDirectory)$(Platform)\MyLib.dll</HintPath>       </Reference>     </ItemGroup>   </Target> </Project> 

So far so good. Now to the problem. When adding this NuGet to a new WPF project, I see the reference to the library appearing in the .csproj file like:

<Reference Include="MyLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d64412599724c860, processorArchitecture=x86">   <HintPath>..\packages\MyLib.0.0.1\lib\net45\MyLib.dll</HintPath>   <Private>True</Private> </Reference> 

Although I don't see anything mentioned about the .targets file. Is this still the way to do it with NuGet 3? Did I do something wrong? Currently, this fails at runtime when running x64 because of the reference to the x86 lib.

like image 721
Cheesebaron Avatar asked Feb 03 '16 14:02

Cheesebaron


People also ask

What does a Nuspec file do?

A . nuspec file is an XML manifest that contains package metadata. This manifest is used both to build the package and to provide information to consumers. The manifest is always included in a package.


1 Answers

After fiddling with this for way too long, I figured it out.

Apparently, the build.prop and build.target files need to have the exact same name as the NuGet package has, otherwise it will not be added in the csproj file.

EDIT:

I have created a small GitHub repository showing how to use this for your own project.

It demonstrates a solution with 3 projects - one for iOS, one for Android, and a Net45 which targets both x86 and x64.

Notice that in the .props file, the paths are pointing at the folder structure of the unpacked NuGet. So these paths map to what you have put in your nuspec file.

So as in the repo, you define a nuspec like:

<?xml version="1.0"?> <package>   <metadata>     <id>My.Awesome.Library</id>     <version>1.0.0</version>     <title>My Awesome Library</title>     <description>Herpa Derpa</description>   </metadata>   <files>     <file src="My.Awesome.Library.Droid\bin\Release\My.Awesome.Library.*"       target="lib\monodroid70" />      <file src="My.Awesome.Library.iOS\bin\Release\My.Awesome.Library.*"       target="lib\xamarin.ios10" />      <file src="My.Awesome.Library.Net45\bin\x64\Release\My.Awesome.Library.*"       target="build\x64" />      <file src="My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*"       target="build\x86" />     <file src="My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*"       target="lib\net45" />          <file src="My.Awesome.Library.props" target="build\net45" />   </files> </package> 

I put my x86 files into build\x86 and x64 files into build\x64. The name of the folder build could essentially be anything in this case, for these files. What matters here is that the props file, below points at these folders for the respective platforms.

I am not sure whether putting the x86 lib into lib\net45 even matters. You can experiment with that. The props file should pick the correct one for you anyways.

<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">   <ItemGroup>     <Reference Include="My.Awesome.Library" Condition="'$(Platform)' == 'x86'">       <HintPath>$(MSBuildThisFileDirectory)..\x86\My.Awesome.Library.dll</HintPath>     </Reference>     <Reference Include="My.Awesome.Library" Condition="'$(Platform)' == 'x64'">       <HintPath>$(MSBuildThisFileDirectory)..\x64\My.Awesome.Library.dll</HintPath>     </Reference>   </ItemGroup> </Project> 

In this case, $(MSBuildThisFileDirectory) would be the build\net45\ folder, make sure your path correctly points at the dll's. The build\net45 folder is important here. This is how NuGet automatically imports targets and props files.

Also notice the name My.Awesome.Library is pretty consistent all around. What is important here is that the name of your props file matches the NuGet package ID. Otherwise, it seems like NuGet won't import it.

like image 113
Cheesebaron Avatar answered Oct 13 '22 12:10

Cheesebaron