Search code examples
c++cmakeheader-filesinclude-path

Including headers in subfolders


I work on a C++ program which I develop on my personal Ubuntu 15.04 machine which eventually has to run on openSUSE 13.1 at work. To make it work on both systems I carefully chose the libraries and the versions to use.

Now I have a problem with the includes. I want to use Qwt 6, which is available on both distributions. The location of the header files differs, though. On Debian they are at /usr/include/qwt/qwt_*.h but on openSUSE they are at /usr/include/qwt6/qwt_*.h. My code currently has #include <qwt/qwt_plot.h>. This does not work on openSUSE since I would have to insert that 6 there.

The easiest solution that I currently see is just including either directory using CMake and then just writing #include <qwt_plot.h> in the source code. However, I think that this is not a really nice solution since those subdirectoryies of /usr/include are there to provide namespaces. Just adding all directories to the include path will mangle those together and might even lead to conflicts.

Is there a nice way to solve this?

In fairness: This is for a project I am paid to work on.


Solution

  • In CMake you can configure platform checks like you could for autoconf. The idea is that you include a config.h file that always exists but use tools to generate that file in each platform. You can check how here but as a summary you can have a config.h.in file with the checks you want to make and use in your headers.

    #cmakedefine HAVE_QWT_H
    #cmakedefine HAVE_QWT6_H
    

    You then have CMake check if the headers are present and process that file into a final config.h file. In the CMakeLists.txt file you could have the following.

    INCLUDE (CheckIncludeFiles)
    
    CHECK_INCLUDE_FILES (qwt/qwt_plot.h HAVE_QWT_H)
    CHECK_INCLUDE_FILES (qwt6/qwt_plot.h HAVE_QWT6_H)
    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
    

    Finally, in your headers, you include the config.h and use the macros to conditionally include one header or another.

    // always included
    #include "config.h"
    
    // conditionally include headers based one macros from config.h
    #ifdef HAVE_QWT_H
    #include <qwt/qwt_plot.h>
    #elseif HAVA_QWT6_H
    #include <qwt6/qwt_plot.h>
    #else
    #error QWT headers required and not present in supported locations
    #endif