CMakeForFLTK
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 even 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 fileFL/Fl.h
instead ofFL/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 writefind_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 containui.cxx
andui.h
. Now that I am adding these notes, maybe it would have been better if I had chosen something a little less confusing thanUi
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 calledlinUi.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 thefoo
target depends on theUi
target, and therefore thatfoo
must be built afterUi
.TARGET_LINK_LIBRARIES(foo Ui)
- tells CMake thatfoo
needs to be linked against theUi
library target.TARGET_LINK_LIBRARIES(foo ${FLTK_LIBRARIES})
- tells CMake thatfoo
needs to be linked against the libraries in the${FLTK_LIBRARIES}
variable. Where does this variable come from? It is defined as part of theFIND_PACKAGE(FLTK REQUIRED)
call, but you can only find this out by looking at theModules/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.