【问题标题】:Good CMake Style: Inherit Properties良好的 CMake 风格:继承属性
【发布时间】:2018-07-31 10:30:48
【问题描述】:

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

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

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

定义了一组包含目录。而不是定义 target_atarget_btarget_b 的完全相同的包含目录 和target_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 一个库并添加依赖项?

【问题讨论】:

  • “我要不要让 base_target 成为一个库并添加依赖项?” - 是的,您可以创建 INTERFACE 库,向其中添加公共包含目录,并在需要这些公共包含目录时与库链接。
  • 如果你用一些示例代码来装饰你的回复,我想这就是解决方案。
  • 嗯,实际上我之前的评论是对问题文本的第一个想法。但我不太了解您要解决的问题。根据您的代码,您已经base_target 为目标,它只能是库或可执行文件(否则您不能为此调用target_inclide_directories)。如果它是一个库,你可以直接使用target_link_libraries。如果它是可执行文件,为什么要继承它的属性?请详细说明一下。 CMake 提供的模式不仅适用于代码,也适用于 design。用好的代码来做坏的设计并不是那么好。
  • 我想要的是一个实际上不是物理产生的目标,但它会传播一些共同的属性。
  • “我想要的是一个实际上不是物理产生的目标,但它传播了一些共同的属性。” - 是的,这解释了很多。你能在你的问题中添加那个(或类似的)措辞吗?

标签: cmake build-system


【解决方案1】:

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

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

例子:

# 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.

【讨论】:

  • 这仅适用于列入白名单的属性。无法使用 INTERFACE 库传播自定义属性。
【解决方案2】:

最优雅的方法是什么?

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

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

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

【讨论】:

  • 对于 2-3 应用程序,我猜“foreach”方法符合您的理解。至于继承方法,由其命名标识的“虚拟库”(例如“XXX_include_flags_notalib”)将同样透明。
猜你喜欢
  • 1970-01-01
  • 2016-08-31
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-11
  • 2020-01-17
  • 2016-07-17
  • 1970-01-01
相关资源
最近更新 更多