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,一经查实,立即删除!

相关文章

idhttp.post方式 调用datasnap rest 远程方法

idhttp.get方式调用&#xff0c;这种比较简单&#xff0c;大家都会。post方式网上却没有任何成功的代码&#xff0c;本人也是摸索了一个上午才搞定。 分享给大家。 &#xff08;1&#xff09;post方式调用的远程方法&#xff0c;方法名必须加“update”前缀&#xff0c;不加行不…

[转]连接excel数据源时,首行包含列名称选项在连接字符串中的设置。

关于Excel导入的HDRYES; IMEX1详解 ProviderMicrosoft.Jet.OLEDB.4.0;Data Source111.xls;Extended Properties"Excel 8.0;HDRNO"; 其中HDRNO或YES即首行包含列名称选项 (参数HDR的值&#xff1a;HDRYes&#xff0c;这代表第一行是标题&#xff0c;不做为数据使用&am…

C++多线程快速入门(一):基本常用操作

目录case1&#xff1a;创建线程1 join、detachcase2&#xff1a;创建线程2 线程传参 传值或者传引用case3&#xff1a;创建线程 线程传参 functional object作为参数case4&#xff1a;观察多线程程序加速计算case5&#xff1a;future get 获取并发结果case6&#xff1a;互斥锁…

android:configChanges属性总结

原文地址&#xff1a;http://blog.csdn.net/zhaokaiqiang1992/article/details/19921703 android中的组件Activity在manifest.xml文件中可以指定参数android&#xff1a;ConfigChanges&#xff0c;用于捕获手机状态的改变。 在Activity中添加了android:configChanges属性&#…

eclipse 中修改 M2_REPO的值

从eclipse中增加了maven2的插件之后&#xff0c;maven默认的本地库的路径是${user}/.m2/repository/下&#xff0c;一般windows用户的操作系统都安装在C盘&#xff0c;所以这个目录 下的jar包比较危险。我尝试从myeclipse->preferences->java->build path->classpa…

C++多线程快速入门(二)共享数据同步以及数据竞争

目录std::unique_lock类模板仅调用一次线程局部存储原子变量往期内容回顾std::unique_lock类模板 互斥锁保证了线程间的同步&#xff0c;却将并行操作变成了串行操作&#xff0c;对性能有较大影响&#xff0c;所以我们要尽可能减小锁的区间粒度。 lock_guard只能保证在析构的时…

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…

ThinkInJava4读书笔记之第一章对象入门

那句话怎么说来着&#xff0c;原句记不住了好像是出来混的迟早要还的。话说当初学校刚开Java课程&#xff0c;自己没有好好学啊&#xff0c;后来直接做了jsp和servlet&#xff0c;然后学了SSH框架和Extjs、jQuery&#xff0c;接着是mybatis&#xff08;ibatis&#xff09;、fre…

C++多线程快速入门(三):生产者消费者模型与条件变量使用

互斥锁完成 #include <iostream> #include <deque> #include <thread> #include <mutex>std::deque<int> q; std::mutex mtx;static void produce(int val) {while(val--) {std::unique_lock<std::mutex> guard(mtx);q.push_front(val);m…

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

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

题目理解。。

有时候一道大水题&#xff0c;因为英文描述可能有点复杂或者其它云云&#xff0c; 就比如那道PRO。。 别先被一道题吓一跳&#xff0c;&#xff0c;&#xff0c; 英文描述看深入一点总归会能解决的&#xff0c;尽可能多的考虑情况。大胆尝试。转载于:https://www.cnblogs.com/c…

C++多线程快速入门(四)shared_mutex以及读写锁应用

在前面的三讲中我们使用的mutex都是普通的std::mutex&#xff0c;这里介绍一下shared_mutex&#xff0c;版本为C17 std::shared_mutex的底层实现时操作系统提供的读写锁&#xff0c;在读多写少的情况下&#xff0c;该shared_mutex比mutex更加高效。 它提供了常用的四种方法&am…

Tornado/Python 学习笔记(一)

1.源代码下载及安装&#xff1a;http://www.tornadoweb.org/en/stable/ 2.python中xmlrpc库官方文档&#xff1a;https://docs.python.org/3/library/xmlrpc.html?highlightxmlrpc 3.xml介绍与学习&#xff1a;http://www.w3school.com.cn/xml/xml_intro.asp XML 被设计为传输…

spring-aop-annotation

1。假设你已经配好依赖注入那一块。此时的bean.xml为 <?xml version"1.0" encoding"UTF-8"?><beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:cont…

c++实现简单线程池代码

目录完整代码TaskPool.cppTaskPool.hmain.cpp完整代码 TaskPool.cpp // // Created by LENOVO on 2021/10/25. //#include "TaskPool.h" #include <functional>std::mutex printMutex;TaskPool::TaskPool() : m_bRunning(false) {}TaskPool::~TaskPool() {re…

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--函数

函数:具有特定功能的代码段,分为库函数,自定义函数. 函数定义: 函数返回值类型 函数名(形式参数列表) { 代码段; return 返回值; } 注意:每个函数返回值最多只有一个.return是一个函数结束的标志. 形式参数(形参):函数定义时使用的虚拟参数名,用以接收函数调用是传递过来的实际…

公式系统 - TradeBlazer公式基础 - Bar数据

Bar数据 在介绍Bar数据之前&#xff0c;首先&#xff0c;我们需要讨论一下TradeBlazer公式的计算方法&#xff0c;针对上面介绍的各种公式类型&#xff0c;包含公式应用&#xff0c;在公式进行计算时&#xff0c;都是建立在基本数据源(Bar数据)之上&#xff0c;我们这里所谓的B…