cmake的使用

news/2023/5/28 7:43:43

使用CMake组织C++工程

这篇文章将介绍一个稍微复杂一些的CMake工程,结合这个工程总结一下在组织一个C/C++工程时最为常用的一些CMake命令和变量。

为了让下面的说明举例更加容易理解,先给出本文的示例工程目录结构:

├── CMakeLists.txt
├── include
│   └── util.h
├── lib
│   └── libutil.a
└── src└── main.cpp

三个文件夹: include, lib, src分别存放包含文件,库文件,源文件;一个CMakeLists.txt脚本。下面我的任务是编写这个脚本,使得工程包含util.h头文件,编译main.cpp, 链接libutil.a, 最终生成一个可执行文件hello.
给工程起个名字

project(hello)

命令:project( [LANGUAGES] […])

让CMake找到我的头文件

include_directories(./include)

作用:把当前目录(CMakeLists.txt所在目录)下的include文件夹加入到包含路径

include_directories(${CMAKE_CURRENT_LIST_DIR}/include)

命令: include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …])

作用:

把dir1, [dir2 …]这(些)个路径添加到当前CMakeLists及其子CMakeLists的头文件包含路径中;AFTER 或者 BEFORE 指定了要添加的路径是添加到原有包含列表之前或之后若指定 SYSTEM 参数,则把被包含的路径当做系统包含路径来处理

第二种写法里用到了CMAKE_CURRENT_LIST_DIR这个变量,它表示当前CMakeLists所在的路径.
让CMake找到我的源文件

 aux_source_directory(./src ${hello_src})

作用: 把当前路径下src目录下的所有源文件路径放到变量hello_src中

上面的例子中,hello_src是一个自定义变量,在执行了aux_source_directory(./src ${hello_src})之后,我就可以像这样来添加一个可执行文件:add_executable(hello ${hello_src}), 意思是用hello_src里面的所有源文件来构建hello可执行程序, 不用手动列出src目录下的所有源文件了。
注意:
aux_source_directory 不会递归包含子目录,仅包含指定的dir目录

CMake官方不推荐使用aux_source_directory及其类似命令(file(GLOB_RECURSE …))来搜索源文件,原因是这样包含的话,如果我再在被搜索的路径下添加源文件,我不需要修改CMakeLists脚本,也就是说,源文件多了,而CMakeLists并不需要(没有)变化,也就使得构建系统不能察觉到新加的文件,除非手动重新运行cmake,否则新添加的文件就不会被编译到项目结果中。

让CMake找到我的库文件

link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)

命令:link_directories(directory1 directory2 …)
作用:不必细说,与include_directories()类似,这个命令添加了库包含路径。
告诉CMake我的构建目标

加上:add_executable(${PROJECT_NAME} ${hello_src})

告诉CMake我要链接哪个库文件

target_link_libraries(${PROJECT_NAME} util)

命令:target_link_libraries( [item1 [item2 […]]] [[debug|optimized|general] ] …)

作用:仅需知道,名字叫${PROJECT_NAME}这个target需要链接util这个库,会优先搜索libutil.a(windows上就是util.lib), 如果没有就搜索libutil.so(util.dll, util.dylib)’

上面的例子意思是,让hello去链接util这个库。
如果我的main.cpp里面用到了C++11,那么我需要告诉CMake在生成的Makefile里告诉编译器启用C++11。与此类似,我可能也要传递其他FLAGS给编译器,怎么办?

答案是:设置CMAKE_CXX_FLAGS变量

加上:

set(CMAKE_CXX_COMPILER      "clang++" )         # 显示指定使用的C++编译器
set(CMAKE_CXX_FLAGS   "-std=c++11")             # c++11
set(CMAKE_CXX_FLAGS   "-g")                     # 调试信息
set(CMAKE_CXX_FLAGS   "-Wall")                  # 开启所有警告
set(CMAKE_CXX_FLAGS_DEBUG   "-O0" )             # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " )   # release包优化

解释

CMAKE_CXX_FLAGS 是CMake传给C++编译器的编译选项,通过设置这个值就好比 g++ -std=c++11 -g -WallCMAKE_CXX_FLAGS_DEBUG 是除了CMAKE_CXX_FLAGS外,在Debug配置下,额外的参数CMAKE_CXX_FLAGS_RELEASE 同理,是除了CMAKE_CXX_FLAGS外,在Release配置下,额外的参数

开始构建

通过以上步骤, 最后,在文件头部添加CMake版本检查,以我的电脑上的环境为例,我的CMake版本是3.0,那么我在脚本最开始加上:

cmake_minimum_required ( VERSION 3.0)

完整的CMakeLists.txt如下所示:

cmake_minimum_required ( VERSION 3.0)project(hello)include_directories(${CMAKE_CURRENT_LIST_DIR}/include)link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src ${hello_src})add_executable(${PROJECT_NAME} ${hello_src})target_link_libraries(${PROJECT_NAME} util)set(CMAKE_CXX_COMPILER      "clang++" )         # 显示指定使用的C++编译器set(CMAKE_CXX_FLAGS   "-std=c++11")             # c++11
set(CMAKE_CXX_FLAGS   "-g")                     # 调试信息
set(CMAKE_CXX_FLAGS   "-Wall")                  # 开启所有警告set(CMAKE_CXX_FLAGS_DEBUG   "-O0" )             # 调试包不优化
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG " )   # release包优化

原文:https://elloop.github.io/tools/2016-04-10/learning-cmake-2-commands
其他:https://www.cnblogs.com/hbccdf/p/introduction_of_cmake.html

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

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

第五届字节跳动青训营 前端进阶学习笔记(四)TypeScript入门

文章目录前言TypeScript概要1.什么是TypeScript2.TypeScript基本语法基础数据类型对象类型函数类型函数重载数组类型补充类型泛型约束和泛型默认参数类型别名和类型断言高级类型1.联合类型2.交叉类型3.类型守卫类型谓词总结前言 课程重点: TypeScript概要TypeScri…

回溯法之旅行商问题解题思路详解

问题定义 输入: 完全无向带权图G(V,E) |V|n, |E|m 对于E中的某条边e,其长度为c(e) 输出: 最短哈密顿回路(经过每个节点一次且仅一次的回路) ps.这是一个NP问题,没有有效的算法…

【精讲】PCIe基础篇——Memory IO 地址空间

在早期的PC中,IO设备中的内部寄存器/存储是通过IO地址空间(由Intel定义)来访问的。然而,由于与IO地址空间相关的一些限制和不良影响(我们在这里不讨论),IO地址空间很快就失去了软件和硬件供应商的青睐。这导致IO设备的内部寄存器/存储被映射到…

Matlab遗传算法用于旅行商问题优化TSP

Matlab遗传算法用于旅行商问题优化要求第一步:参数编码和初始群体设定第二步:计算路径长度的函数设计第三步:计算选择算子第四步:计算交叉算子第五步:计算变异算子结果及分析MATLAB总代码要求 利用遗传算法求旅行商问…

(三)计算机组成原理——总线

文章目录(三)计算机组成原理——总线总线的基本概念单总线双总线面向CPU以存储器为中心总线的分类片内总线系统总线数据总线地址总线控制总线通信总线总线特性及性能指标总线特性机械特性电气特性功能特性时间特性性能指标总线标准总线结构单总线多总线双…

TSP_旅行商问题 - 蛮力法DFS(一)

一、前言 【旅行商问题】旅行商问题(TravelingSalesmanProblem,TSP)是一个经典的组合优化问题。经典的TSP可以描述为:一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应…

由旅行商问题认识何为状态压缩

动态规划 动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法。20世纪50年代初美国数学家R.E.Bellman等人在研究多阶段决策过程(multistep decision process)的优化问题时,提出了著名的最优化原理(pri…

[AI] 模拟退火算法解决旅行商问题(matlab)

华电北风吹 天津大学认知计算与应用重点实验室 日期:2015/6/28 模拟退火算法解决旅行商问题。 根据概率产生新解主要包含两个途径:二交换和三交换 二交换是在TSP回路中选择两个城市直接交换 三交换是在TSP回路中选择三个点,p1,p2,p3&am…

【回溯算法】旅行商问题--TSP问题

【问题描述】 一销售商从n个城市中的某一城市出发,不重复地走完其余n—1个城市并回到原出发点,在所有可能的路径中求出路径长度最短的一条。本题假定该旅行商从第1个城市出发。 输入 对每个测试例,第1行有两个整数:n(4≤n≤10)…

广义旅行商问题

问题描述 广义旅行商问题&#xff1a;给定一个加权图G(V, E,W)&#xff0c;其中图中的边上有权值&#xff08;所有权值为正&#xff09;。给定一个源顶点s&#xff0c;和一个目标顶点点t&#xff0c;以及一个包含k个顶点的查询集合Q{vi1,vi2,…,vik}&#xff0c;其中k<5。要…

在 VMware Workstation 16 Pro 中安装 Ubuntu Server 22.04.1 并配置静态 IP 地址

文章目录1.下载 Ubuntu Server 22.04.12.新建虚拟机向导3.编辑虚拟机设置4.开启此虚拟机并配置Ubuntu系统5.设置 root 用户的密码6.允许远程连接 root 用户7.配置静态 IP 地址7.1 查看 Windows 的网络信息7.2 查看 Ubuntu 的网络信息7.3 修改配置文件7.4 测试 Windows 能否互相…

fastp: 极速全能的FASTQ文件自动质控+过滤+校正+预处理软件

软件作者介绍陈实富博士&#xff0c;海普洛斯联合创始人 / CTO海普洛斯是全球领先的精准医疗和基因大数据国家高新技术企业&#xff0c;拥有 Illumina NovaSeq、 HiSeq X10、NextSeq等全系列测序仪&#xff0c;致力于整合液体活检、基因测序、人工智能、大数据等前沿新兴科技&a…

判断地图上一个点是否在多边形内部--射线法

判断一个点是否在多边形内部射线法实现 探索&#xff1a; 在地图上画了一个多边形和一个点&#xff0c;现在我要给出一种通用的方法来判断这个点是不是在多边形内部。 首先想到的一个解法是从这个点做一条射线&#xff0c;计算它跟多边形边界的交点个数&#xff0c;如果交点个…

Cesium基础-加载地图服务

最近工作中遇到一个问题&#xff1a;本地发布了wgs-1984坐标系的TMS局部地图服务&#xff08;在上层叠加&#xff09;&#xff0c;和一份google标准的TMS全球底图服务&#xff08;在下层&#xff09;。使用UrlTemplateImageryProvider加载两幅地图时&#xff0c;发现不能叠在一…

2022秋招算法岗面经题:训练模型时loss除以10和学习率除以10真的等价吗(SGD等价,Adam不等价)

问题描述&#xff1a;训练深度学习模型时loss除以10和学习率除以10等价吗&#xff1f; 先说结论 这个问题的答案与优化器有关 使用Adam、Adagrad、RMSprop等带有二阶动量vtv_tvt​的优化器训练时&#xff0c;当我们将loss除以10&#xff0c;对训练几乎没有影响。使用SGD、Mo…

【H5小游戏】-使用js复刻经典小游戏【接鸡蛋】,快来帮助鸡妈妈找回蛋宝宝吧

接鸡蛋游戏需求&#x1f447;核心玩法&#x1f447;&#x1f447;界面原型&#x1f447;&#x1f447;成品演示&#x1f447;1.游戏演示2.暂停演示游戏开发1.游戏素材准备2.代码实现1.创建index.html页面复刻经典小游戏【接鸡蛋】&#xff0c;快来帮助鸡妈妈找回它的蛋宝宝吧 …

C语言枚举法应用题目,又直观又好用的枚举法

原标题&#xff1a;又直观又好用的枚举法又直观又好用的枚举法枚举法又称为穷举法&#xff0c;适用于以下两种情况&#xff1a;1、当题目出现操作次数比较少或者要比较的数据(题目或选项)比较小时&#xff0c;优先考虑枚举法。2、当题目出现操作过程一致或者要比较的数据非常大…

百钱买百鸡(枚举法)

百钱买百鸡&#xff08;枚举法&#xff09;&#xff08;不断优化&#xff09; 百钱买百鸡的问题算是一套非常经典的不定方程的问题&#xff0c;题目很简单&#xff1a;公鸡5文钱一只&#xff0c;母鸡3文钱一只&#xff0c;小鸡3只一文钱&#xff0c; 题目1&#xff1a;用100文钱…

暴力枚举法

暴力枚举法 思路及算法 最容易想到的方法是枚举数组中的每一个数 x&#xff0c;寻找数组中是否存在 target - x。 当我们使用遍历整个数组的方式寻找 target - x 时&#xff0c;需要注意到每一个位于 x 之前的元素都已经和 x 匹配过&#xff0c;因此不需要再进行匹配。而每一…

【枚举法(穷举法)】

枚举法&#xff08;穷举法&#xff09; 定义 在进行归纳推理时&#xff0c;如果逐个考察了某类事件的所有可能情况&#xff0c;因而得出一般结论&#xff0c;那么该结论是可靠的&#xff0c;这种归纳方法叫做枚举法。 基本思想 在分析实际问题时&#xff0c;通过循环或者递归逐…