Visual Studio 2022使用MinGW来编译调试C/C++程序

本文详细介绍了如何在Visual Studio 2022中配置CMake以使用MinGW编译器(GCC和Clang)进行C/C++程序的编译和调试。通过修改CMakePresets.json或CMakeSettings.json文件,设置编译器路径和IntelliSense模式,并配置调试器以使用GDB。同时,针对遇到的问题如Clang编译器与lld链接器的冲突,给出了相应的解决方法。


Visual Studio的新版本已经可以像VSCode一样创建CMake项目了,但是默认的情况下是使用的Visual Studio编译器及调试器不包括MinGW中的工具集,参见下面的默认可选工具集:

在这里插入图片描述

本文就以实例来简单介绍一下VS2022中如何使用MinGW来编译、调试C/C++程序。
本文链接地址:https://blog.csdn.net/witton/article/details/126211289?spm=1001.2014.3001.5501

一、创建项目

首先,创建一个新项目:

在这里插入图片描述

然后,选择CMake项目:

在这里插入图片描述

填写项目名称,比如test

在这里插入图片描述

项目创建好后如下所示,由于笔者并未安装VS的Windows C/C++开发工具,也就没有VS的C/C++编译、调试器,所以会报错。

在这里插入图片描述

二、配置CMake

在VS2022中CMake的配置有两个文件,一个是“CMakePresets.json”,另一个是“CMakeSettings.json”,在VS的“工具”/“选项”/“CMake”/“常规”中可以进行设置使用哪个文件来进行CMake配置,如下图所示:

在这里插入图片描述

默认是如果有“CMakePresets.json”则使用“CMakePresets.json”,否则使用“CMakeSettings.json”。
下面就分别介绍如何使用这两个文件来配置CMake,二选一即可。

1.修改“CMakePresets.json”预设编译工具集

新建项目后,默认是生成了“CMakePresets.json”,打开“CMakePresets.json”,可以看到默认的编译是cl.exe

在这里插入图片描述

A. 使用MinGW GCC编译器

为了使用MinGW中编译器,将之改为gcc.exe和g++.exe(必须在PATH路径中可以找到),如下图所示:

在这里插入图片描述

此时即可正常编译了:

在这里插入图片描述

但是此时的智能感知识别并未正常工作,无法跳转到定义,此时需要设置智能感知模式(intelliSenseMode),打开“CMakePresets.json”,在cacheVariables后添加:

"vendor": {
          "microsoft.com/VisualStudioSettings/CMake/1.0": {
            "intelliSenseMode": "linux-gcc-x86"
          }
        }

即:

"cacheVariables": {
          "CMAKE_C_COMPILER": "gcc.exe",
          "CMAKE_CXX_COMPILER": "g++.exe"
        },
        "vendor": {
          "microsoft.com/VisualStudioSettings/CMake/1.0": {
            "intelliSenseMode": "linux-gcc-x86"
          }
        },

如果是64位程序,则将"linux-gcc-x86"改为"linux-gcc-x64"。

B. 使用MinGW Clang编译器

如果想要使用MinGW中的Clang编译器,则将之改为clang.exe和clang++.exe(必须在PATH路径中可以找到),如下图所示:
在这里插入图片描述
此时检测到Clang编译器为with GNU-like command-line
在这里插入图片描述

VS会自动设置环境变量:

CXXFLAGS=--target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths
CFLAGS=--target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths

在这里插入图片描述

如果没有安装Clang的lld链接器,则会报错:

1> [CMake] -- The C compiler identification is Clang 17.0.6 with GNU-like command-line
1> [CMake] -- The CXX compiler identification is Clang 17.0.6 with GNU-like command-line
1> [CMake] -- Detecting C compiler ABI info
1> [CMake] -- Detecting C compiler ABI info - failed
1> [CMake] -- Check for working C compiler: G:/msys64/mingw64/bin/clang.exe
1> [CMake] -- Check for working C compiler: G:/msys64/mingw64/bin/clang.exe - broken
1> [CMake] CMake Error at C:/Program Files/Microsoft Visual Studio/2022/Enterprise/Common7/IDE/CommonExtensions/Microsoft/CMake/CMake/share/cmake-3.28/Modules/CMakeTestCCompiler.cmake:67 (message):
1> [CMake]   The C compiler
1> [CMake] 
1> [CMake]     "G:/msys64/mingw64/bin/clang.exe"
1> [CMake] 
1> [CMake]   is not able to compile a simple test program.
1> [CMake] 
1> [CMake]   It fails with the following output:
1> [CMake] 
1> [CMake]     Change Dir: 'C:/Users/Admin/Desktop/CMakeProject1/out/build/x64-debug/CMakeFiles/CMakeScratch/TryCompile-c7naid'
1> [CMake]     
1> [CMake]     Run Build Command(s): "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe" -v cmTC_a96c0
1> [CMake]     [1/2] G:\msys64\mingw64\bin\clang.exe   --target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths  -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview -MD -MT CMakeFiles/cmTC_a96c0.dir/testCCompiler.c.obj -MF CMakeFiles\cmTC_a96c0.dir\testCCompiler.c.obj.d -o CMakeFiles/cmTC_a96c0.dir/testCCompiler.c.obj -c C:/Users/Admin/Desktop/CMakeProject1/out/build/x64-debug/CMakeFiles/CMakeScratch/TryCompile-c7naid/testCCompiler.c
1> [CMake]     [2/2] C:\Windows\system32\cmd.exe /C "cd . && G:\msys64\mingw64\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib --target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths  -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview -Xlinker /subsystem:console CMakeFiles/cmTC_a96c0.dir/testCCompiler.c.obj -o cmTC_a96c0.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:cmTC_a96c0.lib -Xlinker /pdb:cmTC_a96c0.pdb -Xlinker /version:0.0   -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames  && cd ."
1> [CMake]     FAILED: cmTC_a96c0.exe 
1> [CMake]     C:\Windows\system32\cmd.exe /C "cd . && G:\msys64\mingw64\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib --target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths  -O0 -D_DEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd -g -Xclang -gcodeview -Xlinker /subsystem:console CMakeFiles/cmTC_a96c0.dir/testCCompiler.c.obj -o cmTC_a96c0.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:cmTC_a96c0.lib -Xlinker /pdb:cmTC_a96c0.pdb -Xlinker /version:0.0   -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames  && cd ."
1> [CMake]     clang: error: unable to execute command: program not executable
1> [CMake] 
1> [CMake]     clang: error: linker command failed with exit code 1 (use -v to see invocation)
1> [CMake] 
1> [CMake]     ninja: build stopped: subcommand failed.
1> [CMake]     
1> [CMake]     
1> [CMake] 
1> [CMake]   
1> [CMake] 
1> [CMake]   CMake will not be able to correctly generate this project.
1> [CMake] Call Stack (most recent call first):
1> [CMake]   CMakeLists.txt:14 (project)
1> [CMake] -- Configuring incomplete, errors occurred!

在这里插入图片描述
从上面的日志可以看出clang.exe -fuse-ld=lld-link使用了lld-link命令,在MSYS2中使用命令:
pacman -S mingw-w64-x86_64-lld
安装即可。

如果不想安装,也可以在CMakePresets.json中设置环境变量:

"environment": {
  "CFLAGS": "",
  "CXXFLAGS": ""
},

去掉VS默认的target为msvc的参数,这样检测到Clang编译器不再带有with GNU-like command-line
在这里插入图片描述

C. 生成时输出命令行详细信息:

有时需要在生成时查看详细的命令行信息,可以在CMakePresets.json文件点右键添加生成预设

在这里插入图片描述
在生成的buildPresets中添加verbosetrue即可:

"buildPresets": [
  {
      "name": "x64-debug",
      "displayName": "x64 Debug",
      "description": "自定义生成预设说明",
      "configurePreset": "x64-debug",
      "verbose": true
  }
]

在这里插入图片描述

2.使用CMake设置编辑器来配置CMake

新建的项目,默认是生成的“CMakePresets.json”预设文件,先将之删除掉或者在VS选项中设置CMake为“从不使用CMakePresets.json”,然后在项目中选择“test的CMake设置”,此时项目中会创建一个CMakeSettings.json的文件

在这里插入图片描述

双击即可打开CMake的设置编辑器,如下图所示:

在这里插入图片描述

此时工具集中是默认可用的工具集,可以看到并没有MinGW。点击右边的“编辑JSON”,即可看到JSON格式的配置文件:

在这里插入图片描述

删除"inheritEnvironments"所在行,并添加:

"variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "gcc",
          "type": "FILEPATH"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "g++",
          "type": "FILEPATH"
        }
      ],
      "intelliSenseMode": "linux-gcc-x64"

或者直接在配置中选中“x64-Debug"删除掉

在这里插入图片描述

然后再添加MinGW配置
在这里插入图片描述

此时工具集中可以看到MinGW了:

在这里插入图片描述

在下面的CMake变量中可以看到重新定义了CMAKE_C_COMPILER和CMAKE_CXX_COMPILER变量:

在这里插入图片描述

如果没有定义env.BIN_ROOT变量则会找不到gcc和g++,可以直接使用PATH变量,所以把CMAKE_C_COMPILER改为gcc,CMAKE_CXX_COMPILER改为g++即可:

在这里插入图片描述

强烈推荐使用此方式来设置为MinGW,它会自动设置intelliSenseMode为"linux-gcc-x64":

在这里插入图片描述

不管是使用CMake的预设文件“CMakePresets.json”还是“CMakeSettings.json”都只是设置了编译器为MinGW中的gcc/g++,目前只能编译,不能使用gdb调试。

三、配置调试

想要调试,需要做如下设置,在“解决方案资源管理器”中的CMakeLists.txt文件上右键,在弹出的菜单中选择“添加调试配置”,如下图所示:

在这里插入图片描述

然后在弹出的“选择调试程序”对话框中选择“MinGW/Cygin(gdb)的C/C++启动”,如下图所示:

在这里插入图片描述

此时会创建一个launch.vs.json文件,如下图所示:

在这里插入图片描述

将"projectTarget"设置为编译的exe文件,这里为test.exe;把"miDebuggerPath"设置成"gdb.exe"(要求gdb.exe在PATH路径中);将gdb的反汇编格式设置为intel格式,如下所示:

{
  "version": "0.2.1",
  "defaults": {},
  "configurations": [
    {
      "type": "cppdbg",
      "name": "CMakeLists.txt",
      "project": "CMakeLists.txt",
      "projectTarget": "test.exe",
      "cwd": "${workspaceRoot}",
      "program": "${debugInfo.target}",
      "MIMode": "gdb",
      "miDebuggerPath": "gdb.exe",
      "externalConsole": true,
      "setupCommands": [
        {
          "description": "为 gdb 启用整齐打印",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        },
        {
          "description": "将反汇编风格设置为 Intel",
          "text": "-gdb-set disassembly-flavor intel",
          "ignoreFailures": true
        }
      ]
    }
  ]
}

再把调试目标设置为“CMakeLists.txt”,

在这里插入图片描述

此时我们直接按F5键即可进行调试:

在这里插入图片描述

VS2022 17.8.3 版本默认设置了两个环境变量:

CXXFLAGS=--target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths
CFLAGS=--target=amd64-pc-windows-msvc -fdiagnostics-absolute-paths

这会导致MinGW中的Clang编译出现问题,解决办法是在CMakeLists.txt中的project语句之前添加如下代码:

if(DEFINED ENV{CFLAGS})
message(STATUS $ENV{CFLAGS})
unset(ENV{CFLAGS})
endif()
if(DEFINED ENV{CXXFLAGS})
message(STATUS $ENV{CXXFLAGS})
unset(ENV{CXXFLAGS})
endif()

至此就可以畅快地在Visual Studio中使用MinGW开发调试C/C++程序了。

笔者后面还有一系列的Visual Studio 2022的相关博文:

Visual Studio 2022 CMake+MinGW+GDB 调试目标程序
Visual Studio 2022使用CMake+MinGW+Clang+LLDB作为开发环境
Visual Studio 2022连接远程系统进行C/C++开发
VS2022解决Protobuf compiler version 23.4 doesn‘t match library version 4.23.4

如果本文对你有帮助,欢迎点赞收藏!

评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值