IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> VScode C++ 开发 (六):CMake -> 正文阅读

[开发工具]VScode C++ 开发 (六):CMake

前言

  • CMake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)。
  • CMake可以说已经成为大部分C++开源项目标配

1. Cross-platform development

Let’s assume you have some cross-platform project with C++ code shared along different platforms/IDEs. Say you use Visual Studio on Windows, Xcode on OSX and Makefile for Linux:
在这里插入图片描述
What you will do if you want to add new bar.cpp source file? You have to add it to every tool you use:
在这里插入图片描述
To keep the environment consistent you have to do the similar update several times. And the most important thing is that you have to do it manually (arrow marked with a red color on the diagram in this case). Of course such approach is error prone and not flexible.

CMake solve this design flaw by adding extra step to development process. You can describe your project in CMakeLists.txt file and use CMake to generate tools you currently interested in using cross-platform CMake code:
在这里插入图片描述
Same action - adding new bar.cpp file, will be done in one step now:

在这里插入图片描述
Note that the bottom part of the diagram was not changed. I.e. you still can keep using your favorite tools like Visual Studio/msbuild, Xcode/xcodebuild and Makefile/make!

2. 语法特性介绍

基本语法格式:指令(参数 1 参数 2…)

  • 参数使用括弧括起
  • 参数之间使用空格或分号分开
  • 指令是大小写无关的,参数和变量是大小写相关的
1 set(HELLO hello.cpp)
2 add_executable(hello main.cpp hello.cpp)
3 ADD_EXECUTABLE(hello main.cpp ${HELLO})
  • 变量使用${}方式取值,但是在 IF 控制语句中是直接使用变量名

3. 重要指令和CMake常用变量

3.1 重要指令

  • cmake_minimum_required - 指定CMake的最小版本要求
1 # CMake最小版本要求为2.8.3
2 cmake_minimum_required(VERSION 2.8.3)

语法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])

- project - 定义工程名称,并可指定工程支持的语言

1 # 指定工程名为HELLOWORLD
2 project(HELLOWORLD)

语法:project(projectname [CXX] [C] [Java])

  • set - 显式的定义变量
1 # 定义SRC变量,其值为main.cpp hello.cpp
2 set(SRC sayhello.cpp hello.cpp)
  • include_directories - 向工程添加多个特定的头文件搜索路径 —>相当于指定g++编译器的-I参数
1 # 将/usr/include/myincludefolder 和 ./include 添加到头文件搜索路径
2 include_directories(/usr/include/myincludefolder ./include)

- link_directories - 向工程添加多个特定的库文件搜索路径 —>相当于指定g++编译器的-L参数

1 # 将/usr/lib/mylibfolder 和 ./lib 添加到库文件搜索路径
2 link_directories(/usr/lib/mylibfolder ./lib)

- add_library - 生成库文件

1 # 通过变量 SRC 生成 libhello.so 共享库
2 add_library(hello SHARED ${SRC})

语法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)

  • add_compile_options - 添加编译参数
1 # 添加编译参数 -Wall -std=c++11
2 add_compile_options(-Wall -std=c++11 -O2)
  • add_executable - 生成可执行文件
1 # 编译main.cpp生成可执行文件main
2 add_executable(main main.cpp)

语法:add_library(exename source1 source2 … sourceN)

  • target_link_libraries - 为 target 添加需要链接的共享库 —>相同于指定g++编译器-l参数
1 # 将hello动态库文件链接到可执行文件main
2 target_link_libraries(main hello)

语法:target_link_libraries(target library1library2…)

  • add_subdirectory - 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
1 # 添加src子目录,src中需有一个CMakeLists.txt
2 add_subdirectory(src)

语法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

  • aux_source_directory - 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
1# 定义SRC变量,其值为当前目录下所有的源代码文件
2 aux_source_directory(. SRC)
3 # 编译SRC变量所代表的源代码文件,生成main可执行文件
4 add_executable(main ${SRC})

语法:aux_source_directory(dir VARIABLE)

3.2 CMake常用变量

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

CMAKE_BINARY_DIR
PROJECT_BINARY_DIR

__BINARY_DIR
1.这三个变量指代的内容是一致的。
2.如果是 in source build,指的就是工程顶层目录。
3.如果是 out-of-source 编译,指的是工程编译发生的目录。
4.PROJECT_BINARY_DIR 跟其他指令稍有区别,不过现在,你可以理解为他们是一致的。

CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
__SOURCE_DIR

  1. 这三个变量指代的内容是一致的,不论采用何种编译方式,都是工程顶层目录。
  2. 也就是在 in source build时,他跟 CMAKE_BINARY_DIR 等变量一致。
  3. PROJECT_SOURCE_DIR 跟其他指令稍有区别,现在,你可以理解为他们是一致的。

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

4 CMake编译工程

CMake目录结构:项目主目录存在一个CMakeLists.txt文件

两种方式设置编译规则:

  1. 包含源文件的子文件夹包含CMakeLists.txt文件,主目录的CMakeLists.txt通过add_subdirectory添加子目录即可;
  2. 包含源文件的子文件夹未包含CMakeLists.txt文件,子目录编译规则体现在主目录的CMakeLists.txt中;

4.1 编译流程

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

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

4.2 两种构建方式

**内部构建(in-source build):**不推荐使用

内部构建会在同级目录下产生一大堆中间文件,这些中间文件并不是我们最终所需要的,和工程源文件放在一起会显得杂乱无章。

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

外部构建(out-of-source build):推荐使用

将编译输出文件与源文件放到不同目录中

1 ## 外部构建
2
3 # 1. 在当前目录下,创建build文件夹
4 mkdir build 
5 # 2. 进入到build文件夹
6 cd build
7 # 3. 编译上级目录的CMakeLists.txt,生成Makefile和其他文件
8 cmake .. #.. CMakeLists.txt 所在目录
9  4. 执行make命令,生成target
10 make

5 【实战】CMake代码实践

针对第五章写的两个小项目来写对应的CMakeLists.txt:github地址

5.1 最小CMake工程

1 # Set the minimum version of CMake that can be used
2 cmake_minimum_required(VERSION 3.0)
3
4 # Set the project name
5 project (HELLO)
6
7 # Add an executable
8 add_executable(hello_cmake main.cpp)

5.2 多目录工程 - 直接编译

 1 # Set the minimum version of CMake that can be used
 2 cmake_minimum_required(VERSION 3.0)
 3
 4 #project name
 5 project(SWAP)
 6
 7 #head file pat
 8 include_directories( include )
 9
10 #source directory files to var
11 add_subdirectory( src DIR_SRCS )
12
13 #add executable file  
14 add_executable(swap_02 ${TEST_MATH})
15
16 #add link library  
17 target_link_libraries(${FS_BUILD_BINARY_PREFIX}sqrt ${LIBRARIES}) 

5.3 多目录工程 - 生成库编译

1 # Set the minimum version of CMake that can be used
2 cmake_minimum_required(VERSION 3.0)
3
4 #project name  
5 project(SWAP_LIBRARY)
6
7 #add compile options
8 add_compile_options("-Wall -std=c++11")
9
10 #set CMAKE_BUILD_TYPE
11 set( CMAKE_BUILD_TYPE Debug ) 
12
13 # set output binary path  
14 set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
15
16 ############################################################
17 # Create a library
18 ############################################################
19
20 #Generate the static library from the library sources
21 add_library( swap_library STATIC src/Swap.cpp )
22
23 target_include_directories( swap_lib PUBLIC ${PROJECT_SOURCE_DIR}/include )
24
25 ############################################################
26 # Create an executable
27 ############################################################
28
29 # Add an executable with the above sources
30 add_executable( swap_01 main.cpp )
31
32 # link the new swap_01 target with the swap_lib target
33 target_link_libraries( swap_01 swap_liby )
  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:09:16  更:2022-01-01 14:11:34 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:34:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码