cmake原理

CMake原理与快速入门

CMake是一个跨平台构建(build)工具,完成代码编译链接打包过程。在开发AI应用平台时,由于开发的平台是在边缘设备运行的,而边缘设备的算力不高,所以对平台的效率要求比较高,都是优先使用C++开发的。

在C++开发中,CMake是不可或缺的,与CMake类似的工具有微软的MSBuild(在Visual Studio中使用)、安卓开发的Gradle(Android Studio)。

上图是c/cpp的编译流程:编译cpp时是以单个文件为单位,每个cpp文件会得到一个.o的文件,里面包含了机器可以执行的代码。有多个文件的时候,会用到其它头文件里定义的函数,而编译这个cpp时编译器是不知道要调用的函数地址是什么,所以会暂时设置为0,直到链接过程才会修正。

随着项目的复杂化,编译的.cpp和.h文件越来越多,这个编译和链接的过程也越来越复杂,于是make工具(Makefile)出现了,这个古老的技术(1977)可以帮助我们构建一颗依赖树,然后通过make命令来递归执行构建。

在这里插入图片描述

然而,随着项目变得更复杂,Makefile也变得繁杂了起来,而且对于不同平台,要写的Makefile还不一样,于是cmake出现了。CMake可以通过CMakeLists.txt来生成makefile来给make用。

快速例子

CMake依赖于CMakeLists.txt这个文本文件。

# 使用`#`来注释文件
# 这一行表示cmake的最低版本
cmake_minimum_required(VERSION 3.10)
# 项目名称,输出的文件就叫这个名字
project(Example)
# 项目Example需要构建可执行文件,由main.cpp编译得到
add_executable(Example main.cpp)

有了CMakeLists.txt之后,CMake需要根据编译平台进行配置(Configure),然后进行build。

build直接使用cmake build即可。

CMake参数和命令

  • add_executable

    就是为项目添加所有的源代码,可以无限加

    add_executable(Example main.cpp my1.cpp my2.cpp my3.cpp)
    
  • aux_source_directory(dir var)

    glob操作,将dir下的所有源文件存到var变量中,后续通过${var}进行调用

    aux_source_directory(. SRC_LIST)
    add_executable(Example ${SRC_LIST})
    
  • include_directories(dir)

    之前是编译cpp文件,假如定义和实现分开,你有很多头文件,则可以让cmake自动去dir下寻找头文件(也可以多个目录)

    include_directories(./include1 ./include1)
    
  • add_library(lib_name STATIC/SHARED src)

    生成静态库或者动态库,和add_executable的用法类似。

    # 第一个参数是生成的库的名称 第二个是动态或者静态 后面是源文件
    add_library(func_shared SHARED ${SRC_LIST})
    add_library(func_shared STATIC ${SRC_LIST})
    
  • set_target_properties()

    设置目标的属性,一般可以用来设置版本号和输出名称

    # 更改输出文件名
    # 将 hello_static 更名为 hello
    SET_TARGET_PROPERTIES (hello_static PROPERTIES OUTPUT_NAME "hello")# 设置版本号
    # 将hello的动态库版本设置为1.2 API版本设置为1
    SET_TARGET_PROPERTIES (hello PROPERTIES VERSION 1.2 SOVERSION 1)
    
  • set

    用来定义或者修改变量的值,这些变量可以是普通变量、缓存变量或环境变量。

    # EXECUTABLE_OUTPUT_PATH是系统变量,这里设置可执行文件的输出目录到bin下
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin)
    # LIBRARY_OUTPUT_PATH是系统变量,这里设置链接库的输出目录到lib下
    set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../lib)
    
  • find_library(var lib_name lib_path1 lib_path2)

    在lib_path路径下查找库(.so .a),并存到var变量

    # 将库myfunc的位置存到FUNC_LIB中
    find_library(FUNC_LIB myfunc ${PROJECT_BINARY_DIR}/../lib)
    
  • target_link_libraries(target lib_name)

    用来把lib连接到一个可执行文件中

    # 上一步找到的库连接到可执行文件
    target_link_libraries(hello ${FUNC_LIB})
    
  • find_package

    从计算机上寻找库,寻找到的库会保存XXX_FOUND/_DIR/_INCLUDE_DIR/_LIBS等变量。REQUIRED表示必须要找到package,否则报错。

    # 找OpenCV
    find_package(OpenCV REQUIRED)
    # 接下来可以使用这些路径了
    ${OpenCV_DIR}
    ${OpenCV_INCLUDE_DIRS}
    ${OpenCV_LIBS}
    # 也可以进行一些逻辑控制(if中直接用变量名)
    if(OpenCV_FOUND)target_link_libraries(...)
    else(OpenCV_FOUND)message(FATAL_ERROR ”GLOG library not found”)
    endif(OpenCV_FOUND)
    
  • 常用变量

    PROJECT_BINARY_DIR:cmake配置命令的目录,通常是build目录下。

    PROJECT_SOURCE_DIR:代码的路径

    通常假如源码路径是src,那么在src下创建一个build,再进入build,然后cmake ..,表示build的上一级是源码,但是编译结果保存在build下。

常用编译流程

rm -rf build  # 删除旧的build,假如没有旧的或者makefile没有变化,则不需要这一步
mkdir build
cd build
cmake ..      # 根据CMakeLists.txt生成makefile
make          # 根据txt生成makefile进行编译make clean    # 不一定需要,删除make之前生成的缓存

参考:

【软件构建: CMake 快速入门】 https://www.bilibili.com/video/BV1rR4y1E7n9/?share_source=copy_web&vd_source=cdc2983e744e85d26061233640e163f4

【cmake学习】set_target_properties 常见属性以及获取target 属性_set——target-CSDN博客

CMake,make,CMakeLists.txt,CMakeFiles之间的关系_.cmake .cmake.in cmakefile.txt 的关系-CSDN博客

【隐藏的细节:编译与链接】 https://www.bilibili.com/video/BV1TN4y1375q/?share_source=copy_web&vd_source=cdc2983e744e85d26061233640e163f4
2911202/article/details/85337968)

【隐藏的细节:编译与链接】 https://www.bilibili.com/video/BV1TN4y1375q/?share_source=copy_web&vd_source=cdc2983e744e85d26061233640e163f4

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

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

相关文章

SFTP全解析:深入了解组件功能与适用场景

文章目录 一、组件功能二、适用场景三、SFTP优势四、SFTP原理五.SFTP与同类产品对比六、部署方案1.裸金属部署2.k8s容器化部署 七、高可用方案八、监控方案九、常见问题及解决方法 一、组件功能 安全文件传输协议SFTP(SSH File Transfer Protocol)是文件传输协议(F…

java——Spring MVC的工作流程

Spring MVC的工作流程是基于模型-视图-控制器(MVC)设计模式的一个典型实现,以下是其主要工作流程步骤: 客户端请求提交: 用户通过浏览器向服务器发送请求,该请求首先到达Spring MVC的前端控制器DispatcherS…

Mutex::Autolock 和 std::lock_guard 的区别

Mutex::Autolock 和 std::lock_guard 都是 C 中用于管理互斥锁(mutex)的一种方式,它们的目标是自动获取和释放锁,避免手动管理锁的复杂性,从而防止死锁和遗漏解锁等问题。尽管它们有相似的功能,但二者也存在…

<项目代码>YOLOv8 红绿灯识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

mac下安装Ollama + Open WebUI + Llama3.1

本文介绍mac下安装Ollama Open WebUI Llama3.1 8b具体步骤。 目录 推荐配置Ollama Open WebUI Llama3.1简介安装Ollama安装Open WebUI 推荐配置 m1以上芯片,16g内存,20g以上硬盘空间 Ollama Open WebUI Llama3.1简介 Ollama: 下载,管理…

Linux 无图形界面磁盘空间排查与优化实践20241127

Linux 无图形界面磁盘空间排查与优化实践 引言:磁盘空间问题的痛点与挑战 🔍 常见问题 当系统磁盘空间超过 90% 时,不仅可能导致性能下降,还可能让关键操作无法正常完成。这种情况下,如何高效且精准地排查磁盘占用来…

【AI】JetsonNano启动时报错:soctherm OC ALARM

1、问题描述 将JetsonNano烧写SD卡镜像为Ubuntu20.04后,启动时报错:soctherm OC ALARM,启动失败;然后系统一直重启 2、原因分析 “soctherm OC ALARM”是检测到系统温度超过安全阈值时发出的过热警告。 “soctherm”代表系统…

SycoTec 4060 ER-S德国高精密主轴电机如何支持模具的自动化加工?

SycoTec 4060 ER-S高速电主轴在模具自动化加工中的支持体现在以下几个关键方面: 1.高精度与稳定性:SycoTec 4060 ER-S锥面跳动小于1微米,确保了加工过程中的极高精度,这对于模具的复杂几何形状和严格公差要求至关重要。高精度加工…

d3-contour 生成等高线图

D3.js 是一个强大的 JavaScript 库,用于创建动态、交互式数据可视化。d3-contour 是 D3.js 的一个扩展模块,用于生成等高线图(contour plots)。 属性和方法 属性 x: 一个函数,用于从数据点中提取 x 坐标。y: 一个函…

Docker 部署 MongoDB

🚀 作者主页: 有来技术 🔥 开源项目: youlai-mall 🍃 vue3-element-admin 🍃 youlai-boot 🍃 vue-uniapp-template 🌺 仓库主页: GitCode💫 Gitee &#x1f…

鸿蒙MVVM模式介绍与使用

文章目录 鸿蒙MVVM模式介绍与使用背景MVVM模式介绍相关装饰器介绍State状态变量Prop、Link的作用 MVVM架构模式的实现以及相关装饰器的使用具体实现效果 总结 鸿蒙MVVM模式介绍与使用 背景 最近在学习鸿蒙开发,想到了以前写安卓移动端应用时经常会用到的MVVM架构模式,就想着能…

解决SpringBoot连接Websocket报:请求路径 404 No static resource websocket.

问题发现 最近在工作中用到了WebSocket进行前后端的消息通信,后端代码编写完后,测试一下是否连接成功,发现报No static resource websocket.,看这个错貌似将接口变成了静态资源来访问了,第一时间觉得是端点没有注册成…

【RISC-V CPU 专栏 -- 香山处理器介绍】

文章目录 RISC-V 香山处理器介绍雁栖湖处理器南湖处理器RISC-V 香山处理器介绍 相信很多小伙伴对于“香山”都不陌生,它是一款开源RISC-V处理器核,香山的每一代架构,都是采用了湖的名字,第一代架构被命名为雁栖湖,第二代架构则叫做 “南湖”。 “雁栖湖”这款处理器的 R…

网络安全原理与技术思考题/简答题

作业1(第1章、第2章、第8章) 1. 网络安全的基本属性有哪些?简单解释每个基本属性的含义。网络安全的扩展属性包括哪些? 基本属性: 1.机密性(Confidentiality): 含义:确保信息不被未授权的用户…

小米note pro一代(leo)线刷、twrp、magisk、TODO: android源码编译

本文主要说android5 整体思路 android 5.1 twrp magisk Zygisk(Riru) Dreamland(xposed) Riru不支持android5.1, 因此只能选择Zygisk : 如果你正在使用 Android 5,你必须使用 Zygisk 因为 Riru 并不支持 Android 5. 基于magisk之上的xposed 其中提到的 作者…

英语知识网站:Spring Boot技术构建

6系统测试 6.1概念和意义 测试的定义:程序测试是为了发现错误而执行程序的过程。测试(Testing)的任务与目的可以描述为: 目的:发现程序的错误; 任务:通过在计算机上执行程序,暴露程序中潜在的错误。 另一个…

Android 常用命令和工具解析之GPU相关

目录 1、GPU基本信息 1.1 获取GPU基本信息 1.2 伪造GPU基本信息 2、GPU内存信息 3、经典案例 案例1:GPU伪造信息方案 案例2:GPU内存统计算法 GPU 指的是 Graphics Processing Unit,即图形处理单元。GPU 是一种专门用于处理图形和图像相…

NIO三大组件

现在互联网环境下,分布式系统大相径庭,而分布式系统的根基在于网络编程,而netty恰恰是java领域的网络编程的王者,如果要致力于并发高性能的服务器程序、高性能的客户端程序,必须掌握netty网络编程。 NIO基础 NIO是从ja…

Vue3 el-table 默认选中 传入的数组

一、效果&#xff1a; 二、官网是VUE2 现更改为Vue3写法 <template><el-table:data"tableData"border striperow-key"id"ref"tableRef":cell-style"{ text-align: center }":header-cell-style"{background: #b7babd…

【Python】绝地求生PUBG等FPS游戏辅助压枪软件脚本编写

【Python】绝地求生PUBG等FPS游戏辅助压枪软件脚本编写 更新以gitee为准&#xff1a; https://gitee.com/Mike_Zhou_Group/PUBG_Key/开源的是辅助压枪软件 不开源的是将之前的地图测距和压枪辅助整合在一起的整合包 关于地图测距&#xff1a; https://gitee.com/Mike_Zhou_G…