Search code examples
c++cmakeshared-librariesdirectory-structure

Directory Structure for Library CMake Projects


I've an Application project Demo which depends on my Shared library Hello. Library Hello should be redistributable. So I need to distribute the headers of Hello as well as use it in my Demo projects. What directory structure and CMake configuration should I use ? I previously had a flat structure and Hello was a header only subdirectory with no CMakeLists.txt. Now I am planning this directory structure.

Demo
    main.cpp
    app.h
    app.cpp
    CMakeLists.txt
    Hello
       includes
           matrix.hpp          // header only
           diagonal.hpp
           point.hpp
           store.h
           analyzer.h
       sources
           store.cpp
           alanyzer.cpp
       CMakeLists.txt

Previously the analyzer was header-only which is now splited in header and source. I am mixing header-only things. Is this a good structure ? But I prefer to use the nice #include <Hallo/matrix.hpp> not the ugly one #include "Hallo/includes/matrix.hpp" or just #include "matrix.hpp". I expect this library Hello will be used for other applications and libraries as well.

Demo/CMakeList.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(Demo)
ADD_SUBDIRECTORY(Demo)

SET(Demo_HEADERS
  app.h
)

SET(Demo_SOURCES
  app.cpp
  main.cpp
)

INCLUDE_DIRECTORIES(${Hello_INCLUDE_DIRS})
# ^^^^ Is this how I need to access the headers ? or just ADD_SUBDIRECTORY() will work

ADD_EXECUTABLE(Demo ${Demo_SOURCES} ${Demo_HEADERS})

TARGET_LINK_LIBRARIES(Demo Hello)

Hello/CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
PROJECT(Hello)

FIND_PACKAGE(Boost COMPONENTS filesystem program_options thread system serialization date_time chrono REQUIRED)

INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})

SET(Hello_SOURCES
  store.cpp
  analyzer.cpp
)

INCLUDE_DIRECTORIES((${HELLO_SOURCE_DIR}/includes)
# ^^^^ Is this how I need to access the headers ?

ADD_LIBRARY(Hello ${Hello_SOURCES})

TARGET_LINK_LIBRARIES(Hello ${Boost_LIBRARIES})

I am kind of confused with all this as there is no one specific way to do these all.

--- EDIT ---

Should I have this structure ? or Do some other libraries generally use this structure ? or what are the structures generally practiced ?

hallo
  includes
    hallo
  sources 

Solution

  • If you want to access your headers like this:

    #include <matrix.hpp>
    

    then you need to include directories. I suggest you the next:

    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
    INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Hello/includes)
    

    Your mistake is that you never defines Hello_INCLUDE_DIRS variable in global scope, only in local. So your include do nothing. CMAKE_SOURCE_DIR is always defined and safe to use for includes. Thus you need either define Hello_INCLUDE_DIRS in global scope or use INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/Hello/includes).

    Usage is up to the developer as always. I prefer the structure:

    + Project Root
    +-> Build
    +-> Documentation
    +-> Include
    +-> Source
    +-> Test
    + CMakeLists.txt
    

    Then I can preset in root CMakeLists.txt next useful variables:

    SET(Project_Include_Dir         "${CMAKE_SOURCE_DIR}/Include")
    SET(Project_Source_Dir          "${CMAKE_SOURCE_DIR}/Source")