我创建了一个依赖于CEFsharp的库,它需要为特定平台构建库。所以没有AnyCPU支持。
现在我想将它打包成NuGet。据我所知,你必须将这些文件放入build文件夹并有一个.targets
文件,该文件选择正确的dll来引用。所以我最终得到了一个看起来像这样的NuGet包:
lib
monodroid
MyLib.dll
xamarin.ios10
MyLib.dll
net45
MyLib.dll (x86)
build
net45
x86
MyLib.dll (x86)
x64
MyLib.dll (x64)
MyLib.targets
我将以下内容放在.targets
文件中:
<?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>
到目前为止一切顺利。现在来问题了。将此NuGet添加到新的WPF项目时,我会看到.csproj
文件中出现的库的引用,如:
<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>
虽然我没有看到有关.targets
文件的任何内容。这仍然是使用NuGet 3的方法吗?我做错什么了吗?目前,由于对x86库的引用,在运行x64时运行时会失败。
答案 0 :(得分:18)
经过长时间摆弄这个问题后,我想出来了。
显然,build.prop和build.target文件需要与NuGet包具有完全相同的名称,否则它将不会添加到csproj文件中。
修改强>
我创建了一个small github repository,展示了如何将它用于您自己的项目。
它演示了一个包含3个项目的解决方案,一个用于iOS,一个用于Android,另一个用于x86和x64。
注意,在.props文件中。路径指向解压缩的NuGet的文件夹结构。因此,这些路径会映射到您在nuspec文件中放置的内容。
因此在repo中,您可以定义一个类似于
的nuspec<?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>
我将build\x86
和x64文件中的x86文件放入build\x64
。对于这些文件,文件夹构建的名称在本例中基本上可以是任何内容。这里重要的是道具文件,下面指向各个平台的这些文件夹。
我不确定将x86 lib放入lib\net45
是否重要。你可以尝试一下。道具文件应该为你选择正确的。
<?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>
在这种情况下,$(MSBuildThisFileDirectory)
将是build\net45\
文件夹,请确保您的路径正确指向dll。 build\net45
文件夹在这里很重要。这就是NuGet自动导入目标和道具文件的方式。
另请注意,名称My.Awesome.Library
非常一致。这里重要的是你的props文件的名称与NuGet包ID相匹配。否则,似乎NuGet不会导入它。
答案 1 :(得分:2)
我从上述解决方案中有一些不同意的事情。
如果通过将文件添加到nuget文件夹中来使用默认文件结构,则nuspec文件不必具有任何<Files>
信息。但是如果你想从解决方案文件夹中运行nuget文件,则需要
更好的nuspec内容:
<?xml version="1.0"?>
<package>
<metadata>
<id>YourProjectName</id>
<version>1.0.0</version>
<authors>John Doe</authors>
<title>Your Project Name</title>
<description>Herpa Derpa</description>
</metadata>
</package>
我也不同意他在build
文件夹中有.dll,这些应该放在你的lib
文件夹中,而build
文件夹中应该包含你的.targets
和.props
个文件。
nuget here的文档提到了这一点。
lib
文件夹也适用于参考文献中的.dll文件。其次,添加到build
文件夹中的.dll是在某些情况下可能需要的补充dll,类似于SQlite为其interop
dll执行此操作的方式。因此,在这种情况下,保留它们的更好位置是在lib文件夹中。
更好的文件夹结构:
- nuget
-- project.nuspec
-- build
---- YourProjectName.props
---- YourProjectName.targets
-- lib
--- <x64>
---- YourProjectName.dll
--- <x86>
---- YourProjectName.dll
.props文件内容:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x86'">
<HintPath>$(MSBuildThisFileDirectory)x86\YourProjectName.dll</HintPath>
</Reference>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x64'">
<HintPath>$(MSBuildThisFileDirectory)x64\YourProjectName.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
.targets文件内容:
<?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') and '$(TargetFrameworkVersion)'=='v4.6'">
<Reference Include=" YourProjectName ">
<HintPath>$(MSBuildThisFileDirectory)..\..\lib\net46\$(Platform)\ YourProjectName.dll</HintPath>
</Reference>
</ItemGroup>
</Target>
</Project>
您可以通过使用Nuget Package Manager APP打开您的nuspec文件并检查您添加的所有文件来检查上述情况是否有效。现在,当您将这些添加到项目时,它将根据为其引用的项目选择的架构加载dll。另请注意目标文件中,如果&#34;任何CPU&#34;已选中,并通知用户他们必须在x86和x64之间进行选择
修改强>
一点不清楚的是.target和.props的命名需要与nuget包文件名相同(也就是版本)。 如果没有这个,重新打开visual studio时会出现双引用。
答案 2 :(得分:-1)
为了阐明整个解决方案,这是它对我而言完美工作的方式
.nuspec文件
<?xml version="1.0"?>
<package>
<metadata>
<id>YourProjectName</id>
<version>1.0.0</version>
<authors>John Doe</authors>
<title>Your Project Name</title>
<description>Herpa Derpa</description>
</metadata>
</package>
文件夹结构
-- project.nuspec
-- build
---- YourProjectName.props
---- YourProjectName.targets
-- tools
--- <x64>
---- YourProjectName.dll
--- <x86>
---- YourProjectName.dll
.props文件
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x86'">
<HintPath>$(MSBuildThisFileDirectory)..\tools\x86\YourProjectName.dll</HintPath>
</Reference>
<Reference Include="YourProjectName" Condition="'$(Platform)' == 'x64'">
<HintPath>$(MSBuildThisFileDirectory)..\tools\\x64\YourProjectName.dll</HintPath>
</Reference>
</ItemGroup>
</Project>
.targets文件
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="PlatformCheck" BeforeTargets="BuildOnlySettings"
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>
</Project>
这是100%有效的解决方案。