[Qt-interest] cmake: how to set up a deep project tree
Rui Maciel
rui.maciel at gmail.com
Tue Feb 14 13:17:16 CET 2012
After a bit of digging for information on how to use cmake to set up a deep
project tree for a Qt project, here's a small how-to guide.
The software project, named foo, consists of a small Qt program and a couple
of static libraries: a UI library based on Qt (henceforth refered to as "ui
library") and a library which relies only on standard C++ ("data library").
First of all, the intended project tree will be like this:
<project>
~
~/src
~/src/data
~/src/ui
<project>
with '~' referring to the project's base directory (i.e., "/home/user/foo"
if foo's project directory is stored in "/home/user"). The complete project
tree, after the cmake project is up and running, will look like this:
<project>
.
├── CMakeLists.txt
├── src
│ ├── CMakeLists.txt
│ ├── config.h.in
│ ├── data
│ │ ├── CMakeLists.txt
│ │ ├── Data.c++
│ │ ├── Data.h++
│ ├── main.c++
│ └── ui
│ ├── CMakeLists.txt
│ ├── MainWindow.c++
│ ├── MainWindow.h++
│ └── MainWindow.ui
├── README
└── TODO
</project>
First, a CMakeLists.txt file is added to '~'. This file will be used to
define the settings for this project, include global options and include
libraries. For this project, this file will only be used to set compiler
flags, set up the project name, include Qt and libsigc++ and setup a
config.h file.
<file name="~/CMakeLists.txt">
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
SET(CMAKE_CXX_FLAGS "-O0 -g -Wall -std=c++0x")
PROJECT (foo)
FIND_PACKAGE( Qt4 REQUIRED)
FIND_PACKAGE(PkgConfig REQUIRED)
# check for libraries
pkg_check_modules(SIGC2 REQUIRED sigc++-2.0>=2.1)
SET(foo_VERSION_MAJOR 0)
SET(foo_VERSION_MINOR 1)
CONFIGURE_FILE (
"${PROJECT_SOURCE_DIR}/src/config.h.in"
"${PROJECT_BINARY_DIR}/src/config.h"
)
INCLUDE(${QT_USE_FILE})
INCLUDE_DIRECTORIES(${SIGC2_INCLUDE_DIRS})
ADD_SUBDIRECTORY(src)
</file>
In "~/src", the executable for project foo is added. The deep project tree
structure is set up by specifying the macros which add the "data" and "ui"
subdirectories to the build, which will include a dedicated CMakeLists.txt
file that define how the files included in them are built. This
CMakeLists.txt file looks like this:
<file name="~/src/CMakeLists.txt">
include_directories ("${PROJECT_SOURCE_DIR}/data")
include_directories ("${PROJECT_SOURCE_DIR}/ui")
include_directories ("${PROJECT_BINARY_DIR}/src")
include_directories ("${PROJECT_BINARY_DIR}/src/ui")
add_subdirectory (data)
add_subdirectory (ui)
SET(foo_SOURCES main.c++ )
SET(foo_HEADERS )
SET(foo_FORMS )
QT4_WRAP_CPP(foo_HEADERS_MOC ${foo_HEADERS})
QT4_WRAP_UI(foo_FORMS_HEADERS ${foo_FORMS})
INCLUDE(${QT_USE_FILE})
ADD_DEFINITIONS(${QT_DEFINITIONS})
ADD_EXECUTABLE(foo ${foo_SOURCES} ${foo_HEADERS_MOC} )
TARGET_LINK_LIBRARIES(foo data ui ${QT_LIBRARIES} ${SIGC2_LIBRARIES})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
</file>
Now, let's move to "~/src/data". This directory is used to include source
code files which will be bundled as a static library. As this code consists
exclusively of standard C++, and therefore no third-party library is needed,
then this CMakeLists.txt file won't require any calls to any cmake macro.
Therefore, it will be kept simple.
<file name="~/src/data">
set(data_SOURCES
Data.c++
)
set(data_HEADERS
Data.h++
)
add_library(data STATIC ${data_SOURCES})
</file>
Finally, we'll look at the Qt static library at "~/src/ui". This directory
is used to include source code files which rely on Qt to implement a GUI.
This directory also includes a UI file created by Qt Designer, which is used
to setup a UI widget. As a consequence, the files stored in this directory
require a bit of moc and uic magic to be successfully built. The
CMakeLists.txt file looks like this:
<file name="~/src/ui">
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
set(ui_HEADERS
MainWindow.h++
)
set(ui_SOURCES
MainWindow.c++
)
set(ui_FORMS
MainWindow.ui
)
QT4_WRAP_CPP(ui_HEADERS_MOC ${ui_HEADERS})
QT4_WRAP_UI(ui_FORMS_HEADERS ${ui_FORMS})
add_library(ui STATIC ${ui_SOURCES} ${ui_HEADERS_MOC} ${ui_FORMS_HEADERS} )
</file>
With all CMakeLists.txt files in place, just build the Makefile and run
make. Everything should run smoothly.
Rui Maciel
More information about the Qt-interest-old
mailing list