CMake 命名空间真的有意义吗?
Do CMake namespaces actually mean anything?
在现代 CMake 中,习惯于在命名空间内导出目标,例如将您的 foo
项目导出 foo::foo
,也许还有 foo::bar
等
我的问题是:这些名称空间本身是否真正意味着什么,或者它们只是一个名称的一部分,没有 CMake 分隔 ::-分隔的名称组件?
如果前者为真,您能否说“命名空间中的所有目标”或以其他方式使用命名空间?
我(还)没有看到任何允许单独处理命名空间导出目标的名称组件的 CMake 功能。但是我发现CMake的命名空间还是有一个含义,影响CMake的行为:
命名空间目标永远不是文件名
在 target_link_libraries(…)
调用中使用包含 ::
的目标名称将确保 CMake 仅将其解析为通过 find_package(…)
找到的所谓 IMPORTED targets。它阻止了通常的回退机制也尝试将其解析为磁盘上的库文件名(例如 -lName
将在磁盘上查找 libName.so
)。
该行为记录在 CMake Policy 0028 中。不一定到处都启用,但CMake≥3.0.2如果不启用会警告。
这也很有用。我刚刚遇到了一个由 CMake 的后备行为 (see) 引起的令人困惑的问题。因此,我将在 target_link_libraries(…)
.
中严格使用带有 ::
的命名空间目标名称
遗憾的是,从 another piece of CMake documentation 看来,识别 IMPORTED 目标的这一特征可能是 CMake 命名空间的唯一含义:
A NAMESPACE
with double-colons is specified when exporting the targets for installation. This convention of double-colons gives CMake a hint that the name is an IMPORTED
target when it is used by downstreams with the target_link_libraries()
command. This way, CMake can issue a diagnostic if the package providing it has not yet been found.
包组件是另一回事
乍一看,在我看来,每个 CMake 包都有一个命名空间,每个包组件在该命名空间中都有一个目标名称。因此,在 find_package(noms COMPONENTS fruit veg)
之后,您将有 noms::fruit
和 noms::veg
可用于 target_link_libraries(…)
。但这只是一种广泛(且有用)的当前做法。从技术上讲,包组件不一定映射到一个目标 ()。
在现代 CMake 中,习惯于在命名空间内导出目标,例如将您的 foo
项目导出 foo::foo
,也许还有 foo::bar
等
我的问题是:这些名称空间本身是否真正意味着什么,或者它们只是一个名称的一部分,没有 CMake 分隔 ::-分隔的名称组件?
如果前者为真,您能否说“命名空间中的所有目标”或以其他方式使用命名空间?
我(还)没有看到任何允许单独处理命名空间导出目标的名称组件的 CMake 功能。但是我发现CMake的命名空间还是有一个含义,影响CMake的行为:
命名空间目标永远不是文件名
在 target_link_libraries(…)
调用中使用包含 ::
的目标名称将确保 CMake 仅将其解析为通过 find_package(…)
找到的所谓 IMPORTED targets。它阻止了通常的回退机制也尝试将其解析为磁盘上的库文件名(例如 -lName
将在磁盘上查找 libName.so
)。
该行为记录在 CMake Policy 0028 中。不一定到处都启用,但CMake≥3.0.2如果不启用会警告。
这也很有用。我刚刚遇到了一个由 CMake 的后备行为 (see) 引起的令人困惑的问题。因此,我将在 target_link_libraries(…)
.
::
的命名空间目标名称
遗憾的是,从 another piece of CMake documentation 看来,识别 IMPORTED 目标的这一特征可能是 CMake 命名空间的唯一含义:
A
NAMESPACE
with double-colons is specified when exporting the targets for installation. This convention of double-colons gives CMake a hint that the name is anIMPORTED
target when it is used by downstreams with thetarget_link_libraries()
command. This way, CMake can issue a diagnostic if the package providing it has not yet been found.
包组件是另一回事
乍一看,在我看来,每个 CMake 包都有一个命名空间,每个包组件在该命名空间中都有一个目标名称。因此,在 find_package(noms COMPONENTS fruit veg)
之后,您将有 noms::fruit
和 noms::veg
可用于 target_link_libraries(…)
。但这只是一种广泛(且有用)的当前做法。从技术上讲,包组件不一定映射到一个目标 (