Developing using CMake

From FlightGear wiki
Jump to navigation Jump to search

This article assumes familiarity with building via Cmake.

CMake

The minimum required version of CMake is found in the first lines of the CMakeLists.txt file at the top level of each git clone you are building. As of July 2018, we require CMake versions above 3.0.

 cmake_minimum_required (VERSION 3.0)


Adding new files to the build

Add source files to the SOURCES list, and headers to the HEADERS list. Note technically you only need to add source files, but omitting headers confuses project generation and distribution / packaging targets.

For target conditional files, you can append to the SOURCES or HEADERS lists inside an if() test, for example:

    if(APPLE)
    	list(APPEND SOURCES extraFile1.cxx extraFile2.cxx)
    endif()
  • APPLE
  • WIN32
  • LINUX

Setting include directories

In any CMakeList.txt, you can do the following:


    include_directories(${PROJECT_SOURCE_DIR}/some/path)

For example, this can be done in particular subdirectory, or at the project root, or an intermediate level.

Setting target specific compile flags, includes or defines

Use set_target_properties(), for example


    set_target_properties(fgfs PROPERTIES COMPILE_DEFINITIONS FOO BAR=1)

You can set a property on an individual source file:


    set_property(SOURCE myfile.cxx PROPERTY COMPILE_FLAGS "-Wno-unsigned-compare")

Adding optional Features

Open the top-level CMakeLists.txt file $SG_SRC or $FG_SRC, locate the section named "FlightGear build options":

# FlightGear build options
option(SIMGEAR_SHARED    "Set to ON when SimGear was built as a shared library" OFF)
option(LOGGING           "Set to ON to build FlightGear with logging support (default)" ON)
option(SP_FDMS           "Set to ON to build FlightGear with special-purpose FDMs" OFF)
option(ENABLE_UIUC_MODEL "Set to ON to build FlightGear with UIUCModel FDM" OFF)
option(ENABLE_LARCSIM    "Set to ON to build FlightGear with LaRCsim FDM" OFF)
option(ENABLE_YASIM      "Set to ON to build FlightGear with YASIM FDM (default)" ON)
option(ENABLE_JSBSIM     "Set to ON to build FlightGear with JSBSim FDM (default)" ON)
option(EVENT_INPUT       "Set to ON to build FlightGear with event-based Input support" ${EVENT_INPUT_DEFAULT})
option(ENABLE_RTI        "Set to ON to build FlightGear with RTI support" OFF)
option(ENABLE_PROFILE    "Set to ON to build FlightGear with gperftools profiling support" OFF)
option(JPEG_FACTORY      "Set to ON to build FlightGear with JPEG-factory support" OFF)
option(SYSTEM_SQLITE     "Set to ON to build FlightGear with the system's SQLite3 library" OFF)

Add your own build option to the end of the list.

Detecting Features / Libraries

For most standard libraries (Gtk, wxWidget, Python, GDAL, Qt, libXml, Boost), cmake provides a standard helper. To see the available modules, run:

    cmake --help-module-list

In the root CMakeLists file, use a statement like:


    find_package(OpenGL REQUIRED)

Each package helper sets various variables such aaa_FOUND, aaa_INCLUDE_DIR, and aaa_LIBRARY. Depending on the complexity of the package, these variables might have different names (eg, OPENSCENEGRAPH_LIBRARIES).

If there's no standard helper for a library you need, find a similar one, copy it to CMakeModules/FindABC.cmake, and modify the code to fit. Generally this is pretty straightforward. The built-in modules reside in the Cmake 'share' directory, eg /usr/share/cmake/modules on Unix systems.

Note libraries support by pkg-config can be handled directly, with no need to create a custom FindABC helper.

After invoking the find_package() command, you'll typically want to set up custom definitions for optional code, e.g.:

find_package(osgEarth REQUIRED)
if(OSGEARTH_FOUND)
 message(STATUS "Okay, osgEarth found via CMake:${OSGEARTH_LIBRARY}")
 add_definitions(-DENABLE_OSGEARTH=1)
endif(OSGEARTH_FOUND)


In your C++ code, use include guards to wrap any optional code, e.g.:

#ifdef ENABLE_OSGEARTH
 initializeOsgEarth();
#endif

Adding a new executable target

    add_executable(myexecutable ${SOURCES} ${HEADERS})
    target_link_libraries(myexecutable .... libraries ... )
    install(TARGETS myexecutable RUNTIME DESTINATION bin)

(If the executable should not be installed, omit the final line above)

If you add an additional line


    add_test(testname ${EXECUTABLE_OUTPUT_PATH}/myexecutable)

Then running 'make test' will run your executable as a unit test. The executable should return either a success or failure result c