Development/Tutorials/CMake (de)

    From KDE TechBase
    The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.


    Development/Tutorials/CMake


    Zusammenfassung

    CMake ist das Build-System, das KDE benutzt. Diese Anleitung beschreibt, wie man CMake benutzt und wie man die Projektdateien schreibt.

    Einführung

    CMake liest Script Dateien ein und gibt Eingabedateien für das native Buildsystem der Platform auf der es läuft aus. Es kann GNU Makefiles, KDevelop Projekt Dateien, XCode Projekt Dateien und Visual Studio Projekt Dateien ausgeben.

    CMake ist freie Software, die unter einer BSD-artigen Lizenz veröffentlicht wird. Entwickelt wird es von Kitware Inc.

    Hier einige Links, wo man etwas über CMake im Allgemeinen lernen kann (meist englisch):

    Es gibt auch eine CMake Mailing List.

    Warum CMake benutzen ?

    CMake ist nach einer Entscheidung im März 2006 das offizielle Werkzeug von KDE 4, vorwiegend aus technischen Vorteilen gegenüber den älteren KDE Werkzeugen automake und unsermake:

    • CMake wird unabhänging von KDE entwickelt und kann auch von anderen Projekten benutzt werden.
    • Die Übersetzungszeit ist sehr viel kürzer, hauptsächlich weil die libtool nicht mehr benutzt wird.
    • Die CMake-Dateien sind einfacher zu schreiben.

    Wie man KDE mit Hilfe von CMake übersetzt

    CMake runterladen und installieren

    Linux, BSD und andere Unix Systeme

    Die neuste Version von CMake kann von [1] heruntergeladen werden.

    Einmal heruntergeladen, muss es entpackt und übersetzt werden: $ mkdir cmake-build $ cd cmake-build $ ../bootstrap $ make $ make install

    Standardmäßig wird CMake in /usr/local installiert, daher muss /usr/local/bin in Pfad für ausführbare Dateien stehen. Um das Installationspräfix zu ändern (z.B. in /usr in debian), muss die '--prefix=PATH' Option zum bootstrap Kommando hinzugefügt werden.

    Möchte man die aktuelle Entwicklerversion von CMake benutzen, findet man hier eine Anleitung.

    Windows

    Neuste Version von CMake von hier herunterladen.

    Dann den Cmake-installer aufrufen

    Standardmäßig wird CMake in C:\$(Program Files)\CMake 2.4 installiert.

    Möchte man die aktuelle Entwicklerversion von CMake benutzen, findet man hier eine Anleitung.

    Run CMake

    Linux, BSD, and other Unix Systems

    Um die Build-Dateien für das System zu erzeugen, muss CMake aufgerufen werden. Sowohl Übersetzungsvorgänge innerhalb des Codes als auch in einem gesonderten werden von CMake unterstützt, wobei KDE derzeit einen Übersetzungsvorgang innerhalb des Quellcodes verbietet.

    Hat man zum Beispiel kdelibs/ in ~/src/kdelibs/, dann ruft man folgende Befehle auf: $ ls kdelibs/ $ mkdir kdelibs-build $ cd kdelibs-build $ cmake ../kdelibs Das wird die Makefiles im Verzeichnis kdelibs-build erzeugen, die zum Übersetzen von kdelibs benötigt werden.

    Windows

    Um die Build-Dateien für das System zu erzeugen, muss CMake aufgerufen werden. Sowohl Übersetzungsvorgänge innerhalb des Codes als auch in einem gesonderten werden von CMake unterstützt, wobei KDE derzeit einen Übersetzungsvorgang innerhalb des Quellcodes verbietet.

    Hat man zum Beispiel kdelibs\ in c:\daten\kde4, dann ruft man folgende Befehle auf: c:\daten\kde4> cd kdelibs\win c:\daten\kde4> cmake c:\daten\kde4> make c:\daten\kde4> make install c:\daten\kde4> cd .. c:\daten\kde4> mkdir kdelibs-build c:\daten\kde4> cd kdelibs-build c:\daten\kde4\kdelibs-build> cmake ..\kdelibs

    Dadurch werden die Makefiles, um kdelibs\ zu erzeugen in kdelibs-build angelegt. Siehe auch KDE On Windows für mehr Informationen über das Übersetzen von KDE unter Windows.

    KDevelop Project Files

    If you prefer project files for KDevelop (which will basically be Makefiles accompanied by some extra files for KDevelop), run it like this: $ cmake ../kdelibs -GKDevelop3 Use 'cmake -h' to find out which generators CMake supports and the other options.

    CMake and Qt4

    To locate Qt 4, CMake searches for qmake in your execute path. CMake does not use the QTDIR environment variable. So make sure that the first qmake found in the execution path is the one you like to use.

    More Details

    When CMake has finished, it will have created a file called "CMakeCache.txt". This file contains all the settings CMake has detected on your system. If you want to run CMake with another generator or you want CMake to detect everything again, delete this file.

    If CMake didn't find something, but you know it is somewere on your box, you can tell CMake manually where to find it. CMake uses variables to store this information. These variables are cached in the already mentioned file CMakeCache.txt. You have three options to adjust these variables manually:

    • tell CMake the correct value via the command line: cmake ../kdelibs -DNAME_OF_THE_VARIABLE=value
    • use ccmake, which provides a curses based GUI to adjust the CMake variables (run: ccmake ../kdelibs)
    • edit the file CMakeCache.txt directly (not recommended)

    You should run "ccmake ../kdelibs" at least once so that you get an impression which variables CMake uses. Press "T" to see also the "advanced" variables. So, if CMake didn't find something, start ccmake and adjust it manually.

    Command Line Variables

    Some cmake command line variables you may want to set:

    • CMAKE_INSTALL_PREFIX: cmake ../kdelibs -DCMAKE_INSTALL_PREFIX=/opt/kde4 is the equivalent to ./configure --prefix=/opt/kde4
    • CMAKE_BUILD_TYPE: decide which type of build you want. You can chose between "debugfull", "debug", "profile", "relwithdebinfo" and "release". The default is "relwithdebinfo" (-O2 -g). See FindKDE4Internal.cmake for details.
    • KDE4_BUILD_TESTS=ON: creates Makefiles with build test programs and also provides 'test' targets
    • KDE4_TEST_OUTPUT=xml: Unit tests using the QTestLib framework will create xml formatted logfiles.
    • KDE4_DISABLE_MULTIMEDIA=ON: Build KDE without any multimedia (audio and video) support.
    • RPATH_STYLE: This is not available anymore. By default everything will be built with RPATH set correctly. If you don't want RPATH at all, set CMAKE_SKIP_RPATH to TRUE.
    • BUILD_foo=OFF: disables the build for the project in subdirectory 'foo'.
    • WITH_foo: there are several options, e.g. WITH_CUPS or WITH_Jasper. If you disable them, cmake will not even try to find this package. If it is enabled, cmake will try to find it. If it fails with this, you can still adjust it manually as described above.

    Environment Variables

    If you have headers and libraries installed in non-standard locations that cmake cannot find (e.g., fink on Mac OSX installs to /sw), then set the following as environment variables. Despite the similar naming convention, these will not work as arguments on the cmake command line:

    • CMAKE_INCLUDE_PATH, eg. export CMAKE_INCLUDE_PATH=/sw/include
    • CMAKE_LIBRARY_PATH, eg. export CMAKE_LIBRARY_PATH=/sw/lib

    For more information on variables, see this cmake.org wiki page

    Going Further

    If cmake finishes with "Generating done" then there was no errors, but if it finishes with "Configuring done" then there was errors that you have to fix. Once cmake finishes successfully, run your buildtool (i.e. make, KDevelop, XCode or MSVC) and build and wait until it has finished. Then "make install".

    If you got a failure that says something like CMake Error: This project requires some variables to be set, and cmake can not find them. Please set the following variables: X11_XTest_LIB (ADVANCED) then you may have a missing library (or other dependency). To find out which library, search in the cmake/modules directory for the variable that cmake can't find. In the example above, it is FIND_LIBRARY(X11_XTest_LIB Xtst ${X11_LIB_SEARCH_PATH}) So the missing library is Xtst. You then need to find it (perhaps installing a libXtst-devel library) and re-run cmake.

    Using CMake for a Simple Application

    Here's the most simple CMakeLists.txt: add_executable(hello main.cpp) This will create an executable named "hello" (or "hello.exe" under Windows) from the source file main.cpp. You can mix C and C++ files as you want. You can have multiple executables and libraries in one CMakeLists.txt. The same source file can be used in multiple targets, it will be compiled for each target independently from the other targets. Probably the most important part of the cmake language are the variables: SET( MY_SOURCES main.cpp widget.cpp) MESSAGE(STATUS "my sources: ${MY_SOURCES}") So, use the SET() command to set the value of a variable. If you list more than one string, the variable will be a list. A list is a list of strings separated by semicolons. If you set it to only one item, it will have just that value. To get the value of a variable, use ${VAR}. You can iterate over a list using FOREACH(): FOREACH(next_ITEM ${MY_SOURCES})

      MESSAGE(STATUS "next item: ${next_ITEM}")
    

    ENDFOREACH(next_ITEM ${MY_SOURCES}) The commands in CMake are case-insensitive. Names of variables and names of parameter are case-sensitive.

    You can also test for various things: IF (UNIX)

      MESSAGE(STATUS "This is UNIX (including OS X and CygWin)")
    

    ENDIF (UNIX)

    IF (MSVC)

      SET(MY_SRCS ${MY_SRCS} winextra.cpp)
    

    ENDIF (MSVC) In this second example you can see also how to append items to a list.

    In the cmake Wiki there is also a tutorial on using cmake to build KDE 4 software. It is recommended reading.

    Using CMake for a KDE Project

    Here's a basic CMakeList file that builds a small KDE 4 project: PROJECT(kde4project) FIND_PACKAGE(KDE4 REQUIRED) INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} )

    SET(KDE4ProjectSources kde4mainapp.cpp someclass.cpp someotherclass.cpp)

    KDE4_ADD_EXECUTABLE(kde4project ${KDE4ProjectSources} )

    TARGET_LINK_LIBRARIES(kde4project ${KDE4_KDEUI_LIBS} ${KDE4_KPARTS_LIBS} )

    Variables, macros and other useful information specific to KDE can be found at the Development/KDE and CMake Together page.

    Extending CMake

    CMake can be extended using cmake scripts. CMake comes with a number of scripts; under UNIX they are by default installed to /usr/local/share/CMake/Modules/. The KDE libraries install also a set of cmake modules into share/apps/cmake/modules/. The files located there will be preferred over the ones in the system global cmake module path. For detecting software packages there are FindFOO.cmake files, see here for more information. You can also write macros in CMake. They are powerful enough to do most things you will need to build software, but they are not intended to be used as a general purpose programming language.

    Converting autotools-based KDE software to CMake

    In kdesdk/cmake/ you can find a script am2cmake . This is a ruby script, so you need to have ruby installed. Run am2cmake in the toplevel directory of your sources: $ cd src/mykooltool/ $ am2cmake --kde4 Don't forget the switch "--kde4", otherwise it won't generate files suitable for KDE 4 software. The converted files 'may' work as they are, but complicated projects will require some additional editing.

    You may have to:

    • add more include direcories, using INCLUDE_DIRECTORIES()
    • add more link libraries, using TARGET_LINK_LIBRARIES()
    • add some compile switches, using ADD_DEFINITIONS()
    • add some "configure" checks, see How To Do Platform Checks and How To Find Installed Software
    • take special care of former libtool convenience libraries. They are not supported by cmake, instead there will be a file ConvenienceLibs.cmake created. In this file you will find for every convenience lib a variable, which contains all source files of this convenience lib. For the targets which linked to this convenience lib, just add the variable to the sources.
    • a file AdditionalInfo.txt will be created. There you will see all *.in and *.in.in files of your project. The stuff done in these files will have to be converted manually to cmake.

    Frequently Asked Questions

    How can I teach my favorite editor about CMake syntax and indentation ?

    Read the CMake Wiki section CMake Editors Support. It describes how to setup Emacs (XEmacs works too), VIM, Kate, KWrite, and KDevelop.

    I need to generate some files during the build. How do I do this ?

    Use ADD_CUSTOM_COMMAND(). It's explained here in the CMake wiki: How can I generate a source file during the build

    I need to build an executable which is used later on during the build to generate files. How do I do this ?

    Let's say the executable is called genembed. Then use KDE4_ADD_EXECUTABLE(foo RUN_UNINSTALLED ${fooSources})to create the executable. The RUN_UNINSTALLED option is important, because the executable has to run from the build dir and has to link to the libraries in the builddir. To achieve this, the executable is compiled with RPATH set accordingly and a wrapper shell script, named just like the executable but with the suffix ".sh" is created. This shell scripts sets up LD_LIBRARY_PATH and the calls the actual executable. Use this wrapper shell script in the ADD_CUSTOM_COMMAND() as described above. You can find out the name and exact location by querying the property WRAPPER_SCRIPT. Here's a full example taken from kdelibs/kstyles/keramik/ :

    1. build the executable

    KDE4_ADD_EXECUTABLE(genembed RUN_UNINSTALLED ${genembed_SRCS})

    1. get the name of the generated wrapper script (which sets up LD_LIBRARY_PATH)

    GET_TARGET_PROPERTY(GENEMBED_EXECUTABLE genembed WRAPPER_SCRIPT)

    1. and the custom command

    ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/keramikrc.h

     COMMAND ${GENEMBED_EXECUTABLE} --file ${CMAKE_CURRENT_BINARY_DIR}/keramikPics.txt > \
     ${CMAKE_CURRENT_BINARY_DIR}/pixmaps.keramik
     DEPENDS genembed ${keramikPics}
    

    )

    As you can see genembed is also listed as a dependency, this means cmake knows that it has to build the executable genembed before executing this rule.

    I don't want to set the -DCMAKE_INSTALL_PREFIX command line option. Does cmake support the KDEDIR environment variable?

    No. $KDEDIR is deprecated in KDE 4.

    Why do i get compile errors like /usr/lib/qt4/include/QtCore/qstring.h:536: undefined reference to `QString::fromLatin1_helper(char const*, int)'?

    A: If you have an old Qt4 version in your qt/lib directory you must delete the old (4.0.1) files.

    How do I tell cmake to create noisy makefiles? I want to see the exact commands that are run during the make process.

    Pass the VERBOSE variable to make, i.e. % make VERBOSE=1 or % VERBOSE=1 make

    For more details see the CMake wiki: Is there an option to produce more 'verbose' compiling?

    There is no 'make distclean' target in the generated Makefiles. How do I clean up everything, including the cache files?

    Simply remove the build directory, or just the contents of the build directory.