<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[jkp woz 'ere]]></title>
  <link href="http://www.kirkconsulting.co.uk/atom.xml" rel="self"/>
  <link href="http://www.kirkconsulting.co.uk/"/>
  <updated>2012-02-14T10:42:49+01:00</updated>
  <id>http://www.kirkconsulting.co.uk/</id>
  <author>
    <name><![CDATA[Jamie Kirkpatrick]]></name>
    <email><![CDATA[jkp@kirkconsulting.co.uk]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Superfly Ninja Builds]]></title>
    <link href="http://www.kirkconsulting.co.uk/blog/2012/01/29/superfly-ninja-builds/"/>
    <updated>2012-01-29T09:10:00+01:00</updated>
    <id>http://www.kirkconsulting.co.uk/blog/2012/01/29/superfly-ninja-builds</id>
    <content type="html"><![CDATA[<p>Recently I&#8217;ve been doing some work on an <a href="http://code.google.com/p/chromiumembedded/">open-source project</a> which uses <a href="http://gyp.googlecode.com/">Google&#8217;s GYP</a> tool.  Like <a href="http://www.cmake.org/">CMake</a>, it is used generate projects files for various build systems from a single specification.</p>

<p>Cross-platform build generators like this are great since they give the developer a choice about what environment to use, but in this case I found that the projects it generated had several problems: namely unwieldiness (a gazillion targets in one huge XCode project) but more seriously, they were impossibly slow to <em>actually start building</em>.</p>

<p>Efficient development is all about short feedback loops - just like you don&#8217;t want to wait six months to discover the feature you just added wasn&#8217;t what was required, you also want to find out as quick as possible when you have introduce syntax error in your code.</p>

<p>In my opinion this is the one thing Apple got right with Xcode 4, when they integrated the clang parser right <a href="http://developer.apple.com/technologies/tools/whats-new.html#fix-it">into the IDE</a>.  You&#8217;d be amazed how much less you actually hit the build button if you can already see your errors as you type.</p>

<p>That said: I actually try to avoid working in XCode whenever I can since it mostly sucks and is just too painful to make me productive - I prefer to use Emacs where possible. One thing I do miss though (when coding in C++ especially) is the kind of tight integration with the compiler tool-chain I mentioned before.</p>

<p>Turns out that Emacs does actually have an answer to this problem - it&#8217;s called <a href="http://www.emacswiki.org/emacs/FlyMake">flymake</a>.  Better still it seems the Google guys have been down this very road and have their own flymake <a href="http://src.chromium.org/svn/trunk/src/tools/emacs/flymake-chromium.el">Emacs module</a> which lets it work with <a href="http://martine.github.com/ninja/">ninja</a> (a new build system which focuses on speed and is now supported in GYP).</p>

<p>Unfortunately when I hooked this up I was disappointed: far from shortening the feedback loop flymake ran dog-slow - it took something like 12 seconds (during which Emacs blocks input) to get feedback into my Emacs buffer which was next to useless.  Googling for &#8220;slow flymake&#8221; didn&#8217;t turn up anything useful - it seemed to be working for other users so I concluded it must be something about my setup that was causing the problem.</p>

<p>Determined to make this work I took the next logical step - stop guessing and <a href="http://stackoverflow.com/questions/568150/tips-for-profiling-misbehaving-emacs-lisp">profile</a> the misbehaving code.  Sure enough I saw almost instantly where Emacs was spending it&#8217;s time - it seemed to take forever to parse the output for errors.  Odd.  Next I tried to do the same myself: parse the output line-by-line to see if anything in particular was slowing it down.  Bingo.</p>

<p>Turns out that when ninja fails a build it (logically) spits out the full command line that failed.  The problem was that this line was ginormous and flymake was taking forever to run the various regexps it uses to extract errors and warnings from the build output.  The good news is that this can be fixed: I just needed a way to stop Emacs bothering to parse this line since it would clearly never contain any errors or warnings itself.</p>

<p>Whilst I know the proper way to do this was probably to write a wrapper for the offending function and install it with <a href="http://www.delorie.com/gnu/docs/elisp-manual-21/elisp_212.html">advise</a>, it was early in the morning and my elisp-foo wasn&#8217;t up to it.  Instead I turned to the simple solution: a trusty shell-script.</p>

<div><script src='https://gist.github.com/1699160.js?file='></script>
<noscript><pre><code>#!/bin/bash
ninja $@ | grep -v ^FAILED
exit ${PIPESTATUS[0]} </code></pre></noscript></div>


<p>With the help of this wrapper I finally achieved what I was after - I now have near instantaneous feedback when I introduce new build errors to my code - awesome!</p>
]]></content>
  </entry>
  
</feed>

