我创建了一个C++/CLI(混合)程序集,它有一个围绕某些非托管C++代码的托管包装类.托管部分以.NET 4.6.1为目标,我得到了一个entry.cpp
只有这一行的文件来做到这一点:
[assembly:System::Runtime::Versioning::TargetFrameworkAttribute(L".NETFramework,Version=v4.6.1", FrameworkDisplayName = L".NET Framework 4.6.1")];
Run Code Online (Sandbox Code Playgroud)
当我现在在.NET 4.6.1项目中手动包含已编译的程序集时,我可以按预期使用托管类.
该项目可以构建四种方式:x86或x64作为调试或发布版本.它没有托管依赖项.
现在我想要一个(或者如果需要多个)NuGet包,我可以上传到我的feed并在我想要的每个.NET 4.6.1兼容项目中轻松使用包装器组件.我该如何实现这一目标?
到目前为止我尝试了两种方法:
首先,我创建了一个.autopkg
文件,根据这篇博文文章提供本机DLL的方式.该files
文件的部分如下所示:
files {
// include: { *.h };
[x86,v120,release] {
symbols: { ..\Release\*.pdb; }
bin: { ..\Release\*.dll; }
};
[x86,v120,debug] {
symbols: { ..\Debug\*.pdb; }
bin: { ..\Debug\*.dll; }
};
};
Run Code Online (Sandbox Code Playgroud)
此过程会生成三个.nupkg
文件,我可以将其上传到我的Feed.但是当我尝试将该软件包安装到.NET 4.6.1项目时,我收到以下错误消息:
无法安装包'MyCppCliWrapper.redist 1.0.0.2'.您正在尝试将此软件包安装到以".NETFramework,Version = v4.6.1"为目标的项目中,但该软件包不包含任何与该框架兼容的程序集引用或内容文件.有关更多信息,请与软件包作者联系.
所以我重新考虑是否应该使用托管程序集的方式来创建,.nupkg
因为程序集有一个我想从托管代码中使用的托管类.我创建了一个.nuspec
(使用nuget spec
)并提供了元数据.然后我尝试像这样创建我的包:
nuget pack MyCppCliWrapper.nuspec -Prop Configuration=Release -Prop Platform=x86 -Build
Run Code Online (Sandbox Code Playgroud)
但是这会产生一个包含整个项目的包,包含所有源文件和临时文件,就像该文件夹的zip文件一样.
显然,也缺少有关目标框架的元信息.
当我尝试使用项目文件来创建包(就像使用C#程序集)时,这也会失败:
请指定要使用的nuspec,project.json或项目文件
.vcxproj
NuGet似乎不支持C++项目文件(我使用的是NuGet 3.5.0.1938命令行实用程序).
我是否需要手动构建和提供的所有文件中files
的部分.nuspec
?如果是的话,他怎么会从这一行知道哪个DLL是针对哪个.NET框架加平台?
<file src="bin\**\*.dll" target="lib" />
Run Code Online (Sandbox Code Playgroud)
我相信Hans Passant是对的,这只是一个常规的管理nuget包,但打包器不处理.vcxproj
文件所以我自己编写.nuspec
:
<?xml version="1.0"?>
<package >
<metadata>
...
</metadata>
<files>
<file src="readme.txt" target="" />
<file src="bin\Win32\Release\*.dll" target="lib\net461" />
<file src="bin\Win32\Release\*.pdb" target="lib\net461" />
</files>
</package>
Run Code Online (Sandbox Code Playgroud)
这种方式生成的包有效.
还有一个问题:这样,我是否必须做两个包,一个用于32位,一个用于64位 - 或者是否可以将它们包含在一个包中(我更喜欢)并让消费项目使用一个或另一个取决于目标架构(any-cpu大多是32位)?
我不知道这是否仍然可以帮助你,但我已经设法包装了x64和x86 C++代码,以及在AnyCPU上编译的C#包装器.
在我的C#项目中,我有两个平台:"x86"和"x64".
在我的Nuget文件夹中,我有以下结构:
\Project
\Project.1.0.nuspec
\build
\x64
\*.dll
\*.pdb
\x86
\*.dll
\*.pdb
\Project.targets
\lib
\net452
\Wrapper.dll
\Wrapper.pdb
Run Code Online (Sandbox Code Playgroud)
Project.nuspec:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Project</id>
<version>1.0</version>
<authors>nilsonneto</authors>
<owners>nilsonneto</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Example.</description>
<references>
<reference file="Wrapper.dll" />
</references>
</metadata>
<files>
<file src="build\Project.targets" target="build\Project.targets" />
<file src="build\x64\**" target="build\x64" />
<file src="build\x86\**" target="build\x86" />
<file src="lib\net452\Wrapper.dll" target="lib\net452\Wrapper.dll" />
<file src="lib\net452\Wrapper.pdb" target="lib\net452\Wrapper.pdb" />
</files>
</package>
Run Code Online (Sandbox Code Playgroud)
Project.targets:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeLibs Include="$(MSBuildThisFileDirectory)\$(Platform)\*.*" />
<Content Include="@(NativeLibs)">
<Link>%(RecursiveDir)%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
注意$(Platform),这是在Visual Studio上构建的Platform的名称,这就是为什么我将文件夹中的C++ DLL与Visual Studio中的平台同名.
根据文档(https://docs.microsoft.com/en-us/nuget/create-packages/native-packages),所有本机DLL都必须放在\ build目录中.
针对native的本机NuGet包然后在\ build,\ content和\ tools文件夹中提供文件; 在这种情况下不使用\ lib(NuGet不能直接添加对C++项目的引用).包中还可能包含\ build中的目标和props文件,NuGet会自动导入到使用该包的项目中.这些文件的名称必须与包含.targets和/或.props扩展名的包ID相同.
因此,只需根据.NET项目和您的集合支持的平台调整文件夹名称.
归档时间: |
|
查看次数: |
3186 次 |
最近记录: |