PresentationPythonMeetupApr92009 - maartennieber


Nov 5, 2013 (4 years and 6 months ago)



C++ build automation based on CMake and Python

Maarten Nieber, 2009

A preliminary remark

CSnake was developed at the Universitat Pompeu
Fabra. It is
not yet

publicly available, and
not yet

open source


C++ build automation using CMake

Goals of CSnake

CSnake architecture

CSnake features

Future work

What is build automation?

(Adapted from Wikipedia) Build automation is the
act of scripting or automating the task of compiling
computer source code into binary code

What is C++ build automation?

C++ files: hola.cpp, hi.cpp

Binary code: hello (library)

Compiler: gcc

Linker: ld

Writing a Makefile for building 'hello' is an example
of build automation

C++ build automation using CMake

Instead of writing a Makefile, write a platform
independent CMakeLists

C++ source files, CMakeLists → [CMake] →
Makefile/.sln/.kdevelop → [gcc/msdev/kdevelop] → binary

Example CMake file

project (HELLO)

add_subdirectory (Hello)

add_subdirectory (Demo)

add_library (Hello hello.cxx)

include_directories (${HELLO_SOURCE_DIR}/Hello)

link_directories (${HELLO_BINARY_DIR}/Hello)

add_executable (helloDemo demo.cxx demo_b.cxx)

target_link_libraries (helloDemo Hello)

Problems with CMake

CMake syntax is primitive and not OO

Has some convenience functions

Messy code when projects get large

Not very modular

A CMake script may call the CMake scripts for dependency projects, but
usually only the top
level script works stand

No debugger

Overhead in creating Use
file and Config

Link dependencies are not recursive

Install step may take long

CSnake: a CMake code generator

Do build automation using Python scripts while
being able to integrate existing CMakeLists

CSnake file → [CSnake] → CMakeLists → [CMake]
→ Makefile → [make] → binary

Improvements offered by CSnake

Build automation scripts are written in Python

Basic usage must suit non
expert programmers

Scripts use OO and are modular

A CSnake script creates Project objects

Any Project is usable as top
level target in a configuration

Handles project inter

Generates CMake Use file and Config file

Build folder is usable as install folder

CSnake script

import csnProject

from csnExamples import *

greetMe = csnProject.Executable("GreetMe")


greetMe.AddIncludeFolders(['tests', 'src'])

greetMe.AddTests(['tests/*.h', 'tests/*.cpp'], cxxTest)


Script versus Context

A script describes a target


which source files?


which include folders?


which dependencies on other projects?

The context describes which target to build and how:


which csnake script? (


which instance? (greetMe)


which compiler? (kdevelop)


debug build or release build? (release)


where to store build results? (~/build)

Smallest code to build a target

context = csnContext.Load(“GreetMe.csnakecontext”)

csnProject.globalContext = context

module = csnUtility.LoadModule(

exec “module.%s.Generate()” % context.instance

# module.greetMe.Generate()

The global context

# in CSnake script file

greetMe = csnProject.CreateExecutable("GreetMe")

This is syntactic sugar for

csnProject.globalContext.CreateProject("GreetMe", “executable”)

Note that instantiating the Context is de
coupled from instantiating

the Project.

CSnake architecture: Project class

The Project class has functions that delegate to manager objects

(pseudo code)

class Project:


# dependency projects


# source files, include folders, ...


# files and folders to install


# associated test projects


# rootFolder, buildSubfolder


# writes cmake files


each manager has a back
link to its containing Project, and can use the other
managers (but usually this does not happen)

CSnake architecture: Project class

# example of delegating work to a manager object

folders = [“src”, “include”]

project.AddIncludeFolders(folders, win

# is handled as

project.compileManager.AddIncludeFolders(folders, win

CSnake architecture: flags

Instead of using:

if project.context.IsForPlatform(win


I often get cleaner code writing

project.AddIncludeFolders(folders, win

which is handled inside the Compiler manager class as follows:

def AddIncludeFolders(folders, win
, notWin

if not self.project.context.IsForPlatform(win
, notWin


# do work

CSnake architecture: flags

An improvement would be to generalize by replacing boolean args with a
Flags class

def AddIncludeFolders(folders, flags):

if not self.project.context.IsForPlatform(flags):

That way, you could write

# include from 'folders' on Windows machines when in debug mode

project.AddIncludeFolders(folders, [win
, debugMode]);

Summary of main features

Write configuration files in Python

CSnake configuration files are very clean compared to pure CMake files

Modular (any dependency project can be a target)

Recursive handling of dependencies

OO access to all configuration information

Projects can depend on pure CMake projects

Applications run directly in the build folder

Extra necessary files must be installed once to the build folder

Generates use file and config file (but ...!)

Other features

Support for installing files (to the build folder)

Can schedule folders for installation

Skips source control files

Can automatically re
install new files

Support for Visual Studio:


Defines ProjectName_EXPORT macro for you

Support for KDevelop:

Patches kdevelop file to show full source tree

Integrates with CxxTest


Writes project structure to an XML file

GUI Features

Can import an existing source project

Generates a CSnake file

Allows to fine
tune the selection of projects in the

tune which test projects to include

Select which plugin
modules to build along with the target

Future work

Better integration with CMake

Generate standard CMake packages!

Use the FIND_PACAKAGE macro for installed pure CMake projects

Test replacing CSnake
generated CMakeLists with a custom one

Work around CMake inheritance “feature”

Make files generated by CMake depend on configuration order!

Improve customization with Context classes

In addition to, csnVisualStudio
, etc.

Option to write output as Scons files

Release as open source

Review with a second developer

Further reading

→ articles