Qt with cmake is a Makefile generator, that means it does not replace the "make" program (in contrast to e.g. scons).
Thus cmake is comparable to autotools (see Qt with autotools). However:
- cmake also works on Windows
- cmake is much easier to learn than autotools
- cmake scripts are much easier to read than autotools scripts
- cmake comes with many configure test macros built in
- cmake comes with support for Qt and KDE
Contents []
- 1 History: KDE4
- 2 Using cmake
- 3 cmake for Qt/KDE 3
- 4 cmake for Qt 4
- 5 Installing files
- 6 Configure tests
- 7 Sample Projects
[ edit] History: KDE4
cmake was one of the alternatives investigated by the KDE project to replace the usage of autotools for KDE4. SCons was chosen initially, but got dropped due to some inherent problems and currently (May 2006) it looks like cmake will be the default build system for KDE4. Since KDE is built upon Qt, it is logical that cmake support for both Qt and KDE will be very good once KDE4 is released. However Qt/KDE in cmake support already is very good right now.
[ edit] Using cmake
When you have a cmake based project and just want to compile it, do the following:
cd project
mkdir build
cd build
cmake ..
make
make install
Or if you want to install to /home/foo/bar instead of the default install prefix:
cd project
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/home/foo/bar ..
make
make install
You can also use "ccmake" instead of "cmake". This will give you a more or less graphical tool to configure the application - a graphical window on windows and a text/menu based program on unix.
[ edit] cmake for Qt/KDE 3
Note: we will require cmake 2.4 here. However some/most of the code below may work with previous versions, too. Here we have a look at a simple cmake based project for Qt3/KDE3. I am going to use the KDE3 macros, because I come from a KDE background and I find them much simpler to use, than the plain Qt variants, but I think you don't actually need KDE for them.
Suppose we have a simple project:
To turn it into a cmake project, we add two CMakeLists.txt files, one per directory. The qtproject/CMakeLists.txt file will look like this:
project(qtproject) # the name of your project
cmake_minimum_required(VERSION 2.4.0)
find_package(Qt3 REQUIRED) # find and setup Qt3 for this project
find_package(KDE3 REQUIRED) # find and setup KDE3 for this project
add_definitions(${QT_DEFINITIONS} ${KDE3_DEFINITIONS})
# tell cmake where to search for libraries:
link_directories(${KDE3_LIB_DIR})
# tell cmake where to search for Qt/KDE headers:
include_directories(${KDE3_INCLUDE_DIR} ${QT_INCLUDE_DIR})
# tell cmake to process CMakeLists.txt in that subdirectory
add_subdirectory(src)
A closer look at some macros used here:
- find_package(Qt3 REQUIRED): this is some kind of configure test. It searches for Qt3 and defines a couple of variables that we will use later on. This will be required for your Qt3 based project.
- find_package(KDE3 REQUIRED): this does the same for KDE3. Skip this if your project is Qt only.
- link_directories() this adds directories to the path where cmake searches for libraries, nothing else. Pretty much a -L<directory> when it comes to g++.
- include_directories() this does not "include" a directory to cmake, but rather tells the compiler where to search for include files. I.e. -I<directory> when it comes to g++.
The actually interesting things happen in qtproject/src/CMakeLists.txt:
# the variable "qtproject_SRCS" contains all .cpp files of this project
set(qtproject_SRCS
main.cpp
top.cpp
)
# tell cmake to create .moc files for all files in the variable qtproject_SRCS that require such a file.
# note: this assumes that you use #include "header.moc" in your files
# also note that you don't actually require kde to use this command
kde3_automoc(${qtproject_SRCS})
# create an executable file named "qtproject" from the source files in the variable "qtproject_SRCS".
add_executable(qtproject ${qtproject_SRCS})
# link the "qtproject" target (i.e. the executable file added above) agains the Qt and the kdecore libraries.
target_link_libraries(qtproject ${QT_AND_KDECORE_LIBRARIES})
- set(<variable> <value>): this is pretty much a "<variable> = <value>" statement. The first argument is the variable name, the rest is a list (space or newline separated) of values for it. I just emphasize it, because it looked cryptic to me a long time ago :-)
- kde3_automoc(): add #include "header.moc" next to your #include "header.h" and then use this macro. It will do all the moc work for you.
- target_link_libraries(qtproject ${QT_AND_KDECORE_LIBRARIES}): link qtprojects against some libraries. You can add more to that list, adding library names (just the name, neither a prefix such as "lib", nor a suffix, such as ".so") to it (space separated). Instead of $ {QT_AND_KDECORE_LIBRARIES} you could use (for example):
- ${QT_LIBRARIES} - only the Qt libraries, no KDE libraries
- ${QT_AND_KDECORE_LIBRARIES} kdeui - create a KDE GUI program
[ edit] cmake for Qt 4
Qt4 support in cmake is being developed in particular with the KDE project for KDE4. Qt4 support in cmake is already (cmake version 2.4.x) good at this point. Most things can be done similar as in Qt/KDE 3, so have a look at the section above for a full introduction.
qtproject/CMakeLists.txt:
project(qtproject) # the name of your project
cmake_minimum_required(VERSION 2.4.0)
find_package(Qt4 REQUIRED) # find and setup Qt4 for this project
# tell cmake to process CMakeLists.txt in that subdirectory
add_subdirectory(src)
qtproject/src/CMakeLists.txt:
# the next line sets up include and link directories and defines some variables that we will use.
# you can modify the behavior by setting some variables, e.g.
# set(QT_USE_OPENGL TRUE)
# -> this will cause cmake to include and link against the OpenGL module
include(${QT_USE_FILE})
# the variable "qtproject_SRCS" contains all .cpp files of this project
set(qtproject_SRCS
main.cpp
top.cpp
)
# tell cmake to create .moc files for all files in the variable qtproject_SRCS that require such a file.
# note: this assumes that you use #include "header.moc" in your files
#在需要moc的文件中必须包含#include "你的头文件.moc"在你的cpp文件中。
qt4_automoc(${qtproject_SRCS})
# create an executable file named "qtproject" from the source files in the variable "qtproject_SRCS".
add_executable(qtproject ${qtproject_SRCS})
# link the "qtproject" target against the Qt libraries. which libraries exactly, is defined by the "include(${QT_USE_FILE})" line above, which sets up this variable.
target_link_libraries(qtproject ${QT_LIBRARIES})
- If you need cmake to generate ui*.h files from .ui files then you need to use QT4_WRAP_UI macro like this:
SET(qtproject_UIS
main_window.ui
)
QT4_WRAP_UI(qtproject_UIS_H ${qtproject_UIS})
#Now add these generated files to the ADD_EXECUTABLE step
# If this is NOT done, then the ui_*.h files will not be generated
add_executable(qtproject ${qtproject_SRCS} ${qtproject_UIS_H} )
- If you don't use the #include "header.moc" convention, you can use the QT4_WRAP_CPP macro. This generates a list of moc_xxxx.cxx files to be generated. You pass in the list of headers to be moc'ed, and get back a list of source files to add to your build target. This is similar to how qmake works with Qt4. An example usage is:
SET(foo_SRCS
Class1.cpp
Class2.cpp
Class3.cpp
)
SET(foo_MOC_HDRS
Class1.h
Class2.h
Class3.h
)
# After this call, foo_MOC_SRCS = moc_Class1.cxx moc_Class2.cxx moc_Class3.cxx.
QT4_WRAP_CPP(foo_MOC_SRCS ${foo_MOC_HDRS})
ADD_EXECUTABLE(foo ${foo_SRCS} ${foo_MOC_SRCS})
- To add support for Qt4 libraries like network or qttest, you need to add both the include files and corresponding libraries. For example, to add support for the network and qttest libraries, you can use:
INCLUDE_DIRECTORIES(
${QT_INCLUDE_DIR}
${QT_QTNETWORK_INCLUDE_DIR}
${QT_QTTEST_INCLUDE_DIR}
)
TARGET_LINK_LIBRARIES(
${QT_LIBRARIES}
${QT_QTNETWORK_LIBRARIES}
${QT_QTTEST_LIBRARIES}
)
- To build a Qt plugin, you must add some defines and build your library as a shared library. For example, to build a plugin in release mode:
ADD_DEFINITIONS(${QT_DEFINITIONS})
ADD_DEFINITIONS(-DQT_PLUGIN)
ADD_DEFINITIONS(-DQT_NO_DEBUG)
ADD_DEFINITIONS(-DQT_SHARED)
...
ADD_LIBRARY(foo SHARED ${foo_SRCS}) [ edit] Installing files
Installing in cmake is very easy - to install the "qtproject" executable created above add this to the end of the CMakeLists.txt file:
install(TARGETS qtproject DESTINATION bin)
This will install to the "bin" subdirectory of CMAKE_INSTALL_PREFIX.
Instead of TARGETS you could also use FILES, which would allow you to install any random file that exists in the source directory.
For a complete reference of the install() macro, see the cmake documentation at http://www.cmake.org.
发表于: 2006-08-31 ,修改于: 2006-09-08 11:25,已