Search code examples
c++cmakebuck

Is there a cmake equivalent to BUCK's header_namespace?


The BUCK build tool allows me to define a header namespace for a library. For example, if I have a library called libA, with this directory structure:

root
    include
        a.h
    src
        a.cpp

I can set a header_namespace on the library as, say, examples/liba, such that in a separate project that uses libA I can:

#include "examples/liba/a.h"

This is nice because it allows me to keep a simplified directory structure in my projects, while also keeping my includes organized in a manner that is more readable.

Does CMake offer anything like this? I have not yet found something similar. My goal is to have BUCK and CMake build files to make it easier to build on systems without java (one of BUCK's dependencies).


Solution

  • No, CMake does not have such a facility.

    The standard way to manage headers is organizing them in the filesystem in such a way that they are unlikely to conflict with other code.

    root
        include
           liba
                a.h
        src
           a.cpp
    

    Then it is a simple matter of:

    include_directories(include)
    

    or better,

    target_include_directories(liba PUBLIC include)
    

    or, most modern of all,

    target_include_directories(liba PUBLIC
      "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
      "$<INSTALL_INTERFACE:include>")
    

    which simply says make available on the include path to anyone using liba the contents of the subdirectory include in the current source directory and anyone installing liba the contents of the include subdirectory (interpreted relative to an installation prefix).

    Then installation is typically something like:

    install(DIRECTORY include/
      DESTINATION include)
    

    for the headers, installing everything under the source include directory and

    install(TARGETS liba
      RUNTIME DESTINATION bin
      LIBRARY DESTINATION lib
      ARCHIVE DESTINATION lib)
    

    for the actual library target ("libliba.a" or "libliba.so"). Even better is to use variables from include(GNUInstallDirs) for GNU standard folder names.

    In your code, at all times you just refer to code in the usual conflict-free method:

    #include "liba/a.h"
    

    So, there's should never be any conflict on file or code, unless you are really bad at naming!