{"id":1463,"date":"2013-06-18T11:38:00","date_gmt":"2013-06-18T11:38:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2013\/06\/18\/deep-dive-into-nuget-native-part-one\/"},"modified":"2019-02-27T07:23:04","modified_gmt":"2019-02-27T07:23:04","slug":"deep-dive-into-nuget-native-part-one","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/deep-dive-into-nuget-native-part-one\/","title":{"rendered":"Deep Dive into NuGet Native (Part One)"},"content":{"rendered":"<p>Howdy!<\/p>\n<p>Today I thought I\u2019d start explaining how NuGet supports C\/C++ packages under the covers, and look into how one could (theoretically) manually construct a package without using the CoApp PowerShell tools.<\/p>\n<p>&nbsp;<\/p>\n<p>As I mentioned before, C\/C++ packages built for NuGet didn&#8217;t require a whole lot of change in NuGet itself\u2014primarily because if we had made the Package Manager do all the complex work that was necessary to hook up a project, we\u2019d be still implementing it all a year from now.<\/p>\n<p>Instead we chose to add a fairly simple (and often requested) feature to NuGet, the ability to import MSBuild project file fragments into the consuming project. Previously, some package creators had hacked their way into something similar by including an <strong><strong><code>install.ps1<\/code><\/strong><\/strong> PowerShell script in the package. While this sort of thing was workable, it opens up an awful can of worms.\u00a0 As well, NuGet needed to support actually working on C++ project types and needed to shoe-horn in a new \u201cframework type\u201d that could represent native packages (which was simply called <strong><code>native<\/code><\/strong> ).<\/p>\n<p>&nbsp;<\/p>\n<p>As of NuGet 2.5, when the package installs, it checks inside the <strong><code>\/build\/&lt;framework&gt;<\/code><\/strong> folder for files that are either called <strong><code>&lt;pkgName&gt;.targets<\/code><\/strong> or <strong><code>&lt;pkgName&gt;.props<\/code><\/strong> . If it finds a <strong><code>.props<\/code><\/strong>, it places an <strong><code>&lt;Import&gt;<\/code><\/strong> into the <em>top<\/em> of the project file.\u00a0 If it finds a <strong><code>.targets<\/code><\/strong> file, it places an <strong><code>&lt;Import&gt;<\/code><\/strong> into the <em>bottom<\/em> of the project file.\u00a0 This allows the package creator to have finer grained control as to when something is declared\u2014and if it can get overridden in the consuming project or not.<\/p>\n<p>At that point, NuGet\u2019s involvement on how the package is integrated in the consuming project is pretty much complete. It\u2019s now up to the package creator to craft the <strong><code>.targets<\/code><\/strong> and\/or <strong><code>.props<\/code><\/strong> files in such a way enables the consuming project to effectively use the contents.<\/p>\n<h3>The Simplest Package<\/h3>\n<p>Assume for a moment that we wanted to create a very simple package that contained only a single header file, and didn\u2019t have any <strong><code>.lib<\/code><\/strong> files and didn\u2019t have any redistributable files (ie, <strong><code>.dll<\/code><\/strong>\u00a0 files).<\/p>\n<p>Given a simple <strong><code>mysample.h<\/code><\/strong> file:<\/p>\n<pre class=\"lang:default decode:true\">#pragma\u00a0once\r\n#include\u00a0&lt;stdio.h&gt;\r\n\/*\u00a0some\u00a0simple\u00a0function\u00a0*\/\r\n#define\u00a0SimpleWriteString(\u00a0str\u00a0)\u00a0printf(\u00a0str\u00a0)\r\n<\/pre>\n<p>We then need to create the <strong><code>mysample.targets<\/code><\/strong> file that will ensure that we add the <strong><code>include<\/code><\/strong> directory into the consuming project.<\/p>\n<pre class=\"lang:default decode:true\">\u00a0\r\n&lt;?xml\u00a0version=\"1.0\"\u00a0encoding=\"utf-8\"?&gt;\r\n&lt;Project\u00a0ToolsVersion=\"4.0\"\u00a0xmlns=\"http:\/\/schemas.microsoft.com\/developer\/msbuild\/2003\"\u00a0&gt;\r\n\u00a0\u00a0&lt;ItemDefinitionGroup&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;ClCompile&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;AdditionalIncludeDirectories&gt;$(MSBuildThisFileDirectory)..\\..\\lib\\native\\include\\;%(AdditionalIncludeDirectories)&lt;\/AdditionalIncludeDirectories&gt;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;PreprocessorDefinitions&gt;HAS_MYSAMPLE;%(PreprocessorDefinitions)&lt;\/PreprocessorDefinitions&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;\/ClCompile&gt;\r\n\u00a0\u00a0&lt;\/ItemDefinitionGroup&gt;\r\n&lt;\/Project&gt;\r\n<\/pre>\n<p>A very simple <strong><code>mysample.nuspec<\/code><\/strong> file (the .nuspec file is the manifest file used by NuGet to tell what is in the package. You can find more about the .nuspec file format from the <a href=\"http:\/\/docs.nuget.org\/docs\/reference\/nuspec-reference\">docs on nuget.org<\/a>\u00a0).<\/p>\n<pre class=\"lang:default decode:true\">&lt;?xml\u00a0version=\"1.0\"\u00a0encoding=\"utf-8\"?&gt;\r\n&lt;package&gt;\r\n\u00a0\u00a0&lt;metadata&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;id&gt;MySample&lt;\/id&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;version&gt;1.2.3&lt;\/version&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;authors&gt;Garrett\u00a0Serack&lt;\/authors&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;owners&gt;CoApp\u00a0Project,\u00a0Garrett\u00a0Serack&lt;\/owners&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;requireLicenseAcceptance&gt;false&lt;\/requireLicenseAcceptance&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;description&gt;A\u00a0sample\u00a0library.&lt;\/description&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;releaseNotes&gt;First\u00a0Release\u00a0of\u00a0MySample\u00a0library&lt;\/releaseNotes&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;copyright&gt;Copyright\u00a02013&lt;\/copyright&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;title&gt;MySample\u00a0Library&lt;\/title&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;summary&gt;A\u00a0sample\u00a0library&lt;\/summary&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;tags&gt;native,\u00a0MySample&lt;\/tags&gt;\r\n\u00a0\u00a0&lt;\/metadata&gt;\r\n\u00a0\u00a0&lt;files&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;file\u00a0src=\"MySample.h\"\u00a0target=\"\\lib\\native\\include\\mysample.h\"\u00a0\/&gt;\r\n\u00a0\u00a0\u00a0\u00a0&lt;file\u00a0src=\"mysample.targets\"\u00a0target=\"\\build\\native\\mysample.targets\"\u00a0\/&gt;\r\n\u00a0\u00a0&lt;\/files&gt;\r\n&lt;\/package&gt;\r\n<\/pre>\n<p>Once we have those, it&#8217;s fairly trivial to build the package with just the <strong><code>NuGet<\/code><\/strong> command-line tool:<\/p>\n<pre class=\"lang:default decode:true  \">c:\\MySample\\&gt;\u00a0nuget\u00a0pack\r\nAttempting\u00a0to\u00a0build\u00a0package\u00a0from\u00a0'MySample.nuspec'.\r\nSuccessfully\u00a0created\u00a0package\u00a0'C:\\MySample\\MySample.1.2.3.nupkg'\r\n<\/pre>\n<p>Of course if all libraries were this easy, we&#8217;d never needed to make a special tool to build packages for C++.<\/p>\n<p><strong>Next Time:<\/strong> We&#8217;ll dig into how we hook up .lib files to the linker, and making sure that redistributable files are copied to the output directory.<\/p>\n<p><strong>Also :<\/strong>\u00a0In case you missed it, you might want to check out the <a title=\"Channel 9 Interview on NuGet\/C++\" href=\"https:\/\/channel9.msdn.com\/Shows\/C9-GoingNative\/GoingNative-16-Garrett-Serak-Inside-NuGet-for-C\">Channel 9 Interview on NuGet\/C++<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Howdy! Today I thought I\u2019d start explaining how NuGet supports C\/C++ packages under the covers, and look into how one could (theoretically) manually construct a package without using the CoApp PowerShell tools. &nbsp; As I mentioned before, C\/C++ packages built for NuGet didn&#8217;t require a whole lot of change in NuGet itself\u2014primarily because if we [&hellip;]<\/p>\n","protected":false},"author":277,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[140,190,191,41,192],"class_list":["post-1463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus","tag-c","tag-libraries","tag-nuget","tag-vs2010","tag-vs2012"],"acf":[],"blog_post_summary":"<p>Howdy! Today I thought I\u2019d start explaining how NuGet supports C\/C++ packages under the covers, and look into how one could (theoretically) manually construct a package without using the CoApp PowerShell tools. &nbsp; As I mentioned before, C\/C++ packages built for NuGet didn&#8217;t require a whole lot of change in NuGet itself\u2014primarily because if we [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/277"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=1463"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/1463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=1463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=1463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=1463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}