15

I'm trying to set up my project to build several dynamic libraries that encompass its complete functionality. There are subfolders for each library. The subfolder libraries are dependent on each other, so they must reference functions from each other. I seem to have managed to get CMake to run without errors on the project, but when I go to build, I have trouble with my headers finding each other. It seems at build time, the include path isn't set up correctly. How can I fix this? Are there additional steps I need to take to set up the include path correctly?

The structure looks something like this

root
    CMakeLists.txt
    bin
    lib
    lib0
        CMakeLists.txt
        lib0.h
        lib0.cpp
    lib1
        CMakeLists.txt
        lib1.h
        lib1.cpp
    ...

In the CMakeLists.txt for the root directory I have declarations like this:

set(ROOT /blah/blah/root)    

include_directories(${ROOT}/lib0)
include_directories(${ROOT}/lib1)

add_subdirectory(lib0)
add_subdirectory(lib1)

In the CMakeLists.txt for the subfolders, I have:

set(lib0_SOURCES "")
list(APPEND lib0_SOURCES lib0.cpp)
add_library(lib0_lib ${lib0_SOURCES})

And my headers for the libraries look like (suppose this is lib0.h):

#include "lib1/lib1.h"
...

CMake runs fine with no errors, but when I go to compile, I get an error like:

In file included from /blah/blah/root/lib0/lib0.cpp:1:0:
/blah/blah/root/lib0/lib0.h:1:30: fatal error: lib1/lib1.h: No such file or directory
dusktreader
  • 3,845
  • 7
  • 30
  • 40

3 Answers3

14

You told GCC to #include the file "lib1/lib1.h". When you build, CMake will ask to look for extra headers in "${ROOT}/lib0" and "${ROOT}/lib1"

So, GCC is trying "${ROOT}/lib0/lib1/lib1.h" and "${ROOT}/lib1/lib1/lib1.h" Yup, cant work.

To fix it:

  • you can use in your root CMakeLists.txt : include_directories(".")
  • keep your CMakeLists but #include the file "lib1.h"
  • remove the include_directories in CMakeLists and #include the file "../lib1/lib1.h"

IMO, I'd go for the first option!

ablm
  • 1,265
  • 10
  • 19
1

You need to use the double naming scheme or specify the base directory as the include path:

root
    CMakeLists.txt
    bin
    lib
    lib0
        CMakeLists.txt
        lib0.cpp
        lib0
            lib0.h
    lib1
        CMakeLists.txt
        lib1.cpp
        lib1
            lib1.h
    ...
Steve-o
  • 12,678
  • 2
  • 41
  • 60
1

I would ask CMake to just consider the ROOT directory for C/C++ include look-ups:

set(ROOT /blah/blah/root)

include_directories(${ROOT})

add_subdirectory(lib0)
add_subdirectory(lib1)

Then, in C/C++, use angle braquets ('<' and '>') rather than double quotes ('"'):

#include <lib1/lib1.h>
Denis Arnaud
  • 388
  • 1
  • 4
  • 7
  • Why use '<' and '>' ? I thought it's same than double quotes but people use them to include system headers. no? – ablm Aug 19 '12 at 21:26
  • 2
    Double quotes (") have the pre-processor first search in the same directory as the current (parsed) file. Angle brackets involve a more general search, in all the include paths given to the pre-processor (e.g., through -I directives). See also [this](http://stackoverflow.com/questions/3162030/difference-between-angle-bracket-and-double-quotes-while-including-heade) and [this](http://stackoverflow.com/questions/21593/what-is-the-difference-between-include-filename-and-include-filename) – Denis Arnaud Sep 09 '12 at 18:53