在现代CMake中,通常在名称空间中导出目标,例如让您的foo
项目导出foo::foo
,也许还有foo::bar
等等。
我的问题是:这些名称空间本身是否意味着什么,还是它们仅仅是单个名称的一部分,而没有CMake分离::-分隔的名称组件?
如果前者是真的,您能说“名称空间中的所有目标”之类的话吗?或者以其他方式使用名称空间吗?
发布于 2020-06-20 19:08:37
我还没有看到任何允许单独处理名称空间导出目标的名称组件的CMake功能。但我发现CMake名称空间仍然有一个含义,即影响CMake的行为:
命名空间的目标从来不是文件名。
在::
调用中使用包含target_link_libraries(…)
的目标名称将确保CMake只将其解析为通过find_package(…)
找到的所谓进口目标。它防止了通常的回退机制,也可以尝试将其解析为磁盘上的库文件名(比如-lName
在磁盘上查找libName.so
的位置)。
这种行为在CMake政策0028中有记载。它不一定在任何地方都启用,但CMake≥3.0.2将发出警告。
它也很有用。我刚刚遇到了一个由CMake的回退行为(看见)引起的令人困惑的问题。因此,我将在::
中严格使用target_link_libraries(…)
中的命名空间目标名称。
遗憾的是,从另一篇CMake文档来看,识别导入目标的这一特性可能是CMake名称空间的唯一含义:
在导出要安装的目标时,将指定带有双冒号的
NAMESPACE
。这种双冒号的约定为CMake提供了一个提示,即当target_link_libraries()
命令被下行流使用时,名称是一个target_link_libraries()
目标。这样,如果还没有找到包,CMake就可以发出诊断。
包组件是另一回事。
乍一看,在我看来,每个CMake包有一个名称空间,每个包组件的名称空间中有一个目标名称。这样,在find_package(noms COMPONENTS fruit veg)
之后,noms::fruit
和noms::veg
就可以用于target_link_libraries(…)
了。但这只是目前一种普遍(且有用)的做法。从技术上讲,包组件并不一定映射到一个目标(详细信息)。
https://stackoverflow.com/questions/60605281
复制相似问题