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} DEFAULT ${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 ENABLE_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 in this case).
  • Every time CMake runs, it checks the current value of the ENABLE_LIB_GBXADVANCED variable. If the user has configured it to OFF, then the value of build variable will become OFF (aka 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.

It is sometimes useful to disable compilation of all targets and then selectively enable a few. To do this set GBX_DISABLE_ALL to ON. In this case, all default compilation settings for all targets are set to OFF. It is still possible to individually enable targets with e.g. ENABLE_LIB_GBXADVANCED=ON. For GBX_DISABLE_ALL to take effect, make sure you clear CMake cache first, by deleting CMakeCache.txt file.

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} DEFAULT ${srcs} )
    TARGET_LINK_LIBRARIES( ${lib_name} ${dep_libs} )

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 or libGbxAdvanced.a
  • Specifies library type. Valid options are SHARED, STATIC, or DEFAULT (the prefered option). DEFAULT is resolved to the user-specified variable GBX_DEFAULT_LIB_TYPE (which initially is set to SHARED).
  • 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.

Now you can see why we bothered with defining variables. These commands are generic and can be easily used for other libraries.

    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 comprehensive list of CMake variables defined by GearBox

Build system configuration:
GBX_DEFAULT_LIB_TYPE    # Valid options {SHARED, STATIC}. Defaults to SHARED.

Project description:

GBX_PROJECT_VERSION_MAJOR
GBX_PROJECT_VERSION_MINOR
GBX_PROJECT_VERSION_PATCH
GBX_PROJECT_VERSION         (=MAJOR.MINOR.PATCH)
GBX_PROJECT_NAME_LOWER      (e.g. 'gearbox' )
GBX_PROJECT_NAME_UPPER      (e.g. 'GEARBOX' )
GBX_PROJECT_NAME_CAP        (e.g. '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

Under Linux, an additional variable if defined

GBX_PROC_64BIT

Source and binary directories can be distinguished as so

GBX_PROJECT_BINARY_DIR
GBX_PROJECT_SOURCE_DIR

Install directories can be referenced with absolute paths

GBX_BIN_INSTALL_DIR
GBX_CMAKE_INSTALL_DIR
GBX_CMAKE_PKGCONFIG_INSTALL_DIR
GBX_INCLUDE_INSTALL_DIR
GBX_LIB_INSTALL_DIR
GBX_PKGCONFIG_INSTALL_DIR
GBX_SHARE_INSTALL_DIR
.. or path relative to the install directory
GBX_BIN_INSTALL_SUFFIX
GBX_CMAKE_INSTALL_SUFFIX
GBX_CMAKEPKGCONFIG_INSTALL_SUFFIX
GBX_INCLUDE_INSTALL_SUFFIX
GBX_LIB_INSTALL_SUFFIX
GBX_PKGCONFIG_INSTALL_SUFFIX
GBX_SHARE_INSTALL_SUFFIX
 

Generated for GearBox by  doxygen 1.4.5