良好的 CMake 风格:继承属性



Daniel Pfeifer在他的演讲"Effective CMake"中, 提出一个观点,建议避免变量 定义尽可能多。

现在,如何将属性放入各种构建中 目标。也就是说,例如

target_include_directories(base_IncludeFlags
INTERFACE 
first/dir
second/dir
...)

定义一组包含目录。而不是定义 完全相同的包括target_atarget_btarget_c,我想让那些目标继承包含来自"base_target"的目录,类似于

target_link_libraries(target_a PUBLIC base_IncludeFlags) 
target_link_libraries(target_b PUBLIC base_IncludeFlags)
target_link_libraries(target_c PUBLIC base_IncludeFlags)

如果base_IncludeFlags不是真正的物理目标, 更像抽象基类接口的东西。

另一方面,我不想使用include_directories因为这会影响所有目标。使用foreach更好吗? 最优雅的方法是什么?我该做base_target库并添加依赖项?

我想要的是一个实际上不是物理产生的目标,但它传播了一些共同的属性。

正是为此目的,CMake 具有接口库 - 不同属性的容器,当此库链接到另一个目标时,这些属性会传播。

例:

# Create "container" target
add_library(base_target INTERFACE)
# Add some INTERFACE properties for that target
target_include_directories(base_target INTERFACE 
first/dir
second/dir)
# Some 'other_target' (library or executable) may easily consume all common properties:
target_link_libraries(other_target PUBLIC base_target)
# Now 'other_target' has aforementioned include directories too.
# Instead of PUBLIC other linking types (PRIVATE, INTERFACE) may be used.

最优雅的方法是什么?

考虑到 CMake 文件通常由非 CMake 专家的人阅读和编辑。与其追求优雅,不如考虑追求简单:保持简单,愚蠢。

如果您引入抽象,任何类型的隐藏隐式行为,每个人都将更难维护 CMake 文件。

对我来说,在这种情况下,简单意味着复制(复制)条目,如果只有 2-3 个。如果有更多的库,我会把标题放在一个变量中。"有效 CMake"演示文稿指出要避免不必要的一次性变量定义。我认为这个标题列表将是一个有用的变量,值得创建。

最新更新