[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