将 x86 和 x64 库添加到 NuGet 包 [英] Adding x86 and x64 libraries to NuGet package

查看:75
本文介绍了将 x86 和 x64 库添加到 NuGet 包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个依赖于 CefSharp 的库,它需要为特定平台构建库.所以不支持 AnyCPU.

现在我想把它打包成一个 NuGet.据我了解,您必须将这些文件放入 build 文件夹中,并有一个 .targets 文件来选择正确的 dll 进行引用.所以我最终得到了一个看起来像这样的 NuGet 包:

lib独角兽库文件xamarin.ios10库文件网45MyLib.dll (x86)建造网45x86MyLib.dll (x86)x64MyLib.dll (x64)MyLib.targets

我将以下内容放在 .targets 文件中:

<项目工具版本=4.0";xmlns=http://schemas.microsoft.com/developer/msbuild/2003"><目标名称=平台检查"BeforeTargets="InjectReference"条件=(('$(Platform)' != 'x86') AND ('$(Platform)' !='x64'))"><Error Text="$(MSBuildThisFileName) 在$(Platform)"平台上不能正常工作.您需要指定平台(x86 或 x64)."/></目标><目标名称=InjectReference";BeforeTargets=ResolveAssemblyReferences"><ItemGroup Condition="'$(Platform)' == 'x86' or '$(Platform)' == 'x64'"><Reference Include=MyLib"><HintPath>$(MSBuildThisFileDirectory)$(Platform)\MyLib.dll</HintPath></参考></项目组></目标></项目>

到目前为止一切顺利.现在到了问题.将此 NuGet 添加到新的 WPF 项目时,我看到对库的引用出现在 .csproj 文件中,例如:

虽然我没有看到任何关于 .targets 文件的内容.这仍然是使用 NuGet 3 的方法吗?我做错什么了吗?目前,由于对 x86 库的引用,这在运行 x64 时会在运行时失败.

解决方案

在摆弄这个问题太久之后,我想通了.

显然,build.prop 和 build.target 文件需要与 NuGet 包的名称完全相同,否则将不会添加到 csproj 文件中.

我创建了一个小型 GitHub 存储库,展示了如何将其用于您自己的项目.>

它展示了一个包含 3 个项目的解决方案 - 一个用于 iOS,一个用于 Android,以及一个面向 x86 和 x64 的 Net45.

请注意,在 .props 文件中,路径指向解压后的 NuGet 的文件夹结构.因此,这些路径映射到您放入 nuspec 文件中的内容.

就像在 repo 中一样,您定义了一个 nuspec,如:

<包装><元数据><id>My.Awesome.Library</id><version>1.0.0</version><title>我很棒的图书馆</title><description>Herpa Derpa</description></元数据><文件><file src=My.Awesome.Library.Droid\bin\Release\My.Awesome.Library.*";目标=lib\monodroid70";/><file src=My.Awesome.Library.iOS\bin\Release\My.Awesome.Library.*";目标=lib\xamarin.ios10";/><file src=My.Awesome.Library.Net45\bin\x64\Release\My.Awesome.Library.*";目标=build\x64";/><file src=My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*";目标=build\x86";/><file src=My.Awesome.Library.Net45\bin\x86\Release\My.Awesome.Library.*";目标=lib\net45";/><file src="My.Awesome.Library.props";目标=build\net45";/></文件></包>

我将 x86 文件放入 build\x86,将 x64 文件放入 build\x64.在这种情况下,对于这些文件,文件夹 build 的名称基本上可以是任何名称.这里重要的是 props 文件,下面指向各个平台的这些文件夹.

我不确定将 x86 库放入 lib\net45 是否重要.你可以试验一下.无论如何,道具文件应该为您选择正确的.

<项目工具版本=4.0";xmlns=http://schemas.microsoft.com/developer/msbuild/2003"><项目组><Reference Include=My.Awesome.Library"条件='$(平台)'=='x86'"><HintPath>$(MSBuildThisFileDirectory)..\x86\My.Awesome.Library.dll</HintPath></参考><Reference Include=My.Awesome.Library"条件='$(平台)'=='x64'"><HintPath>$(MSBuildThisFileDirectory)..\x64\My.Awesome.Library.dll</HintPath></参考></项目组></项目>

在这种情况下,$(MSBuildThisFileDirectory) 将是 build\net45\ 文件夹,请确保您的路径正确指向 dll.build\net45 文件夹在这里很重要.这就是 NuGet 自动导入目标和道具文件的方式.

另请注意 My.Awesome.Library 的名称非常一致.这里重要的是 props 文件的名称与 NuGet 包 ID 匹配.否则,NuGet 似乎不会导入它.

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.

解决方案

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.

这篇关于将 x86 和 x64 库添加到 NuGet 包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆