Perform the following steps to get the [http://www.cmake.org CMake Make System] working for you. The example shows how to set things up such that the binary startCompletionServer is built by a call to make and that the distribution autocomplete-0.1.tar.gz is built by a call to make package_source.

Basic workcycle

Let us assume that all your soruce files (.h and .cpp files) are located in one top level directory called autocompletion. In this directory, create a file called CMakeLists.txt with the following content:

# BUILDING
PROJECT(autocompletion)

SET(BASEFILES 
               Globals.cpp            Globals.h 
               HYBCompleter.cpp       HYBCompleter.h 
               IndexBase.cpp          IndexBase.h 
               History.cpp            History.h
               codes.cpp              codes.h
               nrutil.c               nrutil.h
               QueryParameters.cpp    QueryParameters.h 
               HYBIndex.cpp           HYBIndex.h 
               WordsFile.cpp          WordsFile.h 
               ConcurrentLog.cpp      ConcurrentLog.h 
               DocsDB.cpp             DocsDB.h 
               Document.cpp           Document.h 
               ExcerptsGenerator.cpp  ExcerptsGenerator.h
               CompletionServer.cpp   CompletionServer.h
               CompleterBase.cpp      CompleterBase.h
)

ADD_EXECUTABLE(startCompletionServer StartCompletionServer.cpp ${BASEFILES})

# TODO: the following ist not portable!
# we could use IF(UNIX) or IF($ENV{OSTYPE} EQUAL linux-gnu)

ADD_DEFINITIONS(-fexceptions
                -static
                 -O6 -Wall
                -DVERSION=\"'`date +\"Version %d%b%y %H:%M\"`'\"
                -DNDEBUG -D_FILE_OFFSET_BITS=64 
                -D_LARGEFILE_SOURCE -D_REENTRANT
                )

TARGET_LINK_LIBRARIES(startCompletionServer pthread z)

This tells CMake the name of the project, the basic .h and .cpp files that every executable is made from, the name and the dependencies of the executable startCompletionServer that you want to build, some compiler and linker options to be applied in every copiler and linker run, and the libraries against which startCompletionServer has to be linked.

Now create a sibling directory, change into this directory and make an "out-of-source" build:

$ cd ..
$ mkdir build
$ cd build
$ cmake ../autocompletion # out-of-source: build in a completely different tree
$ make
$ ./startCompletionServer

Some terminology

Before we go any further, let us try to clarify some important CMake terminology:

The source tree is where source files (*.c, etc.) and configuration files (CMakeList.txt, etc.) live.

The build tree is where you build the software. It contains everything that is configured or built. It has got a lot of files in it (e.g., *.o) that are essential to the build of executables or libraries, but which are not of interest to pure users of the software. It is possible to do an in-source build where the build tree is superimposed on the source tree, but it is just easier to keep the two separate since it allows you to entirely remove your build tree and start over without molesting your source tree. The latter is called an out-of-source build.

The install tree is where you install the subset of the build tree that is used by pure users. So it consists normally of just executables, libraries, and documentation. The various CMakeLists.txt files that are in the source tree specify exactly what is to be put in the install tree. The install tree should be kept entirely separate from the source tree and from the build tree.

A source package normally just contains a packager-specified subset of the source tree (e.g., the packager would want to skip .svn or CVS directories) in some packager-specified format (e.g., compressed tarball). A software packager can generate source packages of his software using CMake (via the CPack utility). Users of source packages obviously have to build the packaged software for themselves using CMake, but that gives them a lot of freedom since CMake configures the build for the special circumstances of their particular system. For example, it is very good at finding 3rd-party libraries required for the build that happen to be in non-standard locations or modifying the build (e.g., dropping parts of it) if certain 3rd-party components are not found.

A binary package contains everything that is in the install tree in some packager-specified format (e.g., compressed tarball). A software packager can generate binary packages of his software using CMake (via CPack). Users of binary packages do not have to build anything (they just use the executables and libraries that are supplied), but such binary packages demand a lot in terms of standardization. For example, they normally expect 3rd-party libraries to be of the same version and in the same location for the user as they were for the packager. So binary packages are great if built for a standard environment, such as a particular Linux distribution, but if there is any variation in the standard (e.g., Debian versus RedHat), the departure from the expected standards leads to trouble, and the user is better off building the software from a source package.

Installing

# INSTALLING
INSTALL(TARGETS startCompletionServer RUNTIME DESTINATION bin)

Use the command line definition CMAKE_INSTALL_PREFIX:

$ cmake .. -DCMAKE_INSTALL_PREFIX=.

Packaging

Testing

ADD_EXECUTABLE(test-adler32 test-adler32.cpp ${BASEFILES})
TARGET_LINK_LIBRARIES(test-adler32 pthread z)
ADD_TEST(adler32 test-adler32 4711)

Using subdirectories

# Recurse into subdirs
ADD_SUBDIRECTORY( src )

Generating config.h

INCLUDE (CheckIncludeFiles)

# usage: CHECK_INCLUDE_FILES (<header> <RESULT_VARIABLE> )
CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H)

# If another header is required to use the header you are looking for,
# you have to list the header files separated by semicolons
CHECK_INCLUDE_FILES ("sys/param.h;sys/mount.h" HAVE_SYS_MOUNT_H)

INCLUDE (CheckFunctionExists)
CHECK_FUNCTION_EXISTS(memcpy HAVE_MEMCPY)
CHECK_FUNCTION_EXISTS(floedeldoe HAVE_FLODELDOE)

CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake 
               ${CMAKE_CURRENT_BINARY_DIR}/config.h)

Useful options

CMAKE_MINIMUM_REQUIRED(VERSION 2.4)
ENABLE_TESTING()

# the following line works in 2.4, but not in 2.0 :-)
# CMAKE_MINIMUM_REQUIRED(VERSION 2.4 FATAL_ERROR)

# workaround for stopping cmake
IF(CMAKE_SYSTEM_VERSION LESS 2.4)
  MESSAGE(FATAL_ERROR "STOPPED! You need at least CMake version 2.4 for this.")
ENDIF(CMAKE_SYSTEM_VERSION LESS 2.4)

# option to produce more 'verbose' compiling
#SET(CMAKE_VERBOSE_MAKEFILE ON)