Tup: Make Alternative for Embedded Systems


I hate Make.  With a fiery burning passion, I hate Make.  From day one, I found it difficult to understand, difficult to write Makefiles, difficult to modify Makefiles, and difficult to use Makefiles.  Over the years, I have built a collection of boilerplate Makefiles that only sort-of worked for a given project, and any time I wanted to do something creative with the build system, it was a challenge to figure out how to force Make to do what I knew damn well how to do via the command line.

There has to be a better way!
There has to be a better way!

Wasting time on HackerNews, I saw a post about a build system called Tup.  It was designed as a pet project for a pet project, but I was able to understand the syntax in just a couple hours of reading and experimenting.  Seriously, in just a couple hours, I was writing Tupfiles from scratch, something I would never think of doing with Make.

Tup has some seriously huge benefits if you’re building projects with thousands of files, and lots of nested directories.  Tup uses inotify and some other tricks to automatically figure out what needs to be rebuilt, and when it needs to be rebuilt.  I’ve been told that you can do a lot of this using Make, but I have never been able to write a Makefile that didn’t try to rebuild everything all the time, so even though I shouldn’t be saving build time using Tup on small embedded projects, I am, by a huge margin.

In fact, “tup monitor -a” is probably the most magical command I’ve encountered in any build system ever.  Because tup uses inotify, the monitor daemon can receive notifications that files in the build chain have changed, and automatically determine what parts of the project need to be rebuilt.  As a result of this, my project is often rebuilt by the time I’ve alt-tabbed to the terminal to check the results of the build and upload to the board.  Serious, magic.

Most of my projects lately have been built on AVR8 processors, so I’ve created two Tup skeletons on github, if you’d like to try it out:



The first is an Arduino skeleton project that allows you to easily write Arduino code using whatever text editor and programmer you damn well please.  Simply #include “Arduino.h” at the top of every file, and you’re in Arduino-land.  Works out-of-the-box with any AVR processor used on an Arduino, including the AtMega328, and AtMega2560.  Other processors will require a pin definition file in order to work with Arduino functions.  To use, clone it, run “tup init” then “tup upd”.

The second is a skeleton project for LUFA, the AVR USB library.  I’ve been using LUFA with the Teensy++ 2.0, but there are plenty of other boards and processors that can make use of the library.

If you want to improve the skeletons, or submit your own, I welcome all pull requests.  I’m also happy to help folks get started with tup.  The more folks using it, the more well-supported it will be in the future!

Add comment