cmake别名的用处

CD8*_*D86 9 alias cmake

我不完全得到别名表达式的应用程序.我明白我可以写这样的东西

cmake_minimum_required(VERSION 3.5.1 FATAL_ERROR)
project(myLibs)
add_library(${PROJECT_NAME} src/test.cpp)
add_library(myLibs::myLibs ALIAS ${PROJECT_NAME})
...
Run Code Online (Sandbox Code Playgroud)

然后使用

  target_link_libraries(${TARGET_NAME}
  myLibs::myLibs
Run Code Online (Sandbox Code Playgroud)

在另一个文件中将库链接到某些可执行文件等.

但为什么我会这样做?我不妨跳过别名定义,直接使用构建库的targetname

target_link_libraries(${TARGET_NAME}
myLibs
Run Code Online (Sandbox Code Playgroud)
  • 任何人都可以向我解释为什么存在别名
  • 为什么他们使用::语法?别名不是完全随意的吗?

Flo*_*ian 5

以你的add_library()例子中,CMake的目标的名字将如直接链接到目标的输出文件名.

因此,ALIAS目标主要用于通过添加"命名空间"来为目标提供更多拼写或结构化名称.

cmake-developer文档提供了有关命名空间的以下建议:

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


Cra*_*ott 5

TLDR:它为其他使用您的项目提供了更大的灵活性。

对我来说,添加 ALIAS 的主要动机与安装/打包以及其他项目如何使用您的项目有关。安装项目后,它可以导出其目标。该install()命令的两种相关形式是:

install(TARGETS target... EXPORT exportName ...)
install(EXPORT exportName ... NAMESPACE myNS:: ...)
Run Code Online (Sandbox Code Playgroud)

第一个是安装您的实际目标(即二进制文件),但它也包括EXPORT关键字。这告诉 CMake 这个目标安装是exportName导出集的一部分。上面的第二个命令然后为exportName导出集安装一个文件,其中包含为集中的每个目标创建导入目标的 CMake 代码。它将附加myNS::到该集合中的所有目标(这是您问题的关键点)。这个导出的文件将包含在您项目的配置包文件中(这是一个相当复杂的主题,您可以在此处获得更多详细信息)。然后,其他项目可以通过首先执行 a 来针对您安装的项目进行构建find_package(),这将重新创建所有导出的目标,除了它们现在都带有前缀myNS::. 然后它链接到这些命名空间目标,就好像它们是它自己构建的一部分。我跳过了相当多的细节,但这些是与您的问题最相关的要点。

现在,可能是消费项目不想使用find_package(),而是它可能希望使用add_subdirectory(). 这将是一种从源代码而不是针对预先构建的二进制包构建项目的方法。自从在 CMake 3.11 中添加FetchContent 模块以来,它正成为一种更流行的方法。如果您的项目为 ALIAS 目标提供了与导出的目标名称匹配的名称,则使用项目无需更改其任何target_link_libraries()命令。无论它是针对预先构建的二进制包构建还是通过 引入您的项目add_subdirectory(),它都会链接到命名空间目标名称(即myLibs::myLibs在您的问题中),无论哪种情况,它都可以正常工作。

至于它的::作用,当一个包含的名称::出现在target_link_libraries()命令中时,它只会被解释为 CMake 目标(假设策略 CMP0028 设置为 NEW,现在确实应该如此)。如果不存在这样的目标,CMake 将失败并显示错误,而不是假定它是系统提供的库的名称。