【编程技巧】如何写好CMakeList【常见命令汇总】

news2024/11/8 5:03:20

【编程技巧】如何写好CMakeList【常见命令汇总】

一、问题背景

开发过程中经常需要构建新的C++项目。受限于工期,往往草草从旧项目中抄一个CMakeList,要么是包含的头文件或者导入的库过多,加重了编译负担,要么就是删减过程中多删了某个头文件或者依赖的库,导致开发流水线被阻塞。所以总需要返工反复调试修改CMakeList文件。

写好一个CMakeList对于现在的我来说确实绝非易事,所以产生了以初学者的心态,重头学习的想法,目标在于:

  1. 能优雅的写好CMakeList文件,不过多添加依赖库和头文件,也不在缺乏依赖的情况下commit代码。
  2. 编译过程报错时,能迅速分析定界是代码问题还是CMakeList问题,并实施修改。

二、CMakeList常用命令

(1) project(<项目名称> [LANGUAGES <语言列表>])

用于定义项目的名称和使用的编程语言(如 C、C++、Fortran 等),其中 [LANGUAGES <语言列表>]为可选项。例如:

project(MyProject)
project(MyProject LANGUAGES C CXX)
(2)cmake_minimum_required(VERSION <版本号>)

用于指定 CMake 的最低版本要求,例如:

cmake_minimum_required(VERSION 3.10)
(3)set(<变量> <值>)

设置变量值,例如设置编译选项,例如:

set(MY_VARIABLE "Hello, World!") # 字符串
set(IS_DEBUG TRUE) # boolset(MY_LIST "apple" "banana" "cherry") # 列表

再次使用set命令可以修改变量:

set(MY_VARIABLE "Hello, World!")
message(${MY_VARIABLE})
set(MY_VARIABLE "Goodbye, World!")
message(${MY_VARIABLE})

${MY_VARIABLE}对变量取值,message用于打印,以上命令将依次打印"Hello, World!",“Goodbye, World!”

(4)add_compile_options(<选项…>)

添加编译器选项,适用于整个项目:

add_compile_options(-Wall -Werror)

这条命令将 -Wall-Werror 编译选项添加到所有目标中。

  • -Wall:启用所有常见的警告。
  • -Werror:将所有警告视为错误,编译过程中如果有警告则会停止编译。
(5)add_executable(<目标名> <源文件…>)

以下命令声明了一个名为 MyApp 的可执行文件目标,并指定了两个源文件 main.cpputils.cpp

set(ProjectName MyApp)
add_executable(${ProjectName} main.cpp utils.cpp)
(6)add_library(<库名> [STATIC | SHARED | MODULE] <源文件…>)

add_library 用于声明库目标的命令。库可以是静态库(.a.lib)、动态库(.so.dll),或者是模块库。

set(LibName MyLib)
add_library(${LibName} STATIC lib.cpp)
  • STATIC:生成静态库。
  • SHARED:生成动态库。
  • MODULE:生成模块库,通常用于插件系统。
(7)find_package(<包名> [版本] [REQUIRED] [COMPONENTS <组件列表>])

find_package 用于查找和加载外部库或工具的命令。

# 查找 Boost 库,并要求必须找到 filesystem 和 system 组件
find_package(Boost 1.65 REQUIRED COMPONENTS filesystem system)
# 链接 Boost 库
target_link_libraries(MyApp PRIVATE Boost::filesystem Boost::system)
(8)include_directories(<目录…>)

用于指定编译器在查找头文件时需要搜索的目录。通过使用 include_directories,可以添加一个或多个目录,使编译器能够在这些目录中查找头文件。

include_directories(${CMAKE_SOURCE_DIR}/include
					${CMAKE_SOURCE_DIR}/src/include)

以上命令包含CMake路径下的include路径和src/include路径下的所有头文件

(9)target_include_directories(<目标> PRIVATE|PUBLIC|INTERFACE <目录…>)

用于指定编译目标(如可执行文件或库)需要包含的头文件搜索路径的一个命令。target_include_directoriesinclude_directories的区别在于作用域,include_directories的作用域为全局,target_include_directories的作用域为编译目标。

add_library(my_library src/my_library.cpp) # 创建一个my_library的库文件
target_include_directories(my_library PRIVATE include/my_project) # 包含另一个项目的头文件
  • PRIVATE: 包含目录仅对当前目标可用,不会传递给依赖于这个目标的其他目标。
  • PUBLIC: 包含目录不仅对当前目标可用,也会传递给所有依赖于这个目标的目标。
  • INTERFACE: 包含目录只传递给依赖于这个目标的目标,但不对当前目标产生影响。这个选项通常用于库的目标,以告诉使用该库的其他目标需要哪些额外的包含路径。
(10)target_link_libraries(<目标> PRIVATE|PUBLIC|INTERFACE <库1> [<库2> …])

用于指定编译目标(例如可执行文件或库)需要链接的库,而无需手动管理链接顺序或路径。

target_link_libraries(my_executable PRIVATE my_library)
  • PRIVATE: 指定的库仅对当前目标有用,不会传递给依赖于这个目标的其他目标。
  • PUBLIC: 指定的库不仅对当前目标有用,还会传递给所有依赖于这个目标的目标。
  • INTERFACE: 指定的库只传递给依赖于这个目标的目标,但不对当前目标产生影响。这个选项主要用于库目标,以告诉使用该库的其他目标需要链接哪些额外的库。
(11)add_subdirectory(<子目录>)

包含子目录中的 CMakeLists.txt,以构建该子目录的内容:

set(SUB_SRC sub/src)
add_subdirectory(${SUB_SRC})
(12)include(<文件>)

用于包含另一个CMake文件,例如配置文件等

config.cmake

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")

function(print_message message)
    message(STATUS "Custom message: ${message}")
endfunction()

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(MyProject)

include(config.cmake) # 引入配置文件
add_executable(my_executable src/main.cpp)
print_message("Hello, World!") # 使用config.cmake中的函数
(13)file(GLOB <variable> [RELATIVE <path>] <pattern> …)

根据模式匹配文件并将其路径存储到变量中的命令

  • <variable>: 存储匹配结果的变量名。
  • [RELATIVE <path>]: 可选参数,用于指定结果路径相对于哪个目录。如果不指定,则结果路径是绝对路径或相对于当前源目录的路径。
  • <pattern> ...: 一个或多个文件匹配模式。模式可以包含通配符,如 *?
file(GLOB SRC_FILES src/*.cpp src/*.h) # 收集 src 目录下的所有 .cpp 和 .h 文件
(14)AUX_SOURCE_DIRECTORY(<dir> <variable>)

用于获取指定目录中的所有源文件,并将这些文件的路径存储到一个变量中。与file(GLOB ...)的不同点在于AUX_SOURCE_DIRECTORY 会递归地扫描指定目录及其子目录中的所有源文件。

  • <dir>: 要扫描的目录路径。
  • <variable>: 存储找到的源文件路径的变量名。
AUX_SOURCE_DIRECTORY(src SRC_FILES) # 收集 src 目录下的所有源文件
message(STATUS "Source files: ${SRC_FILES}") # 输出收集到的文件列表
(16)install(TARGETS <目标> [DESTINATION <路径>])

用于指定如何安装目标(如可执行文件、静态库、动态库等)的命令

file(GLOB SRC_FILES src/*.cpp src/*.h) # 收集 src 目录下的所有 .cpp 和 .h 文件
install(DIRECTORY ${SRC_FILES} DESTINATION /usr/local/include) # 安装头文件到 /usr/local/include

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

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

相关文章

idea、pycharm等软件的文件名红色怎么变绿色

1.问题 有时候在写完代码打算提交的时候&#xff0c;会遇到某个资源文件不是绿色的&#xff0c;不能提交 2.解决方法 右键该文件——git——添加即可 3.不同颜色含义 3.1 蓝色&#xff08;Blue&#xff09; 含义&#xff1a;文件被修改了但尚未保存。蓝色通常表示文件自上…

Python进阶之IO操作

文章目录 一、文件的读取二、文件内容的写入三、之操作文件夹四、StringIO与BytesIO 一、文件的读取 在python里面&#xff0c;可以使用open函数来打开文件&#xff0c;具体语法如下&#xff1a; open(filename, mode)filename&#xff1a;文件名&#xff0c;一般包括该文件所…

ECharts折线图背景渐变设置

目录 引入 1.在一个HTML文件中编写两个图表 2.渐变背景 引入 如何在一个HTML文件中编写两个图表&#xff1a;&#xff08;这个例子基于这个篇文章的基础&#xff09;一篇搞懂前端获取数据-CSDN博客 一个例子&#xff1a; 1.在一个HTML文件中编写两个图表 重点在于名字的不重…

基于SpringBoot的“乐校园二手书交易管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“乐校园二手书交易管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统首页界面图 用户注册界面图 二手…

CSS弹性布局:灵活布局的终极指南

在网页设计中&#xff0c;CSS 弹性布局&#xff08;Flexbox&#xff09;是一个不可或缺的工具。它能帮助你轻松地排列和对齐元素&#xff0c;尤其是在响应式设计中表现出色。今天&#xff0c;我们就来深入探讨一下 Flexbox 的各个属性&#xff0c;让你彻底掌握这个强大的布局工…

OpenJDK Vendor下载选择

首先JDK可以通过idea进行安装 File➡️Project Structure➡️SDK➡️Add SDK➡️Download JDK 然后在JDK版本选择时&#xff0c;Idea提供了很多版本&#xff0c;让我茫然了 OpenJDK国外厂商 供应商 说明 Amazon Corretto 亚马逊云基于OpenJDK构建&#xff0c;收费 Eclipse…

SAP-ABAP开发-ONLINE 程序、DIALOG屏幕开发

目录 一、Online 程序概览 1、程序类型 2、Online程序的主要对象 二、界面 1、SAP的屏幕开发 2、屏幕功能实现 3、界面中的事件块&#xff08;Event Block&#xff09; 4、界面的创建 三、简单界面元素 1、文本/输入框控件 2、数据检查 3、一些常用的关键字 四、复…

基于vue框架的的留守儿童帮扶系统143b5(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;留守儿童,帮扶活动,申请记录,帮扶机构,帮扶进度,帮扶人,申请加入记录,参与帮扶记录 开题报告内容 基于Vue框架的留守儿童帮扶系统开题报告 一、研究背景与意义 随着城乡经济差异的不断扩大&#xff0c;大量农村劳动力涌向城市寻求更好…

xftp连接中不成功 + sudo vim 修改sshd_config不成功的解决方法

我们使用sudo vim不成功&#xff0c;但是我们使用sudo su就可以 了&#xff01; root用户权利更大&#xff01; 喵的&#xff0c;终于成功了&#xff0c;一个xftp连接半天不成功。&#xff08;添加上面的内容就可以连接成功了↑&#xff09;

这款Chrome 插件,使浏览器页面快速滑动到最底部和最顶部,并且还能...

前言 前几日我在使用谷歌浏览器&#xff0c;也就是chrome的时候&#xff0c;浏览一个内容很长的页面&#xff0c;由于页面上的内容有前后关联&#xff0c;所以我必须不停地切换到上面和下面。这非常不方便。使我非常抓狂。后来&#xff0c;我灵机一动&#xff0c;去谷歌浏览器…

嵌入式linux中设备树控制硬件的方法

大家好,今天主要给大家分享一下,如何使用linux系统下的设备树进行硬件控制方法。 第一:linux系统中设备树驱动LED原理 在linux系统中可以使用设备树向Linux内核传递相关的寄存器地址,linux驱动中使用OF函数从设备树中获取所需的属性值,然后使用获取到的属性值来初始化相关…

2024年网鼎杯青龙组|MISC全解

转载或摘抄时请标明出处 MISC01 wdbflag{22226aba1d98c4302a6f508cad7da5d8} MISC02 一把梭工具没有任何结果&#xff0c;估计缺少符号表&#xff0c;直接strings flag > out.txt导出后慢慢找线索 在桌面上发现了png和txt文件&#xff0c;用文件名做一次筛选 第一行发现bas…

AI驱动无人驾驶:安全与效率能否兼得?

内容概要 如今&#xff0c;人工智能正以其神奇的魔力驱动着无人驾驶的浪潮&#xff0c;带来了无数令人兴奋的可能性。这一领域的最新动态显示&#xff0c;AI技术在车辆的决策过程和实时数据分析中发挥着重要作用&#xff0c;帮助车辆更聪明地应对复杂的交通环境。通过实时监测…

华为手机卸载系统应用的方法

摘要&#xff1a; 1.手机环境&#xff1a;手机需要开启开发者模式并使用usb连接电脑&#xff0c;并选择文件传输模式 2.电脑环境&#xff1a;使用鸿蒙工具箱进行傻瓜操作或安装adb工具进行命令卸载 3.鸿蒙工具箱和adb工具本质都是使用adb shell pm uninstall -k --user 0 xx…

一文看懂芯片算力TOPS

AI算力的发展与TOPS&#xff08;Tera Operations Per Second&#xff09;紧密相关。TOPS是衡量芯片每秒能执行的基本操作次数的单位&#xff0c;通常用于评估AI芯片性能&#xff0c;特别是在处理大量整数或定点运算任务时。随着AI技术进步&#xff0c;对算力的需求不断增加&…

在Linux系统中高效查找文件所在位置的方法

目录 引言 一、使用find命令查找文件 二、使用locate命令快速查找文件 三、利用which和whereis命令查找可执行文件 四、使用findmnt和mount命令查找挂载点 五、其他查找文件的方法 六、总结与最佳实践 引言 Linux操作系统以其强大的功能和灵活性而闻名&#xff0c;其文件…

连锁餐饮企业-凡塔斯,用千里聆RPA搭建用户评价管理系统,提升门店服务满意度

凡塔斯是大型连锁餐饮企业昊澜餐饮集团旗下餐饮品牌&#xff0c;是牛排自助餐头部品牌&#xff0c;旗下拥有凡塔斯、百分好、食物链KING自助烤肉及餐饮人才商学院等多个行业知名品牌。 创立至今&#xff0c;集团管理门店已发展到福建、广东、江西、浙江等十多个省市&#xff0c…

MES管理系统的生产绩效分析与资源可追踪性

在探讨MES管理系统的核心功能时&#xff0c;生产绩效分析与资源可追踪性是两个不可或缺的关键要素。它们共同构成了MES管理系统中对于生产效率、成本控制以及产品质量进行精细管理的基石。以下是对这两个关键领域的深入剖析与重新阐述。 MES管理系统中的生产绩效分析&#xff0…

远程控制项目第四天 功能实现

发送屏幕内容 代码详解 1. 创建 CImage 对象并获取屏幕内容 首先&#xff0c;我们创建一个 CImage 对象&#xff0c;用于接收屏幕上的内容。要获取屏幕内容&#xff0c;我们需要先获取当前设备上下文&#xff08;DC&#xff09;。调用 ::GetDC(NULL) 函数&#xff0c;参数 NU…

无线领夹麦克风哪个品牌音质最好?无线麦克风品牌排行榜前十名

​无线领夹麦克风哪个品牌音质最好&#xff1f;选择无线麦克风时&#xff0c;音质和耐用性至关重要。近年来&#xff0c;无线麦克风产品越来越智能化和多样化&#xff0c;但也存在着大量的劣质产品。作为测评师&#xff0c;我发现这些低质量无线麦克风由于缺乏专业调校&#xf…