【项目构建】04:动态库与静态库制作

OVERVIEW

      • 1.编译动态链接库
        • (1)编译动态库
        • (2)链接动态库
        • (3)运行时使用动态库
      • 2.编译静态链接库
        • (1)编译静态库
        • (2)链接静态库
        • (3)运行时使用静态库
      • 3.make install

1.编译动态链接库

动态链接库:不会把代码编译到二级制文件中,而是在运行时才去加载,所以只需要维护一个地址即可,

动态库编译完成之后需要发布,否则程序运行时找不到,

windows环境下动态库为.dll、linux环境下动态库为.so

  1. 编译成 .o 文件:g++ -c -fpic soTest.cpp -o soTest.o

  2. 编译动态库:g++ -shared soTest.o -o libsoTest.so

    • -c:得到二进制文件aTest.o
    • -shared:共享
    • -fPIC:产生位置无关的代码,
    • -l:小写l,指定动态库,
    • -L:手动指定库文件搜索目录,默认只链接共享目录,
    • -I:大写i,指定头文件目录(默认当前目录),
  3. 链接成执行文件:

    g++ [.cpp] -l [libName] -L [libPath] -o [test.out]

g++ soTest.cpp -shared -fPIC -o libsoTest.so
(1)编译动态库

文件目录结构如下,将其打包成动态库,

在这里插入图片描述

// soTest.h
#ifndef _SOTEST_H
#define _SOTEST_H#include <iostream>
using namespace std;class soTest {
public:void func1();virtual void func2();virtual void func3() = 0;
};#endif
// soTest.cpp
#include "soTest.h"void soTest::func1()
{cout << "this is func1" << endl;
}void soTest::func2()
{cout << "this is func2" << endl;
}
# makefile
libsoTest.so:$(CXX) soTest.cpp -shared -fPIC -L ./ -o libsoTest.so
clean:$(RM) libsoTest.so

使用make libsoTest.so 命令成功完成对 libsoTest.so 动态库的打包操作,

(2)链接动态库

在动态库成功打包出来之后,在其他项目中通过引入 soTest.hlibsoTest.so文件,来使用打包好的动态库,

文件目录结构如下,将第三方动态库动态载入,编译自己的项目,

在这里插入图片描述

//test.cpp
#include <iostream>
#include "soTest.h"
using namespace std;class Test:public soTest{
public:void func2() {cout << "Test:this is func2" << endl;}void func3() {cout << "Test:this is func3" << endl;}
};int main() {Test t1;t1.func1();t1.func2();t1.func3();return 0;
}
# makefile
test:$(CXX) test.cpp -lsoTest -L ./ -I ./ -o test.out
clean:$(RM) *.out

使用make test 命令成功完成第三方动态库的链接,编译成功目录下出现 test.out 的可执行文件,

(3)运行时使用动态库

由于动态库的特点,若只在编译时使用的动态库,而运行时没有指定动态库位置,则程序将无法正常运行,

即动态库编译完成之后需要进行发布操作,否则程序运行时会找不到动态库位置而产生报错,如下所示:

./a.out: error while loading shared libraries: libsoTest.so: cannot open shared object file: No such file or directory
  • 解决方案1:将动态库so文件拷贝到对应的目录下(发布),才能运行程序

    • linux下默认动态库路径配置文件:/etc/ld.so.conf/etc/ld.so.conf.d/*.conf

    • /usr/lib

    • /usr/local/lib

  • 解决方案2:运行时手动指定动态库的所在目录

    mac环境:

    • DYLD_LIBARY_PATH=./your_lib_path
    • export DYLD_LIBARY_PATH

    linux环境:

    • LD_LIBARY_PATH=./your_lib_path
    • export LD_LIBARY_PATH

在这里插入图片描述

2.编译静态链接库

静态链接库:会将库中的代码编译到二进制文件中,当程序编译完成后,该库文件可以删除,

与静态库不同的是,动态链接库必须与程序同时部署,还要保证程序能正常加载得到的库文件。静态库可以不用部署已经加载到程序中,而且运行时的速度更快,

但是会导致程序体积更大,并且库中的内容如果有更新,则需要重新编译生成程序,

windows环境下动态库为.lib、linux环境下动态库为.a

  1. 编译成 .o 文件:g++ -c aTest.cpp -o aTest.o

  2. 编译静态库:ar -r libaTest.a aTest.o

    • -c:得到二进制文件aTest.o
    • ar:备份压缩命令,将目标文件打包成静态链接库,
    • -r:将文件插入备存文件中,
  3. 链接成执行文件:

    g++ [.cpp] [.a] -o [test.out]

    g++ [.cpp] -l [libName] -L [libPath] -o [test.out]

(1)编译静态库

文件目录结构如下,将其打包成静态库,

在这里插入图片描述

// aTest.h
#ifndef _ATEST_H
#define _ATEST_H#include<iostream>
using namespace std;class aTest{
public:void func1();
};#endif
// aTest.cpp
#include "aTest.h"void aTest::func1()
{cout << "aTest:func1" << endl;
}
# makefile
libaTest.a:$(CXX) -c aTest.cpp -L ./ -I ./ -o aTest.o$(AR) -r libaTest.a aTest.o
clean:$(RM) *.a *.o

使用make libaTest.a 命令成功完成对 libaTest.a 静态库的打包操作,

(2)链接静态库

在静态库成功打包出来之后,在其他项目中通过引入 aTest.hlibaTest.a文件,来使用打包好的静态库,

文件目录结构如下,将第三方静态库动态载入,编译自己的项目,

在这里插入图片描述

// test.cpp
#include <iostream>
#include "aTest.h"
using namespace std;int main() {aTest t1;t1.func1();return 0;
}
# makefile
test:$(CXX) test.cpp -laTest -L ./ -I ./ -o test.out
clean:$(RM) *.out 

使用make test 命令成功完成第三方静态库的链接,编译成功目录下出现 test.out 的可执行文件,

(3)运行时使用静态库

由于静态库的特点,在编译时已经将库中的代码编译到二进制文件中,当编译完成后,该库文件可以删除,并且程序可以直接运行,

在这里插入图片描述

3.make install

  1. make,编译链接:

    将源文件,编译成二进制的可执行文件(包括各种库文件)

  2. make install,配置相关的运行环境:

    创建目录,将可执行文件拷贝到指定目录(安装目录)

    加全局可执行的路径

    加全局的启动停止脚本

  3. make clean

    重置编译环境,删除无关文件

TARGET:=my_test
OBJ:=$(TARGET).osCC:=g++PATHS:=/tmp/test/
BIN:=/usr/local/bin/START_SH:=$(PATHS)$(TARGET)
STOP_SH:=$(PATHS)$(TARGET)$(TARGET):$(OBJ)install:$(TARGET)if [ -d $(PATHS) ];						\then echo $(PATHS) exist;			\else 									\mkdir $(PATHS);						\cp $(TARGET) $(PATHS);				\ln -sv $(PATHS)$(TARGET) $(BIN);	\touch $(LOG);						\chmod a+rwx $(LOG);					\echo "$(TARGET)>$(LOG) & echo $(TARGET) running...">$(PATHS)$(START_SH);	\echo "killall $(TARGET)">$(PATHS)$(START_SH); 								\chmod a+x $(PATHS)$(START_SH);												\chmod a+x $(PATHS)$(STOP_SH);												\ln -sv $(PATHS)$(START_SH) $(BIN);											\ln -sv $(PATHS)$(STOP_SH) $(BIN);											\fi;clean:$(RM) $(TARGET) $(OBJ) $(BIN)$(TARGET) $(BIN)$(START_SH) $(BIN)$(STOP_SH)$(RM) -rf $(PATHS).PHONY:clean install

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

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

相关文章

【链表——数据结构】

文章目录 1.单链表1.定义2.基本操作2.1.不带头结点2.2后插2.3前插2.4删除2.5按位查找2.6按值查找2.7求单链表长度2.8 建表 2.双链表1.初始化2.插入(后插)3.删除(后删)4.遍历 3.循环链表1.循环单链表2.循环双链表3.代码问题 4.静态链表1.简述基本操作的实现1.初始化3.删除某个结…

学习Rust的第21天:mini_grep第1部分

在本文中&#xff0c;我们开始用 Rust 构建一个类似 grep 的程序。我们涵盖了读取命令行参数、读取文件内容&#xff0c;并开始通过将程序构造为函数和结构体来重构程序。 Introduction 介绍 Running the following command will create a new project 运行以下命令将创建一个新…

应急学院物联网应急安全产教融合基地解决方案

第一章 背景 1.1物联网应急安全产教融合发展概况 物联网应急安全产教融合发展是当前社会发展的重要趋势。随着物联网技术的广泛应用&#xff0c;应急安全领域对人才的需求日益迫切。因此&#xff0c;产教融合成为培养高素质、专业化人才的关键途径。在这一背景下&#xff0c;…

02.Kafka部署安装

1 Linux 安装 Kafka 1.1 安装前的环境准备 由于 Kafka 是用 Scala 语言开发的&#xff0c;运行在 JVM 上&#xff0c;因此在安装Kafka之前需要先安装JDK。 yum install java-1.8.0-openjdk* -y kafka 依赖 zookeeper&#xff0c;所以需要先安装 zookeeper。 wget https://ar…

LLM优化:开源星火13B显卡及内存占用优化

1. 背景 本qiang~这两天接了一个任务&#xff0c;部署几个开源的模型&#xff0c;并且将本地经过全量微调的模型与开源模型做一个效果对比。 部署的开源模型包括&#xff1a;星火13B&#xff0c;Baichuan2-13B, ChatGLM6B等 其他两个模型基于transformers架构封装&#xff0…

表单提交出现问题却没有报错

最近搞毕设提交表单传给后台总是出现错误&#xff0c;有时候可以运行成功&#xff0c;有时候运行不了但是没有报错&#xff0c;以为是jQuery导入的问题尝试换了jQuery的其他导入方式没有解决&#xff0c;后来发现前端页面的表单要防止默认操作&#xff01;&#xff01;&#xf…

qt学习篇---C++基础学习

本学习笔记学习下面视频总结&#xff0c;感兴趣可以去学习。讲的很详细 【北京迅为】嵌入式学习之QT学习篇_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1tp4y1i7EJ/?spm_id_from333.337.search-card.all.click&vd_source8827cc0da16223b9f2ad8ae7111de9e2 目录 C…

PDCA循环:持续精进的工具

文章目录 一、什么是PDCA二、PDCA的应用场景三、PDCA在信息系统项目管理中的应用 一、什么是PDCA PDCA循环是由美国质量管理专家沃特阿曼德休哈特&#xff08;Walter A. Shewhart&#xff09;在20世纪30年代提出的&#xff0c;最初用于制造业的质量管理。休哈特博士在构想PDCA…

【C++题解】1418. 求一个5位数的各个位之和

问题&#xff1a;1418. 求一个5位数的各个位之和 类型&#xff1a;基本运算、拆位求解 题目描述&#xff1a; 从键盘读入一个 5 位的正整数&#xff0c;请求出这个 5 位数的各个位之和。 输入&#xff1a; 一个 5 位的正整数 n 。 输出&#xff1a; 这个 5 位数的各个位之…

Aiseesoft Blu-ray Player for Mac:蓝光播放器

Aiseesoft Blu-ray Player for Mac是一款功能强大且易于使用的蓝光播放器&#xff0c;专为Mac用户打造。它以其卓越的性能和简洁的操作界面&#xff0c;为用户带来了全新的高清蓝光播放体验。 Aiseesoft Blu-ray Player for Mac v6.6.50激活版下载 这款软件支持播放任何高质量的…

ArcGIS Pro3.0软件破解版安装教程

软件名称&#xff1a;ArcGIS Pro 3.0 安装环境&#xff1a;Windows 软件大小&#xff1a;7.3GB 硬件要求&#xff1a;CPU2GHz&#xff0c;内存4G(或更高) 百度云下载链接 &#xff1a; https://pan.baidu.com/s/1CXy1MSwdQXdVnJoV2X422A 提 取 码 &#xff1a;r0w1 教学内…

AI图书推荐:ChatGPT写论文的流程与策略

论文一直是任何学术学位的顶峰。它展示了学生在研究领域的兴趣和专业知识。撰写论文也是一个学习经验&#xff0c;为学术工作以及专业研究角色做好准备。但是&#xff0c;论文工作总是艰苦的&#xff0c;通常是充满乐趣和创造性的&#xff0c;但有时也是乏味和无聊的。生成式人…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-6.4

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

采用前后端分离Vue,Ant-Design技术开发的(手麻系统成品源码)适用于三甲医院

开发环境 技术架构&#xff1a;前后端分离 开发语言&#xff1a;C#.net6.0 开发工具&#xff1a;vs2022,vscode 前端框架&#xff1a;Vue,Ant-Design 后端框架&#xff1a;百小僧开源框架 数 据 库&#xff1a;sqlserver2019 系统特性 麻zui、护理、PACU等围术期业务全覆…

FreeRTOS学习——FreeRTOS队列(上)

本篇文章记录我学习FreeRTOS队列的相关知识&#xff0c;主要包括队列简介、队列的结构体、队列创建等知识。 队列是为了任务与任务、任务与中断之间的通信而准备的&#xff0c;可以在任务与任务、任务与中断之间传递消息&#xff0c;队列中可以存储有限的、大小固定的数据项目。…

Android 在attrs.xml添加属性时出现 Found item Attr/****** more than one time

Android 在attrs.xml添加属性时出现 Found item Attr/****** more than one time 问题描述解决办法方式一方式二 小结 问题描述 在Android应用开发过程中&#xff0c;经常需要自定义控件&#xff0c;并且定义控件的属性&#xff0c;方便灵活的修改控件的显示样式&#xff0c;提…

IT廉连看——UniApp——样式绑定

IT廉连看——UniApp——样式绑定 一、样式绑定 两种添加样式的方法&#xff1a; 1、第一种写法 写一个class属性&#xff0c;然后将css样式写在style中。 2、第二种写法 直接把style写在class后面 添加一些效果&#xff1a;字体大小 查看效果 证明这样添加样式是没有问题的…

【提示学习论文】PMF:Efficient Multimodal Fusion via Interactive Prompting论文原理

Efficient Multimodal Fusion via Interactive Prompting&#xff08;CVPR2023&#xff09; 基于交互式提示的高效多模态融合方法减少针对下游任务微调模型的计算成本提出模块化多模态融合架构&#xff0c;促进不同模态之间的相互交互将普通提示分为三种类型&#xff0c;仅在单…

websocket 单点通信,广播通信

Websocket协议是对http的改进&#xff0c;可以实现client 与 server之间的双向通信&#xff1b; websocket连接一旦建立就始终保持&#xff0c;直到client或server 中断连接&#xff0c;弥补了http无法保持长连接的不足&#xff0c;方便了客户端应用与服务器之间实时通信。 参…

大数据005-hadoop003-了解MR及Java的简单实现

了解MapReduce MapReduce过程分为两个阶段&#xff1a;map阶段、reduce阶段。每个阶段搜键-值对作为输入和输出。 要执行一个MR任务&#xff0c;需要完成map、reduce函数的代码开发。 Hellow World 【Hadoop权威指南】中的以分析气象数据为例&#xff0c;找到每年的最高气温。…