从非托管(C ++ / C)代码创建Nuget包

时间:2016-08-03 10:23:25

标签: c# c++ nuget-package

我有几个用C / C ++编写的遗留组件,并希望将它们包装到Nuget包中,并使用C#代码中的这个包。 在nuget包中实际包装C ++代码的最佳方法是什么? 我查看了CoApp解决方案,但现在似乎不受支持(稳定版离线)。

1 个答案:

答案 0 :(得分:1)

我可以回答你如何将 c++ 打包为 Visual Studio 2017/2019 的 nuget 包。

这是我以前在visual studio中将zlib C++库打包为nuget包的方法。我广泛使用 Visual Studio 中内置的 T4 模板来生成我们需要的文件。

这假设您希望将 x86/release/debug 和 x64/release/debug 打包在同一个包中。您需要构建所有目标,然后构建我们在此处创建的新项目以生成 nuget 包。

当你在你自己的代码中包含生成的 nuget 包时,它会自动使用包含和 lib,它的零配置。您需要更改这些部分道具和目标文件以匹配您的配置以实现这一点。

由于大多数 nuget 打包说明都涵盖 c# 或 C++ Unix,因此这些信息很难掌握和整理。我必须找出秘诀。

  1. 在 Visual Studio 中为基本的 c# 应用程序创建新项目。

  2. 您需要创建并添加以下文件。

  3. 添加构建事件

  4. 修补对 nuget.exe 之类的外部引用。

将其放入名为:thirdparty.ttinc

<#@ assembly name="System" 
#><#@ assembly name="System.Core" 
#><#@ import namespace="System.IO" 
#><#@ import namespace="System.Linq" 
#><#@ import namespace="System.Text" 
#><#@ import namespace="System.Configuration" 
#><#@ import namespace="System.Collections.Generic" 
#><#
    string DirRoot      = @"c:\work\thirdparty\";       // Git source code package installed at.
    string NugetPrefix  = "thirdparty";         // base name for 3rd party packages.
#>

将其放入名为:_NugetVersionInclude.ttinc

<#@ include file= "thirdparty.ttinc" #><#
    // Configuration
    // increment this number for each internal release  

    string NugetInternalVersion      = @"1.0.2";                // Internal version number.

    // configured once for each new thirdparty set of code

    string NugetName                 = @"zlib";                 // Nuget name for this package.
    string NugetExternalVersion      = @"1_2_11";               // External version number as used by the original author.

    // you probably dont need to change below.

    string NugetShortname            = NugetPrefix + "-" + NugetName;   
    string NugetRootname             = NugetShortname + "_" + NugetExternalVersion; 
    string NugetFullname             = NugetRootname + "." + NugetInternalVersion;
    string NugetDescription          = NugetPrefix + " " + NugetName + " " + NugetExternalVersion;  
    string NugetOutDir               = "nuget\\";

    string DirSolution = Environment.GetEnvironmentVariable("SOLUTIONDIR");
    
#>

将此添加到 PreBuildEvent

echo on
start NuGetPackagePack.bat 
exit

将此添加到 PostBuildEvent

echo on
start _UpdateTemplate.bat . "thirdparty-zlib_nuspec.tt" "thirdparty-xlw_nuspec.nuspec"

start _UpdateTemplate.bat . "thirdparty-zlib_props.tt" "thirdparty-xlw_props.props"

start _UpdateTemplate.bat . "thirdparty-zlib_targets.tt" "thirdparty-xlw_targets.targets"

start _UpdateTemplate.bat . "NugetPackagePack.tt" "NugetPackagePack.bat"

start _UpdateTemplate.bat . "NugetPackagePush.tt" "NugetPackagePush.bat"

exit 0

将其放入名为:_UpdateTemplate.bat

echo on
del %3
set SOLUTIONDIR=%1
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\Common7\IDE\TextTransform.exe" -out %3 %2

rem uncomment pause to see output to help debug 
rem pause

exit 0

将其放入名为:thirdparty-zlib_nuspec.tt

<#@ template debug="true" hostspecific="true" language="C#" #><#@ 
 include file="_NugetVersionInclude.ttinc" #><#@
 output extension=".nuspec" #><?xml version="1.0"?>
  <package >
    <metadata>
      <id><#= NugetRootname #></id>
      <version><#= NugetInternalVersion #></version>
      <description> <#= NugetDescription #> </description>
      <authors>Original Authors and Anthony Lambert</authors>
      <tags>Native, native</tags>
    </metadata>
    <files>
        <file src="..\nuget\lib\x64\Debug\*"    target="lib\native\x64\Debug"     />
        <file src="..\nuget\lib\x64\Release\*"  target="lib\native\x64\Release"     />
        
        <file src="..\nuget\lib\x86\Debug\*"    target="lib\native\x86\Debug"     />
        <file src="..\nuget\lib\x86\Release\*"  target="lib\native\x86\Release"     />

        <file src="..\nuget\lib\x86\Debug\*"    target="lib\native\win32\Debug"     />
        <file src="..\nuget\lib\x86\Release\*"  target="lib\native\win32\Release"     />

        <file src="..\..\..\..\zlib.h"          target="build\native\include" />
        <file src="..\..\..\..\zconf.h"         target="build\native\include" />

        <file src="..\..\..\..\doc\*"           target="doc"    />

        <file src="README.md"                target="" />

        <file src="<#= NugetShortname #>_props.props"       target="build\native\\<#= NugetRootname #>.props" />
        <file src="<#= NugetShortname #>_targets.targets"   target="build\native\\<#= NugetRootname #>.targets" />
    </files>
</package>

将其放入名为:thirdparty-zlib_props.tt

<#@ template debug="true" hostspecific="true" language="C#" #><#@ 
 include file="_NugetVersionInclude.ttinc" #><#@
  output extension=".props" #><?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0">
  <!-- lambea 2020-06-24 - the mdd and md sub dirs are not used at present. Not sure any of this is used, picked up from example code. -->
  <PropertyGroup>
    <LibraryType Condition="'$(Configuration)'=='Debug'">mdd</LibraryType>
    <LibraryType Condition="'$(Configuration)'=='Release'">md</LibraryType>
  </PropertyGroup>
  <ItemGroup>
      <FilamentLibs Include="$(MSBuildThisFileDirectory)\lib\native\$(PlatformTarget)\$(Configuration)\*.lib" />
  </ItemGroup>
  <PropertyGroup>
    <!-- Expland the items to a property -->
    <FilamentLibraries>@(FilamentLibs)</FilamentLibraries>
  </PropertyGroup>
  <ItemDefinitionGroup>
      <ClCompile>   <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)\include</AdditionalIncludeDirectories>
      </ClCompile>
      <Link>
        <AdditionalDependencies>$(FilamentLibraries);%(AdditionalDependencies)</AdditionalDependencies>
      </Link>
  </ItemDefinitionGroup>
</Project>

将其放入名为:thirdparty-zlib_targets.tt

<?xml version="1.0" encoding="utf-8"?>

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="15.0" >
  <ItemDefinitionGroup>
    <ClCompile>
      <AdditionalIncludeDirectories>$(MSBuildThisFileDirectory)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
    </ClCompile>
    <Link>
      <AdditionalLibraryDirectories>$(MSBuildThisFileDirectory)lib\$(Configuration)\$(PlatformName);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
      <AdditionalDependencies>zlibstat.lib; zlibwapi.lib; %(AdditionalDependencies) </AdditionalDependencies>
    </Link>
  </ItemDefinitionGroup>
</Project>

将其放入名为 NugetPackagePack.tt 的文件中

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ include file="_NugetVersionInclude.ttinc" #>
<#@ output extension=".bat" #>

_tools\nuget-4.6.2\nuget.exe pack <#= NugetShortname #>_nuspec.nuspec -OutputDirectory <#= NugetOutDir #>

echo "run NugetPackagePush.bat to put on nuget server."
pause

exit

将其放入名为 NugetPackagePush.tt 的文件中

<#@ template debug="true" hostspecific="true" language="C#" #>
<#@ include file="_NugetVersionInclude.ttinc" #>
<#@ output extension=".bat" #>

_tools\nuget-4.6.2\nuget.exe pack <#= NugetShortname #>_nuspec.nuspec -OutputDirectory <#= NugetOutDir #>

echo "run NugetPackagePush.bat to put on nuget server."
pause

exit

调用那些 c lib 函数可能会在其他地方得到解答。寻找 pinvoke 作为起点。