添加_库

使用指定的源文件将库添加到项目中。

普通图书馆

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [<source>...])

添加一个名为 <name> 的库目标,以从命令调用中列出的源文件构建。 <name> 对应于逻辑目标名称,并且在项目中必须是全局唯一的。构建的库的实际文件名是根据本机平台的约定构建的(例如 lib<name>.a<name>.lib)。

在 3.1 版本加入: add_library 的源参数可以使用语法为``$<...>`` 的“生成器表达式”。请参阅 cmake-generator-expressions(7) 手册了解可用的表达式。

在 3.11 版本加入: 如果稍后使用 target_sources() 添加源文件,则可以省略它们。

可以给出 STATICSHAREDMODULE 来指定要创建的库的类型。 STATIC 库是目标文件的存档,供链接其他目标时使用。 SHARED 库动态链接并在运行时加载。 MODULE 库是不链接到其他目标但可以在运行时使用类似 dlopen 的功能动态加载的插件。如果没有明确给出类型,则类型是 STATICSHARED 取决于变量的当前值 BUILD_SHARED_LIBS 是否为 ON。对于 SHAREDMODULE 库, POSITION_INDEPENDENT_CODE 目标属性自动设置为 ONSHARED 库可以用 FRAMEWORK 目标属性标记以创建 macOS 框架。

在 3.8 版本加入: STATIC 库可以用 FRAMEWORK 目标属性标记以创建静态框架。

如果库不导出任何符号,则不得将其声明为“共享”库。例如,Windows 资源 DLL 或不导出非托管符号的托管 C++/CLI DLL 需要是一个“MODULE”库。这是因为 CMake 期望 SHARED 库在 Windows 上始终具有关联的导入库。

默认情况下,库文件将在与调用命令的源树目录相对应的构建树目录中创建。请参阅 ARCHIVE_OUTPUT_DIRECTORYLIBRARY_OUTPUT_DIRECTORYRUNTIME_OUTPUT_DIRECTORY 目标属性的文档以更改此位置。请参阅 OUTPUT_NAME 目标属性的文档以更改最终文件名的 <name> 部分。

如果给出 EXCLUDE_FROM_ALL,则将在创建的目标上设置相应的属性。有关详细信息,请参阅 EXCLUDE_FROM_ALL 目标属性的文档。

有关定义构建系统属性的更多信息,请参阅 cmake-buildsystem(7) 手册。

另请参阅 HEADER_FILE_ONLY 了解如果对某些源进行了预处理,并且您希望可以从 IDE 中访问原始源,该怎么做。

对象库

add_library(<name> OBJECT [<source>...])

创建一个 Object Library。目标库编译源文件但不将它们的目标文件存档或链接到库中。相反,由 add_libraryadd_executable() 创建的其他目标可以使用 $<TARGET_OBJECTS:objlib> 形式的表达式作为源引用对象,其中 `` objlib`` 是对象库名称。例如:

add_library(... $<TARGET_OBJECTS:objlib> ...)
add_executable(... $<TARGET_OBJECTS:objlib> ...)

将 objlib 的目标文件包含在一个库和一个可执行文件中,以及那些从他们自己的源代码编译的文件。对象库可能只包含编译源、头文件和其他不会影响普通库链接的文件(例如 .txt)。它们可能包含生成此类源的自定义命令,但不包含“PRE_BUILD”、“PRE_LINK”或“POST_BUILD”命令。某些本机构建系统(例如 Xcode)可能不喜欢只有目标文件的目标,因此请考虑向任何引用 $<TARGET_OBJECTS:objlib> 的目标添加至少一个真实的源文件。

在 3.12 版本加入: 对象库可以链接到:command:target_link_libraries

接口库

add_library(<name> INTERFACE)

创建一个 Interface LibraryINTERFACE 库目标不会编译源代码,也不会在磁盘上生成库工件。但是,它可能设置了属性,并且可以安装和导出。通常,使用以下命令在接口目标上填充 INTERFACE_* 属性:

  • set_property()

  • target_link_libraries(接口)()

  • target_link_options(接口)()

  • target_include_directories(接口)()

  • target_compile_options(接口)()

  • target_compile_definitions(INTERFACE),和

  • target_sources(接口)()

然后它像任何其他目标一样用作 target_link_libraries() 的参数。

使用上述签名创建的接口库本身没有源文件,也不会作为目标包含在生成的构建系统中。

在 3.15 版本加入: 接口库可以具有 PUBLIC_HEADERPRIVATE_HEADER 属性。可以使用 install(TARGETS) 命令安装由这些属性指定的标头。

在 3.19 版本加入: 可以使用源文件创建接口库目标:

add_library(<name> INTERFACE [<source>...] [EXCLUDE_FROM_ALL])

源文件可以直接在 add_library 调用中列出,或者稍后通过使用 PRIVATEPUBLIC 关键字调用:command:target_sources 添加。

如果接口库有源文件(即设置了 SOURCES 目标属性),或设置了头文件(即设置了 HEADER_SETS 目标属性),它将作为构建出现在生成的构建系统中target 很像 add_custom_target() 命令定义的目标。它不编译任何源代码,但包含由 add_custom_command() 命令创建的自定义命令的构建规则。

备注

在大多数出现 INTERFACE 关键字的命令签名中,其后列出的项目仅成为该目标使用要求的一部分,而不是目标自身设置的一部分。然而,在 add_library 的签名中,INTERFACE 关键字仅指库类型。在 add_library 调用中它后面列出的源是接口库的 PRIVATE 并且不会出现在它的 INTERFACE_SOURCES 目标属性中。

导入库

add_library(<name> <type> IMPORTED [GLOBAL])

创建一个名为 <name>IMPORTED 库目标。没有生成规则来构建它,并且 IMPORTED 目标属性是 True。目标名称在其创建目录及以下目录中具有范围,但 GLOBAL 选项扩展了可见性。它可以像项目中构建的任何目标一样被引用。 IMPORTED 库可用于方便地从 target_link_libraries() 等命令中引用。有关导入库的详细信息通过设置名称以“IMPORTED_”和“INTERFACE_”开头的属性来指定。

<type> 必须是以下之一:

静态共享模块未知

引用位于项目外部的库文件。 IMPORTED_LOCATION 目标属性(或其每个配置变体 IMPORTED_LOCATION_<CONFIG>)指定主库文件在磁盘上的位置:

  • 对于大多数非 Windows 平台上的“共享”库,主库文件是链接器和动态加载器使用的“.so”或“.dylib”文件。如果引用的库文件有一个 SONAME``(或者在 macOS 上,有一个 ``LC_ID_DYLIB@rpath/ 开始),该字段的值应该在 IMPORTED_SONAME 中设置 目标属性。如果引用的库文件没有 SONAME,但平台支持它,则应设置 IMPORTED_NO_SONAME 目标属性。

  • 对于 Windows 上的 SHARED 库, IMPORTED_IMPLIB 目标属性(或其每个配置变体:prop_tgt:IMPORTED_IMPLIB_<CONFIG>)指定 DLL 导入库文件 (. lib.dll.a) 在磁盘上,而 IMPORTED_LOCATION.dll 运行时库的位置(并且是可选的,但 TARGET_RUNTIME_DLLS 需要 生成器表达式)。

额外的使用要求可以在 INTERFACE_* 属性中指定。

UNKNOWN 库类型通常仅用于 查找模块 的实现。它允许使用导入库的路径(通常使用 find_library() 命令找到),而不必知道它是什么类型的库。这在 Windows 上特别有用,其中静态库和 DLL 的导入库都具有相同的文件扩展名。

对象

引用位于项目外部的一组目标文件。 IMPORTED_OBJECTS 目标属性(或其每个配置变体 IMPORTED_OBJECTS_<CONFIG>)指定目标文件在磁盘上的位置。额外的使用要求可以在 INTERFACE_* 属性中指定。

界面

不引用磁盘上的任何库或对象文件,但可以在 INTERFACE_* 属性中指定使用要求。

有关更多信息,请参阅 IMPORTED_*INTERFACE_* 属性的文档。

别名库

add_library(<name> ALIAS <target>)

创建一个 Alias Target,这样 <name> 可用于在后续命令中引用 <target><name> 不会作为生成目标出现在生成的构建系统中。 <target> 可能不是 ALIAS

在 3.11 版本加入: ALIAS 可以针对 GLOBAL Imported Target

在 3.18 版本加入: ALIAS 可以针对非``GLOBAL`` 导入目标。此类别名的范围限于创建它的目录及以下目录。 ALIAS_GLOBAL 目标属性可用于检查别名是否为全局别名。

ALIAS 目标可以用作可链接的目标和从中读取属性的目标。也可以使用常规的 if(TARGET) 子命令来测试它们是否存在。 <name> 不得用于修改 <target> 的属性,也就是说,它不得用作 set_property()set_target_properties() 的操作数, target_link_libraries()ALIAS 目标可能无法安装或导出。

也可以看看