【发布时间】:2021-07-15 18:43:10
【问题描述】:
我创建了两个包含本机库的 NuGet 包。第一个有两个子文件夹(amd64 和 x86),第二个包含构建目录下的 DLL flat。第一个包的 NativeLibraries 应该被复制到 OutputPath 的子文件夹中。第二个包中唯一的 DLL 应该被复制到 OutputPath 下。我使用以下 stackoverflow 条目作为创建包的指南:https://stackoverflow.com/a/30316946/4496150
第一个 NuGet 包文件夹结构如下所示(amd64 和 x86 子文件夹正在构建中):
- 构建
- amd64
- DLL1.dll
- DLL2.dll
- x86
- DLL1.dll
- DLL2.dll
- 包名.targets
- amd64
第一个目标文件:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)**\*.dll" />
<None Include="@(NativeLibs)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
请注意 $(MSBuildThisFileDirectory)** 作为 NativeLibs Include 和 %(RecursiveDir) 作为 Link 属性的一部分。
第二个 NuGet 包结构如下所示(没有正在构建的子文件夹):
- 构建
- DLL1.dll
- 包名.targets
第二个目标文件:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)\*.dll" />
<None Include="@(NativeLibs)">
<Link>%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
请注意 $(MSBuildThisFileDirectory)(不带 **)作为 NativeLibs Include 并且在 Link 属性中缺少 %(RecursiveDir)。
如果您同时引用这两个包,则第一个包中的 DLL 会额外复制到输出文件夹中,这是不需要的。我怀疑这是因为第二个包含步骤也从第一个包中读取 DLL,但随后不使用 %(RecursiveDir)。
一种解决方法是将两者都包含在第二个包中。 和 NativeLibs Include="$(MSBuildThisFileDirectory)***.dll" /> 与第一个包中的完全相同。
但是,我更愿意理解为什么第二个包确保第一个包中的 DLL 被平面复制。
如果我正确读取了https://docs.microsoft.com/de-de/visualstudio/msbuild/msbuild-reserved-and-well-known-properties?view=vs-2019,$(MSBuildThisFileDirectory) 将指向我的 NuGet 缓存中 NuGet 包的目标文件所在的文件夹。所以实际上一切都是正确的。但仍然(可能)复制了错误的 DLL。
编辑
我在两个目标文件中添加了以下 sn-p 以获得一些输出:
<Target Name="OutputPackage1NativeLibs" BeforeTargets="Build">
<Message Text="Package1 %(NativeLibs.Identity)" Importance="high"/>
</Target>
对于 seconds 目标文件,我将目标名称更改为 OutputPackage2NativeLibs 并使用 Packag2 开始文本输出。
当我清理我的 NuGet 包缓存并重建解决方案时,一切都很好。但是在第三次或第四次重建操作之后,第一个包的 DLL 被复制到输出路径下,我得到以下输出:
Package1 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\amd64\DLL1.dll
Package1 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\amd64\DLL2.dll
Package1 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\x86\DLL1.dll
Package1 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\x86\DLL2.dll
Package1 C:\Users\USERNAME\.nuget\packages\PACKAGENAME2\1.0.0.0\build\DLL1.dll
Package2 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\amd64\DLL1.dll
Package2 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\amd64\DLL2.dll
Package2 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\x86\DLL1.dll
Package2 C:\Users\USERNAME\.nuget\packages\PACKAGENAME1\1.2.3.4\build\x86\DLL2.dll
Package2 C:\Users\USERNAME\.nuget\packages\PACKAGENAME2\1.0.0.0\build\DLL1.dll
所以 NativeLibs 显然是在第三次或第四次重建之后从另一个 NuGet 包添加的。
【问题讨论】:
-
我认为您正在使用具有 packages.config nuget 包管理格式的非 sdk 网络框架项目,对吧?在我这边,将 PackageReference 与 new-sdk 项目一起使用可以获得正确的行为。事实上,这两个目标文件不应该相互访问,因为它们是两个不同的单个 nuget 包。
-
我使用的是非 SDK 网络框架项目,但使用了 PackageReference。