【CMake系列】05-静态库与动态库编译
在各种项目类型中,可能我们的项目就是一个 库 项目,向其他人提供 我们开发好的 库 (windows下的 dll /lib ; linux下的 .a / .so);有时候在一个项目中,我们对部分功能 打包成 库,方便在不同地方进行调用
静态库 和 动态库 对项目 实现了 不同程度的解耦,
- 静态库,往往会 链接时 加载,代码会复制一起打包到 可执行程序中
- 动态库 更多是 运行时 加载,加载到内存,供可执行程序调用
学会使用 cmake 构建 静态库 和 动态库,是我们这篇文章的主要内容
本专栏的实践代码全部放在 github 上,欢迎 star !!!
如有问题,欢迎留言、或加群【392784757】交流
涉及命令
add_library(<name> [<type>] [EXCLUDE_FROM_ALL] <sources>...)
其中 type 用来指定构建库的类型【本篇 只针对 shared static 展开】
type
- shared
- static
- ...
使用库
# 路径配置相关 有时候需要
include_directories()
link_directories()
target_link_libraries() # 关键代码
代码部分
log/
|---|---|log.cpp
|---|---|log.h
|---|---|CMakeLists.txt
test_log/
|---|---|test_log.cpp
|---|---|CMakeLists.txt
CMakeLists.txt
log.h
// log.h
#ifndef LOG_H
#define LOG_H
class Log
{
public:
Log();
};
#endif
log.cpp
#include "log.h"
#include <iostream>
using namespace std;
Log::Log()
{
cout << "create Log" << endl;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(log)
add_library(log STATIC log.cpp log.h)
test_log 下
test_log.cpp
#include <iostream>
#include "log.h"
using namespace std;
int main()
{
Log log;
cout << "test log" << endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
project(test_log)
include_directories("../log") # 头文件路径
# 指定库查找路径 windows 自动找 ../log/build/Debug ../log/build/Release
link_directories("../log/build")
add_executable(test_log test_log.cpp)
#指定加载的库
target_link_libraries(test_log log)
构建静态库
type 指定的是 static
cd log
cmake -B build -S .
cmake --build build
cd test_log
cmake -B build -S .
cmake --build build
具体的还可以指定 lib的输出路径
动态库构建
我们 在 log 同级目录下 创建 CMakeLists.txt 内容如下
cmake_minimum_required(VERSION 3.20)
project(log)
include_directories(log)
# 添加log库编译 项目自带预处理变量 log_EXPORTS
add_library(log SHARED log/log.cpp)
add_executable(test_log test_log/test_log.cpp log)
target_link_libraries(test_log log)
windows下构建动态库存在问题
如果我们把 STATIC 改为 SHARED ,然后构建,发现会报错
LINK : fatal error LNK1104: 无法打开文件“Debug\log.lib”
其实 也就是 找不到.lib 文件
log.h 修改
// log.h
#ifndef LOG_H
#define LOG_H
// __declspec(dllexport) 导出 log 到lib文件中
#ifndef _WIN32
#define CPP_API
#else
// 针对 windows 平台
// log 库文件调用 dllexport
// test_log 调用 dllimport
// 通过预定义宏 确定是谁在调用
#ifdef log_EXPORTS
#define CPP_API __declspec(dllexport) // 库项目调用
#else
#define CPP_API __declspec(dllimport) // 调用库项目 调用
#endif
#endif
class CPP_API Log
{
public:
Log();
};
#endif
需要将 dll 中定义的 函数、类符号 等导出到lib 才能找到 【也就是 符号导出】
- dll 二进制代码
- lib 函数 符号 地址 【理解程度有限】
做法就是在 函数、类等 前面 添加 _declspec(dllexport),
关于 dllexport dllimport 的更详细解释,推荐这个
https://zhuanlan.zhihu.com/p/680966160
然后进行构建,成功!
【CMake系列】05-静态库与动态库编译的更多相关文章
- C++ 系列:静态库与动态库
转载自http://www.cnblogs.com/skynet/p/3372855.html 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择 ...
- (转)HelloWorld CMake CMake中构建静态库与动态库及其使用
继续完善Hello World,建立它的共享库, 包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc 向终端输出Hello ...
- VisualGDB系列7:使用VS创建Linux静态库和动态库
根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何在VS中创建静态库和动态库, ...
- C++静态库与动态库
C++静态库与动态库 这次分享的宗旨是--让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...
- 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库
最近在编写的一个Apache kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a 静态库编译的,,,而我们这 ...
- (转)C++静态库与动态库
转自:http://www.cnblogs.com/skynet/p/3372855.html C++静态库与动态库 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别, ...
- 【转】C++静态库与动态库
C++静态库与动态库 这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一 ...
- C++静态库与动态库(比较透彻)
这次分享的宗旨是——让大家学会创建与使用静态库.动态库,知道静态库与动态库的区别,知道使用的时候如何选择.这里不深入介绍静态库.动态库的底层格式,内存布局等,有兴趣的同学,推荐一本书<程序员的自 ...
- C++静态库与动态库详解
1 库的概念? 库是写好的现有的,成熟的,可以复用的代码.现实中每个程序都要依赖很多基础的底层库. 2 动态库与静态库的概念? 先回顾一下编译过程: 2.1 静态库 静态库在链接阶段,会将汇编生成的目 ...
- Windows下静态库、动态库的创建和调用过程
静态库和动态库的使用包括两个方面,1是使用已有的库(调用过程),2是编写一个库供别人使用(创建过程).这里不讲述过多的原理,只说明如何编写,以及不正确编写时会遇见的问题. //注:本文先从简单到复杂, ...
随机推荐
- XIP技术与Flash
XIP技术与Flash 参考: 串行NAND Flash的两大特性导致其在i.MXRT FLASH控制器下无法XiP norflash芯片内执行(XIP) NOR Flash 和 NAND Flash ...
- LLM并行训练4-megascale论文学习
算法优化 并行注意力机制 \[串行版本: y = x + MLP(LayerNorm(x + Attention(LayerNorm(x)))) \] \[并行版本: y = x + MLP(Laye ...
- 2-SET详解
前置知识 SET问题的标准定义:在计算机科学中,布尔可满足性问题(有时称为命题可满足性问题,缩写为SATISFIABILITY或SAT)是确定是否存在满足给定布尔公式的解释的问题.(全是废话) 说人话 ...
- QEMU + Vscode + Arm Arch's Linux调试小记
QEMU + Vscode + Arm Arch's Linux调试小记 前几天看到了一篇讲授如何调试ARM Linux内核的文章,这里现在记录一下调试ARM Linux内核的办法 下载QEMU ...
- Dawwin首位人工智能编程师,未来又会怎么样?
Darwinai是一家快速发展的视觉质量检测公司,为制造商提供端到端解决方案,以提高产品质量并提高生产效率.该公司的专利可解释人工智能(XAI)平台已被众多财富500强公司采用,可以轻松集成值得信赖的 ...
- 2024秋招西山居游戏开发SEED种子实习笔试题
西山居游戏开发SEED种子实习 2024年秋招笔试题目,仅供参考,请大佬多多指教 选择题 逆波兰数,TCP,操作系统FIFO,C语言大小端 填空题 一道LUA脚本写结果,一道并发存储优化题,计算机系统 ...
- 安装和引入方式在Element UI (Vue 2)和Element Plus (Vue 3)中的不同
安装和引入方式 Element UI (Vue 2): // main.js import Vue from 'vue'; import ElementUI from 'element-ui'; im ...
- oeasy教您玩转python - 007 - # 字符本质
字符本质 回忆上次内容 hello world 不是从来就有的 来自于unix和c 虽然我们今天有各种先进的学习手段 最早的高级语言学习是从最早的那张打字机用纸的手写代码起源的 所以输出用的是 p ...
- 使用 useLazyFetch 进行异步数据获取
title: 使用 useLazyFetch 进行异步数据获取 date: 2024/7/20 updated: 2024/7/20 author: cmdragon excerpt: 摘要:&quo ...
- Linux podman容器实验
要求 1.登录到指定的镜像仓库拉取镜像 2.以普通用户contsvc运行 3.配置 systemd-journald 服务,要求永久保留日志数据(物理机,创建文件mkdir /var/log/jour ...