CMakeForFLTK

From KitwarePublic
Jump to: navigation, search

Using CMake to build an FLTK application

Introduction

The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a cross-platform C++ GUI toolkit for UNIX®/Linux® (X11), Microsoft® Windows®, and MacOS® X. It is available from http://www.fltk.org.

In addition to the C++ programming interface, FLTK provides the Fast Light User Interface Designer, or FLUID, which is a graphical editor that is used to produce FLTK source code. FLUID edits and saves its state in .fl files. These files are text, and you can (with care) edit them in a text editor, perhaps to get some special effects.

The programs that I have written using FLTK have been personal projects, intended only for my own use on my Linux system, and I have only ever needed simple hand-crafted Makefiles to build them. However, one project looks like it might have a wider audience, but I have little experience with, or access to, the Windows® or MacOS® programming environments. Therefore I started looking for a cross-platform build environment to simplify the task and avoid potential problems. I had experimented with the GNU autotools suite (autoconf, automake, libtool) and was making slow progress, and then CMake came up in the conversation and I decided to investigate further.

After poring over the CMake documentation, and searching the Internet for clues, I eventually managed to glean enough nuggets of useful information to get the build system in place, for Linux at least. What surprised me was that if you distill down all of the different snippets, the required configuration is very short! This page is intended to help others in the same situation by collecting it all together.

Code Hierarchy

    example/
        src/
            callbacks.cxx
            foo.cxx
            ui.fl

The main application code lives in foo.cxx. The FLTK callback functions live in callbacks.cxx and were created using a standard editor. The user interface layout is defined in ui.fl and was created using FLUID. The corresponding C++ code could have been written from within the interactive FLUID session, but regenerating it using the command line ensures that everything is consistent. The following simple Makefile shows the build process and dependencies:

    FLTK_CXXFLAGS = `fltk-config --cxxflags`
    FLTK_LDFLAGS = `fltk-config --ldstaticflags`

    foo:    foo.o ui.o callbacks.o
        g++ -o foo foo.o ui.o callbacks.o $(FLTK_LDFLAGS)

    foo.o:  foo.cxx ui.h
        g++ -c $(FLTK_CXXFLAGS) foo.cxx

    callbacks.o:    callbacks.cxx ui.h
        g++ -c $(FLTK_CXXFLAGS) callbacks.cxx

    ui.o:   ui.cxx ui.h
        g++ -c $(FLTK_CXXFLAGS) ui.cxx

    ui.cxx ui.h:    ui.fl
        fluid -c ui.fl

CMake configuration

CMakeLists.txt:

    CMAKE_MINIMUM_REQUIRED(VERSION 2.6)

    PROJECT(example)

    FIND_PACKAGE(FLTK REQUIRED)
    FIND_PACKAGE(OpenGL REQUIRED)

    ADD_SUBDIRECTORY(src)

src/CMakeLists.txt:

    FLTK_WRAP_UI(Ui ui.fl)
    ADD_LIBRARY(Ui callbacks.cxx ${Ui_FLTK_UI_SRCS})

    ADD_EXECUTABLE(foo foo.cxx)
    ADD_DEPENDENCIES(foo Ui)
    TARGET_LINK_LIBRARIES(foo Ui)
    TARGET_LINK_LIBRARIES(foo ${FLTK_LIBRARIES})
    TARGET_LINK_LIBRARIES(foo ${OPENGL_LIBRARIES})

Notes:

  • CMAKE_MINIMUM_REQUIRED - you could omit this line, but CMake will keep bugging you about it so you might as well include it!
  • FIND_PACKAGE(FLTK REQUIRED) - if you search the Internet you will find a bug report where this fails because it is looking for the include file FL/Fl.h instead of FL/Fl.H, but as this works on my Linux box it is clearly fixed.
  • FIND_PACKAGE(OpenGL REQUIRED) - the CMake scripting language is not case-sensitive, so you can also write find_package but the names of the things that you are looking for are case-sensitive. This can be confusing, especially when the CMake variables generated change case (e.g. ${OPENFL_LIBRARIES}).
  • FLTK_WRAP_UI(Ui ui.fl) - the first parameter is used as the prefix of a *_FLTK_UI_SRCS variable name that will contain the names of the C++ files corresponding to the FLUID files given in the remaining parameters. In this case ${Ui_FLTK_UI_SRCS} will contain ui.cxx and ui.h. Now that I am adding these notes, maybe it would have been better if I had chosen something a little less confusing than Ui for this example.
  • ADD_LIBRARY(Ui callbacks.cxx ${Ui_FLTK_UI_SRCS}) - the first parameter defines the name of a library target and the remaining parameters define the sources that are used to build that target. Note the use of the ${Ui_FLTK_UI_SRCS} variable defined by the previous step. The library target is called libUi.a on my system.
  • ADD_EXECUTABLE(foo foo.cxx) - the first parameter defines the name of an executable target, and the remaining parameters define the non-library sources that are needed for that target.
  • ADD_DEPENDENCIES(foo Ui) - tells CMake that the foo target depends on the Ui target, and therefore that foo must be built after Ui.
  • TARGET_LINK_LIBRARIES(foo Ui) - tells CMake that foo needs to be linked against the Ui library target.
  • TARGET_LINK_LIBRARIES(foo ${FLTK_LIBRARIES}) - tells CMake that foo needs to be linked against the libraries in the ${FLTK_LIBRARIES} variable. Where does this variable come from? It is defined as part of the FIND_PACKAGE(FLTK REQUIRED) call, but you can only find this out by looking at the Modules/FindFLTK.cmake that comes with the CMake installation, or by browsing the installed CMake documentation.
  • TARGET_LINK_LIBRARIES(foo ${OPENGL_LIBRARIES}) - see above. Required because my installation of FLTK needs to be linked against OpenGL.

Comments?

This was my first exposure to CMake and took a bit of trial and error over the course of a weekend. If anyone has any comments on how to improve this configuration, or how to adapt it for non-Linux platforms, please let me know, or add a section to this page.