静态库和生成的标头

时间:2018-03-12 10:41:11

标签: c++ cmake

假设我有一个项目可以创建两个静态库目标(foobar),它们之间存在循环依赖关系。明确地allows this,它通常可以正常工作,因为构建这些库的顺序并不重要。

但是,如果这两个库都生成一个头文件(Foo.hppfooBar.hppbar),这是其界面的一部分,可能会出现问题,因为标题的生成通常作为构建库的一部分来完成(例如,通过add_custom_targetadd_dependencies)。也就是说,构建foo会生成Foo.hpp,但也需要由Bar.hpp构建的bar,需要Foo.hpp ...

我找到了解决这个问题的方法,初看起来似乎很完美。它包括使用add_custom_command生成标头,然后使用target_sources将标头添加到目标的PUBLIC来源。这样,目标本身及其依赖项都将对标头具有文件级依赖性,这将在正确的时间触发自定义命令。

这是我的解决方案的MWE:

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)

问题是自定义命令仅在从同一目录引用其输出时才起作用(这是documented)。如果我拆分我的项目并将foobar放在不同的目录中,我上面的解决方案就不再适用了。

所以我的问题是:有没有更好的方法来处理生成的静态库头之间的循环依赖?

0 个答案:

没有答案