9

Say I have the following file structure:

project/
  - src/
    - main.cpp
    moduleA/
      - moduleA.cpp
      - moduleA.hpp
    moduleB/
      - moduleB.cpp
      - moduleB.hpp

Within moduleB I would like to use moduleA. As such, I would like to include moduleA.hpp but as a relative path to src. Aka, I would like to be able to write #include moduleA/moduleA.hpp to use moduleA. I have control over all files, and can put CMakeLists.txt or FindModule<>.cmake in any directories.

Note: I want to do this because there are files in each module that have the same name (in this case, parameters.hpp). Therefore, I would like to be able to include parameters.hpp relative to src directory for readability purposes, and to ensure that the correct parameters file is being included.

If this is confusing, or any other information is required, please ask. Thanks for all the help everyone!

Sam
  • 333
  • 1
  • 3
  • 7
  • 1
    [I'll just leave this here](https://cmake.org/cmake/help/latest/command/include_directories.html) –  May 09 '17 at 06:08
  • [And I'll leave this here](https://cmake.org/cmake/help/latest/command/target_include_directories.html) – oLen May 09 '17 at 07:27
  • 2
    `include_directories(${CMAKE_SOURCE_DIR})`, or maybe `include_directories(${CMAKE_SOURCE_DIR}/src)`, depends what your root folder is. – Antonio May 09 '17 at 08:15
  • Possible duplicate of [How to properly add include directories with CMake?](http://stackoverflow.com/questions/13703647/how-to-properly-add-include-directories-with-cmake) – Antonio May 09 '17 at 08:18
  • If I'm not mistaken, the problem (in this case) with `include_directories(bar/foo.h)` is that within a file, I can then just write `#include "foo.h"`. I would like that to error out - and instead require the relative path. As such, you would need to write `#include "bar/foo.h"`. – Sam May 09 '17 at 08:34
  • The problem with `include_directories(bar/foo.h)` is that it wants to "include file", but the command expects a **directory**, where headers will be searched. E.g., if you want to `#include moduleA/moduleA.hpp` from your `.cpp` file, you need `include_directories(/src)`. Actually, it is difficult to say what do you want... – Tsyvarev May 09 '17 at 22:50
  • That was an error on my part Tsyvarev - I meant to write `include_directories(bar)` which would allow you to just write `#include "foo.h" if foo.h was in the bar directory. – Sam May 10 '17 at 16:46

1 Answers1

9

You can use a structure similar to the following:

project/
  - CMakeLists.txt
  - src/
    - CMakeLists.txt
    - main.cpp
  - moduleA/
      - CMakeLists.txt
      - moduleA/
          - moduleA.cpp
          - moduleA.hpp
  - moduleB/
      - CMakeLists.txt
      - moduleB/
          - moduleB.cpp
          - moduleB.hpp

with the following files:


project/CMakeLists.txt:

cmake_minimum_required(VERSION 3.0.2)

project(myProject)

add_subdirectory(moduleA)
add_subdirectory(moduleB)
add_subdirectory(src)

project/moduleX/CMakeLists.txt (X = A or B):

add_library(X STATIC ${moduleX_sources})
# The following line is very practical:
# it will allow you to automatically add the correct include directories with "target_link_libraries"
target_include_directories(X PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# only in CMakeLists.txt of module B, possibly with PRIVATE instead of PUBLIC
target_link_libraries(X PUBLIC A)

project/src/CMakeLists.txt:

add_executable(myExe ${exe_sources})
target_link_libraries(myExe A B) # <-- Automatically sets the correct include directories!!

With all this, you can use

#include "moduleX/moduleX.hpp"

See here for a similar question and more detailed answer.

oLen
  • 5,177
  • 1
  • 32
  • 48
  • Hey, that's a nice little setup! I love it. I guess this was more of a question about directory setup than anything else. I'll tweak this idea to work with my directory setup a little more, but this should totally work. Thanks so much for the idea oLen! – Sam May 10 '17 at 16:45
  • 2
    You missed the inter-module dependency. Something like `target_include_directories(B PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../moduleA)` on the `project/moduleB/CMakeLists.txt` file. – Spidey Nov 13 '19 at 10:26