Wednesday 23 November 2011

Build your C/C++ programs everywhere with SCons



Maximum Power!

In these days I'm trying to realize a small and portable game engine using SDL+OpenGL, fascinated by their power. I begun writing some C files and a simple Makefile.
Portability is a fundamental requisite, so I decided to move to a portable building system. I thought CMake could be a good choice, mainly because it's used by several open-source project: KDE, Inkscape, OGRE, MySQL use CMake. So, I decided to write my platform-indipendent CMakefile. It was one of most boring and error-prone task I've ever saw. After some days, I still can't have a functionally CMake file: I've got less problems writing then a python script for compiling it. Frustrating.



I didn't give up and I tried another two/three times to write it, but CMake syntax remains obscure and its options too cryptic. I seriously thought to use a custom Python script, but looking about KDE-4 's history, I found a clue. During first development, some KDE members tried another building system, SCons. I will talk about this great software.

SCons is Python based

First, SCons is a Python script whom interpret a SConstruct file. What's a SConstruct file? Basically it's a Python script where some instructions are oriented to building a source. This means three things

  1. You have a FULL FEATURED language instead of a configuration file
  2. You can access to Python's library
  3. SCons is portable

So, as you can see, SCons has some very interesting features from its Python nature.

Simplicity

Differently from GNU Automake, SConstruct files looks easy and readable, either if you don't know python. A simple SConstruct file to compile HelloWorld.c looks like this

Program(target="helloworld",source=['HelloWorld.c'])

Launch scons in the same directory and you'll obtain a binary called helloworld. Easy, right? Now, look at the "source" keyword: if you know Python, you will recognize it as a list. So, if out program is composed by many files, is sufficient to add'em to source list and they will be compiled.

Files in other directories

Is your program composed by files in several directories with same root? You can easily add them to your source list. Let's see this structure

source/
     - Geometry/
         - Point.h
         - Point.c
     - Sound/
         - Player.h
         - Player.c
     - Main.c

SCons file will looks like this

Program(target="Example",source=['Main.c',
      'Geometry/Point.c',
      'Sound/Player.c']
      )

Remember: first element in source list must be the C/C++ files containing main function. Launch SCons and you'll have your binary file "Example". Easy and clean!

Static libraries

I used SOIL to add JPEG/PNG/GIF support to my program. I add it as static library included in my program. It's incredible how easily you can do it!

soil=['src/SOIL/SOIL.c',
      'src/SOIL/image_DXT.c',
      'src/SOIL/image_helper.c',
      'src/SOIL/stb_image_aug.c']
libraries=[]
Program(target="Example",source=['Main.c',
               'Point.c',
               'Player.c']
               +soil
               )

I just appended SOIL list to source. When I did it I expected some errors or warnings. No. None of them. It runs at first time.

Dynamic Libraries

This is a bit harder to manage, because it depends a lot on wich OS you use. We must detect our OS? How? Well, SCons is written in Python, so we can use it!

import os
import sys
env=Environment(ENV=os.environ)

#wich OS are we using?
print sys.platform

Detecting OS we can choose different way to compile. E.G.

if sys.platform == 'win32':
    Tool('mingw')(env)
    libraries=['mingw32','SDLmain', 'SDL', 'OpenGL32', 'GLU32']
    ...
else:
    ...

Usually, I prefear to use always Environment variable, to ensure a portability detecting the OS.

Set a #define

How set a #define at compile time?

env.Append(CPPFLAGS='-D'+sys.platform)
Do you expected something harder? ;) CPPFLAGS directive works either on C programs.

Conclusions

SCons is incredibily efficient, easy and clean. As you can see at SCons' wikipedia page, many famous games use it for building. If it's good for Doom 3, it's good for me! Erik Raimond appreciate it, as you can read on this post he wrote about SCons at April 2011.
I conclude: SCons is still supported. Latest version were release on september 2011. I think is the best building system I've ever seen. Try it and use it. And stop use those orrible Makefiles! :)

No comments: