PresentationPythonMeetupApr92009 - maartennieber

fanaticalpumaMechanics

Nov 5, 2013 (3 years and 5 months ago)

108 views

CSnake

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

Outline


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
-
alone


No debugger


Overhead in creating Use
-
file and Config
-
file


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
-
dependencies


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.AddSources(['src/*.cpp'])


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


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


greetMe.AddProjects([hello])



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? (csnGreetMe.py)


-

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(
context
.csnakeFile)


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


# module.greetMe.Generate()




The global context

# in CSnake script file csnGreetMe.py

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:

self.dependenciesManager

# dependency projects

self.compileManager


# source files, include folders, ...

self.installManager



# files and folders to install

self.testsManager



# associated test projects

self.pathsManager



# rootFolder, buildSubfolder

self.cmakeWriter



# 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
32
=True)



# is handled as

project.compileManager.AddIncludeFolders(folders, win
32
=True)





CSnake architecture: flags


Instead of using:

if project.context.IsForPlatform(win
32
):


project.AddIncludeFolders(folders)



I often get cleaner code writing

project.AddIncludeFolders(folders, win
32
=True)



which is handled inside the Compiler manager class as follows:

def AddIncludeFolders(folders, win
32
, notWin
32
):


if not self.project.context.IsForPlatform(win
32
, notWin
32
):


return




# 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
32
, 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:


project.SetPrecompiledHeader


Defines ProjectName_EXPORT macro for you


Support for KDevelop:


Patches kdevelop file to show full source tree


Integrates with CxxTest


project.AddTests


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
configuration


Fine
-
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 csnKDevelop.py, csnVisualStudio
2003
, etc.


Option to write output as Scons files


Release as open source


Review with a second developer

Further reading

http://maartennieber.host
-
ed.net/

→ articles