Loop dependencies in static libraries and generated headers

Let's say I have a project that creates two targets of a static library ( foo and bar ) with a cyclic dependency between them. CMake explicitly allows this , and it works fine, because the build order of these libraries does not matter.

However, if both of these libraries generate a header file ( Foo.hpp for foo , Bar.hpp for bar ), which is part of their interface, problems can arise, since the generation of the header is usually performed as part of building the library (for example, via add_custom_target and add_dependencies ) . That is, building foo will generate Foo.hpp , but also needs Bar.hpp , which is built by bar , which needs Foo.hpp ...

I found a solution to this problem that, at first glance, seems perfect. It consists of generating headers using add_custom_command and then adding headers to the PUBLIC sources of the target using target_sources . Thus, both the goal itself and its dependents will have a file level dependency on the header, which will run the user command at the right time.

Here's the MWE of my solution:

 cmake_minimum_required(VERSION 3.5) project(Foo) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Foo.hpp COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/Foo.hpp COMMENT "Generating Foo.hpp" ) add_library(foo STATIC Foo.cpp) target_include_directories(foo PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_sources(foo PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/Foo.hpp) target_link_libraries(foo bar) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Bar.hpp COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/Bar.hpp COMMENT "Generating Bar.hpp" ) add_library(bar STATIC Bar.cpp) target_include_directories(bar PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) target_sources(bar PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/Bar.hpp) target_link_libraries(bar foo) 

The problem is that user commands only work when their output is referenced from the same directory (this is documented ). If I split my project and put foo and bar in different directories, my solution above does not work anymore.

So my question is: is there a better way to deal with circular dependencies between the generated headers of static libraries?

+5
source share

Source: https://habr.com/ru/post/1275844/


All Articles