VS Code 为 Clang for MSVC 配置 cmake & cmake tools

2023-11-08

介绍

  在windows平台上,由于平台API差异过大,一般为linux设计的项目(POSIX兼容)无法通过MSVC的编译,而是会报非常多的头文件错误。如果要修改,工程量将巨大。Windows平台上,主要有两个类POSIX兼容平台,可以在Windows系统上编译运行为Linux编写的程序(功能支持不完整)。

  1. MinGW Minimalist GNU for Windows: 是将GCC编译器和GNU工具链套件移植到Windows平台下的产物。
  2. LLVM/Clang for Windows: Clang编译器对Windows Target的适配。由于LLVM框架的结构,只需要开发Windows平台对应的后端,而不需要进行迁移。LLVM在Windows平台的后端主要采用Visual Studio的MSVC编译器。

  cmake是一个跨平台项目编译工具,通过CMakeLists.txt文件,可以方便地管理项目文件,并灵活地组织编译。根据工具链的不同,编译结果可以应用于各个平台上。例如,Linux系统中,cmake可以编译出Makefile,并交给linux平台的make程序进行编译。

  一个项目需要在Windows平台上编译,但是是面向linux编写的(Makefile),这时候就需要使用Windows平台上的工具链进行编译。但是,多文件项目管理复杂,一个一个文件进行编译较为繁琐,这时候,就可以使用cmake工具辅助进行编译

  笔者是VS Code重度依赖用户,所以在VS Code上利用cmake tools进行配置。当然也可以使用命令行或是cmake-gui进行配置,只不过cmake tools更加集成和方便。

安装Clang-CL & CMake

Clang-CL for MSVC可以在Visual Studio的组件中找到

在这里插入图片描述

CMake可以在官网下载,安装后注意检查PATH,是否添加cmake

CMake & Toolkits

我们应当明确几个编译概念:

  • Build System 编译系统:又称为Generator 生成器,是编译工具根据规则编译、链接文件的系统,按照是否集成交互,可分为;
    • IDE Build Tool Generators 用于IDE的Build System,生成的项目可以直接被IDE打开、编辑,例如Visual Studio Generators
    • Command-Line Build Tool Generators,使用命令行进行编译构建,有编译工具链即可工作,不需要IDE支持,例如,Make构建系统(即Linux中使用Makefile进行构建的系统),以及Ninja(一套更轻量的命令行构建系统,是CMake Tools 的默认构建系统)
  • Build Toolkits 编译工具链:是直接参与编译、生成可执行文件的一系列工具,包括Compiler 编译器, Linker 链接器等。主流的工具链如下:
    • GNU/GCC: GNU项目组的编译工具链,主要运用于Linux系统,其在Windows上的迁移版本称为MingGW
    • LLVM/Clang:LLVM编译基础设施,采用模块化设计,前后端分离工作,能够很好地适配多种前端语言和后端平台,是越来越流行的编译工具链
    • Visual C++:微软开发的C/C++编译工具链,集成在Visual Studio上,主要用于Windows平台下的程序开发,即MSVC

编译系统使用编译工具链,按照开发者指定的编译规则进行程序的编译链接。那么,CMake属于哪里?CMake 属于更上一层的编译工具,使用CMake,可以生成任何一种适配的Build System所需要的规则,然后再调用这些Build System进行程序编译。

配置 cmake toolkits

在VS Code中,安装插件CMake Tools,并在项目目录中创建CMakeLists.txt文件,插件被激活后,状态栏会显示CMake Toolkits, Build Variant, Build Target等信息。如果是第一次在项目中使用插件,Toolkits工具链会显示No Kit Selected,单击该按钮,出现选择框。

在这里插入图片描述
初次配置,点击Scan for kits,工具会自动扫描电脑上安装的工具链。

Clang for MSVC 对应有四条(名称已经被我修改,正常情况下还有版本信息),Build Target有x86和x64,命令行接口有GNU CLI和MSVC CLI。

接下来,检查工具链配置参数,Ctrl+Shift+P,打开Command Palette,输入cmake kits -> 编辑用户本地CMake 工具包,这会打开一个json文件。
在这里插入图片描述

部分配置如下:

  {
    "name": "Clang 14.0.5 (GNU CLI) for MSVC (VS Community 2022 Release - x86)",
    "visualStudio": "8b689476",
    "visualStudioArchitecture": "x86",
    "compilers": {
      "C": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang.exe",
      "CXX": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\bin\\clang.exe"
    }
  },
  {
    "name": "Clang 14.0.5 (MSVC CLI) for MSVC (VS Community 2022 Release - x64)",
    "visualStudio": "8b689476",
    "visualStudioArchitecture": "x64",
    "preferredGenerator": {
      "name": "Visual Studio 17 2022",
      "platform": "x64",
      "toolset": "ClangCL"
    },
    "compilers": {
      "C": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\x64\\bin\\clang-cl.exe",
      "CXX": "C:\\Program Files\\Microsoft Visual Studio\\2022\\Community\\VC\\Tools\\Llvm\\x64\\bin\\clang-cl.exe"
    }
  },
  • 对于MSVC CLI,Scan kit默认配置为MSVC Generator,注意检查toolset,必须修改为ClangCL,若为host=xxx,则仍将通过传统MSVC工具链编译,仍会遇到API不适配问题
  • 对于GNU CLI,默认配置为Ninja Generator,是一套轻量级、高效率的命令行构建系统,也可以根据需要修改preferredGenerator为MSVC工具链

编译与常用选项

状态栏选项

在这里插入图片描述

  • Build Variant (构建变体,编译选项……XD, anyway):选择工具链的编译输出模式,常见的有Debug调试模式(包含调试信息)、Release发布模式(去除调试信息,增加优化)
  • ToolKits 工具链:为项目选择编译工具链(跨平台项目使用交叉编译工具链)
  • Build 编译:点击编译(Not install)
  • Build Target:编译目标,选择编译哪个项目,默认为[all]全部编译,但是速度很慢,注意更换
  • Debug\Run:调试、运行,不多介绍

Command Palette 命令选项卡

使用命令选项卡可以进行更加完整的配置,常用的有两个:

  • CMake Clean:清除编译文件
  • CMake Install:进行编译安装,将按照CMakeLists.txt指定的安装配置进行生成工具的安装

常见问题与解决方案

Include error - file not found

IDE中显示这个错误,通常有两种来源:

  1. Compiler 编译器错误 (似乎通常显示gcc):此类问题通常不会通过build,是编译阶段报错导致,需要找到include失败原因(没有配置引用等),解决后有时需要删cmake cache重新检测,如果能通过编译,一般此问题会消除。另一种可能是没有执行cmake configure,在command palette 进行cmake: Configure即可修复。
  2. 仅显示 file not found而没有其他提示,这是C/C++ Clang adapter 的报错,这个插件功能完全冗余,而且配置未知,直接卸载即可。

示例

在一个目录下,创建如下文件

G:.
│  CMakeLists.txt
├─include
│      hello_lib.h
├─lib
│  │  CMakeLists.txt
│  ├─include
│  │      hello_lib.h
│  └─src
│          hello_lib.c
└─src
        hello.c
// hello.c
#include <Windows.h>
#include <stdio.h>
#include "hello_lib.h"

int main() {
	printf("Hello World!\n");
	DbgPrint("%s\n", "Hello World");	// defined in hello_lib
	return 0;
}
// hello_lib.h
#include <Windows.h>
#include <stdio.h>
#include <debugapi.h>
#include <stdarg.h>

void DbgPrint(char* FormatStr, ...);
// hello_lib.c
#include "hello_lib.h"

void DbgPrint(char* FormatStr, ...)
{
	char dbgout[1000];
	va_list vaList;

	va_start(vaList, FormatStr);
	sprintf(dbgout, FormatStr, vaList);
	OutputDebugStringA(dbgout);
	va_end(vaList);
}

然后配置CMakeLists:

root

cmake_minimum_required(VERSION 3.0)

project(HELLO)

add_subdirectory(lib)

aux_source_directory(src src_dir)
add_executable(hello ${src_dir})

target_include_directories(hello PUBLIC ${PROJECT_SOURCE_DIR}/include)
target_link_libraries(hello PUBLIC hello_lib)
  • add_subdirectory 增加子项目
  • target_link_libraries 链接库,hello_lib在子项目中定义

lib

cmake_minimum_required(VERSION 3.0)

project(HELLO_LIB)

aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src src_dir)
add_library(hello_lib STATIC ${src_dir})

target_include_directories(hello_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
  • add_library(STATIC)添加静态库

最后,build,输出结果:

[build]   hello_lib.vcxproj -> G:\C\Cmake Test\build\lib\Debug\hello_lib.lib
[build]   hello.c
[build]   hello.vcxproj -> G:\C\Cmake Test\build\Debug\hello.exe
[build] Build finished with exit code 0
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VS Code 为 Clang for MSVC 配置 cmake & cmake tools 的相关文章

  • 无法打开 Python。错误 0xc000007b

    我最近一直在学习 Python 3 我在我的上网本 32 位 Windows 7 上创建简单的小程序没有任何问题 当我将它安装在我的上网本上时 我没有遇到任何问题 但现在我已经开始使用它了 我想将它安装在我的台式机上 并且我有一个 我的桌面
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • Cygwin 下使用 CMake 编译库

    我一直在尝试使用 CMake 来编译 TinyXML 作为一种迷你项目 尝试学习 CMake 作为补充 我试图将其编译成动态库并自行安装 以便它可以工作 到目前为止 我已经设法编译和安装它 但它编译成 dll 和 dll a 让它工作的唯一
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • C# 中值类型和引用类型有什么区别? [复制]

    这个问题在这里已经有答案了 我知道一些差异 值类型存储在堆栈上 而引用类型存储在托管堆上 值类型变量直接包含它们的值 而引用变量仅包含对托管堆上创建的对象位置的引用 我错过了任何其他区别吗 如果是的话 它们是什么 请阅读 堆栈是一个实现细节
  • 如何在 WPF RichTextBox 中跟踪 TextPointer?

    我正在尝试了解 WPF RichTextBox 中的 TextPointer 类 我希望能够跟踪它们 以便我可以将信息与文本中的区域相关联 我目前正在使用一个非常简单的示例来尝试弄清楚发生了什么 在 PreviewKeyDown 事件中 我
  • 使用 C# 在 WinRT 中获取可用磁盘空间

    DllImport kernel32 dll SetLastError true static extern bool GetDiskFreeSpaceEx string lpDirectoryName out ulong lpFreeBy
  • 写入和读取文本文件 - C# Windows 通用平台应用程序 Windows 10

    有用 但在显示任何内容之前 您必须在文本框中输入内容 我想那是因为我使用了 TextChanged 事件处理程序 如果我希望它在没有用户交互的情况下显示文本文件的内容 我应该使用哪个事件处理程序 因此 我想在按下按钮时将一些数据写入 C W
  • win32 GUI 应用程序在作为“app.exe --help”调用时将使用文本写入标准输出

    如何创建执行以下操作的 Windows 应用程序 当不使用命令行参数调用时 它是一个常规的 GUI 应用程序 指定可选的 help 命令行参数会导致应用程序将使用文本写入标准输出 然后终止 它必须是单个可执行文件 让控制台应用程序执行第二个
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • 使用安全函数在 C 中将字符串添加到字符串

    我想将文件名复制到字符串并附加 cpt 但我无法使用安全函数 strcat s 来做到这一点 错误 字符串不是空终止的 我确实设置了 0 如何使用安全函数修复此问题 size strlen locatie size nieuw char m
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • 如何使用 ReactiveList 以便在添加新项目时更新 UI

    我正在创建一个带有列表的 Xamarin Forms 应用程序 itemSource 是一个reactiveList 但是 向列表添加新项目不会更新 UI 这样做的正确方法是什么 列表定义 listView new ListView var
  • 将变量分配给另一个变量,并将一个变量的更改反映到另一个变量中

    是否可以将一个变量分配给另一个变量 并且当您更改第二个变量时 更改会瀑布式下降到第一个变量 像这样 int a 0 int b a b 1 现在 b 和 a 都 1 我问这个问题的原因是因为我有 4 个要跟踪的对象 并且我使用名为 curr
  • 如何连接字符串和常量字符?

    我需要将 hello world 放入c中 我怎样才能做到这一点 string a hello const char b world const char C string a hello const char b world a b co

随机推荐

  • 靶形数独

    我终于AC了 毒瘤卡常题 pragma GCC optimize 1 pragma GCC optimize 2 pragma GCC optimize 3 pragma GCC optimize Ofast pragma GCC opti
  • kettle 转换命名参数从将上一转换的参数传递到下一转换中

    kettle 转换命名参数从将上一转换的参数传递到下一转换中 1 知识点 1 如何将转换中的行记录传递到job 结果 中 2 如何使用转换的命名参数功能获取到上一转换中的参数 2 需求及实现 1 需求 如下图所示在转换1中将转换中的结果值传
  • 一起来算圆周率

    转载自 http www guokr com blog 444081 自古计算圆周率是数学界一项流行运动 各大数学家争相破记录以名垂青史 想象有人为圆周率15年如一日地算 算的不是圆周率而是寂寞啊 自有圆周率 计算比的是数学 后有现代数学
  • r语言怎么把txt数据变成一个Rdata格式_R语言 第2章 数据对象与数据读写(8)

    Rcurl举例 读取拉手深圳美食搜索 解析页面内容 获取门店名称 描述 优惠价 门店价 课后练习1 读取系统日期时间 进行变量类型的转换 对转换前后的变量类型进行辨别对比 1 使用读取系统当前日期时间的3个函数 Sys Date Sys t
  • mac环境搭建

    macpro 11 开发环境搭建 一 基础软件安装 1 1 安装nginx 参考 https www jianshu com p 4f433d219ab7 现在mac认为root安装软件过于危险 不推荐用root账号安装软件 brew in
  • RK3568 应用层 libhwjpeg.so 硬件编解码的使用

    libhwjpeg是RK封装的一个对MJPEG数据进行硬件编解码的so 用起来还是比较方便 相比软编效率也有提升 应用层没有提供接口 所以需要自己封装JNI接口 在SDK hardware rockchip libhwjpeg test 下
  • IDEA 远程断点调试

    IDEA 远程断点调试 有时候 有些bug无法在本地环境复现 此时就需要我们去线上的机器远程debug 可以采用idea Remove JVM Debug模式 首先 点击Edit Configurations 然后点击左上角的Add New
  • Raspberry Pi和Python校准惯性测量单元-陀螺仪-加速度计-磁力计

    惯性测量单元校准 惯性测量单元 IMU 可以由单个传感器或传感器集合组成 这些传感器或传感器集合捕获旨在测量给定参考系中的惯性运动的数据 加速度 旋转速度和磁场强度是IMU中包含的传感器的示例 IMU可以在智能设备 医疗康复 通用机器人 制
  • 修改apk连接服务器地址,修改apk连接服务器地址

    修改apk连接服务器地址 内容精选 换一换 FTP SFTP连接适用于从线下文件服务器或ECS服务器上迁移文件到OBS或数据库 当前仅支持Linux操作系统的FTP 服务器 连接FTP或SFTP服务器时 他们的连接参数相同 如表1所示 FT
  • 【Python蓝桥杯】成绩统计 小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数。

    最近在刷蓝桥杯题目 按题目做一下笔记整理 顺便分享交流一下 有更好的解决方案欢迎大家共同提出探讨 以下源代码为系统提交满分答案 成绩统计 问题描述 资源限制 Python时间限制 1s 内存限制 256M 问题描述 小蓝给学生们组织了一场考
  • freeswitch部署及网关调试

    freeswitch部署及网关调试 目录 freeswitch部署及网关调试 1 一 freeswitch部署 3 一 基础部署 3 二 根据实际情况需求的部署配置 4 1 freeswitch开启支持音频和视频 4 2 配置联通 电信双线
  • 华为OD机试真题 Java 实现【跳房子II】【2023 B卷 100分】,附详细解题思路

    一 题目描述 跳房子 也叫跳飞机 是一种世界性的儿童游戏 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格 然后获得一次选房子的机会 直到所有房子都被选完 房子最多的人获胜 跳房子的过程中 如果有踩线等违规行为会结束当前回合 甚至
  • C++最简单的一个小小计算机

    这个小小计算机主要以前边为函数 在main函数里才开始调用并实现各种用户的指令功能 include
  • 什么是多态,多态的实现

    目录 1 多态的概念 1 1概念 2 多态的好处 3 多态的实现思路 4 多态的实现方式 4 1向上转型对象与向下转型对象 4 2接口实现多态 1 多态的概念 1 1概念 多态是面向对象三大特征之一 多态通俗来说 就是多种形态 具体点就是去
  • Python 对图像进行base64编码及解码读取为numpy、opencv、matplot需要的格式

    Python 对图像进行base64编码及解码读取为numpy opencv matplot需要的格式 1 效果图 2 源码 参考 这篇博客将介绍Python如何对图像进行base64编解码及读取为numpy opencv matplot需
  • 手把手教你用Keras实现英文到中文机器翻译 seq2seq+LSTM

    原文链接 https blog csdn net qq 44635691 article details 106919244 该模型实现的是英文到中文的翻译 下图为了更好展示模型架构借用大佬的图 这里没有用到Embeddings 本文完整代
  • spring boot 定时任务管理

    spring boot 有scheduler 可以做定时任务 我们也可以通过scheduler做定时任务管理 实现新增 删除 修改定时任务功能 先创建线程池 package cn com cgn config import org spri
  • 学习大数据的第三天——Java基础语法的学习3

    学习大数据的第三天 Java基础语法的学习3 循环结构的第二种 while循环 语句定义格式 基本格式 while 判断条件语句 循环体语句 扩展格式 初始化语句 while 判断条件语句 循环体语句 控制条件语句 while循环可以和fo
  • 自动删除java不可达代码_java unreachable code不可达代码

    例子 static int test int testval int target 1 if testval gt target System out println 1 return 1 下边是永远不会达到的代码 所以编译器提示错误 un
  • VS Code 为 Clang for MSVC 配置 cmake & cmake tools

    介绍 在windows平台上 由于平台API差异过大 一般为linux设计的项目 POSIX兼容 无法通过MSVC的编译 而是会报非常多的头文件错误 如果要修改 工程量将巨大 Windows平台上 主要有两个类POSIX兼容平台 可以在Wi