CMake中组件和命名空间的命名规则

14

简述:

在使用命名空间时,cmake库目标是否有首选的命名约定?

注意:

除非确实有客观原因,否则我不是在询问个人偏好,而是在问是否存在“官方”(例如,由kitware推荐)或已经建立的(可能有所偏差)惯例。

详细信息:

假设我有一个名为foo的库/框架,其中包含独立的组件barbaz。到目前为止,我的命名约定看起来像这样:

add_library(foo-bar src1.cpp, scr2.cpp)
add_library(foo-baz src3.cpp, src4.cpp)

现在我想使用命名空间(::)约定来添加别名目标。例如:
add_library(Foo::Bar ALIAS foo-bar)
add_library(Foo::Baz ALIAS foo-baz)

(当然,这个问题也适用于导出集,但我不想让问题变得更加复杂)但是,我确实找不到有关这些目标的首选命名约定甚至官方命名约定。
我看到过以下内容:
命名空间部分: 某些项目似乎将第一个字母大写,而另一些则没有(前者似乎更常见)
组件部分: 在某些项目中,组件名称与二进制名称相同 使用或不使用“lib”前缀(libfoo-bar vs foo-bar) 使用或不使用命名空间(foo-bar vs bar) 某些项目将第一个字母大写 某些项目使用CamelCase或snake_case,即使二进制文件或项目名称不遵循这些约定。
我猜主要问题是一般情况下没有库的命名约定,所以这使得在CMake中制定命名约定比较困难,但至少命名空间和组件的首字母大写似乎相当普遍,因此我想知道是否应该遵循某些指南来处理未来的项目。
1个回答

14

cmake-developer文档对命名空间提出了以下建议:

在提供导入目标时,应该对它们进行命名空间(因此需要使用Foo::前缀);CMake将识别传递给target_link_libraries()的包含::在其名称中的值应作为导入目标(而不仅仅是库名称),如果该目标不存在,则会生成相应的诊断消息(请参见策略CMP0028)。

CMP0028策略文档中关于命名空间使用的“常见模式”如下:

双冒号的使用是用于命名空间IMPORTED目标和ALIAS目标的常见模式。计算目标的链接依赖项时,每个依赖项的名称可以是目标,也可以是磁盘上的文件。以前,如果找不到与匹配名称相对应的目标,则认为该名称指的是磁盘上的文件。如果目标名称有误,则可能会导致令人困惑的错误消息。

否则,没有CMake特定的命名约定用于库目标的命名。但是由于名称默认为目标的输出名称:

  • 我喜欢将目标的名称与我的源代码目录相同
  • 不添加lib前缀,因为这取决于您使用的平台,CMake会自动添加

来自CMake教程

您可以获得的最权威的来源可能是由Kitware的Ken Martin和Bill Hoffman编写的"Mastering CMake"书籍的摘录。

该书中的教程所有组件/目标名称都使用CamelCase和无命名空间。

参考资料


2
由于您在此处没有导入目标,建议不要使用命名空间。如果 my-lib-target-name 应该是一个 cmake 目标(即使是本地目标),我很高兴直接从 cmake 听到它找不到该目标,而不是 cmake 盲目地将 -lfoo 传递给链接器,然后编译器或链接器抛出一些更或多或少加密的错误。我认为“导入目标”的重要部分是“目标”,而不是“导入”。 - MikeMB
“但是由于默认情况下别名目标没有输出名称,因此该名称被视为目标的输出名称。” 这对于别名目标来说并不适用,因为它们没有输出,但这似乎是一个很好的通用建议。 - MikeMB
感谢提供链接。所有模块变量前面的 Xxx_ 似乎表明,至少对于包名和命名空间,首字母大写是首选。 - MikeMB
据我所知,调用target_link_library(my_lib Foo::foo)不需要先定义Foo::foo - MikeMB
@MikeMB 你说得对。我试过了,如果目标在项目的其他地方定义,target_link_libraries() 调用中也可以使用带有命名空间的目标。而且,当目标不是项目的一部分时,使用 cmake_policy(SET CMP0028 NEW) 会出现类似于 "Target "MyExe" links to target "Foo::Bar" but the target was not found." 的错误。我之前并不知道这一点,不得不承认这是一个非常方便的目标名称命名空间特性。 - Florian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接