Hhut
Hhut

Reputation: 1198

cmake: install header order and dependencies on target

I've a set of libraries and executables all with their own CMakeLists.txt. All libraries are building their targets to the same path (for example ../build/bin and ../build/lib)... as well as exporting their header files (../build/inc).

Now I wish to build one build system and let CMake figure out the dependencies (using add_subdirectory and global build settings).

The problem is: all libraries do export their headers to build/inc after they are build (when make install in invoked). When I do a whole system build make install is not invoked until after the end (and everything has build). So for example executable progfoo with target_link_libraries( progfoo onelib ) will fail, because CMake figures out the dependency to onelib (which builds fine), but progfoo fails because it looks for headers in build/inc... which were not exported yet. The same thing in general applies to many libraries.

What is the correct CMake-Way to handle these cases? Thank you!

Upvotes: 3

Views: 2063

Answers (1)

CoffeDeveloper
CoffeDeveloper

Reputation: 8317

Install is the final step, the one that should be visible to the user. So when you export binaries and headers you should already have binaries built against headers in their original locations.

From CMake point of view you have only 1 target at a time. For example you can build a Web Server and using as dependencies libcurl and boost::asio. It is very possible (and good) to add dependencies to current target using add_subdirectory, but when you have to add include directories you have to do that on a per dependency basis, it would be convenient in example if each of the dependencies provides already a variable with current absolute path to includes.

In example see this dummy libcurl's CMakeLists.txt that set path to absolute include directory

get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

// export into parent scope libcurl header location
set (LIBCURL_INCLUDES ${_DIR}/include PARENT_SCOPE) 

Then you can use it from Web Server's CMakeLists.txt for building and later use the same path again to extract files for installing them where required

add_subdirectory(PATH_TO_LIBCURL_CMAKELISTS)

# add include directories for building web server
include_directories( ${LIBCURL_INCLUDES})

#I assume you are installing headers because final user will need them,
#in case you needed them just for building you are already done here
#without even installing them

#gather headers list
file(GLOB libCurlHeadersList
    "${LIBCURL_INCLUDES}/*.h"
    "${LIBCURL_INCLUDES}/*.hpp"
    )


#install header list
install( FILES
         ${libCurlHeadersList}
         DESTINATION ../build/inc/libcurl
       )

Upvotes: 2

Related Questions