Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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. :)

like image 788
BartekPL Avatar asked Oct 24 '16 20:10

BartekPL


2 Answers

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.

like image 123
rubenvb Avatar answered Sep 22 '22 07:09

rubenvb


Your cmake project template looks fine and self-contained. First, I'm going to assume GAITPARAMS_SRCS was supposed to be PROJEXEC_SRCS which is currently pointing at proj_exec.cc contains a main() method. (If you're going to manage a SRCS list, be careful not to add source files at the top of the list, add_executable expects the main function to be in the first entry)

Secondly, the problem is in your ProjLib/CMakeLists.txt. Try replacing your target_include_directories call with this:

target_include_directories (ProjLib PUBLIC ${PROJLIB_INCLUDE_DIR})

This will propagate the include directory information to the ProjExec when the target_link_libraries command is applied. If you don't wan't to do that, I guess you can access via #include <include/ProjLib.h> but that's just confusing. My recommendation is to add another folder in the include folder (named exactly the same with the cmake folder) and add your headers in it. Like this:

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

This lets you include your headers with a foldername (Not to mention preventing name collision.). Like this:

#include <ProjLib/proj_lib.h>

And to configure your CMakeLists.txt files to match the pattern.

like image 42
Akaedintov Avatar answered Sep 20 '22 07:09

Akaedintov