What is C++ build automation?
Download
Report
Transcript What is C++ build automation?
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, win32=True)
# is handled as
project.compileManager.AddIncludeFolders(folders, win32=True)
CSnake architecture: flags
Instead of using:
if project.context.IsForPlatform(win32):
project.AddIncludeFolders(folders)
I often get cleaner code writing
project.AddIncludeFolders(folders, win32=True)
which is handled inside the Compiler manager class as follows:
def AddIncludeFolders(folders, win32, notWin32):
if not self.project.context.IsForPlatform(win32, notWin32):
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, [win32, 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, csnVisualStudio2003, 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