Visual Studio 2022使用CMake+MinGW+Clang+LLDB作为开发环境

news2024/11/29 12:40:56

笔者前面写了两篇关于Visual Studio 2022使用MinGW的博文:《Visual Studio 2022使用MinGW来编译调试C/C++程序》、《Visual Studio 2022 CMake+MinGW+GDB 调试目标程序》,这两篇博文都是介绍的是GCC+GDB的编译与调试,本文笔者介绍的则是Clang+LLDB的编译与调试。读完本文,读者可以在GCC、Clang与GDB、LLDB之间进行随意组合。

GCC与GDB的编译调试组合在Linux下是默认组合,像Linux内核以及Linux的绝大多数软件都是使用GCC来编译,使用GDB来调试的。Clang+LLDB是作为新秀存在的,在近年来的MacOS中却是作为默认的编译调试组合。Clang作为编译器的新秀,是有许多优点的,比如Clang的编译速度比GCC快许多,编译出的错误提示非常友好,模块化比GCC做得好等等;LLDB调试器也有许多优点,比如下面一段代码,引用笔者前面的博文《对C++变长参数中的字符串进行转义》

template<typename ... Args>
string FormatSQL(const char* fmt, Args&& ... args)
{
	vector<char*> vct;
	size_t len = strlen(fmt);
	string str;
	Concat(str, len, fmt, EscapeArg(len, vct, args)...);
	for (auto iter : vct)
		delete[] iter;
	return str;
}

在调试到Concat(str, len, fmt, EscapeArg(len, vct, args)...);时,默认情况下,使用GDB进入EscapeArg函数执行到最后一句时,在VS中按F10执行逐过程,就会跳过Concat函数,即不会进入Concat函数,需要按F11执行逐语句,才会进入Concat函数,这个行为与VC的调试器不一致,而LLDB就与VC的调试器的行为一致,按F10执行逐过程可以进入Concat函数。GDB的这种行为不知道是否可以配置,有知道的读者可以在评论区留言或者讨论。

一、在MinGW中安装Clang和LLDB

MinGW的安装这里就不再赘述了,直接去MSYS2官网就可以下载最新的MinGW安装包安装就可以了。

安装好MinGW后,在MinGW终端使用下面的命令安装Clang和LLDB:

pacman -S mingw-w64-x86_64-clang
pacman -S mingw-w64-x86_64-clang-tools-extra
pacman -S mingw-w64-x86_64-clang-analyzer
pacman -S mingw-w64-x86_64-lldb
pacman -S mingw-w64-x86_64-lldb-mi

二、Visual Studio 2022配置

Visual Studio 2022有一系列的CMake模板配置,有本机VC的,有WSL的、有MinGW的,有ARM的,也有Linux远程的:

在这里插入图片描述

这些模板配置位于Visual Studio 2022的安装目录C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMakeSettingsTemplates,该目录下有许多json文件:

在这里插入图片描述

MinGW的相关配置就在MinGW.json中,内容如下:

{
  "configurations": [
    {
      // Test Comment
      "environments": [
        {
          "MINGW64_ROOT": "C:/msys64/mingw64",
          "BIN_ROOT": "${env.MINGW64_ROOT}/bin",
          "FLAVOR": "x86_64-w64-mingw32",
          "TOOLSET_VERSION": "9.1.0",
          "PATH": "${env.MINGW64_ROOT}/bin;${env.MINGW64_ROOT}/../usr/local/bin;${env.MINGW64_ROOT}/../usr/bin;${env.MINGW64_ROOT}/../bin;${env.PATH}",
          "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION};${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/tr1;${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/${env.FLAVOR}",
          "environment": "mingw_64"
        }
      ],
      "name": "Mingw64-Debug",
      "description": "TemplateDescription_Localize_Mingw64Debug",
      "generator": "Ninja",
      "configurationType": "Debug",
      "inheritEnvironments": [
        "mingw_64"
      ],
      "buildRoot": "${projectDir}\\out\\build\\${name}",
      "installRoot": "${projectDir}\\out\\install\\${name}",
      "cmakeCommandArgs": "",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "intelliSenseMode": "linux-gcc-x64",
      "variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "${env.BIN_ROOT}/gcc.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "${env.BIN_ROOT}/g++.exe"
        }
      ]
    },
    {
      "environments": [
        {
          "MINGW64_ROOT": "C:/msys64/mingw64",
          "BIN_ROOT": "${env.MINGW64_ROOT}/bin",
          "FLAVOR": "x86_64-w64-mingw32",
          "TOOLSET_VERSION": "9.1.0",
          "PATH": "${env.MINGW64_ROOT}/bin;${env.MINGW64_ROOT}/../usr/local/bin;${env.MINGW64_ROOT}/../usr/bin;${env.MINGW64_ROOT}/../bin;${env.PATH}",
          "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION};${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/tr1;${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/${env.FLAVOR}",
          "environment": "mingw_64"
        }
      ],
      "name": "Mingw64-Release",
      "description": "TemplateDescription_Localize_Mingw64Release",
      "generator": "Ninja",
      "configurationType": "RelWithDebInfo",
      "inheritEnvironments": [
        "mingw_64"
      ],
      "buildRoot": "${projectDir}\\out\\build\\${name}",
      "installRoot": "${projectDir}\\out\\install\\${name}",
      "cmakeCommandArgs": "",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "intelliSenseMode": "linux-gcc-x64",
      "variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "${env.BIN_ROOT}/gcc.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "${env.BIN_ROOT}/g++.exe"
        }
      ]
    }
  ]
}

(一)、GCC配置

1.配置MinGW根目录和TOOLSET_VERSION

可以看到MinGW中分别配置了Mingw64-DebugMingw64-Release,里面配置了MinGW的环境变量,使用的编译器,编译目录、安装目录等等。MinGW的安装目录默认为C:/msys64/mingw64,可以根据自己的实际情况更改安装目录以及TOOLSET_VERSION,比如笔者的GCC目前已经更新到13.1.0了,所以需要把TOOLSET_VERSION修改为13.1.0,否则可能会在VS中无法打开头文件。

2.配置调试格式

GCC与Clang在编译时添加调试信息的参数默认都是-g,但是各自生成的调试格式是不一定相同的。

GCC的官方文档解释-g

-g
Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
On most systems that use stabs format, -g enables use of extra debugging information that only GDB can use; this extra information makes debugging work better in GDB but probably makes other debuggers crash or refuse to read the program. If you want to control for certain whether to generate the extra information, use -gvms (see below).

即使用的操作系统本地的调试格式,可能是stabs或者COFF或者XCOFF或者 DWARF,GDB是可以识别这些调试格式的。

Clang的官方文档:

-g
Generate complete debug info.

Controlling Debugger “Tuning”
While Clang generally emits standard DWARF debug info (http://dwarfstd.org), different debuggers may know how to take advantage of different specific DWARF features. You can “tune” the debug info for one of several different debuggers.
-ggdb, -glldb, -gsce, -gdbx
Tune the debug info for the gdb, lldb, Sony PlayStation® debugger, or dbx, respectively. Each of these options implies -g. (Therefore, if you want both -gline-tables-only and debugger tuning, the tuning option must come first.)

即默认是使用标准的DWARF格式,GDB是可以识别的,所以GCC与Clang使用参数-g生成的程序,都可以使用GDB来调试。

LLDB官方文档中提到的功能说明:

Debug symbol file parsers to incrementally extract debug information from object files. Support currently includes DWARF & Mach-O symbol tables.

即目前LLDB只支持DWARFMach-O符号表,那MinGW中就只能是DWARF了。DWARF格式目前已经发展到第5个版本了,LLDB目前只支持到第4个版本。

所以为了让GDB与LLDB都能进行调试,在使用GCC编译时需要指定调试格式为DWARF,即需要使用参数-gdwarf-4

前面的json文件中variables部分添加CMAKE_C_FLAGS_DEBUGCMAKE_CXX_FLAGS_DEBUG变量,如下配置:

"variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "${env.BIN_ROOT}/gcc.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "${env.BIN_ROOT}/g++.exe"
        },
		{
          "name": "CMAKE_C_FLAGS_DEBUG",
          "value": "-gdwarf-4",
          "type": "STRING"
        },
		{
          "name": "CMAKE_CXX_FLAGS_DEBUG",
          "value": "-gdwarf-4",
          "type": "STRING"
        }
      ]

(二)、Clang配置

Clang编译器可以使用GCC的库libstdc++,也可以使用Clang自己的C++库libc++(参见笔者之前的博文《CentOS 6.X安装GCC 9.1和LLVM/Clang 8.0》中的CLANG_DEFAULT_CXX_STDLIB说明),Clang的libc++库头文件是在v1目录中,所以配置时需要让Clang可以查找到GCC的头文件以及Clang的头文件目录。TOOLSET_VERSION还是填写MinGW中当前安装的GCC的版本号,然后在environmentsINCLUDE中添加${env.MINGW64_ROOT}/include/c++/v1variables设置编译器为clang.exe以及clang++.exe

"variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "${env.BIN_ROOT}/clang.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "${env.BIN_ROOT}/clang++.exe"
        }
      ]

由于Clang在MinGW默认就是使用的dwarf格式,所以可以不用指定。下面列出Mingw64-Clang-Debug的完整配置:

{
      // Test Comment
      "environments": [
        {
          "MINGW64_ROOT": "H:/msys64/mingw64",
          "BIN_ROOT": "${env.MINGW64_ROOT}/bin",
          "FLAVOR": "x86_64-w64-mingw32",
          "TOOLSET_VERSION": "13.1.0",
          "PATH": "${env.MINGW64_ROOT}/bin;${env.MINGW64_ROOT}/../usr/local/bin;${env.MINGW64_ROOT}/../usr/bin;${env.MINGW64_ROOT}/../bin;${env.PATH}",
          "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}/include/c++/v1;${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION};${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/tr1;${env.MINGW64_ROOT}/include/c++/${env.TOOLSET_VERSION}/${env.FLAVOR}",
          "environment": "mingw_64"
        }
      ],
      "name": "Mingw64-Clang-Debug",
      "description": "TemplateDescription_Localize_Mingw64ClangDebug",
      "generator": "Ninja",
      "configurationType": "Debug",
      "inheritEnvironments": [
        "mingw_64"
      ],
      "buildRoot": "${projectDir}\\out\\build\\${name}",
      "installRoot": "${projectDir}\\out\\install\\${name}",
      "cmakeCommandArgs": "",
      "buildCommandArgs": "-v",
      "ctestCommandArgs": "",
      "intelliSenseMode": "linux-gcc-x64",
      "variables": [
        {
          "name": "CMAKE_C_COMPILER",
          "value": "${env.BIN_ROOT}/clang.exe"
        },
        {
          "name": "CMAKE_CXX_COMPILER",
          "value": "${env.BIN_ROOT}/clang++.exe"
        }
      ]
    },

配置好后可以在CMakeSettings对话框中看到:
在这里插入图片描述

如果要使用Clang的libc++库,CMakeLists.txt中添加下面两句:

add_compile_options("-stdlib=libc++")
link_libraries(c++)

(三)、GDB调试配置

下面直接列出一个简单的配置:

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

可以参见:《Visual Studio 2022使用MinGW来编译调试C/C++程序》、《Visual Studio 2022 CMake+MinGW+GDB 调试目标程序》

如果每次都添加setupCommands命令,也比较烦,我们可以在USERPROFILE环境变量所指目录中添加一个.gdbinit文件,将上面的命令放在里面,每次GDB启动时都会去执行里面的命令:

set disassembly-flavor intel

(四)、LLDB配置

LLDB配置与GDB配置类似:

{
      "type": "cppdbg",
      "name": "CMakeLists.lldb",
      "project": "CMakeLists.txt",
      "projectTarget": "t.exe",
      "cwd": "${workspaceRoot}",
      "program": "${debugInfo.target}",
      "MIMode": "lldb",
      "miDebuggerPath": "${env.MINGW_PREFIX}\\bin\\lldb-mi.exe",
      "externalConsole": true,
      "setupCommands": [
        {
          "description": "为 gdb 启用整齐打印",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        },
        {
          "description": "将反汇编风格设置为 Intel",
          "text": "setting set target.x86-disassembly-flavor intel",
          "ignoreFailures": true
        }
      ]
    }

只需要把MIMode改为lldbmiDebuggerPath设置为lldb-mi.exe,如果反汇编格式使用Intel格式的命令为setting set target.x86-disassembly-flavor intel。同样地,为了方便省事,可以在USERPROFILE环境变量所指目录中添加一个.lldbinit文件,将命令放在里面,每次LLDB启动时都会去执行里面的命令:

setting set target.x86-disassembly-flavor intel

Btw:目前Visual Studio 2022使用LLDB调试器对源码反汇编还有Bug,期待新版本能快速修复。VSCode目前也可以使用LLDB进行调试,但是反汇编也是有Bug的

若对你有所帮助,欢迎点赞收藏!

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

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

相关文章

微服务框架 01SOA和传统服务与微服务的差别

SOA思想 1.SOA思想介绍 面向服务的架构&#xff08;SOA&#xff09;是一个组件模型&#xff0c;它将应用程序的不同功能单元&#xff08;称为服务&#xff09;进行拆分&#xff0c;并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的&#xff0c…

20行代码来爬取某某云的榜单音乐

今天来爬爬音乐&#xff0c;一丝丝的无聊 前期准备 软件环境 Python3.8pycharm 模块 requests、re、os 三个 其中requests是第三方模块需要手动安装一下 re、os都是内置模块&#xff0c;不需要安装 浏览器开发者工具 咱们需要学会如何使用开发者工具。 对此很多小伙伴都…

基于Spring Boot的仿豆瓣平台

访问【WRITE-BUG数字空间】_[内附完整源码和文档] 后端为了提高性能和用户体验&#xff0c;该系统平台使用Spring Boot集合Spring&#xff0c;Spring MVC和MyBatis框架做基础&#xff0c;并且集成Spring Data框架&#xff0c;MySQL做数据持久化&#xff0c;Redis缓存提高速度&…

专业解读财务共享实现财务数智化转型的有效路径

近年来&#xff0c;随着数字经济的飞速发展&#xff0c;各大企业全面开启数智化转型之路&#xff0c;作为企业数智化转型的重要内容&#xff0c;财务数智化转型始于财务共享服务。然而&#xff0c;财务共享建设并不是一蹴而就的&#xff0c;如何通过财务共享实现财务数智化转型…

Linux安装与配置ansible

文章目录 Linux安装Ansible一、安装ansible二、配置管理节点和远程主机的连接使用ssh-keygen生成密钥复制SSH密钥到远程主机验证SSH配置 三、主机清单配置文件四、Ansible的配置文件 Linux安装Ansible 在Linux上安装Ansible可以通过以下步骤完成&#xff1a; 一、安装ansible…

npm更换成淘宝镜像源及cnpm使用

1.需求由来 由于node安装插件是从国外服务器下载&#xff0c;受网络影响大&#xff0c;速度慢且可能出现异常。所以如果npm的服务器在中国就好了&#xff0c;所以我们乐于分享的淘宝团队&#xff08;阿里巴巴旗下业务阿里云&#xff09;干了这事。来自官网&#xff1a;“这是一…

Python常见错误(Error)一览大全——初学者必看

路漫漫其修远兮&#xff0c;学习python任重而道远&#xff0c;对于初学者来说&#xff0c;最难受的就是报错&#xff0c;其次是错误翻译好了&#xff0c;可是又不会改了&#xff0c;那么今天&#xff0c;我已IKUN老师的身份&#xff0c;结合我们常见的错误&#xff0c;做一个常…

堆排序之——TopK问题

思维导图&#xff1a; 一&#xff0c;TopK算法的运用 TopK的算法在我们的日常生活中可谓是大有用处&#xff0c;比如你在点外卖时外卖榜单上的销量前几名的筛选&#xff0c;富豪排行榜的榜单人物的筛选&#xff0c;游戏排位……等等领域都会有TopK算法的涉及。TopK问题的用处可…

javaWeb ssh旅游景点网站系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh旅游景点网站系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0…

类型转换-Java 如何计算两个时间的差

一、背景&#xff1a; 今天一个小伙伴在开发中&#xff0c;常取不到数&#xff0c;像string转换int,int转换string 虽然好像只是倒过来了&#xff0c;但是实现的逻辑不一样&#xff0c;今天就是日期在计算过程中的转换做一个总结 二、步聚 1.JAVA中与日期时间相关的类 1.1j…

聚合函数(基础版)

QUESTION ONE: # Write your MySQL query statement below select id,movie,description,rating from cinema where description <> boring and mod(id,2) 1 order by rating desc很简单的两个条件&#xff0c;一个通过 <> 解决不等于的情况&#xff0c;而确定奇…

java基础知识一

1、Java语言概述 1、java的出现标志着真正的分布式系统的到来 2、Java与c的区别 2.1、全局变量 Java中没有全局变量&#xff0c;使用类中的公共的静态变量作为这个类的全局变量 2.2、指针 Java中没有任何在指针操作 2.3、条件转移指令 Java中没有goto语句&#xff0c;通…

【day 01】初始vue

Vue的相关背景&#xff1a; vue2 > vue3 >vue实战 vue Taylor otwell (程序员中的网红) 框架 库 &#xff08;功能 方法&#xff09;axios 框架 生态 引入第三方功能库 社区 Vue2 Vue3 需要准备的小工具 vscode : snipper Vetur 浏览器需要准备 Vue Devtools Vue 引入方式…

nvm版本控制工具安装及使用

一、nvm介绍 nvm全英文也叫node.js version management&#xff0c;是一个nodejs的版本管理工具。nvm和n都是node.js版本管理工具&#xff0c;为了解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js。 二、nvm下载安装及使用 2.1 nvm下载 安装包…

【C++】容器篇(三)—— stack的基本介绍及其模拟实现

前言&#xff1a; 在之前的学习中我们已经了解了 vector 和 list &#xff0c;今天我将带领学习的是关于STL库中的 stack的学习&#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;基本介绍 1、基本概念 2、容器适配器 &#xff08;二&#xff09;基本使…

Flutter 笔记 | Flutter 功能性组件

拦截返回键&#xff08;WillPopScope&#xff09; 为了避免用户误触返回按钮而导致 App 退出&#xff0c;在很多 App 中都拦截了用户点击返回键的按钮&#xff0c;然后进行一些防误触判断&#xff0c;比如当用户在某一个时间段内点击两次时&#xff0c;才会认为用户是要退出&a…

docker 服务环境搭建(mysql、rabbitmq、redis、nginx、springboot)

一般来说一个项目&#xff0c;百分之80都会用到以上这些&#xff0c;尤其是产品初期的demo 这些我都写过博客&#xff0c;但是我每次要去安装&#xff0c;都要去我不同的博客里面翻找&#xff0c;很烦&#xff0c;把他们聚在一起&#xff0c;方便我以后cv&#xff0c;就是这篇博…

注意力Transformer

注意力 注意力分为两步&#xff1a; 计算注意力分布 α \alpha α 其实就是&#xff0c;打分函数进行打分&#xff0c;然后softmax进行归一化 根据 α \alpha α来计算输入信息的加权平均&#xff08;软注意力&#xff09; 其选择的信息是所有输入向量在注意力下的分布 打…

基于中序有序的二叉搜索树

文章目录 什么是二叉搜索树二叉搜索树的中序遍历二叉搜索树的查找查找的非递归写法查找的递归写法 二叉搜索树的插入非递归递归 二叉搜索树的删除非递归递归 二叉搜索树的使用场景k模型kv模型 什么是二叉搜索树 二叉搜索树是普通二叉树的升级&#xff0c;普通二叉树除了存储数…

3、js - 垃圾回收机制

1、基础概念 &#xff08;1&#xff09;js内存的生命周期 -1- 内存分配&#xff1a;当声明变量、函数、对象时&#xff0c;系统会自动分配内存给它们 -2- 内存使用&#xff1a;即读写内存&#xff0c;也就是使用变量、函数 -3- 内存回收&#xff1a;使用完毕&#xff0c;由垃圾…