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

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

Adding a codeplex repo to strider

After my last post, I can now get an authenticated user's repositores. However, I am experiencing a couple of issues. First, the codeplex oauth tokens expire after an hour. Because of this, I am seeing a number of authentication errors. In order to solve this, I need to get the... Read More

Making a strider plugin

When I last left off, my codeplex plugin for strider was able to pull in repos from codeplex by passing in a valid codeplex username. While it was a great proof of concept, it isn't the way that strider wants (and in fact needs to) to interract with source control... Read More

My first module

In my previous post, I started a project to create a codeplex plugin for strider. Today, I will take another baby step. Because baby steps are the easiest. Unless you're a baby. A node baby. Ahem. In order to make it useful, I did a little bit of refactoring. I... Read More