cmake制作并链接动静态库

news2024/11/20 23:14:05

cmake制作并链接动静态库

  • 制作静态库
    • add_library(库名称 STATIC 源文件1 [源文件2] ...)
    • LIBRARY_OUTPUT_PATH指定库的生成路径
  • 制作动态库
    • add_library(库名称 SHARED 源文件1 [源文件2] ...)
  • 连接动静态库
    • link_libraries连接静态库
    • link_directories到哪个路径去找库
    • target_link_libraries连接动态库
  • find_library

之前我们已经了解了cmake的一些基本操作,如果还有小伙伴不了解cmake是什么,可以点击这里:

(https://blog.csdn.net/qq_67693066/article/details/136658388)[https://blog.csdn.net/qq_67693066/article/details/136658388]

今天我们要了解的如何利用cmake制作动静态库并链接他们:

制作静态库

首先我们先制作一些头文件:
在这里插入图片描述

#pragma once
#include<iostream>

int add(int x,int y);

#pragma once
#include<iostream>

int my_div(int x,int y);

#pragma once
#include<iostream>

int mul(int x,int y);

#pragma once
#include<iostream>

int sub(int x,int y);

然后在对应的cpp文件中实现:
在这里插入图片描述

#include"my_add.h"

int add(int x,int y)
{
    return x + y;
}
#include"my_div.h"

int my_div(int x,int y)
{
    if(y == 0)
    {
        perror("y is zero");
        exit(EXIT_FAILURE);
    }

    return x / y;
}
#include"my_mul.h"

int mul(int x,int y)
{
    return x * y;
}
#include"my_sub.h"

int sub(int x,int y)
{
    return x - y;
}

这里注意一下,我们制作动静态库不需要对应的入口函数,只需要对应头文件和相应的实现。

然后我们编写一个基本的CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)

project(Mylibrary)

aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件

include_directories(include) # 包括头文件

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

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

是用来制作静态库的命令:

cmake_minimum_required(VERSION 3.0)

project(Mylibrary)

aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件

include_directories(include) # 包括头文件


add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取

我们来运行一下:
在这里插入图片描述
这个时候,我们的build目录下会多一个libcalc.a的静态库:
在这里插入图片描述

LIBRARY_OUTPUT_PATH指定库的生成路径

我们可以用LIBRARY_OUTPUT_PATH指定库的生成路径:

cmake_minimum_required(VERSION 3.0)

project(Mylibrary)

aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件

include_directories(include) # 包括头文件

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) # 库生成在根目录下的lib目录下

add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取

在这里插入图片描述
我们可以到lib目录下找到我们的库文件:
在这里插入图片描述

制作动态库

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

其实和静态库的方法差不多,只不过把STATIC换成了SHARED:

cmake_minimum_required(VERSION 3.0)

project(Mylibrary)

aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC) # 在对应的文件下搜索所有的源文件

include_directories(include) # 包括头文件

set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) # 库生成在根目录下的lib目录下

add_library(calc SHARED ${MY_SRC}) # 生成动态库

# add_library(calc STATIC ${MY_SRC}) # 库名称为calc,源文件从MY_SRC中提取

在这里插入图片描述在这里插入图片描述

连接动静态库

首先我们创建一个新的文件夹,然后进去:
在这里插入图片描述使用对应的库的时候要首先把它对应的头文件包括进来,所以我们把对应的头文件拷贝到这个新的文件夹下:
在这里插入图片描述在这里插入图片描述
然后把对应的库拿过来:
在这里插入图片描述在这里插入图片描述
然后我们创建自己的src文件,build文件来管理:
在这里插入图片描述
还有CMakeLists.txt:

在这里插入图片描述

在这里插入图片描述
首先我们要在CMakeLists.txt中包括我们的头文件,因为这是我们自己写的第三方库,所以我们要显示的写:

project(MyTest)

include_directories(${PROJECT_SOURCE_DIR}/include) # 包括头文件

link_libraries连接静态库

我们可以用link_libraries连接静态库,这里静态库的名字可以是全名 libxxx.a
也可以是掐头(lib)去尾(.a)之后的名字 xxx

link_libraries(<static lib> [<static lib>...])
project(MyTest)

include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件

# 连接静态库
link_libraries(calc)

但是这个是我们自己写的第三方库,可能出现找不到的情况,所以我们要告诉cmake到哪里去找:

link_directories到哪个路径去找库

我这里的库是放在lib下的,所以可以这样写:

project(MyTest)

include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件

# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)

# 到这个路径下找库
link_directories(${PROJECT_SOURCE_DIR}/lib)

# 连接静态库
link_libraries(calc)

# 生成可执行文件
add_executable(mytest ${MY_SRC})

然后在main函数里编写:

#include"my_add.h"

int main()
{
    std::cout << add(2,3) << std::endl;

    return 0;
}

在这里插入图片描述
我们可以测试一下:
在这里插入图片描述

target_link_libraries连接动态库

动态库的链接和静态库是完全不同的:

target_link_libraries(
    <target> 
    <PRIVATE|PUBLIC|INTERFACE> <item>... 
    [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

静态库会在生成可执行程序的链接阶段被打包到可执行程序中,所以可执行程序启动,静态库就被加载到内存中了。
动态库在生成可执行程序的链接阶段不会被打包到可执行程序中,当可执行程序被启动并且调用了动态库中的函数的时候,动态库才会被加载到内存

因此,在cmake中指定要链接的动态库的时候,应该将命令写到生成了可执行文件之后,同时,这是我们自己写的第三方库,所以也要告诉cmake到哪里去找库:

project(MyTest)

include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件

# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)

# 到这个路径下找库
link_directories(${PROJECT_SOURCE_DIR}/lib)

# 连接静态库
#link_libraries(calc)

# 生成可执行文件
add_executable(mytest ${MY_SRC})

# 链接动态库
target_link_libraries(mytest calc) # 将calc链接到mytest中

在这里插入图片描述

find_library

寻找库文件,不仅可以用link_directories还可用find_library:

find_library() 是 CMake 中的一个内置命令,用于在系统中查找指定库文件的路径。这个命令主要用于那些不提供标准 CMake 配置文件(如 calcConfig.cmake 或 calc-config.cmake)的库,或者在需要更精细控制库查找过程的场景中。以下是 find_library() 命令的基本用法、参数和示例:

find_library(<variable>
             NAMES <name1> [<name2> ...]
             HINTS <hint1> [<hint2> ...]
             PATHS <path1> [<path2> ...]
						...])
  • <variable>: 存储找到的库文件路径的变量名。如果找到库,该变量将被设置为库文件的全路径;否则,变量将保留未定义状态或被设置为空字符串。
  • NAMES: 指定要查找的库文件名。通常包括库的基础名称(如 calc)和可能的后缀(如 .a.so.dll 等)。可以指定多个备选名称。
  • HINTSPATHS: 提供查找库文件的额外路径提示或直接路径。HINTS 的优先级高于 PATHS。这些路径将被添加到 CMake 的默认查找路径中。
project(MyTest)

include_directories(${PROJECT_SOURCE_DIR}/include) # 包括文件

# 源文件
aux_source_directory(${PROJECT_SOURCE_DIR}/src MY_SRC)

# 到这个路径下找库
# link_directories(${PROJECT_SOURCE_DIR}/lib)
find_library(CALC_LIBRARY NAMES calc PATHS "${PROJECT_SOURCE_DIR}/lib")

# 连接静态库
#link_libraries(calc)

# 生成可执行文件
add_executable(mytest ${MY_SRC})

# 链接动态库
target_link_libraries(mytest ${CALC_LIBRARY})

在这里插入图片描述

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

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

相关文章

ssh爆破服务器的ip-疑似肉鸡

最近发现自己的ssh一直有一些人企图使用ssh暴力破解的方式进行密码破解.就查看了一下,真是网络安全太可怕了. 大家自己的服务器密码还是要设置好,管好,做好最基本的安全措施,不然最后只能沦为肉鸡. ssh登陆日志可以在/var/log下看到,ubuntu的话为auth.log,centos为secure文件 查…

ubuntu 应用程序设置 开机自启动

1. 通过.desktop方式 autostart 中.desktop 配置文件 1.1 用户级自启动 登录后才可以启动服务。 可视化配置&#xff1a;在ubuntu自带的可视化程序来配置&#xff0c;就是StartupApplications&#xff0c;它在启动台中可以找到。 在ubuntu下目录是 ~/.config/autostart 添…

kotlin项目引用

概要&#xff1a; 记录项目引用kotlin具体事项 1 object下build.gradle buildscript {//声明引用版本ext.kotlin_version "1.4.20"repositories {google()mavenCentral()}dependencies {classpath "com.android.tools.build:gradle:4.2.0"//引用kotlinc…

DataX案例,MongoDB数据导入HDFS与MySQL

【尚硅谷】Alibaba开源数据同步工具DataX技术教程_哔哩哔哩_bilibili 目录 1、MongoDB 1.1、MongoDB介绍 1.2、MongoDB基本概念解析 1.3、MongoDB中的数据存储结构 1.4、MongoDB启动服务 1.5、MongoDB小案例 2、DataX导入导出案例 2.1、读取MongoDB的数据导入到HDFS 2…

Ubuntu去除烦人的顶部【活动】按钮

文章目录 一、需求说明二、打开 extensions 网站三、安装 GNOME Shell 插件四、安装本地连接器五、安装 Hide Activities Button 插件六、最终效果七、卸载本地连接器命令参考 本文所使用的 Ubuntu 系统版本是 Ubuntu 22.04 ! 一、需求说明 使用 Ubuntu 的过程中&#xff0c;屏…

【网络编程】高性能并发服务器源码剖析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之洪水网络攻击&#xff0c;在这篇文章中&#xff0c;你将会学习到在网络编程中如何搭建一个高性能的并发服务器&#xff0c;并且我会给出源码进行剖析&#xff0c;以及手绘UML图来帮助大家来理解&#xf…

机器学习—特征工程(三)

什么是特征工程 特征工程是使用专业背景知识和技巧处理数据&#xff0c;使得特征能在机器学习算法上发挥更好的作用的过程。 意义︰会直接影响机器学习的效果 特征工程的位置与数据处理的比较 pandas:—个数据读取非常方便以及基本的处理格式的工具sklearn:对于特征的处理提…

鹏哥C语言复习——数据存储

目录 版本差异&#xff1a; 数据类型&#xff1a; 进制表示&#xff1a; 大小端储存&#xff1a; 数据运算&#xff1a; 浮点型在内存中的存储&#xff1a; 版本差异&#xff1a; debug和release的区别&#xff1a; 在栈区开辟地址一般是先从高地址开辟 debug创建数组和单…

深度学习图像处理基础工具——opencv 实战2 文档扫描OCR

输入一个文档&#xff0c;怎么进行文档扫描&#xff0c;输出扫描后的图片呢&#xff1f; 今天学习了 opencv实战项目 文档扫描OCR 问题重构&#xff1a;输入图像 是一个含有文档的图像——> 目标是将其转化为 规则的扫描图片 那么怎么实现呢&#xff1f; 问题分解&#…

leetcode.45题:跳跃游戏II

Leetcode.45题&#xff1a;跳跃游戏II /* 题意的理解&#xff1a; nums[0] 只能跳 1 ~ nums[0]步 依次类推&#xff1a;从nums[0] - nums[n - 1] 最少需要多少步数 nums 2 3 1 1 4 nums[0] 2,初始只能跳 1/2步&#xff0c;如跳1步&#xff0c;达到nums[1] 而nums[1] 3,顾第二…

Python学习笔记22 - 文件操作

文件读写的原理 文件读写的操作 常用的文件打开模式 文件对象的常用方法 with语句&#xff08;上下文管理器&#xff09;

kubekey 离线安装harbor、k8s、kubesphere

目录 参考文献 了解kubekey 英文和中文 前提条件 部署准备 下载kubukey 离线包配置和制作 配置离线包 制作离线包 离线安装集群 复制KubeKey 和制品 artifact到离线机器 创建初始换、安装配置文件 安装镜像仓库harbor 初始化harbor 项目 修改配置文件 安装k8s集…

一.表单校验

为什么要表单验证&#xff1f; 是为了减轻服务器的压力&#xff0c;让用户体验更好&#xff0c;保证输入的数据符合要求 常用的表单验证 日期格式 表单元素是否为空 用户名和密码 E-mail 地址 身份证号码 实现验证的思路 问题&#xff1a;当输入的表单数据不符合要求时&…

内网渗透-windows权限维持的方法

windows权限维持的方法 文章目录 windows权限维持的方法一、影子账户二、粘滞键后门三、logon scripts后门五、注册表自启动后门六、屏幕保护程序后门七、计划任务后门八、服务自启动后门九、黄金票据十、白银票据十二、bitsadmin十五、CLR劫持 一、影子账户 1.使用如下命令创…

你真的会处理python代码异常吗?

Python 使用称为异常(exception&#xff09;的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时&#xff0c;它都会创建一个异常对象。如果你编写了处理该异常的代码&#xff0c;程序将继续运行&#xff1b;如果你未对异常进行处理&#xff0c;程序将停…

CodeGemma: Open Code Models Based on Gemma

最近几天&#xff0c;对大模型生成代码的能力比较感兴趣&#xff0c;特此学习了一下大模型怎么在IDE上进行&#xff0c;自动补全你想要的代码。 大模型源码理解-以Gemma为例子 最近也在使用阿里的通义灵码&#xff0c;感觉还挺好用的。通义灵码 摘要&#xff1a; CodeGemma基…

Linux ARM平台开发系列讲解(QEMU篇) 1.2 新添加一个Linux kernel设备树

1. 概述 上一章节我们利用QEMU成功启动了Linux kernel,但是细心的小伙伴就会发现,我们用默认的defconfig是没有找到设备树源文件的,但是又发现kernel启动时候它使用了设备树riscv-virtio,qemu,这是因为qemu用了一个默认的设备树文件,该章节呢我们就把这个默认的设备树文件…

【设计模式学习】单例模式和工厂模式

꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转…

明月三千里许红:25年磨一剑 拒绝网红式短期主义

这是一个关于明月三千里烤肉品牌如何在25年企业经营风口浪尖中&#xff0c;寻求长久生存和发展的故事&#xff1b;也是一个关于明月三千里烤肉品牌如何在25年中追逐流量的同时&#xff0c;不失去初心和品质的深度思考&#xff01; 在当今快速变化的餐饮市场中&#xff0c;淄博烤…

【CSS】利用Vue实现数字翻滚动画效果

利用Vue实现数字翻滚动画效果 在很多数据可视化的需求中&#xff0c;动态呈现数据变化是一个常见且具有较强视觉冲击力的手段&#xff0c;尤其是数字的实时变化。今天我们将探讨如何使用 Vue.js 和 CSS3 来实现数字的翻滚动画效果&#xff0c;即模拟真实物体在Z轴上翻动的效果…