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

news2025/2/3 7:41:23

文章目录

  • 前言
  • 一、动静态链接库的介绍
    • 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
└── Makefile

1 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.cpp

5 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.coloradmin.cn/o/1328826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言易错题之数据类型变换

1.题目 #include<stdio.h> int main() {int arr[]{1,2,3,4,5};short*p (short*)arr;int i 0;for(i0;i<4;i){*(pi)0;}for(i0;i<5;i){printf("%d ",arr[i];}return 0; }2.解析 这道题主要容易错在&#xff0c;大家会以为通过指针赋值的时候&#xff0c;…

基于springboot的日记本系统源码+数据库+安装使用说明

之前写的SpringBoot日记本系统备受好评&#xff0c;考虑到还是有很多小伙伴不会部署&#xff0c;所以这一篇文章就单独来讲一下部署步骤吧。 需要资源 idea&#xff08;破不破解都行&#xff09; MySQL&#xff08;最好5.7以上版本&#xff0c;最好8.0&#xff09; Navicat…

SpringBoot Elasticsearch全文搜索

文章目录 概念全文搜索相关技术Elasticsearch概念近实时索引类型文档分片(Shard)和副本(Replica) 下载启用SpringBoot整合引入依赖创建文档类创建资源库测试文件初始化数据创建控制器 问题参考 概念 全文搜索&#xff08;检索&#xff09;&#xff0c;工作原理&#xff1a;计算…

Node.js-模块化(二)

1. 模块化的基本概念 1.1 什么是模块化 模块化是指解决一个复杂问题时&#xff0c;自顶向下逐层将系统拆分成若干模块的过程。对于整个系统来说&#xff0c;模块是可组合、分解和更换的单元。 1.2 编程领域中的模块化 编程领域中的模块化&#xff0c;就是遵守固定的规则&…

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…

git首次使用--去公司第一次拉取

文章目录 一&#xff0c; 在企业中首次拉取项目二&#xff0c;提交项目1. 提交----新添加的文件2. 将分支上的代码同步到master3. 提交----更改后的文件 三&#xff0c;常见问题1. Git Pull Failed 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一&am…

【组合数学】Pólya 计数理论

目录 1. 引言2. 置换群3. Burnside 引理共轭类k 不动置换类Burnside 引理 4. Plya 计数定理4.1 对点着色问题4.2 对面着色问题4.3 重复球放盒子 1. 引言 Plya 计数理论是数学中的一个分支&#xff0c;主要研究的是对称性在组合计数问题中的应用。该理论以匈牙利数学家乔治波利…

《Python Advanced Programming + Design Patterns + Clean Code》

清洁代码 — 学习如何编写可读、可理解且可维护的代码 高级Python编程知识 Python之常用设计模式 Advanced Programming装饰器 decorators生成器 & 迭代器with 上下文管理器面向对象Mixin 模式反射机制并发编程 Design Patterns设计模式分类简单工厂模式工厂模式 √抽象工厂…

指标体系构建-02-从0开始,梳理数据指标体系

指标体系构建-02-从0开始&#xff0c;梳理数据指标体系 一个例子&#xff0c;看懂并列式指标梳理 并列式指标体系&#xff0c;一般用于&#xff1a;描述个体情况 当我们想从几个不同角度&#xff0c;描述问题的时候&#xff0c;就需要并列关系 举个栗子&#x1f330;&#xf…

安全基础~实战应用

文章目录 HTTP请求头应用X-Forwarded-ForHTTP动作练习(修改请求方式)浏览器信息伪造(修改User-Agent)来源请求伪造(referer应用) 密码的应用SQL注入漏洞测试(前部分)PHP_encrypt_1(ISCCCTF) XShell连接Linxu连接Windows连接 HTTP请求头应用 X-Forwarded-For 原理作用 一般的…

浅谈在线监测系统与配电能效平台在供水水厂的应用

贾丽丽 安科瑞电气股份有限公司 上海嘉定 201800 【摘要】针对自来水厂工艺老化资金有限的问题&#xff0c;设计水厂在线监测系统&#xff0c;采用安科瑞&#xff0c;对原水滤后水、出厂水进行采样分析&#xff0c;并通过基于组态的上位机系统实现水质数据的实时监测。该系统…

深入了解UI标签栏设计细节:你不能错过的要点

UI 标签栏的作用有哪些&#xff1f; 导航是移动 UI 中最常见的组成部分&#xff0c;通常放置在 UI 标签栏上&#xff0c;以帮助我们在不同的页面之间切换。UI 标签栏可以保持界面的可控性&#xff0c;并提高可用性。简而言之&#xff0c;UI 标签栏可以加强交互&#xff0c;让用…

渲染图和效果图的一样吗?渲染图与效果图区别?

在建筑、设计及电影制作等一系列领域&#xff0c;你可能经常听说渲染图和效果图这两个词汇。它们虽然在视觉表现上有许多相似之处&#xff0c;但在实质上却有着极其不同的特性和用途。此文主要探讨提供优质效果图云渲染服务&#xff0c;以及渲染图与效果图之间的区别。 一、 效…

快递收发线上管理教程

前台快递收发几乎是每家公司行政前台的“必修课”&#xff0c;所以网络上制度模板满天飞&#xff0c;但现实中能彻底解决快递收发管理难题的几乎为零&#xff0c;那前台快递收发管理&#xff0c;究竟要如何才能摆脱制度的桎梏&#xff1f; 纵观各种前台快递收发制度范本&#…

Java可变参数(学习推荐版,通俗易懂)

定义 可变参数本质还是一个数组 示例代码 注意事项 1.形参列表中&#xff0c;可变参数只能有一个 2.可变参数必须放在形参列表的最后面 注意是最后面。 name也可以为int类型

Vuex的学习-2

Vuex的核心概念 StateMutationAction 1.State State提供唯一的公共数据源&#xff0c;所有共享的数据都统一放在Store的State中进行存储。 const store new Vuex.Store({state : { count: 0 } }) 这是渲染的页面 组件访问数据的第一种方式 组件访问数据的第二种方式 // 1…

数据结构和算法笔记2:二分法

二分法网上有两种写法&#xff0c;一种左闭右闭&#xff0c;一种左闭右开&#xff0c;个人习惯左闭右闭的写法&#xff0c; 有序数组查找数 这是标准二分法&#xff0c;对应力扣的704. 二分查找&#xff1a; 求值为target的索引 int search(vector<int>& nums, i…

通过几个基本概念说一下为什么openGauss是当下之选?

Database、Schema、User都是数据库的基本概念&#xff0c;SQL标准中也有明确规范。但不同数据库的具体实现也不尽相同&#xff0c;有些甚至大相径庭。这就导致用户在做国产化选型和数据库迁移时可能会遇到种种困难。本文从这几个基本概念展开&#xff0c;说说为什么openGauss系…

YACS(上海计算机学会竞赛平台)三星级挑战——两数之和

题目描述 给定 n 个整数 a[1]​,a[2]​,⋯,a[n]​&#xff0c;并且保证 a[1​]≤a[2​]≤⋯≤a[n]​ 再给定一个目标值 t&#xff0c;请判断能否找到 a[i]​ 与 a[j]​&#xff0c;ai​aj​t 且 i≠j。 输入格式 第一行&#xff1a;单个整数n&#xff1b; 第二行&#xf…

JavaScript高级 构造函数与原型篇

构造函数与原型 1、构造函数 构造函数是一种特殊的函数&#xff0c;主要用来初始化对象&#xff0c;即为对象成员变量赋初始值&#xff0c;它总与new一起使用。我们可以把对象中一些公共的属性和方法抽取出来&#xff0c;然后封装到这个函数里面。 // 定义学生构造函数func…