0

This header-only library has many files across many subdirectories, and here is its cmake file:

https://github.com/zaphoyd/websocketpp/blob/master/CMakeLists.txt

It is not clear to me where in this file the build process is actually informed about all these files and directories. I'm attempting to learn cmake and studying well-known libraries and how they do it, but there is surprising lack of consistency in the techniques.

The lines that appear to maybe do this are:

https://github.com/zaphoyd/websocketpp/blob/master/CMakeLists.txt#L18

and this iteration:

https://github.com/zaphoyd/websocketpp/blob/master/CMakeLists.txt#L27-L32

But it is still not so clear. Can anyone shed some light?

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • `How does this cmakelists file actually add all header files to the build?` - It is not clear what you ask: header files are included by the sources (with `#include` directive), they needn't to be listed by the CMake script unless they are created during build process. But in your case all (or almost all) headers are already exists under `websocketpp/` directory and needn't to be built. – Tsyvarev May 18 '16 at 08:46
  • @Tsyvarev They also need to be listed in case of the `install` target, as happening in the lines pointed by OP – Antonio May 18 '16 at 15:14
  • Hm, **installing** is different from **building**, isn't it? In any case, the question seems inapropriate for Stack Overflow. Without linked content the question has no sence, so some content(code) should be added to the question post itself. But adding code of entire project into the question post is not an option. – Tsyvarev May 18 '16 at 16:46
  • @Tsyvarev and yet the question was answered satisfactorily – johnbakers May 18 '16 at 17:55

1 Answers1

0

Starting from foreach documentation and this piece of code:

foreach (p INCLUDE CMAKE)
  set (var INSTALL_${p}_DIR)
  if (NOT IS_ABSOLUTE "${${var}}")
    set (${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
  endif ()
endforeach ()

This make variables INSTALL_INCLUDE_DIR and INSTALL_CMAKE_DIR absolute paths. So, they are not the place where all the include files are collected.

In the main CMakeLists.txt it doesn't seem anything is done with headers. A subdirectory websocketapp is added, which contains a short CMakeLists.txt:

init_target("websocketpp")
final_target ()

Those are custom macros defined in cmake/CMakeHelpers.cmake (included by the main CMakeLists.txt). The key is in final_target()

macro (final_target)
    if ("${TARGET_LIB_TYPE}" STREQUAL "EXECUTABLE")
        install (TARGETS ${TARGET_NAME} 
                 RUNTIME DESTINATION "bin" 
                 CONFIGURATIONS ${CMAKE_CONFIGURATION_TYPES})
    endif ()

    # install headers, directly from current source dir and look for subfolders with headers
    file (GLOB_RECURSE TARGET_INSTALL_HEADERS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.hpp)
    foreach (hppfile ${TARGET_INSTALL_HEADERS})
      get_filename_component (currdir ${hppfile} PATH)
      install (FILES ${hppfile} DESTINATION "include/${TARGET_NAME}/${currdir}")
    endforeach()
endmacro ()

The last part of the macro add to the install target all headers file, found with a globbing expression.

Said this, there is not really a standard way to do this kind of operation, so you'll see plenty of different approaches across different projects. There is also a war of religion if source files (as header files) should be explicitly listed or found through a globbing expressions, see Specify source files globally with GLOB?.

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197