【问题标题】:Naming convention for components and namespaces in cmakecmake 中组件和命名空间的命名约定
【发布时间】:2018-01-30 14:52:07
【问题描述】:

简而言之:

cmake 库目标是否有任何首选的命名约定 - 特别是在使用命名空间时?

注意:

除非确实有客观原因,否则我不会询问个人喜好,而是询问是否存在“官方”(例如套件推荐)或已建立(可能会偏离)惯例。

详情:

假设我有一个库/框架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 与 foo-bar)
    • 有或没有命名空间(foo-bar vs bar)
    • 有些项目首字母大写
    • 有些项目使用 CamelCase some snake_case,即使二进制文件或项目名称不遵循这些约定。

我想主要的问题是库一般没有命名约定,因此很难在 CMake 中提出命名约定,但至少命名空间和组件的第一个字母的大写似乎很常见,所以我想知道在未来的项目中是否应该遵循一些指导方针。

【问题讨论】:

    标签: cmake naming-conventions


    【解决方案1】:

    cmake-developer documentation 就命名空间给出以下建议:

    当提供导入的目标时,这些应该是命名空间的(因此有Foo:: 前缀); CMake 将识别传递给 target_link_libraries() 且名称中包含 :: 的值应该是导入目标(而不仅仅是库名称),并且如果该目标不存在,将生成适当的诊断消息(请参阅策略 CMP0028 )。

    CMP0028 policy documentation 提到了使用命名空间的“通用模式”:

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

    不,对于库目标的命名没有 CMake 特定的约定。但是由于默认情况下将名称作为目标的输出名称:

    • 我更喜欢为目标使用与我的源代码目录相同的名称
    • 并且不要添加 lib 前缀,因为这是由 CMake 自动添加的,具体取决于您编译项目的平台

    来自 CMake 教程

    您可以获得的最官方来源可能是来自 Kitware 的 Ken Martin 和 Bill Hoffman 撰写的 "Mastering CMake" book 的摘录。

    tutorials from the book 都使用 CamelCase,并且没有用于组件/目标名称的命名空间。

    参考文献

    【讨论】:

    • “由于这里没有导入目标,建议不要使用命名空间。” 你确定你没有对句子解释太多吗?如果 my-lib-target-name 应该是一个 cmake 目标(甚至是本地目标),我会很高兴直接从 cmake 那里听到它找不到所述目标,而不是 cmake 盲目地将 -lfoo 传递给链接器,或者编译器或链接器抛出一些或多或少的神秘错误。我认为importet target 的重要部分是target 而不是imported
    • “但是由于默认情况下将名称作为目标的输出名称” 好吧,不适用于别名目标,因为它们没有输出,但这似乎很好建议
    • 感谢您的链接。所有模块变量前面的Xxx_ 似乎表明,至少对于包名称和命名空间,首选大写首字母。
    • IIRC,对target_link_library(my_lib Foo::foo) 的调用也不需要Foo::foo 已经定义。
    • @MikeMB 你是对的。试一试,如果目标是在项目稍后的某个地方定义的,那么带有命名空间的目标也可以在target_link_libraries() 调用中使用。使用cmake_policy(SET CMP0028 NEW),我收到一个错误,例如“目标“MyExe”链接到目标“Foo::Bar”,但找不到目标。”当目标不是项目的一部分时。不知道这一点,我不得不承认这是带有命名空间的目标名称的一个非常方便的功能。
    猜你喜欢
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多