Creating NuGet Packages

date:

2022-01-28 18:00

updated:

2022-03-31 18:00

author:

geographika

status:

published

Please email any comments or corrections to blog@geographika.net

Background

As part of building and testing the SWIG generated MapScript bindings, I’ve been updating the Building swig.exe using CMake docs. See Updated and tested Windows CMake build docs for recent updates.

Gathering dependencies on Windows always has its problems. NuGet - the package manager for .NET helps with this, especially when trying to automate builds and reproduce them in CI processes. Nuget packages can be installed from the command-line, rather than trying to manually download files.

Unfortunately often dependencies are not kept updated - the SWIG dependencies are as follows:

  • CMake - the latest version on Nuget is 3.15.5 which is fine

  • Bison - only Bison 2 is available in this package, there is no Bison 3

  • PCRE - latest version is 8.33.0.1

SWIG itself is also available on NuGet: https://www.nuget.org/packages/swigwintools/

SWIG requires Bison3 to build without warnings - see Build warnings on Windows when using Bison <3

Bison

From the Bison homepage:

Bison is a general-purpose parser generator that converts an annotated context-free grammar into a deterministic LR or generalized LR (GLR) parser employing LALR(1) parser tables.

Bison is currently being maintained by Akim Demaille and Paul Eggert. A fork maintained by Akim Demaille is available at https://github.com/akimd/bison

A very useful project for Windows is Win flex-bison:

Win flex-bison is a windows port the Flex (the fast lexical analyser) and Bison (GNU parser generator).

This has ready-made exes for Bison at https://sourceforge.net/projects/winflexbison/files/ It also can be downloaded from Chocolatey at https://community.chocolatey.org/packages/winflexbison3

Initially the SWIG build steps used a combination of both NuGet and Chocolatey, but this was over-complicated, and my aim is to get all dependencies using one package manager.

From StackOverflow:

NuGet is designed to allow you to easily add code libraries to your project. Things like JSON.NET, Entity Framework, etc.

Chocolatey is actually built on top of the NuGet package system, but it is designed to fill a different need. Chocolatey wraps up applications and other executables and makes it easy to install them on your computer. For example, tools like Git, Notepad++, etc. can be easily installed with a command like cinst git.

Bison likely falls into the latter category, but as above the aim is to use a single tool for all dependencies.

Building a Bison NuGet Package

I followed the steps based on this blog post

Steps below:

  • Install Nuget from https://www.nuget.org/downloads (v6.0.0 was used, and installed to C:Tools)

  • Clone the Bison GitHub project:

    cd /D D:\GitHub\bison-nuget\source-projects
    git.exe clone --progress -v "https://github.com/akimd/bison" bison
    
  • Copy the doc files:

    AUTHORS
    COPYING
    README
    
  • Get the exe file and rename to bison.exe

    win_flex_bison3-latestwin_bison.exe

  • Create a nuspec file. See docs at https://docs.microsoft.com/en-us/nuget/reference/nuspec

  • Create the package:

    cd /D D:\GitHub\bison-nuget\nuget
    C:\Tools\nuget pack bison.nuspec -OutputDirectory _builds
    
  • Check the contents of the generated Bison.3.7.4.nupkg by opening with 7-Zip.

  • Test installing the package locally:

    nuget sources add -name local-bison -source D:\GitHub\bison-nuget\nuget\_builds
    nuget sources
    C:\Tools\nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison
    
  • Login to https://www.nuget.org/ (create a new MicroSoft account if necessary), and generate an API key.

    C:\Tools\nuget push _builds\*.nupkg -Source https://www.nuget.org/ -Apikey MY_API_KEY
    

Additional notes:

Building a PCRE2 Package

PCRE 8.33.0.1 - is available on NuGet, however we want to build SWIG with PCRE2. From https://www.pcre.org/:

There are two major versions of the PCRE library. The current version, PCRE2, released in 2015, is now at version 10.39.

The older, but still widely deployed PCRE library, originally released in 1997, is at version 8.45. This version of PCRE is now at end of life, and is no longer being actively maintained. Version 8.45 is expected to be the final release of the older PCRE library, and new projects should use PCRE2 instead.

PCRE2 is available on GitHub at https://github.com/PhilipHazel/pcre2. In the steps below w e will get the latest version at the time of writing (pcre2-10.39), and compile the project using CMake:

  • Get the source and build the project:

    cd C:\Tools
    SET PATH=C:\Tools\CMake\CMake-win64.3.15.5\bin;%PATH%
    git clone https://github.com/PhilipHazel/pcre2.git
    cd pcre2
    git checkout tags/pcre2-10.39
    cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_INSTALL_PREFIX=C:/Tools/pcre2 -S . -B build
    cmake --build build --config Release --target install
    
  • Now we can take these files and add them to a NuGet package:

    SET OUTPUT_FOLDER=D:\GitHub\nuget-pcre2
    cd C:\Tools\pcre2
    copy AUTHORS %OUTPUT_FOLDER%
    copy LICENCE %OUTPUT_FOLDER%
    copy README.md %OUTPUT_FOLDER%
    xcopy C:\Tools\pcre2\build\Release %OUTPUT_FOLDER%\lib /E /I
    xcopy C:\Tools\pcre2\include %OUTPUT_FOLDER%\include /E /I
    xcopy C:\Tools\pcre2\doc\html %OUTPUT_FOLDER%\doc /E /I
    
  • Create a nuspec file. See docs at https://docs.microsoft.com/en-us/nuget/reference/nuspec

  • Create the package:

    cd /D D:\GitHub\nuget-pcre2
    C:\Tools\nuget pack pcre2.nuspec -OutputDirectory _builds
    
  • Unsure if the following warning applies to C-builds, or .NET builds only?

    WARNING: NU5101: The assembly 'lib\pcre2grep.exe' is placed directly under 'lib' folder. It is recommended that assemblies be placed inside a framework-specific folder.
    Move it into a framework-specific folder.
    
  • Check the contents of the generated PCRE2.10.39.0.nupkg by opening with 7-Zip.

  • Test installing the package locally:

    nuget sources add -name local-pcre2 -source D:\GitHub\nuget-pcre2\_builds
    nuget sources
    C:\Tools\nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2
    
  • Push the package to https://www.nuget.org/

    cd /D D:\GitHub\nuget-pcre2
    C:\Tools\nuget push _builds\*.nupkg -Source https://www.nuget.org/ -Apikey MY_API_KEY
    

Additional notes:

Signing Packages

TODO: See https://docs.microsoft.com/en-us/nuget/reference/signed-packages-reference