cmake 编译教程

news2024/9/19 16:58:34

 一、只有一个源文件的程序编译

首先在当前目录下创建两个文件
hello.cpp
CMakeLists.txt (注意CMakeLists大小写,不要写错了)
cmake_minimum_required (VERSION 2.8)
 
project (learn_cmake)
 
add_executable(hello hello.cpp)
  • 第一行意思是cmake最低版本要求2.8,
  • 第二行是本项目的工程名
  • 第三行:第一个变量:要生成的可执行文件名为hello,后面的参数是需要的依赖。
接着在当前目录下执行 cmake . 接着会发现目录下多生成了一些文件,例如Makefile,然后使用GNU make命令来编译程序,会生成可执行程序。

二、同一目录下多个源文件

此时在当前目录新增两个依赖,并mian函数的执行需要依赖这两个文件

add.cpp

add.h

只需要在CMakeLists.txt中添加所依赖的.cpp文件,编译步骤和上面相同。

cmake_minimum_required (VERSION 2.8)
 
project (learn_cmake)
 
add_executable(hello hello.cpp myadd.cpp)

三、同一目录下很多源文件


如果同一目录下有无穷多源文件,那么一个一个添加就很慢了。此时可以使用cmake中的函数存储这些源文件

aux_source_directory(dir var)

他的作用是把dir目录中的所有源文件都储存在var变量中

然后需要用到源文件的地方用 变量var来取代

此时 CMakeLists.txt 可以这样优化

cmake_minimum_required(VERSION 2.8)

project(learn_cmake)

aux_source_directory(. SRC_LIST)

add_executable(hello ${SRC_LIST})

四、头文件在别的文件夹

对于集中的头文件,CMake提供了一个很方便的函数

include_directories ( dir )

他的作用是 自动去dir目录下寻找头文件,相当于 gcc中的 gcc -I dir

此时 CMakeLists.txt 可以这样优化

cmake_minimum_required(VERSION 2.8)

project(learn_cmake)

aux_source_directory(. SRC_LIST)

include_directories(./inc_dir)

add_executable(hello ${SRC_LIST})

 五、头文件源文件分离,并含有多个文件夹

假如说当前的工程目录是这样的,头文件和源文件分离,并含有多个文件夹

此时 CMakeLists.txt 可以这样优化

cmake_minimum_required(VERSION 2.8)

project(learn_cmake)

aux_source_directory(src_dir1 SRC_LIST1)
aux_source_directory(src_dir2 SRC_LIST2)
aux_source_directory(main_dir MAIN_DIR)

include_directories(./inc_dir1 ./inc_dir2)

add_executable(hello ${SRC_LIST1} ${SRC_LIST2} ${MAIN_DIR})

六、生成动态库和静态库

假如说当前的项目目录是这样的

  • inc目录下存放头文件
  • src目录下存放源文件
  • lib目录下存放生成的库
  • build目录下存放构建项目相关的文件,如CMakeLists.txt。而稍后我们也在这个目录下执行cmake和make

 

 此时 CMakeLists.txt 可以这样优化

cmake_minimum_required(VERSION 2.8)

project(learn_lib)

#整合源文件
aux_source_directory(${PROJECT_BINARY_DIR}/../src SRC_LIST)

#引入头文件路径
include_directories(${PROJECT_BINARY_DIR}/../inc)

#生成静态库或者动态库 参数1:生成的库的名称 参数2:静态或动态 参数3:生成库所需要的源文件
add_library(func_shared SHARED ${SRC_LIST})
add_library(func_static STATIC ${SRC_LIST})

#设置最终生成的库的名称
set_target_properties(func_shared PROPERTIES OUTPUT_NAME "myfunc")
set_target_properties(func_static PROPERTIES OUTPUT_NAME "myfunc")

#设置生成的库的路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../lib)

开始编译:

  1. 在build目录下执行 cmake .
  2. 在build目录下执行 make
  3. 查看lib目录下是否生成库文件,

出现库文件就算编译成功

七、链接库文件

库文件目录结构如下:

  • lib目录下存放静态库和动态库
  • main_src目录下存放main函数相关的源文件
  • bin目录存放项目生成的可执行文件

 此时 CMakeLists.txt 可以这样写

cmake_minimum_required(VERSION 2.8)

project(learn_lib)

#整合源文件
aux_source_directory(${PROJECT_BINARY_DIR}/../main_src MAIN_SRC)

#引入头文件路径
include_directories(${PROJECT_BINARY_DIR}/../inc)

#生成静态库或者动态库 参数1:生成的库的名称 参数2:静态或动态 参数3:生成库所需要的源文件
add_library(func_shared SHARED ${SRC_LIST})
add_library(func_static STATIC ${SRC_LIST})

#设置最终生成的库的名称
set_target_properties(func_shared PROPERTIES OUTPUT_NAME "myfunc")
set_target_properties(func_static PROPERTIES OUTPUT_NAME "myfunc")

#设置生成的库的路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../lib)

#查找库文件 第一个参数:存储查找到的库文件 第二个参数:要查找的库文件 第三个参数:要查找的目录
find_library(FUNC_LIB myfunc ${PROJECT_BINARY_DIR}/../lib)

#设置可执行文件生成到哪里
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)

add_executable(hello ${MAIN_SRC})

target_link_libraries(hello ${FUNC_LIB})

八、如何选择动态库和静态库

选择生成动态库(Dynamic Link Library,DLL 在 Windows 上,Shared Object,.so 在 Unix/Linux 上,或 Dynamic Library,.dylib 在 macOS 上)还是静态库(Library Archive,.a 或 .lib)主要取决于以下几个因素:

动态库的优点:

  1. 资源占用: 动态库在多个程序间共享相同的代码,可以节省系统内存和磁盘空间,因为不需要为每个使用该库的应用程序复制整个库。
  2. 更新方便: 更新动态库时,所有依赖它的应用程序都会自动使用新版本,无需重新编译或分发应用程序。
  3. 模块化: 动态库可以更容易地实现模块化编程,允许在运行时加载或卸载库,增强程序的灵活性和扩展性。
  4. 性能: 尽管启动时可能需要一些额外的时间来解析动态库中的符号,但在频繁调用的情况下,动态链接可能会更快,因为它避免了静态链接中的冗余代码。

静态库的优点:

  1. 部署简单: 使用静态库的程序是自包含的,不需要在目标机器上存在额外的库文件。
  2. 可靠性: 不会受到“依赖地狱”问题的影响,即不会因为缺少动态库或者动态库版本不匹配而导致程序崩溃。
  3. 安全性: 避免了由于动态库被恶意替换而导致的安全风险。
  4. 兼容性: 特别是在嵌入式系统或资源受限的环境中,静态链接可以确保软件的完整性和最小化依赖。

选择策略:

  • 如果库的使用者需要减少最终可执行文件的分发复杂度,或者目标平台资源有限,静态库可能是更好的选择。
  • 如果库需要在多个应用之间共享,或者希望简化库的更新流程,动态库更为合适。

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

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

相关文章

基于R语言绘制GGE双标图4

参考资料: https://cran.r-project.org/web/packages/GGEBiplots/GGEBiplots.pdf 1、数据整理 使用GGEBiplots包绘制双标图,分析用数据是二维数据表(行表示品种或基因型,列表示试验点或环境)。当我们的数据表是一维数…

ip地址是公网还是内网?内网电脑ip地址在哪看

在数字化时代,IP地址作为网络设备的唯一标识符,扮演着至关重要的角色。然而,你是否知道IP地址是内网还是外网?对于内网电脑,我们又该如何快速准确地找到其IP地址呢?下面带着这些疑问跟着虎观代理小二一起深…

《python语言程序设计》2018版第6章第37题,随机生成字符,使用RandomCharacter生成100个小写字母,每行15个

一、正常输出方法设计的代码结构 老规矩用正常输出法设计代码结构 def getRandomCharacter(ch1, ch2):return chr(random.randint(ord(ch1), ord(ch2)))def getRandomLowerCaseLetter():return getRandomCharacter(a, z)count 0 for i in range(100):count 1a getRandomLowe…

深度学习实战(1):树叶分类pytorch

Classify Leaves | Kaggle 上面是数据集 数据导入与数据处理 %matplotlib inline import torch from torch.utils import data as Data import torchvision from torch import nn import torchvision.models as models from IPython import display import os import pandas…

leetcode69. x 的平方根,二分法

leetcode69. x 的平方根 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0…

培训第二十三天(mysql主从脚本与mysql详细语句介绍)

上午 在同步时,对删除和修改都比较慎重(监控同步时) mysql主从搭建 前提软件libaio,rsync 1、主2、从3、同步4、测试 注意:先执行从服务器的脚本,再执行主服务器脚本 master-mysql配置脚本 先要在主服务…

企元数智小程序合规分销系统赠送:迎接数字化时代商机

当今时代,随着科技的高速发展和数字化的普及,企业如何抓住数字化时代带来的商机,成为了业界关注的焦点。在这样一个竞争激烈的市场环境下,企业需要不断提高自身的竞争力和应变能力,以应对激烈的市场竞争,开…

Phpstorm实现本地SSH开发远程机器(或虚拟机)项目

适用场景: 1、windows系统想要运行仅支持linux、mac系统的项目,可将项目运行在本地虚拟机,但是在虚拟机里使用vim编辑很麻烦,如何实现在本地用Phpstorm来编辑虚拟机中的代码? 下面的说明都是以本地虚拟机为例&#xff…

java之拼图小游戏(开源)

public class LoginJFrame extends JFrame {//表示登录界面,以后所有跟登录相关的都写在这里public LoginJFrame() {//设置界面的长和宽this.setSize(603,680);//设置界面的标题this.setTitle("拼图登陆界面");//设置界面置顶this.setAlwaysOnTop(true);/…

科研绘图系列:R语言圆形条形图(circular barplot)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 介绍 圆形条形图(circular barplot)是一种条形图,其中的条形沿着圆形而不是线性排列展示。这种图表的输入数据集与普通条形图相同:每个组(一个组即一个条形)需要一个数值。(更多解释请参…

linux文件查找--locate和find命令详解

在文件系统上查找符合条件的文件 文件查找:1.非实时查找(数据库查找):locate2.实时查找: find应用:生产环境中查找到系统中占用磁盘空间较大且时间比较久的大日志文件,对这个较大的日志文件做处理(删除移走等),防止它占用更多的磁…

gps 轨迹点如何绘制路径

作为用户,我们进行户外运动后,有的人喜欢分享自己的运动记录。这个时候就比较关注自己的运动轨迹路线了。 一.将经纬度转化为轨迹方法1 1.将gps 打点文件导出。 2.将经纬度点转换成如下格式。 3.将转换后的经纬度填入如下地址: https://ww…

必了解的 20 个 AI 术语解析(下)

AI 领域的基础概念和相关技术有很多,这篇文章里,作者就深入浅出地介绍了相应的内容,感兴趣的同学们,不妨来看一下。 必了解的 20 个 AI 术语解析(下)© 由 ZAKER科技 提供 本文专为非技术背景的 AI 爱…

如何修改360免费wifi热点的频带为2.4G或者5G

有的时候使用电脑广播出热点给嵌入式设备用进而进行抓包,但是他默认广播的是5G Hz的,嵌入式设备扫不到热点。那么如何让他广播2.4G H在呢? CMD控制台使用命令netsh wlan show drivers查看设备驱动: 802.11g 和 802.11n 意味着你的…

Python酷库之旅-第三方库Pandas(071)

目录 一、用法精讲 286、pandas.Series.dt.to_pydatetime方法 286-1、语法 286-2、参数 286-3、功能 286-4、返回值 286-5、说明 286-6、用法 286-6-1、数据准备 286-6-2、代码示例 286-6-3、结果输出 287、pandas.Series.dt.tz_localize方法 287-1、语法 287-2、…

Selenium 自动化测试最佳实践

1 编码前的准备工作与基本指导思想 测试一个网站就是针对该网站测试场景的一次项目开发,所以项目开发中的理念与思想可以借鉴过来。接到测试需求后,不要一开始就陷入按钮、字段、下拉框等页面元素怎么操作的技术细节当中,而要站在最终用户的…

《MySQL数据库》 可视化工具的使用—/—<3>

一、如何使用可视化工具navicat 1、点击左上角的连接中的MySQL 输入主机地址连接虚拟机,找到自己虚拟机中的ip地址输入即可,连接名随意修改 然后点击测试连接,连接成功即可点击确定 2、新建库 直接鼠标右击连接名称ahao001,点击…

react学习笔记:7

预览:(fetch发送请求、SPA、连续解构赋值、消息订阅、react router路由第三方库) 1、连续解构赋值 总结: 1、连续解构赋值的写法:对象包对象,第二个解构的value一定也是在{}内部的写法 2、消息订阅发布 …

SwiftUI 中 TabView 视图导航栏上按钮丢失问题的解决

问题现象 在某些情况下,SwiftUI 中 TabView 子视图中导航栏上的 ToolbarItem 会消失不见。 如上图所示:在子视图的 Kick Off 导航栏按钮被按下并回退到 TabView 中的主视图之后,其右上角的按钮竟然“神奇”的消失了!该如何解决它呢? 在本篇博文中,您将学到以下内容 问题…

【二分查找】3143. 正方形中的最多点数

本文涉及的基础知识点 C二分查找 LeetCode3143. 正方形中的最多点数 给你一个二维数组 points 和一个字符串 s ,其中 points[i] 表示第 i 个点的坐标,s[i] 表示第 i 个点的 标签 。 如果一个正方形的中心在 (0, 0) ,所有边都平行于坐标轴&…