BartekPL BartekPL - 1 month ago 5
C++ Question

cmake: setup multiple projects and dependiencies between them

I need help with write a good CMakeLists.txt for a C++ projects.

I looked for answer, but I found anything.
This is Structure of my projects:

MainProj
| ProjLib/
| | include/
| | | proj_lib.h
| | src/
| | | proj_lib.cc
| | CMakeLists.txt
| ProjExec/
| | include/
| | | proj_exec.h
| | src/
| | | proj_exec.cc
| | CMakeLists.txt
| CMakeLists.txt


MainProj CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(MainProj CXX)

# enable C and C++ language
enable_language(C CXX)

# Add sub-directories
add_subdirectory(ProjLib)
add_subdirectory(ProjExec)


ProjLib CMakeLists.txt

set (PROJLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
set (PROJLIB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)

set(PROJLIB_SRCS
${CMAKE_CURRENT_SOURCE_DIR}/src/proj_lib.cc
)

include_directories("${PROJLIB_SOURCE_DIR}")
include_directories("${PROJLIB_INCLUDE_DIR}")

add_library(ProjLib SHARED ${PROJLIB_SRCS} ${PROJLIB_INCLUDE_DIR})

target_include_directories (ProjLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})


ProjExec CMakeLists.txt

set (PROJEXEC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
set (PROJEXEC_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

set(PROJEXEC_SRCS
${PROJEXEC_SOURCE_DIR}/proj_exec.cc
)

include_directories("${PROJEXEC_SOURCE_DIR}")
include_directories("${PROJEXEC_INCLUDE_DIR}")

add_executable(ProjExec ${PROJEXEC_SRCS})

target_link_libraries (ProjExec LINK_PUBLIC ProjLib)


proj_exec.cc

#include "proj_lib.h"
...


And it doesn't found proj_lib.h in proj_exec.cc file.
If I need some additional entries in some cmake?

Any help would be appreciated. :)

Answer

You need to make use of the CMake targets and their properties:

MainProj/CMakeLists.txt:

cmake_minimum_required(VERSION 2.8)
project(MainProj)

# Add sub-directories
add_subdirectory(ProjLib)
add_subdirectory(ProjExec)

ProjLib/CMakeLists.txt

add_library(ProjLib SHARED src/proj_lib.cc)
target_include_directories(ProjLib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include)

ProjExec/CMakeLists.txt

add_executable(ProjExec src/proj_exec.cc)
target_include_directories(ProjExec PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)
target_link_libraries(ProjExec ProjLib)

target_link_libraries makes sure that when building a target, its dependencies' PUBLIC and INTERFACE include directories will be used appropriately.