[CMake] Beginner's Question: Organizing Projects
Marcel Loose
loose at astron.nl
Wed Oct 27 08:32:18 EDT 2010
On Wed, 2010-10-27 at 14:02 +0200, Dominik Gabi wrote:
> Hi,
>
> after reading the tutorial I've decided to make my own project using
> cmake but I'm having some troubles here. I'd like to organize my
project
> as follows:
>
> Pixels/
> CMakeLists.txt (0)
> Pixels.cpp
> geometry/
> CMakeLists.txt (1)
> Vector.h Vector.cpp ...
> ui/
> CMakeLists.txt (2)
> MainWindow.h MainWindow.cpp ...
>
> The dependencies are the following: the geometry package should be
self
> sufficient. The ui package needs the geometry library, gtkmm etc. and
> Pixels.cpp for now just calls a static method in MainWindow therefore
> depends only on ui.
>
> I've spent the past few hours trying to get everything to compile but
I
> always end up with some cmake or linker error :(
>
> Here's what I've come up with so far:
>
> ### CMakeLists.txt (1)
> add_library(Geometry Vector.h Vector.cpp ...)
>
> ### CMakeLists.txt (2)
> add_library(Ui MainWindow.h MainWindow.cpp ...)
>
> # Geometry
> include_directories(${PIXELS_SRC_DIR}/geometry)
> link_directories(${PIXELS_BIN_DIR}/geometry)
> target_link_libraries(Ui Geometry)
>
> find_package(PkgConfig)
> # GTKMM
> pkg_check_modules(GTKMM gtkmm-2.4)
> include_directories(${GTKMM_INCLUDE_DIRS})
> link_directories(${GTKMM_LIBRARY_DIRS})
> target_link_libraries(Ui ${GTKMM_LIBRARIES})
>
> # GTKGLEXTMM
> pkg_check_modules(GLEXT gtkglextmm-1.2)
> include_directories(${GLEXT_INCLUDE_DIRS})
> link_directories(${GLEXT_LIBRARY_DIRS})
> target_link_libraries(Ui ${GLEXT_LIBRARIES})
>
> ### CMakeLists.txt (0)
> cmake_minimum_required(VERSION 2.8)
> project(Pixels)
>
> set(PIXELS_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
> set(PIXELS_BIN_DIR ${CMAKE_CURRENT_BINARY_DIR})
>
> add_executable(Pixels Pixels.cpp)
>
> include_directories(${PIXELS_SRC_DIR}/ui)
> add_subdirectory(${PIXELS_SRC_DIR}/ui)
> target_link_libraries(Pixels Ui)
> ### end
>
> Unfortunately, this results in a ton of errors such as
>
> make[2]: *** [CMakeFiles/Pixels.dir/Pixels.cpp.o] Error 1
> make[1]: *** [CMakeFiles/Pixels.dir/all] Error 2
> make: *** [all] Error 2
>
> "Gtk has not been declared", "Vector.h: no such file or directory".
> Obviously I'm not doing it right ;)
>
> The question then is: What am I doing wrong?
>
> Thanks,
> Dominik.
>
Hi Dominik,
You should realize that variables have scope, as have properties you set
on directories (which happens when you use, e.g.,
include_directories()). The GTK stuff is only put on the include path in
the UI directory.
There are, IMO, two ways you can solve this.
1) Search for GTK in you top-level CMakeLists.txt file and use
include_directories() there. This will ensure that the
INCLUDE_DIRECTORIES property is set on all the subdirectories.
2) "Export" the GTK include directory up-level. The IMO fragile way of
doing this is using PARENT_SCOPE, because you have to use that at all
intermediate levels. The safer way is to use a global property.
The first option is definitely the easiest to implement but, for larger
projects, will cause your top-level CMakeLists.txt file to grow
extensively. And, worse, that file will "share implementation details"
of some lower-level directory, requiring package XYZ. So, for larger
projects, I would choose the seconds option.
Hope this helps.
Best regards,
Marcel Loose.
More information about the CMake
mailing list