【CMake保姆级教程】制作动静态链接库、指定动静态库输出路径

文章目录

  • 前言
  • 一、动静态链接库的介绍
    • 1.1 动态链接库 (DLL)
    • 1.2 静态链接库 (LIB)
  • 二、制作静态库
  • 三、制作动态库
  • 四、指定动静态库输出路径
    • 4.1 方式1 - 适用于动态库
    • 4.2 方式2 - 都适用
  • 总结


前言

在软件开发中,我们经常听到动态链接库(Dynamic Link Library,DLL)和静态链接库(Static Link Library,LIB)的术语。它们是一种组织和共享代码的方式,有助于提高代码的可维护性和可重用性。本教程将使用CMake来创建动态链接库和静态链接库,为你提供一份简单易懂的指南,让你轻松理解这两种库的概念和制作过程。


一、动静态链接库的介绍

1.1 动态链接库 (DLL)

动态链接库是一种包含可执行代码和数据的文件,它可以在运行时被加载和执行。这种库的主要优势在于代码的共享,多个程序可以同时使用同一个动态链接库,从而减少内存占用。在不同的操作系统中,DLL的文件后缀不同:

在Windows上,动态链接库的后缀通常是.dll(比如mylibrary.dll)。

在Linux上,通常是.so,表示共享对象(Shared Object,比如libmylibrary.so)。

在macOS上,也是.dylib,表示动态库(Dynamic Library,比如libmylibrary.dylib)。

1.2 静态链接库 (LIB)

相比之下,静态链接库在编译时被嵌入到程序中,程序在运行时不再依赖外部库。这意味着每个程序都包含其所需的所有代码,但也可能导致更大的可执行文件。静态链接库的文件后缀也因操作系统而异:

在Windows上,静态链接库的后缀通常是.lib(比如mylibrary.lib)。

在Linux上,通常是.a,表示归档文件(Archive,比如libmylibrary.a)。

在macOS上,同样是.a,表示静态库(Static Library,比如libmylibrary.a)。

二、制作静态库

在cmake中,如果要制作静态库,需要使用的命令如下:

add_library(库名称 STATIC 源文件1 [源文件2] ...) 

STATIC后面的为你要生成静态库的源文件

在Linux中,静态库名字分为三部分:lib+库名字+.a,此处只需要指定出库的名字就可以了,另外两部分在生成该文件的时候会自动填充。

在Windows中虽然库名和Linux格式不同,但也只需指定出名字即可。

首先,我们创建一个a.cpp作为示例:

.
├── a.cpp
├── bin
├── build
├── CMakeLists.txt
├── include
└── src

接下来我们在cmake里面添加上这句:

add_library(testlib a.cpp)

然后我们使用cmake和make命令

Consolidate compiler generated dependencies of target app
[ 60%] Built target app
[ 80%] Building CXX object CMakeFiles/testlib.dir/a.cpp.o
[100%] Linking CXX static library libtestlib.a
[100%] Built target testlib
ubuntu@ubuntu-2204:~/C/csdn-cmake/build$ tree -L 1
.
├── app
├── CMakeCache.txt
├── CMakeFiles
├── cmake_install.cmake
├── libtestlib.a
└── Makefile1 directory, 5 files

接下来我们看一下文件:

.
├── a.cpp
├── bin
│   └── app
├── build
│   ├── app
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── libtestlib.a
│   └── Makefile
├── CMakeLists.txt
├── include
│   └── func.h
└── src├── func.cpp└── main.cpp5 directories, 11 files

可以看到libtestlib.a这边就有Linux的静态文件夹了

在这里插入图片描述

三、制作动态库

制作动态库
在cmake中,如果要制作动态库,需要使用的命令如下:

add_library(库名称 SHARED 源文件1 [源文件2] ...)

我们只需要把STATIC 换成 SHARED 即可

add_library(testlib SHARED a.cpp)

在这里插入图片描述
可以看到,这样就成功生成了我们的so动态库文件

四、指定动静态库输出路径

4.1 方式1 - 适用于动态库

对于生成的库文件来说和可执行程序一样都可以指定输出路径。由于在Linux下生成的动态库默认是有执行权限的,所以可以按照生成可执行程序的方式去指定它生成的目录:

cmake_minimum_required(VERSION 3.0)
project(test)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# 设置动态库生成路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
add_library(test SHARED ${SRC_LIST})

4.2 方式2 - 都适用

由于在Linux下生成的静态库默认不具有可执行权限,所以在指定静态库生成的路径的时候就不能使用EXECUTABLE_OUTPUT_PATH宏了,而应该使用LIBRARY_OUTPUT_PATH,这个宏对应静态库文件和动态库文件都适用。

cmake_minimum_required(VERSION 3.0)
project(CALC)
include_directories(${PROJECT_SOURCE_DIR}/include)
file(GLOB SRC_LIST "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
# 设置动态库/静态库生成路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
# 生成动态库
#add_library(test SHARED ${SRC_LIST})
# 生成静态库
add_library(test STATIC ${SRC_LIST})

总结

通过CMake,我们可以轻松地创建和管理动态链接库和静态链接库,使得代码的组织和共享变得更加简单。动态链接库允许多个程序共享相同的代码,而静态链接库将代码嵌入到程序中,减少了对外部依赖的需求。选择使用哪种库取决于你的项目需求和偏好,但理解它们的差异将有助于你更好地设计和组织你的代码。希望这个保姆级教程能够让你对动态链接库和静态链接库有一个清晰的认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/293126.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python实现模块热加载

为什么需要热加载 在某些情况,你可能不希望关闭Python进程并重新打开,或者你无法重新启动Python,这时候就需要实现实时修改代码实时生效,而不用重新启动Python 在我的需求下,这个功能非常重要,我将Python…

web前端游戏项目-堆木头游戏【附源码】

web前端游戏项目-堆木头游戏 《堆木头》游戏玩法简单,通过鼠标点击放木头的按钮,叠加在一起,构建出各种结构。游戏适合所有年龄段的孩子,可以锻炼孩子的动手能力和手眼协调能力,激发孩子的创造力和想象力 运行效果 …

如何在服务器上安装宝塔面板

要安装宝塔面板,你可以按照以下步骤进行操作: 登录到你的服务器。可以使用SSH登录或者通过服务器提供商提供的控制面板登录。打开宝塔面板的官方网站,访问 https://www.bt.cn/ ,下载最新版本的宝塔面板安装包。根据你的服务器操作…

LLM微调(四)| 微调Llama 2实现Text-to-SQL,并使用LlamaIndex在数据库上进行推理

Llama 2是开源LLM发展的一个巨大里程碑。最大模型及其经过微调的变体位居Hugging Face Open LLM排行榜(https://huggingface.co/spaces/HuggingFaceH4/open_llm_leaderboard)前列。多个基准测试表明,就性能而言,它正在接近GPT-3.5…

聚焦云安全 | 安全狗多项安全能力获权威认可

12月21日,以“云融未来,安全内在”为主题的第七届云安全联盟大中华区大会在深圳成功举办。 作为国内云原生安全领导厂商,安全狗也受邀参与此次活动。 厦门服云信息科技有限公司(品牌名:安全狗)创办于2013…

Spring源码分析 @Autowired 是怎样完成注入的?究竟是byType还是byName亦两者皆有

1. 五种不同场景下 Autowired 的使用 第一种情况 上下文中只有一个同类型的bean 配置类 package org.example.bean;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class FruitCo…

OpenAI 官方 Prompt 工程指南:写好 Prompt 的六个策略

其实一直有很多人问我,Prompt 要怎么写效果才好,有没有模板。 我每次都会说,能清晰的表达你的想法,才是最重要的,各种技巧都是其次。但是,我还是希望发给他们一些靠谱的文档。 但是,网上各种所…

手绘风格绘画白板:自由创作艺术空间 | 开源日报 No.118

firebase/firebase-ios-sdk Stars: 4.8k License: Apache-2.0 这个项目是 Firebase 苹果开源开发平台,包含了除 FirebaseAnalytics 之外的所有 Apple 平台 Firebase SDKs 的源代码。它提供了一系列工具来帮助你构建、增长和盈利你的应用程序。主要功能和核心优势如…

NC65 查询单据所处的流程状态以及流程平台客户端工具类

1、查询单据所处的流程状态 nc.bs.wfengine.engine.EngineService的queryFlowStatus()方法 /*** 查询单据所处的流程状态* * param billId* param billType* param result* return* throws DbException*/public int queryFlowStatus(String billId, String billType, int flo…

『番外篇五』SwiftUI 进阶之如何动态获取任意视图的 tag 和 id 值

概览 在某些场景下,我们需要用代码动态去探查 SwiftUI 视图的信息。比如任意视图的 id 或 tag 值: 如上图所示:我们通过动态探查技术在运行时将 SwiftUI 特定视图的 tag 和 id 值显示在了屏幕上。 这是如何做到的呢? 在本篇博文,您将学到如下内容: 概览1. “如意如意,…

Mybatis的关联查询(association和collection)

关联查询 实体间的关系(拥有 has、属于 belong) OneToOne:一对一关系(account ←→ user) OneToMany:一对多关系(user ←→ account) ManyToMany:多对多关系&#xff0…

【递归 回溯】LeetCode-17. 电话号码的字母组合

17. 电话号码的字母组合。 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digit…