I used to work in a predominantly Windows-based environment using Visual Studio to write my source code. This is the norm in the games industry, at least here in Sweden. When I moved away from that, I ended up using Emacs as my development environment, and now I have a great dislike for IDEs and huge, cumbersome editor/debugger/compiler suites.

One thing that Visual Studio did bring, however, was a standardised way of managing project builds. I haven’t quite settled on anything like that in Linux. In the beginning I was using plain Makefiles for the most part, glancing at autotools but getting frustrated with the slowness of it and having to update .in-files constantly. Since then I’ve found waf, and that does the job most of the time.

I did develop something of a passion for writing build systems in the process, however.

The first one I brought to a pretty much functional state (meaning that it bootstraps itself) is cake. Written in C++ and lua, it is pretty much something that tries to do what waf does better. I abandoned that a while ago.

Just recently, I wrote artifex. This time, it’s all python, and the purpose is somewhat different: I don’t want or need a tool that replaces the more complicated build systems like waf or autotools. I’m more interested in something lightweight which does things the way I want by default, so I can keep the build files per project as small as possible. There is some work left to be done on this front, but as of right now I can use artifex with tiny build scripts to manage most of my projects where I’m using C or C++.

Here’s a quick example of a build script for a small project:

#!/usr/bin/env python
from artifex import *
def myprogram(self):
    self.source = "main.c util.c"

This will track dependencies for the two source files, automatically rebuild the minimal set of files needed when something changes (using a combination of timestamps and SHA-1 checksums) and compile them into an executable called myprogram. By default, the executable is placed in a folder called bin/ and all temporary files into obj/, but this is easily changed.

A more complicated example is the script I use to build another of my projects:

#!/usr/bin/env python
from artifex import *

def breakout(cfg): = "config.hpp"
    cfg.DEBUG = 1

def breakout(s):
    s.pkgconfig(["freetype2", "gl"])
    s.include += ["-Iinclude"]
    s.libs += ["-lGLU", "-lfreeimage"]
    s.source = "src/*.cpp test/breakout.cpp"

This shows off some other features like config.h-generation, globbing in source directives, compiler flags and pkg-config support.

Previous Post
Next Post
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: