INTRODUCTION
Overview
Download and Install
Documentation
Publications

REPOSITORY
Libraries

DEVELOPER
Dev Guide
Dashboard

PEOPLE
Contributors
Users

SourceForge.net Logo
Project
Download
Mailing lists

 

         

Tutorial for the GearBox Build System

The term build system refers the software and procedures responsible for compiling, installing, and distributing source code. GearBox uses CMake to handle its build system. CMake is a cross-platform tool, designed as a replacement for autotools.

Contents:

Basics

Builds are controlled by a set of files called 'CMakeLists.txt'. There is approximately one in each directory, and builds descend recursively through the source tree.

An individual developer only needs to be concerned with writing CMakeLists.txt files in the directory containing his or her library code and below.

Example

Here's an example of a CMakeLists.txt file to builid a library. We'll go through it line by line.

SET ( lib_name GbxAdvanced )
GBX_ADD_LICENSE( GPL )

SET ( build TRUE )

# Check for human input
GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )

# Check arbitrary variables
GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )

# Check local targets (libraries or executables)
SET( dep_libs basic )
GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${dep_libs} )

IF ( build )
    
    INCLUDE( ${GBX_CMAKE_DIR}/UseBasicRules.cmake )

    FILE( GLOB hdrs *.h )
    FILE( GLOB srcs *.cpp )

    GBX_ADD_LIBRARY( ${lib_name} SHARED ${srcs} )
    TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )

    GBX_ADD_HEADERS( gbxadvanced ${hdrs} )

ENDIF ( build )

Line-by-Line

SET ( lib_name GbxAdvanced )
All variables in CMake contain text. Assignment is done with SET function. (The C++ equivalent of this line: string lib_name = "GbxAdvanced").
  • You can get more information on this and all other CMake commands.
    $ cmake --help-command SET
    

Notice the GearBox convention for naming CMake variables:

  • All "local" variables created in this CMakeLists.txt are in low case, e.g. lib_name.
  • All "global" variables created somewhere else are in upper case.
  • All custom "global" variables created by GearBox start with "GBX_", e.g. GBX_CMAKE_DIR.
  • Note that the standard CMake variables are also in upper case and some start with "CMAKE_", e.g. CMAKE_INSTALL_PREFIX and some don't, e.g. PROJECT_NAME.

GBX_ADD_LICENSE( GPL )
This macro adds license information about this library to the global list which will be dumped into the LICENSE file at the top level of the distribution (check out what it looks like). This is a custom GearBox macro as indicated by the "GBX_" prefix. Any text can be put into this macro, e.g. "LGPL (with written permission from the original authors)".

SET ( build TRUE )
This and the following few lines determine whether we are going to build this library or not. We start with the assumption that we will and then check a few requirements sequentially. We define a variable called build and set it to TRUE, i.e. "this library will be built". Failure to meet any one of the requirements will assign FALSE to this "cumulative variable".

# Check for human input
GBX_REQUIRE_OPTION( build LIB ${lib_name} ON )
Any text following "#" is a comment. Use them to explain uncommon usage.

This GearBox macro checks for user input into the build process. It is actually a shortcut which does several things:

  • Defines a CMake cache variable called BUILD_LIB_GBXADVANCED which can be used a user-controlled switch for turning compilation of this library ON and OFF. You will see this option when you run the ccmake tool. The option variable is defined the very first time CMake is run, and it is assigned the specified default value (ON).
  • Every time CMake runs, it checks the current value of the BUILD_LIB_GBXADVANCED variable. If the user configured it FALSE, then the value of build variable will also become FALSE.
  • If it is decided that the library will not be built due to user input a corresponding entry will be added to a global list and the name of the library will be printed out at the end of the CMake process under the "Will NOT build..." heading.

Notice that to evaluate the variable you have to inclose it in braces and add a dollar sign, i.e. ${lib_name}. Without this, CMake would just treat it as text. (Similar to the UNIX shells).

This macro is quite flexible. You can specify custom names for the option variables and provide a custom description.

  • Here's the complete signature.
    GBX_REQUIRE_OPTION( cumulative_var [EXE | LIB] module_name default_option_value [option_name] [option_description] )
    
    The last two parameters are optional and have sensible defaults. Nothing else in the build depends on these variables so it's safe to specify them.

GBX_REQUIRE_VAR( build LIB ${lib_name} GBX_OS_LINUX "only Linux OS is supported" )
Next comes another "REQUIRE_" macro. This one checks that an arbitrary variable, in this case GBX_OS_LINUX, evaluates to TRUE. Examples of usage are: check that the OS is supported, the compiler version is acceptable, that dependencies are found, versions of required libraries are new enough, etc.

  • This is the most common macro. Typically, several of these macros check variables one after another. The complete signature:
    GBX_REQUIRE_VAR ( cumulative_var [EXE | LIB] module_name test_var reason )
    
  • If you want to require that a variable evaluates to FALSE, just invert it and evaluate:
    SET( not_os_win NOT GBX_OS_WIN )
    GBX_REQUIRE_VAR( build LIB ${lib_name} not_os_win "anything but Windows is supported" )
    

SET( dep_libs basic )
GBX_REQUIRE_TARGETS( build LIB ${lib_name} ${dep_libs} )
The last of the "REQUIRE_" macros: very useful if you link to other libraries in GearBox. Important: this one is for working with internal libraries only. You have to make sure that the required libraries are going to be built because they may be disabled for the same reasons as this one, i.e. user configuration, unsupported OS, lack of prerequisites. Notice that dep_libs can contain a list of libraries separated by a space. In this case we only have one called "basic". In order to reduce the amount of typing required we will reuse this variable later when it comes to actually linking.

  • The complete signature of this macro and a related "singular" version:
    GBX_REQUIRE_TARGETS( cumulative_var [EXE | LIB] module_name TARGET0 [TARGET1 TARGET2 ...] )
    GBX_REQUIRE_TARGET( cumulative_var [EXE | LIB] module_name TARGET [reason] )
    

IF ( build )
Ok, we've checked everything. Now build variable can tell us to build or not to build.

A note on slightly funky CMake syntax: notice that in the IF statement and in other places with a boolean context, CMake accepts both the variable name, i.e. build, and it's evaluation, i.e. ${build}. We find that more consistent results are obtained with the variable names.

    INCLUDE( ${GBX_CMAKE_DIR}/UseBasicRules.cmake )
Commonly used CMake scripts are stored in a one directory [GEARBOX-SRC]/cmake. For convenience, this path is stored in the special variable GBX_CMAKE_DIR. The INCLUDE command literally pastes the contents of the referenced scripts right here in the middle of our file. So you can take a look at that script to see what it does. Importantly, it adds -Wall compiler definition.

    FILE( GLOB hdrs *.h )
    FILE( GLOB srcs *.cpp )
Search for file in the current directory which fit the specified pattern and assign the list to the variables hdrs and srcs.
  • Instead of searching you can just list the files you need.
    SET( srcs util.cpp )
    

    GBX_ADD_LIBRARY( ${lib_name} SHARED ${srcs} )
    TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )
Here we tell CMake to create rules for building a shared library and to specify dependencies. Now you can see why we bothered with defining variables. These commands are generic and can be easily used for other libraries.

GBX_ADD_LIBRARY is a custom GearBox macro. It does several things:

  • Actually defines a library target (with a standard command ADD_LIBRARY ). In Linux, this will produce libGbxAdvanced.so
  • Specifies standard installation directory: [PREFIX]/lib/gearbox/
  • Adds the name of the library to the global list of libraries which will be built (for feedback).

TARGET_LINK_LIBRARIES is a standard CMake command. It specifies that our library is to be linked to our dependencies.

    GBX_ADD_HEADERS( gbxadvanced ${hdrs} )
This custom macro doesn't save much space but prevents easily-made mistakes. It specifies destination for header files to be [PREFIX]/include/gearbox/gbxadvanced. With the custom macro only the module subdirectory needs to be specified.

ENDIF ( build )
Don't forget to close the IF structure. Notice that CMake is quite strict with IF statements: the signature of the closing ENDIF must be identical.

A list of useful CMake variables defined by GearBox

OS variables: evaluate to TRUE when running on the corresponding OS, otherwise to FALSE. We define our own because the standard CMake ones are inconsistently named and the one for Linux is not defined.
GBX_OS_LINUX
GBX_OS_MAC
GBX_OS_QNX
GBX_OS_WIN

Path variables:

GBX_BIN_INSTALL_DIR
GBX_LIB_INSTALL_DIR
GBX_INCLUDE_INSTALL_DIR
GBX_PROJECT_BINARY_DIR
GBX_PROJECT_SOURCE_DIR
GBX_SHARE_INSTALL_DIR
 

Generated for GearBox by  doxygen 1.4.5