CMakeLists.txt 中add_libraries()生成动态库和静态库的区别,以及各自链接依赖库的区别

在Linux中,动态库和静态库是两种不同的库文件类型,它们在编译和运行时的处理方式有所不同。

静态库

  • 定义:静态库是一个包含了多个目标文件的归档文件,通常以 .a 作为文件扩展名。
  • 编译过程:在编译时,静态库的代码会被复制到最终生成的可执行文件中。这意味着可执行文件包含了所有需要的代码。
  • 优点
    • 不依赖于外部库文件,部署时只需分发可执行文件。
    • 启动速度较快,因为所有代码都已经包含在可执行文件中。
  • 缺点
    • 可执行文件的体积较大,因为包含了所有库的代码。
    • 更新库时需要重新编译所有依赖于该库的可执行文件。

动态库

  • 定义:动态库是一个在运行时被加载的库文件,通常以 .so 作为文件扩展名(共享对象)。
  • 编译过程:在编译时,动态库的引用会被记录在可执行文件中,而不是将库的代码直接复制到可执行文件中。
  • 优点
    • 可执行文件体积较小,因为只包含了对动态库的引用。
    • 更新库时,只需替换动态库文件,而不需要重新编译依赖于该库的可执行文件。
  • 缺点
    • 运行时需要加载动态库,可能导致启动速度稍慢。
    • 如果动态库缺失或版本不兼容,可能导致运行时错误。

运行加载的区别

  1. 静态库

    • 在编译时,静态库的代码被直接嵌入到可执行文件中,因此在运行时不需要额外加载库文件。
  2. 动态库

    • 在运行时,操作系统会根据可执行文件中的信息查找并加载所需的动态库。这通常通过动态链接器(如 ld.so)来完成。
    • 动态库可以在多个程序之间共享,节省内存和存储空间。

总结

  • 静态库:编译时链接,运行时不需要外部库,体积大,更新不便。
  • 动态库:运行时链接,体积小,更新方便,但依赖于外部库的存在和兼容性。

选择使用静态库还是动态库,通常取决于具体的应用需求和部署环境。
在 CMake 中,add_library() 函数可以用来创建库,但默认情况下它并不总是创建静态库。具体来说,add_library() 的行为取决于你提供的参数。

add_library() 的用法

  1. 创建静态库
    如果你使用 add_library() 并且没有指定库类型,CMake 默认会创建一个静态库。示例:

    add_library(my_static_lib source1.cpp source2.cpp)
    
  2. 创建动态库
    如果你想创建一个动态库(共享库),需要明确指定库类型为 SHARED。示例:

    add_library(my_shared_lib SHARED source1.cpp source2.cpp)
    
  • 默认情况下,add_library() 创建的是静态库。
  • 如果需要创建动态库或模块库,必须显式指定 SHARED

生成静态库不需要链接动态库

在生成静态库时,通常不需要链接依赖的动态库。静态库(如 .a 文件)是将目标文件(.o 文件)打包在一起的文件,编译时会将这些目标文件的代码直接包含在最终的可执行文件中。

然而,在编译静态库时,如果你的静态库的代码依赖于某些动态库的接口(例如,使用了动态库中的函数),你仍然需要在编译时确保这些接口的声明可用(通常通过包含相应的头文件)。但在生成静态库的过程中,不会将动态库的代码链接到静态库中。

当你使用这个静态库生成最终的可执行文件时,链接器会在链接阶段查找并链接所需的动态库。 因此,最终的可执行文件在运行时仍然需要这些动态库。所以生成静态库时,即使你target_link_libraries() 没有设置需要链接的动态库的信息也不会报错。但是使用这个静态库生成最终可执行文件时,会报undefined reference to 的错误。

虽然在CMakeLists.txt中通过 target_link_libraries()设置了动态库的信息但是在静态库对应的build.make文件中是不会出现静态库依赖的动态库.so的信息。如果想查看莫个静态库依赖了哪些动态库,可以先用一个可执行文件链接这个静态库,然后通过ldd(只能用于动态库和可执行文件)命令查看这个可执行文件依赖哪些动态库。

生成动态库需要链接动态库

在生成动态库时,通常不会将其依赖的库直接链接到生成的动态库中。动态库(如 .dll.so 文件)在编译时会记录其依赖的其他库的信息,但这些依赖库不会被嵌入到动态库中。

具体来说,动态库的生成过程通常包括以下几个步骤:

  1. 编译源代码:将源代码编译成目标文件(.o 或 .obj 文件)。
  2. 链接:在链接阶段,动态库会引用它所依赖的其他库,但不会将这些库的代码直接包含在动态库中。相反,动态库会在运行时动态加载这些依赖库。

因此,当你使用一个动态库时,确保在运行时能够找到其依赖的库是非常重要的。这通常涉及到设置正确的库路径或环境变量,以便操作系统能够找到这些依赖库。

总结来说,动态库在生成时不会将依赖的库链接到库中,而是通过动态链接的方式在运行时加载这些依赖库。在动态库对应的build.make文件中会出现依赖的动态库.so的信息

cmake是一个跨平台的自动化构建工具,可用于生成各种类型的项目文件。CMakeLists是cmake的配置文件,用于描述如何生成编译器所需的构建信息。 在linux系统静态库动态库是常见的可重定向目标文件。静态库是将所有依赖项打包在一起,并在应用程序链接时一起编译的。而动态库是在应用程序运行时加载并链接到运作时环境的生成静态库非常简单。在CMakeLists,我们可以添加的名称和源文件,然后调用add_library命令来构建静态库。例如,下面的代码段定义了一个叫做mylibrary的静态库,并将两个源文件相连: add_library(mylibrary STATIC source1.cpp source2.cpp) 生成静态库文件通常被命名为libmylibrary.a。 现在我们想要使用上述静态库生成一个动态库,我们需要在CMakeLists再一次调用add_library命令,但这次类型应该是“SHARED”,表示动态库。同时需要注意的是,在生成动态库的同时,我们需要链接到之前生成静态库。下面是一个示例代码: add_library(mylibrary_dynamic SHARED source3.cpp) target_link_libraries(mylibrary_dynamic mylibrary) 上述代码会将源文件source3.cpp编译为动态库,并将之前生成静态库mylibrary链接动态库mylibrary_dynamic生成动态库文件通常被命名为libmylibrary_dynamic.so。 总之,cmakelists可以用来生成静态库动态库生成静态库时我们需要调用add_library命令,并指定STATIC类型;而生成动态库时,我们需要调用add_library命令,并指定SHARED类型,同时会涉及到链接上一个静态库。以上就是使用cmakelists来生成静态库并用静态库生成动态库的具体方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值