好的CMake样式:继承属性
Daniel Pfeifer在他的演讲“有效的CMake”中, 提出一个观点,即建议避免变量 尽可能多的定义 现在,如何在各种构建中获得属性 目标。比如说,好的CMake样式:继承属性,cmake,build-system,Cmake,Build System,Daniel Pfeifer在他的演讲“有效的CMake”中, 提出一个观点,即建议避免变量 尽可能多的定义 现在,如何在各种构建中获得属性 目标。比如说, target_include_directories(base_IncludeFlags INTERFACE first/dir second/dir
target_include_directories(base_IncludeFlags
INTERFACE
first/dir
second/dir
...)
定义一组包含目录。而不是定义
同样包括target_a
,target_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\u IncludeFlags
is不应是真正的物理目标,
更像是一个抽象基类或接口
另一方面,我不想使用include\u目录
因为这会影响所有目标。使用foreach
是否更好?
最优雅的方式是什么?我应该把base\u设为目标吗
库和添加依赖项
最优雅的方式是什么
考虑到CMake文件通常由非CMake专家的人阅读和编辑。而不是追求优雅,你可以考虑追求简单:保持简单,愚蠢。
如果引入抽象、隐藏的任何类型的隐式行为,那么每个人都很难维护CMake文件
对我来说,在这种情况下,简单意味着复制条目,如果只有2-3条。如果有更多的库,我会把标题放在一个变量中。“有效的CMake”演示强调避免不必要的、一次性使用的变量定义。我认为这个标题列表是一个有用的变量,值得创建
最优雅的方式是什么
考虑到CMake文件通常由非CMake专家的人阅读和编辑。而不是追求优雅,你可以考虑追求简单:保持简单,愚蠢。
如果引入抽象、隐藏的任何类型的隐式行为,那么每个人都很难维护CMake文件
对我来说,在这种情况下,简单意味着复制条目,如果只有2-3条。如果有更多的库,我会把标题放在一个变量中。“有效的CMake”演示强调避免不必要的、一次性使用的变量定义。我认为这个标题列表是一个有用的变量,值得创建
我想要的是一个不是实际生成的目标,而是传播一些公共属性的目标 正是出于这个目的,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为不同的属性提供了一个容器,当这个库链接到另一个目标时,这些属性会被传播 例如:
# 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.
“我是否要将base_作为库的目标并添加依赖项?”-是的,您可以创建接口库,向其中添加公共包含目录,并在需要这些公共包含目录时与库链接。如果您用一些示例代码装饰您的响应,我想这就是解决方案。嗯,事实上,我之前的评论是关于问题文本的第一个想法。但我不太明白你想解决的问题。根据您的代码,您已经有了target
base\u target
,它只能是一个库或一个可执行文件(否则您不能为它调用target\u inclide\u目录)。如果它是一个库,您可以只使用target\u link\u库
。如果它是可执行文件,为什么要继承它的属性?请详细说明一下。CMake提供的模式不仅用于代码,也用于设计。用好的代码来做糟糕的设计并不好。我想要的是一个不是实际生成的目标,但它传播一些公共属性。“我想要的是一个不是实际生成的目标,但它传播一些公共属性。”-是的,这解释了很多。你能在你的问题中添加这样(或类似)的措辞吗?“我能让base_以库为目标并添加依赖项吗?”-是的,你可以创建接口库,向其中添加公共包含目录,并在需要这些公共包含目录时与库链接。如果你用一些示例代码来修饰你的回答,我想这就是解决问题的办法。嗯,实际上我之前的评论是对问题文本的第一个想法。但我不太明白你想解决的问题。根据您的代码,您已经有了targetbase\u target
,它只能是一个库或一个可执行文件(否则您不能为它调用target\u inclide\u目录)。如果它是一个库,您可以只使用target\u link\u库
。如果它是可执行文件,为什么要继承它的属性?请详细说明一下。CMake提供的模式不仅用于代码,也用于设计。用好的代码来做糟糕的设计并不好。我想要的是一个不是实际生成的目标,但它传播一些公共属性。“我想要的是一个不是实际生成的目标,但它传播一些公共属性。”-是的,这解释了很多。你能在你的问题中添加这样(或类似)的措辞吗?对于2-3应用程序,我想“foreach”方法符合你的意思。至于继承方法,“虚拟库”通过其名称标识,如“XXX\u include\u flags\u notalib”将是同样透明的。对于2-3应用程序,我想“foreach”方法符合您的意思。至于继承方法,由其命名标识的“虚拟库”(如“XXX\u include\u flags\u notalib”)同样透明。这仅适用于白名单属性。定制