本文介绍如何使用CMake与mingw进行C/C++代码的开发编译调试工作
1、为什么使用 VsCode + CMake + mingw
- 本人也用过一段时间VS,如果只想编写windows平台的软件,无疑用VS会更香,若想要代码跨平台运行,那么VS可能没那么方便,并且根据当下国际环境,大厂都需要排除涉A软件,因此暂时也用不上VS。
- 使用VS替代品 CLion,在公司开发中,使用CLion作为主力开发软件,CLion是JB公司旗下的一款产品,主要用于C/C++的开发,若没听过 CLion 的同学,应该也用过鼎鼎大名的 pythonIDE —— PyCharm,没错,就是他们家的,两个软件的操作方式大致相同,因此会用一个之后,也会使用另外一个。
CLion 本身默认集成了CMake来构建工程,因此天生对跨平台的支持比较好,同时有win版本、Linux版本、Mac版本,而且对于重构来说非常方便,支持的重构方法基本能够满足日常的重构需求,缺点是需要Licenses(有pojie绿色版,但是没找到最新版的,自行寻找资源)个人使用的话成本比较高,而且是基于java虚拟机上运行,默认虚拟机内存2G,需要手动调整配置文件,修改java虚拟机内存,否则会容易出现卡顿的情况。 - 对于个人使用来说,工程代码量不大的情况下(<1W行),其实用VsCode也可,特别是想做小工具跨平台使用,或者平时学习代码都可。
2、环境配置
- 下载VsCode,官网下即可
- 下载mingw ,最好选择别人打包好的,官网下载的文件,需要进软件内选择下载的内容,一般会比较慢,暂时先懒得上传,人多需要我再打包我的文件吧。
- 下载 CMake,官网 https://cmake.org/download/
- 配置VsCode,首先需要安装插件
C/C++ C++ Intellisense CMake CMake tools CMake Tools Helper
- 设置环境变量,将安装好的mingw与cmake的bin文件夹添加到PATH
- 新建工程,个人习惯按照下面的目录结构来组成
3、第一个工程
接下来创建一个可用的工程模板,构建了第一个后,其他工程基于模板来复制一份即可。
3.1 编写工程文件
这个部分设计3个非常简单的文件,实现hello world功能:func.c 、func.h 、main.c。
- func.c 位于src文件夹,实现一个打印输出函数
#include "stdio.h" void FUNC_Print(void) { printf("Hello, this is print function.\n"); }
- func.h 位于src文件夹,声明函数
#ifndef FUNC_H #define FUNC_H void FUNC_Print(void); #endif
- main.c 位于test文件夹,主函数
#include "func.h" int main(void) { FUNC_Print(); return 0; }
3.2 编写CMake文件
本工程中分了3个CMake文件,根目录CMake、src目录CMake、test目录CMake
- 根目录CMake负责管理该工程的版本、编译选项、需要编译的库等内容
cmake_minimum_required(VERSION 3.16) PROJECT(example) set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") include_directories(.) include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/include) add_subdirectory(src) add_subdirectory(test)
- src目录CMake负责管理源码目录的库的构建,将src中的源码生成1个或多个库,供外部链接使用,同时可以按照需要,自行再src中增加文件夹与CMake
PROJECT(mytest) aux_source_directory(. SRC) add_library(mytest ${SRC})
- test目录CMake负责链接测试代码所需要使用的库,并生成可执行文件,用于运行或调试
PROJECT(main) aux_source_directory(. SRC) add_executable(main ${SRC}) target_link_libraries(main mytest)
- CMake比较简单,更多CMake语法的知识暂时不展开,后续再开一个文章来记录,读者需提前自行找资料学习一下
3.3 编写vscode启动调试文件
这部分分为2个文件,一般来说只需再新建工程模板的时候需要配置,之后直接复制该模板,就基本不需要改动,了解即可
- launch.json,这个文件是VsCode调用可执行文件的配置,以及GDB路径的设置,其他设置可以鼠标悬停来查看详细描述
{ "version": "0.2.0", "configurations": [ { "name": "gcc.exe - 生成和调试活动文件", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}\\build\\test\\main.exe", // 生成的可执行文件 "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "D:\\work\\mingw64\\bin\\gdb.exe", // gdb 的路径 "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true } ], } ] }
- settings.json,设置编译器默认配置
{ "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools" }
4、构建并调试工程
4.1 构建工程,生成可执行文件
为了不想让CMake执行后的缓存与Makefiile文件在工程的各个目录下满天飞,引入了build目录,将过程文件都统一存放在buiild中,保持工程目录的整洁。
构建工程有2个步骤:
- 进入build目录,使用CMake生成Makefiles
若是第一次构建工程,带上 -G 参数,CMake 总是需要找到CMakeList.txt 作为入口,由于在该工程下,工程根目录下的CMakeList.txt 是主入口(多团队开发的工程,可以不止一个CMake入口)cd .\build\
若是之后构建,直接cmake …cmake .. -G "Unix Makefiles"
cmake ..
- 使用make构建工程,直接在build目录下,执行make命令即可生成exe文件,
代码行数稍微多一点的,可以带上 -j 参数,开启多线程编译,线程不是开的越多越好,受编译器优化与能否并行处理的文件影响,所以并不是成倍的缩减时间,一般做法是根据CPU的线程数来设置即可,例如我的是6核12线程,那么使用 -j12,也能达到比较快的编译效果。make
make -j12
如果是第一次用,这一步一般会提示找不到make的,不要慌,这是因为mingw的make是带前缀的,需要重命名。
进入mingw的bin文件夹内,找到一个叫mingw-make.exe的文件,复制一个,改成make就好了,由于前面已经将这个目录路径加到系统变量里,所以其他地方直接用make的话就可以调用它。接下来在重新 make 试试吧。
4.2 运行与调试
launch.json 文件中已经配置好 gdb 的路径,因此调试的过程中,vscode会以来gdb的命令,好处是不需要手动的敲gdb命令,可以可视化的看到栈、变量值、地址等信息,同时也可打断点。
按F5即可启动调试,若没有打断点,则直接运行,可以在终端看到运行的结果,蓝色框中的是按F5后,执行的命令,红色框则是运行程序的输出。
OK,至此已经搭建完工程,后续有新的项目需要,直接按照这个套路搭建环境,或者拷贝一份过去改也行,其实想要利用vscode跑通工程,关键是要配置json文件即可,CMake的话,一处通,处处通,因为CMake的本质是跨平台构建工具,语法简单好用,更加不会受编辑器的限制。