[C/C++] -- CMake使用

CMake(Cross-platform Make)是一个开源的跨平台构建工具,用于自动生成用于不同操作系统和编译器的构建脚本。它可以简化项目的构建过程,使得开发人员能够更方便地管理代码、依赖项和构建设置。

CMake 使用一个名为 CMakeLists.txt 的配置文件来描述项目的构建过程。在 CMakeLists.txt 文件中,可以指定项目的源代码文件、依赖项以及构建选项等信息。然后,CMake 会根据这些信息生成对应平台的构建脚本(如 Makefile 或 Visual Studio 项目文件),从而完成项目的构建过程。

1.下载安装

  1. Windows

    • 在 CMake 官方网站 上下载 Windows 版本的安装程序。
    • 运行安装程序,按照提示进行安装。
  2. macOS

    • 可以使用 Homebrew 进行安装,命令为 brew install cmake
  3. Linux

    • 在大多数 Linux 发行版的软件仓库中都可以找到 CMake,可以使用系统自带的软件包管理器进行安装,比如:
      • Ubuntu/Debian:sudo apt install cmake
      • Fedora:sudo dnf install cmake
      • CentOS:sudo yum install cmake

2.CMake使用介绍

1. 创建项目目录结构

假设你有以下项目目录结构:

project/
    |- src/
        |- main.cpp
        |- helper.cpp
    |- include/
        |- helper.h
    |- CMakeLists.txt

2. 编辑 CMakeLists.txt 文件

在项目根目录下创建一个 CMakeLists.txt 文件,并添加以下内容:

cmake_minimum_required(VERSION 3.10)

project(MyProject)

# 添加可执行文件
add_executable(my_executable src/main.cpp src/helper.cpp)

# 添加头文件路径
target_include_directories(my_executable PUBLIC include)

3. 生成构建系统

在项目根目录下创建一个 build 目录,进入该目录,并运行以下命令生成构建系统:

cmake ..

4. 构建项目

根据生成的构建系统进行构建操作,比如使用 make 命令(如果是在 Linux/macOS):

make

5. 运行程序

构建成功后,在 build 目录下会生成可执行文件,你可以运行它:

./my_executable

其他常见用法

  • 指定编译选项:
target_compile_options(my_executable PRIVATE -Wall -Wextra)
  • 添加库文件依赖:
find_package(SomeLibrary REQUIRED)
target_link_libraries(my_executable PRIVATE SomeLibrary::SomeLibrary)

3.使用示例

  • 基本的 CMakeLists.txt 配置文件

cmake命令会执行目录下的CMakeLists.txt配置文件里面的配置项

cmake_minimum_required (VERSION 2.8) #要求cmake最低的版本号
project (demo) # 定义当前工程名字
set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)
add_executable(main main.c)
#进入子目录下执行 CMakeLists.txt文件 这里的lib和tests里面都有可编译的代码文件
add_subdirectory(lib)
add_subdirectory(tests)

整个流程

生成一个main.cpp源文件,输出"hello world",然后在同级目录创建一个CMakeLists.txt文件

1.test.cpp

#include <iostream>

using namespace std;
int main()
{
    cout <<"Hello World!"<< endl;
    return 0;
}

2.CMakeLists.txt

cmake_minimum_required (VERSION 2.8) #要求cmake最低的版本号
project (TestCMake) # 定义当前工程名字
set(CMAKE_BUILD_TYPE "Debug")#设置debug模式,如果没有这一行将不能调试设断点
add_executable(main test.cpp)

3.执行cmake .命令

产生了CMake的一些中间文件和Makefile文件

Makefile里面实现了clean,所以使用make clean可以清除生成的文件,然后重新编译源码。

4.make编译,生成最终可执行文件

源文件处理

如果需要编译的有多个源文件,可以都添加到add_executable(main main.cpp test.cpp)列表当中, 但是如果源文件太多,一个个添加到add_executable的源文件列表中,就太麻烦了,此时可以用 aux_source_directory(dir var)来定义源文件列表,使用如下:

cmake_minimum_required (VERSION 2.8)
project (demo)
aux_source_directory(. SRC_LIST) # 定义变量,存储当前目录下的所有源文件
add_executable(main ${SRC_LIST})

aux_source_directory()会把指定目录下的所有源文件都加进来,可能会加入一些我们 不需要的文件,此时我们可以使用set命令去新建变量来存放需要的源文件,如下

cmake_minimum_required (VERSION 2.8)
project (demo)
set( SRC_LIST
./main.cpp
./test.cpp)
add_executable(main ${SRC_LIST})

正式工程构建

一个正式的源码工程应该有这几个目录:

-bin                    存放最终的可执行文件

-build                 存放编译中间文件

-include             头文件

        --test.h

-src                    源代码文件

        --test.cpp

main.cpp

-CMakeLists.txt

CMakeLists.txt如下:

cmake_minimum_required (VERSION 2.8)
project (math)
# 设置cmake的全局变量
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#添加头文件路径,相当于makefile里面的-I
include_directories(${PROJECT_SOURCE_DIR}/include)
aux_source_directory (src SRC_LIST)
add_executable (main main.cpp ${SRC_LIST})

然后在build目录里面执行cmake .. 命令,这样所有的编译中间文件都会在build目录下,最终的可执行 文件会在bin目录里面

然后使用make编译

最终生成的文件在bin目录下

静态库和动态库的编译控制

把上面的test源文件直接生成静态库或者动态库,让外部程序进行链接使用,代码结构如下:

-bin                    存放最终的可执行文件

-build                 存放编译中间文件

-lib                     存放编译生成的库文件

-include             头文件

        --test.h

-src                    源代码文件

        --test.cpp

        --CMakeLists.txt

-test                   测试代码

   --main.cpp

   --CMakeLists.txt

-CMakeLists.txt

最外层的CMakeLists.txt是总控编译:

cmake_minimum_required (VERSION 2.8)
project (cmaketest)
add_subdirectory (test)
add_subdirectory (src)

src里面的源代码要生成静态库或动态库,CMakeLists.txt内容如下:

set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
include_directories (../include) 
# 生成库,动态库是SHARED,静态库是STATIC
add_library (test SHARED test.cpp)
# 修改库的名字
#set_target_properties (test PROPERTIES OUTPUT_NAME "libtest")

test里面的CMakeLists.txt内容如下:

set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
include_directories (../include) # 头文件搜索路径
link_directories (${PROJECT_SOURCE_DIR}/lib) # 库文件搜索路径
add_executable (main main.cpp) # 指定生成的可执行文件
target_link_libraries (main test) # 执行可执行文件需要依赖的库

在build目录下执行cmake ..命令,然后执行make,如下

执行编译生成的可执行文件

查看生成的可执行文件,检验其链接的库有哪些

CMake常用的预定义命令

PROJECT_NAME : 通过 project() 指定项目名称
PROJECT_SOURCE_DIR : 工程的根目录
PROJECT_BINARY_DIR : 执行 cmake 命令的目录
CMAKE_CURRENT_SOURCE_DIR : 当前 CMakeList.txt 文件所在的目录
CMAKE_CURRENT_BINARY_DIR : 编译目录,可使用 add subdirectory 来修改
EXECUTABLE_OUTPUT_PATH : 二进制可执行文件输出位置
LIBRARY_OUTPUT_PATH : 库文件输出位置
BUILD_SHARED_LIBS : 默认的库编译方式 ( shared 或 static ) ,默认为 static
CMAKE_C_FLAGS : 设置 C 编译选项
CMAKE_CXX_FLAGS : 设置 C++ 编译选项
CMAKE_CXX_FLAGS_DEBUG : 设置编译类型 Debug 时的编译选项
CMAKE_CXX_FLAGS_RELEASE : 设置编译类型 Release 时的编译选项
CMAKE_GENERATOR : 编译器名称
CMAKE_COMMAND : CMake 可执行文件本身的全路径
CMAKE_BUILD_TYPE : 工程编译生成的版本, Debug / Release

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QML中常见热区及层级结构

目录 引言层级结构默认层级结构z值作用范围遮罩实现-1的作用 热区嵌套与普通元素与其他热区与Flickable 事件透传总结 引言 热区有很多种&#xff0c;诸如MouseArea、DropArea、PinchArea等等&#xff0c;基本都是拦截对应的事件&#xff0c;允许开发者在事件函数对事件进行响…

kubectl 创建 Pod 背后到底发生了什么?

想象一下&#xff0c;如果我想将 nginx 部署到 Kubernetes 集群&#xff0c;我可能会在终端中输入类似这样的命令&#xff1a; $ kubectl run --imagenginx --replicas3然后回车。几秒钟后&#xff0c;你就会看到三个 nginx pod 分布在所有的工作节点上。这一切就像变魔术一样…

Java学习15-- 面向对象学习3. 对象的创建分析【★】

&#xff08;本章看不懂多读几遍&#xff0c;弄懂后再往下章看&#xff09; 面向对象学习3. 对象的创建分析 Java Memory Structure: 如上图所示&#xff1a; 主要分为Stack和Heap Memory 其中Stack主要放method包括main 程序从main开始所以main最先进入Stack&#xff0c;等…

蓝桥杯第八届省赛题笔记------基于单片机的电子钟程序设计与调试

题目要求&#xff1a; 一、基本要求 1.1 使用 CT107D 单片机竞赛板&#xff0c;完成“电子钟”功能的程序设计与调试&#xff1b; 1.2 设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”&#xff1b; 1.3 Keil 工程文件以准考证号命名&#xff0c;保存在…

C语言系列-文件操作

&#x1f308;个人主页: 会编程的果子君 ​&#x1f4ab;个人格言:“成为自己未来的主人~” 为什么使用文件 如果没有文件&#xff0c;我们写的程序的数据是存储在电脑的内存上&#xff0c;如果程序退出&#xff0c;内存回收&#xff0c;数据就会丢失了&#xff0c;等再次运行…

MySQL 日志管理

4.6&#xff09;日志管理 MySQL 支持丰富的日志类型&#xff0c;如下&#xff1a; 事务日志&#xff1a;transaction log 事务日志的写入类型为 "追加"&#xff0c;因此其操作为 "顺序IO"&#xff1b; 通常也被称为&#xff1a;预写式日志 write ahead…

[职场] 服务行业个人简历 #笔记#笔记

服务行业个人简历 服务员个人简历范文1 姓名: XXX国籍:中国 目前所在地:天河区民族:汉族 户口所在地:阳江身材: 160cm43kg 婚姻状况:未婚年龄: 21岁 培训认证:诚信徽章: 求职意向及工作经历 人才类型:普通求职 应聘职位: 工作年限:职称:初级 求职类型:全职可到职日期:随时 月薪…

住宅供暖设备行业调研:市场环境将稳定发展阶段中

为使人们生活或进行生产的空间保持在适宜的热状态而设置的供热设施。 向一定的空间加热量的办法&#xff0c;可以直接把产生热量的火炉装在其中;也可以抽出其中的空气&#xff0c;加热后再送回;也可以在其中装置保持在较高温度的物体&#xff0c;向所在空间放热。这种温度较高的…

极值图论基础

目录 一&#xff0c;普通子图禁图 二&#xff0c;Turan问题 三&#xff0c;Turan定理、Turan图 1&#xff0c;Turan定理 2&#xff0c;Turan图 四&#xff0c;以完全二部图为禁图的Turan问题 1&#xff0c;最大边数的上界 2&#xff0c;最大边数的下界 五&#xff0c;…

机器人学、机器视觉与控制 上机笔记(第一版译文版 2.1章节)

机器人学、机器视觉与控制 上机笔记&#xff08;第一版译文版 2.1章节&#xff09; 1、前言2、本篇内容3、代码记录3.1、新建se23.2、生成坐标系3.3、将T1表示的变换绘制3.4、完整绘制代码3.5、获取点*在坐标系1下的表示3.6、相对坐标获取完整代码 4、结语 1、前言 工作需要&a…

【前端web入门第四天】03 显示模式+综合案例热词与banner效果

文章目录: 1. 显示模式 1.1 块级元素,行内元素,行内块元素 1.2 转换显示模式 综合案例 综合案例一 热词综合案例二 banner效果 1. 显示模式 什么是显示模式 标签(元素)的显示方式 标签的作用是什么? 布局网页的时候&#xff0c;根据标签的显示模式选择合适的标签摆放内容。…

编码安全风险是什么,如何进行有效的防护

2011年6月28日晚20时左右&#xff0c;新浪微博突然爆发XSS&#xff0c;大批用户中招&#xff0c;被XSS攻击的用户点击恶意链接后并自动关注一位名为HELLOSAMY的用户&#xff0c;之后开始自动转发微博和私信好友来继续传播恶意地址。不少认证用户中招&#xff0c;也导致该XSS被更…

21、数据结构/单向循环链表练习20240203

一、请编程实现单向循环链表的头插&#xff0c;头删、尾插、尾删。 二、请编程实现单向循环链表约瑟夫环 约瑟夫环&#xff1a;用循环链表编程实现约瑟夫问题 n个人围成一圈&#xff0c;从某人开始报数1, 2, …, m&#xff0c;数到m的人出圈&#xff0c;然后从出圈的下一个人…

pytorch入门第一天

今天作为入门pytorch的第一天。打算记录每天学习pytorch的一些理解和笔记&#xff0c;以用来后面回顾。当然如果能帮到和我一样的初学者&#xff0c;那也是不胜荣幸。作为一名初学者&#xff0c;难免有些地方会现错误&#xff0c;欢迎各位大佬指出 预备知识 这里主要介绍pyto…

gtkmm4 应用程序使用 CSS 样式

文章目录 前言css选择器css文件示例源代码效果 前言 程序样式和代码逻辑分离开 使代码逻辑更可观 css选择器 Cambalache提供了两种css-classes 相当于css里的类名:class“类名”css-name 相当于css里的标签名:spin div p 啥的 如上我设置了这个按钮控件的类名为testButton 标…

基于Chrome插件的Chatgpt对话无损导出markdown格式(Typora完美显示)

刚刚提交插件到Chrome插件商店正在审核&#xff0c;想尝试的可以先使用&#xff1a; https://github.com/thisisbaiy/ChatGPT-To-Markdown-google-plugin/tree/main 我将源代码上传至了GitHub&#xff0c;欢迎star, IssueGoogle插件名称为&#xff1a;ChatGPT to MarkDown plus…

元宇宙虚拟数字人实训室:推动高校培养创新技术人才

随着元宇宙时代的到来&#xff0c;虚拟数字人技术逐渐成为当下火热的产业赛道之一。虚拟数字人涉及了计算机、数字媒体、市场营销等学科技术领域&#xff0c;高校可以通过搭建元宇宙虚拟数字人实训室&#xff0c;有效培养对元宇宙行业的专业化理解和研究能力的专业型创新人才。…

Python中的数据类型

如果说python中的数据类型,那我们要从标准数据类型说起,在python中标准数据类型如下: 数字类型: 数字数据类型用于存储数值。 他们是不可改变的数据类型&#xff0c;这意味着改变数字数据类型会分配一个新的对象。 在python2.X中数据类型分的比较多,有int(有符号整型),long(…

原生JS使用PrintJs进行表格打印 -- 遇到的问题总结

需求1&#xff1a;表格自动分页之后&#xff0c;表头在每一页都需要显示 html中表头增加 thead 标签 css样式新增&#xff1a; thead {display: table-header-group; /* 这个属性使thead总是在新的page-break之后重新开始 */ }需求2&#xff1a;表格自动分页之后&#xff0c;…

MySQL优化器

优化器 MySQL存储引擎中存在了一个可插拔的优化器OPTIMIZER_TRACE&#xff0c;可以看到内部查询计划的TRACE信息&#xff0c;从而可以知道MySQL内部执行过程 查询优化器状态 show variables like optimizer_trace;Variable_name Valueoptimizer_trace enabledoff,one_lineoff…
最新文章