[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