我在多个.csproj
项目中导入以下.targets
文件:
<Project>
<PropertyGroup>
...
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
...
</PropertyGroup>
</Project>
LICENSE
和README.md
文件都紧挨着位于存储库根目录的.targets
文件。
但我得到以下错误:
错误NU5030:许可证文件'C:\。。。\程序包中不存在"blah\LICENSE"。[C:\…\bah\whatever\whatever.csproj]
参考文档:
- https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-a许可证表达式或a许可证文件
- https://devblogs.microsoft.com/nuget/add-a-readme-to-your-nuget-package/
问题:
如何将这两个文件打包到NuGet包中?
由于文档中的一条线索,最终找到了原因,尽管这还不足以使其正常工作。
不仅必须有ItemGroup
,而且应该有$(MSBuildThisFileDirectory)
:
<Project>
<PropertyGroup>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)LICENSE" Pack="true" PackagePath="" />
<None Include="$(MSBuildThisFileDirectory)README.md" Pack="true" PackagePath="" />
</ItemGroup>
</Project>
为了推广这个问题的公认答案https://stackoverflow.com/a/75622542/482758,及其交叉柱https://github.com/NuGet/Home/issues/12463:
在CCD_ 8构建属性中指定的许可证文件必须是";包含在包装中";但是,这样做的机制是微妙的,而且缺乏文献记载。
- 许可证文件通常属于默认情况下不包含在包中的类型,因此需要通过
None
项显式包含(None
,因为该文件不需要特殊处理)。- 传递到包含项的路径是文件的正确路径,其形式为从包含项的生成时评估位置开始的绝对路径或相对路径。
- 用于帮助指定此路径的常见属性包括
SolutionDir
,它通常是项目根;MSBuildThisFileDirectory
,是包含文件的目录;以及MSBuildProjectDirectory
,它是正在构建的项目的目录
- 用于帮助指定此路径的常见属性包括
- 传递到包含项的路径是文件的正确路径,其形式为从包含项的生成时评估位置开始的绝对路径或相对路径。
- 除了选择包含外,通常不能通过
IncludeContentInPack
禁用文件包含,其值必须为true
,默认为true
- include项的
PackagePath
属性确定许可证文件在包中显示的虚拟路径,如果保留为空,则计算为原始文件名 PackageLicenseFile
的值必须指向已解析的PackagePath
值
此问题的公认答案有效,因为许可证文件不是通过某些包含项(例如None
)首先明确包含的。我们可以得出这样的结论,因为试图打包包含不存在的文件路径的项目会产生NU5019: File not found
错误。此外,$(MSBuildThisFileDirectory)LICENSE
的特定值之所以有效,是因为该目录包含.targets
文件和许可证文件(该路径在.csproj
文件中解析不正确)。
答案https://stackoverflow.com/a/75622542/482758工作,因为作者手动禁用了IncludeContentInPack
,所以任何配置都不可能工作。当作者纠正该特定错误时,许可证文件已被重新定位到与包含include项的文件相同的目录中,因此该答案不再回答许可证文件位于祖先目录中的原始问题。
总结:
如果LICENSE.txt
文件与.sln
文件位于同一目录中,则无论它位于哪个属性文件中(Directory.Build.props
、Directory.Build.targets
、其他.props
或.targets
、.csproj
),以下配置都将起作用:
<PropertyGroup>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
</PropertyGroup>
<ItemGroup>
<None Include="$(SolutionDir)LICENSE.txt" Pack="true" PackagePath="" />
</ItemGroup>
如果许可证文件不在解决方案目录中,或者不在从解决方案目录轻松访问的目录中,则其他构建属性之一可能更方便。如果文件恰好在.csproj
目录中,则根本不需要路径前缀。