caring-goat-913
caring-goat-913

Reputation: 4049

CMake Include Directories Collision

In my project, I have two versions of the same system library: SysLib1.0 and SysLib2.0. These two libraries are used by other components of the system heavily.

SysLib1.0 headers are located in some directory: /project/include. Here's an example of the contents of the project include directory:

/project/include/syslib/
/project/include/awesomelib/
/project/include/coollib/

So naturally, in CMake, other components use include_directories(/project/include) to gain access to system and other component headers. C++ source code could access the headers like so:

#include <syslib/importantheader.hpp>

SysLib2.0 is installed in a separate location in order to avoid linking issues. SysLib2.0's headers are stored here:

/opt/SysLib2.0/include

So naturally, in CMake, other components which require SysLib2.0 use include_directories(/opt/SysLib2.0/include). C++ source code could access the headers like so:

#include <syslib/importantheader.hpp>

Now we have run into a problem. A new component I'm writing needs access to /project/include in order to access awesomelib, BUT also needs SysLib2.0. This involves including /opt/SysLib2.0/include as well. Now when I say #include <syslib/importantheader.hpp>, that could refer to either version of the library. The compiler yells at me with some redefinition errors, as it should.

Even worse, SysLib1.0 and SysLib2.0 both refer to themselves as syslib/... when looking for headers within their own library, which is just as ambiguous.

Does anyone have an idea of how I could exclude a particular directory from an include path? Even if I am including a parent directory as shown in my example? Any solutions or suggestions are appreciated.

Upvotes: 1

Views: 719

Answers (2)

Adam Kosiorek
Adam Kosiorek

Reputation: 1528

You can create a tree-like directory structure for your project with nested CMakeLists.txt files and include separate directories in different leafs:

Given a directory structure:

A:
|main.cpp
|
|CMakeLists.txt
|
|B-----|
|      |CMakeLists.txt
|      |b.cpp
|
|C-----|
       |CMakeLists.txt
       |c.cpp

A/CMakeLists.txt:
    add_subdirectory(B)
    add_subdirectory(C)
    add_executable(exe main.cpp)
    target_link_libraries(exe a b)

B/CMakeLists.txt:
    include_directories(/project/include)
    add_library(b b.cpp)

C/CMakeLists.txt:
    include_directories(/opt/SysLib2.0/include)
    add_library(c c.cpp)

This way you can include different directories for different source files; pack them up in libraries and link the final target with the libraries

Upvotes: 1

wojciii
wojciii

Reputation: 4325

I don't like using one include path for all includes. I would rather the following structure.

include - your own headers
include/awesomelib
include/coollib
3rd - third party libs
3rd/syslib-1.0/include
3rd/syslib-1.0/src
3rd/syslib-2.0/include
3rd/syslib-2.0/src

src - your source
src/awesomelib (depends on syslib-1.0, includes 3rd/syslib-1.0/include)
src/coollib (depends on syslib-2.0, includes 3rd/syslib-2.0/include)

Then you can specify which syslib to use when building a library.

Upvotes: 0

Related Questions