Compiling .net projects with node-gyp

In order to actually use my custom msbuild logger, it must be compiled. Node has a native compiler that will be run during an npm install: node-gyp. All the documentation seems to indicate that this is only for c/c++ projects. I didn't like that answer, so I did a bit of research into projects I knew used c# in node. And I hit the jackpot with edge (which is itself really cool).

It turns out that you can specify a command line to run as an action. The difference is that instead of allowing node-gyp to create the visual studio project to build (and building it), you just have to specify a command line that will do the build. If using a .csproj file, this is how you'd do so:

{
  'targets': [{
    'target_name': 'my-project',
    'type': 'none',
    'actions': [{
      'action_name': 'compile',
      'inputs': [ 'all.cs', 'your.cs', 'files.cs' ],
      'outputs': [ 'path\to\result.dll' ],
      'message': 'msbuild myproject.csproj',
      'action': ['msbuild', 'myproject.csproj', '/p:Configuration=Release']
    }]
  }]
}

A couple of notes:

  • inputs and outputs must be specified, or node-gyp won't run your action during a build
  • inputs can be a blank array, but outputs must have at least one item, or node-gyp won't build it.
  • The project specified as the argument to msbuild will specify where to output the file, so outputs doesn't really matter.
  • Likewise, the project file specifies the files to build, so the contents of inputs isn't important.
  • outputs can be useful for other actions that wouldn't build your directory structure for you, as node-gyp will create it.
  • If your code exists in 1 file, consider calling csc (csharp compiler); you won't need a project file.

For my project, here is the resultant binding.gyp:

{
  'targets': [{
    'target_name': 'strider-msbuild-logger',
    'type': 'none',
    'actions': [{
      'action_name': 'compile',
      'inputs': [ ],
      'outputs': [ 'strider.msbuild.logger.dll' ],
      'message': 'msbuild Strider.MsBuild.Logger.csproj',
      'action': ['msbuild', 'Strider.MsBuild.Logger.csproj', '/nologo', '/tv:2.0', '/p:Configuration=Release']
    }]
  }]
}

I'm not using csc here, because I want to force the use of .NET 2.0. That way, all versions of msbuild can use my logger. As far as I'm aware, there is no way to force csc to do so.

I hope this quick tip is enough to get you started. There are more advanced scenarios, such as conditional actions (which would be great for building on linux with mono [in fact, edge does this]).

If you want to see how my project is using this, you can check it out on github.

-AH

Colorizing output from msbuild in strider

Now that I have nuget restoring my projects packages in strider at build time, I wanted to get msbuild's output colorized. I was hoping that it would have an option to force color on, but unfortunately it does not. What I found odd is that you can force it off... Read More

Restoring NuGet packages for .NET projects in Strider

Since getting .NET projects building in strider was pretty easy, I decided to add built-in NuGet package installation. That way, you don't need to store nuget.exe for every single project you create (NuGet package restore). Thankfully, http://nuget.org hosts the latest version of nuget.exe at http://www... Read More

Building .NET Projects in Strider

After successfully getting code from Codeplex, I was eager to get one of my projects building. The two I care about are both .NET projects. I knew there was no .NET support in strider when I first started investigating it, so I knew I was going to have to make... Read More

Fetching code from Codeplex in Strider

Last time, I was able to get strider to recognize my branches in codeplex. However, it still won't fetch the code. Which is the whole point of this entire process! For a Node project, the first thing that strider does is try to get a package.json file from the... Read More

Getting Branches from Codeplex in Strider

After my last post, I was at the point where strider would list my repos, and I could even see a little checkbox by their name. Unfortunately, clicking on the configure buttons would do nothing. This is because clicking those buttons calls getBranches, and I am not yet doing anything... Read More