CMake学习使用(基于vscode)

目录

  • 语法
  • 一些重要指令
  • CMake常用变量
  • CMake编译工程
    • 编译流程
    • 两种构建方式
  • 实例展示

参考:
基于VSCode和CMake实现C/C++开发 | Linux篇

语法

基本语法格式:指令(arg1 arg2 …)

  • 参数使用括弧括起来
  • 参数之间使用空格或者分号分开
    指令是大小写无关的,参数和变量是大小写相关的
set(HELLO hello.cpp) # 将hello.cpp 作为一个名为 HELLO 的变量
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})

变量使用方式取值,但是在IF控制语句里面直接使用变量名,例如:‘IF(HELLO)‘而不是‘IF({}方式取值,但是在IF控制语句里面直接使用变量名,例如:`IF(HELLO)`而不是`IF(IF使IF(HELLO)IF({HELLO})`

一些重要指令

  • cmake_minimum_required : 用来指定CMake的最小版本要求
# CMake最小版本要求为2.8.3
cmake_minimum_required(VERSION 2.8.3)
  • project :用来定义工程名称,并可指定工程支持的语言
project(HELLOWORLD C)
  • set :显示的定义变量
# 定义SRC变量,其值为sayhello.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
  • include_directories :向工程添加多个特定的头文件搜索路径->相当于指定g++编译器的-I参数
# 将usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
include_directories(usr/include/myincludefolder ./include)
  • link_directories:向工程添加多个特定的库文件搜索路径->相当于指定g++编译器的-L参数
# 将usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
link_directories(usr/lib/mylibfolder ./lib)
  • add_library :生成库文件
# 通过变量 SRC 生成 libhello.so 共享库
add_library(hello SHARED ${SRC})
  • add_compile_options :添加编译参数
# 添加编译参数 -Wall -std=c++11 -O2
add_compile_options(-Wall -std=c++11 -O2)
  • add_executable:生成可执行文件
# 编译main.cpp生成可执行文件main
add_executable(main main.cpp)
  • target_link_libraries:为target添加需要链接的共享库->相当于指定g++编译器的-l 参数
# 将hello动态库链接到可执行文件main上
target_link_libraries(main hello)
  • add_subdirectory:向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
# 添加src子目录,src中需要有一个CMakeLists.txt
add_subdirectory(src)
  • aux_source_directory :发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令被用来临时自动构建源文件列表
# 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})

CMake常用变量

  • CMAKE_C_FLAGS :gcc编译选项
  • CMAKE_CXX_FLAGS:g++编译选项
# 在编译选项后追加-std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  • CMAKE_BUILD_TYPE:编译类型(Debug,Release)
# 设定编译类型为debug,调试时需要选择debug
set(CMAKE_BUILD_TYPE Debug)
# 设定编译类型为release,发布时需要选择release
set(CMAKE_BUILD_TYPE Release)
  • CMAKE_BINARY_DIRPROJECT_BINARY_DIR_BINARY_DIR

这三个变量指代的内容是一致的
如果是 in source build,指的是工程顶层目录
如果是out-of-source编译,指的是工程编译发生的目录

  • CMAKE_SOURCE_DIRPROJECT_SOURCE_DIR_SOURCE_DIR

这三个变量指代内容一致,不管采用何种编译方式,都是工程顶层目录
in source build时,与CMAKE_BINARY_DIR等变量一致

  • CMAKE_C_COMPILER:指定C编译器
  • CMAKE_CXX_COMPILER:指定C++编译器
  • EXECUTABLE_OUTPUT_PATH:可执行文件输出的存放路径
  • LIBRARY_OUTPUT_PATH:库文件输出的存放路径

CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件
一般有两种方式设置编译规则
1、包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeList.txt通过add_subdirectory添加子目录即可
2、包含源文件的子文件夹未包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中

编译流程

在linux下使用CMake构建C/C++工程的流程如下:

  • 手写CMakeLists.txt文件
  • 执行命令cmake PATH生成Makefile(PATH是顶层CMakeLists.txt所在的目录)
  • 执行命令make进行编译

两种构建方式

1、内部构建(in-source build):这种方式不推荐使用
内部构建会在同级目录下产生一大堆中间文件,和工程源文件放在一起会显得杂乱无章

# 内部构建
# 在当前目录下,编译本目录的CMakeLists.txt,生成Makefile文件和其他文件
cmake .
# 执行make命令,生成target
make

2、外部构建(out-of-source build) :这种方式推荐使用
该方式将编译输出文件和源文件放在不同目录中

# 外部构建
# 1、在当前目录下,创建build文件夹
mkdir build
# 2、进入build文件夹
cd build
# 3、编译上级目录的CMakeList.txt ,生成Makefile和其他文件
cmake ..
# 4、执行make,生成目标文件
make

实例展示

实例一

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$   tree
.
├── hello
└── hello.cpp

hello.cpp内容为:

#include<iostream>
using namespace std;
int main()
{cout << "hello world!" << endl;return 0;
}      

我们进入目录,然后输入:
code . 这样就能打开vscode了
我们要给这个最简单的cpp程序写一个CMakeLists.txt
CMakeLists.txt一般处于项目的顶层目录,此处就在文件夹下了
一般来说,在vscode中写cmakelists的话会有只能提示的,如果你装了插件的话

# 指定最低版本要求
cmake_minimum_required(VERSION 3.0)
# 指定项目名称
project(HELLO)
# 指定生成的可执行文件的名字 源文件
add_executable(hello_cmake hello.cpp)
## 此时等价于 g++ hello.cpp -o hello_cmake

接下来我们在vscode的终端里面进行外部构建并编译
在这里插入图片描述我们在终端下使用tree命令看看文件结构:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$ tree
.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.16.3
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── hello_cmake.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── hello.cpp.o
│   │   │   ├── link.txt
│   │   │   └── progress.make
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   ├── hello_cmake
│   └── Makefile
├── CMakeLists.txt
├── hello
└── hello.cpp

此时发现可执行文件是在build文件夹下的
实例二
此处用到的实例请参考:
gcc 编译器使用指南
此时工程结构如下:

.
├── include
│   └── swap.h
├── main.cpp
├── sharemain
├── src
│   ├── libswap.a
│   ├── libswap.so
│   ├── swap.cpp
│   └── swap.o
└── staticmain

然后写cmakelists.txt

cmake_minimum_required(VERSION 3.0)project(SWAP)
# 与 -Iinclude 命令对应
include_directories(include)# 此命令相当于 g++ main.cpp src/swap.cpp -Iinclude -o main_cmake
add_executable(main_cmake main.cpp src/swap.cpp)

然后执行cmake、make:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ mkdir build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ cd build/
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ cmake ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dyy/Desktop/GCCTEST/build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ make
Scanning dependencies of target main_cmake
[ 33%] Building CXX object CMakeFiles/main_cmake.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/main_cmake.dir/src/swap.cpp.o
[100%] Linking CXX executable main_cmake
[100%] Built target main_cmake
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ ./main_cmake 
before
10 20
after
20 10

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

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

相关文章

DNS安全浅议、域名A记录(ANAME),MX记录,CNAME记录

相关学习资料 http://baike.baidu.com/link?url77B3BYIuVsB3MpK1nOQXI-JbS-AP5MvREzSnnedU7F9_G8l_Kvbkt_O2gKqFw7vm http://www.rfc-editor.org/rfc/rfc1035.txt http://www.rfc-editor.org/rfc/rfc3596.txt http://www.rfc-editor.org/rfc/rfc2782.txt http://www.rfc-edito…

【blade利刃出鞘】一起进入移动端webapp开发吧

前言 在移动浪潮袭来的时候&#xff0c;小钗有幸进入框架组做webapp框架开发&#xff0c;过程中遇到了移动端的各种坑&#xff0c;也产生了各种激情&#xff0c;就我们公司的发展历程来说 第一阶段&#xff1a;使用传统方式开发移动站点&#xff0c;少量引入HTML5元素 第二阶段…

Android静态图片人脸识别的完整demo(附完整源码)

Demo功能&#xff1a;利用android自带的人脸识别进行识别&#xff0c;标记出眼睛和人脸位置。点击按键后进行人脸识别&#xff0c;完毕后显示到imageview上。 第一部分&#xff1a;布局文件activity_main.xml [html] view plaincopyprint?<RelativeLayout xmlns:android&qu…

图论:最短路径搜索--Dijkstra算法(c代码实现)

最近因为辞职&#xff0c;有不少闲功夫&#xff0c;重温下数据结构&#xff0c;顺便练练手。今天说说最短路径搜索算法中的Dijkstra原理和实现。 一&#xff1a;简介 这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点&#xff0c;求图中其它节点到此源节点的…

C++多线程快速入门(五)简单线程池设计

目录设计思路主线程运行逻辑task以及taskpool设计详细流程讲解完整代码打印结果往期回顾设计思路 线程池实际上就是一组线程&#xff0c;当我们需要异步执行一些任务时&#xff0c;经常要通过OS频繁创建和销毁线程&#xff0c;不如直接创建一组在程序生命周期内不会退出的线程…

C++网络编程快速入门(一):TCP网络通信基本流程以及基础函数使用

目录流程概述服务器端代码实现客户端代码实现函数和结构讲解sockaddr_in和sockaddrsocket &#xff1a; 创建一个socket连接bind &#xff1a;绑定地址以及端口号问题流程概述 客户端与服务器之间的网络通信基本原理如下所示&#xff0c;复杂一点的架构可能会添加消息中间件。…

使用前端框架Foundation 4来帮助简化响应式设计开发

日期&#xff1a;2013-3-12 来源&#xff1a;GBin1.com Foundation是一套使用广泛的前端开发套件&#xff0c;可以帮助你快速的网站。最近ZURB发布了一个新版本的Foundation 4前端框架&#xff0c;能够有效的帮助你快速的开发响应式的网站。 和另外一个套知名的前端框架BootSt…

C++网络编程快速入门(二):Linux下使用select演示简单服务端程序

目录select参数解释select使用规范select使用缺点基本流程实例代码通信效果演示往期文章select参数解释 extern int select (int __nfds, fd_set *__restrict __readfds,fd_set *__restrict __writefds,fd_set *__restrict __exceptfds,struct timeval *__restrict __timeout)…

Android转载一:Android文件命名规范

REF&#xff1a;http://blog.csdn.net/gulianchao/article/details/23391651 (一) Layout命名 1&#xff0e;contentview命名&#xff1a;activity_功能模块.xml 例如&#xff1a;activity_main.xml、activity_more.xml 2&#xff0e;Dialog命名&#xff1a;dialog_描述.xml …

C++网络编程快速入门(三):阻塞与非阻塞式调用网络通信函数

目录阻塞与非阻塞定义send与recvconnect一些问题为什么要将监听socket设置为非阻塞阻塞与非阻塞定义 阻塞模式指的是当前某个函数执行效果未达预期&#xff0c;该函数会阻塞当前的执行线程&#xff0c;程序执行流在超时时间到达或者执行成功后恢复原有流程。非阻塞模式相反&am…

socket 端口和地址复用

https://blog.csdn.net/weibo1230123/article/details/79978745 https://blog.csdn.net/weixin_42157432/article/details/115560824 在linux socket网络编程中&#xff0c;大规模并发TCP或UDP连接时&#xff0c;经常会用到端口复用&#xff1a; int opt 1; if (setsockopt…

MyEclipse老是弹出problem occurred窗口

有的时候是因为jsp页面中的java脚本有误&#xff0c;比如说<% String name"";>就会出现错误&#xff0c;因为结束标签少了一个百分号&#xff05;。转载于:https://www.cnblogs.com/passer1991/archive/2013/03/15/2961624.html

Mysql中代替like模糊查询的一种方法

使用Mysql的函数instr,可代替传统的like方式查询,并且速度更快。 instr函数&#xff0c;第一个参数是字段&#xff0c;第二个参数是要查询的串&#xff0c;返回串的位置&#xff0c;第一个是1&#xff0c;如果没找到就是0. 例如&#xff1a; select username from prefix_user …

Linux网络故障排查命令(ifconfig、ping、telnet、netstat、lsof、nc、curl、tcpdump)

目录ifconfig-s&#xff0c;显示网卡信息的精简列表-a、up、down将IP地址绑定到某个网卡&#xff0c;以及解绑操作pingtelnetnetstatlsofnc模拟一个服务器程序和客户端程序进行通信发送文件curltcpdump参数连接一个正常的监听端口ifconfig 该命令用来查看当前系统的网卡和IP地…

My Oracle Support Metalink站点最近将放弃flash界面转而使用ADF HTML

根据oracle官方博客的报道《The New My Oracle Support User Interface (HTML-based) 》&#xff0c; MY ORACLE SUPPORT开发team会在最近将support.oracle.com站点从原来的flash界面迁移到基于ADF HTML的用户界面上。 实际上在2012年的 January 27&#xff0c; MOS开发team就…

心跳检测以及应用层心跳包机制设计

博主联系方式&#xff1a; QQ:1540984562 微信&#xff1a;wxid_nz49532kbh9u22 QQ交流群&#xff1a;750313950&#xff08;嵌入式方向&#xff09; QQ交流群&#xff1a;856398158&#xff08;后端方向&#xff09; 目录心跳检测应用场景死连接情况保活传递有效业务数据心跳包…

一个DBA的工作写照

一个DBA的工作写照&#xff0c; 一个DBA的内心 Know the DBA Mind! DBA也是 IT民工啊&#xff0c; 民工何苦为难民工&#xff01; 转载于:https://www.cnblogs.com/macleanoracle/archive/2013/03/19/2968227.html

UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)

题意&#xff1a;给一个元素周期表的元素符号&#xff08;114种&#xff09;&#xff0c;再给一个串&#xff0c;问这个串能否有这些元素符号组成&#xff08;全为小写&#xff09;。 解法1&#xff1a;动态规划 定义&#xff1a;dp[i]表示到 i 这个字符为止&#xff0c;能否有…

hdu 1025(最长非递减子序列的n*log(n)求法)

题目链接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1025 经典题。。。最长非递减序列的n*log(n)求法。。。orz... View Code 1 #include<iostream>2 const int N500007;3 using namespace std;4 int city[N];5 int dp[N];//dp[i]保存的是长度为i的最长不降…

消息队列重要机制讲解以及MQ设计思路(kafka、rabbitmq、rocketmq)

目录《Kafka篇》简述kafka的架构设计原理&#xff08;入口点&#xff09;消息队列有哪些作用&#xff08;简单&#xff09;消息队列的优缺点&#xff0c;使用场景&#xff08;基础&#xff09;消息队列如何保证消息可靠传输死信队列是什么&#xff1f;延时队列是什么&#xff1…