Skip to content

搭建vscode-cpp环境

2267字约8分钟

2024-11-05

前提介绍

因为本文使用的编译器为Cqwrteur编译的编译器,所以相比mingw-w64的安装包缺少在linux上的常用构建工具makefile,且因为直接解压缩没有写入注册表,环境变量需要读者自己配置。 本文采用ninja作为构建工具,Cmake作为生成.ninja的项目管理工具。

准备工作

1.下载VScode,ninja,Cmake
2.Windows环境下载mingw64
下载链接
3.解压缩x86-64 w64-mingw32
4.添加至用户环境变量PATH
D:\workfile\gcc15\x86_64-w64-mingw32\bin
D:\workfile\gcc15\x86_64-w64-mingw32\lib
D:\workfile\gcc15\x86_64-w64-mingw32\lib32
5.下载c++插件 alt text

Vscode搭配Cmake

首先需要了解Vscode配置的三个重要的json文件,当然你也可以选择手动在命令行输入编译指令与构建命令.

task.json

1.创建一个文件夹vscodestudy,一个main.cpp文件,在文件中复制下列代码

#include<iostream>

int main(){
    std::cout<<"hello world";
}

2.由于你装了之前的CPP插件,右上角有一个三角形的运行按钮,点击;在vscode上方的任务栏中会出现默认生成的任务供你选择。我们选择第二个任务[1]alt text
alt text
这是根据你本地安装的编译器,且在用户变量中配置后,vscode检测到生成的,本文中使用mingw-w64(GCC)编译器,所以只出现了g++相关配置,之后插件会自动生成task.json文件[1:1]
3.这样就拥有了一个单文件的编译器
4.深入了解task.json
ide的本质还是在终端调用对应编译器的命令来进行编译的,task.json文件就是帮我们在终端进行命令的输出,读者可以在vscode下方的终端中输入 g++ -g main.cpp -o main.exe命令来手动编译。

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe 生成活动文件",
            "command": "D:\...\x86_64-w64-mingw32\\bin\\g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

如上是自动生成的task.json,因为插件的原因,当鼠标触碰到对应字段上会显示对应字段的意义,以下选取一些进行讲解. 1.type为自定义的任务类型,当前只需要了解有默认生成的cppbuild,shell,process就好。对于自定义任务,这可以是shell或process。如果指定shell,则该命令将解释为 shell 命令(例如:bash、cmd 或 PowerShell)。如果process指定,则该命令被解释为要执行的进程 2.lable任务标签,你可以按你喜欢的方式取名字
3.command实际执行的命令,如果你像环境变量添加了某些路径那么不需要将完整路径写出,如上文的 g++ -g ...
4.args 不是必要的,某些命令就不需要参数,如执行在本地exe程序 ./main.exe,你可以直接写入在commnd中而不需要任何参数
5.

task.json具体参数

常见问题:

正在启动生成...
cmd /c chcp 65001>nul && D:\workfile\gcc15\x86_64-w64-mingw32\bin\gcc.exe -fdiagnostics-color=always -g C:\Users\Yuzhiy\Desktop\vscodestudy\main.cpp -o C:\Users\Yuzhiy\Desktop\vscodestudy\main.exe
D:/workfile/gcc15/x86_64-w64-mingw32/bin/../lib/gcc/x86_64-w64-mingw32/15.0.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Yuzhiy\AppData\Local\Temp\cc0yAYeW.o: in function `main':
C:/Users/Yuzhiy/Desktop/vscodestudy/main.cpp:4:(.text+0x1f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
D:/workfile/gcc15/x86_64-w64-mingw32/bin/../lib/gcc/x86_64-w64-mingw32/15.0.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\Yuzhiy\AppData\Local\Temp\cc0yAYeW.o:main.cpp:(.rdata$.refptr._ZSt4cout[.refptr._ZSt4cout]+0x0): undefined reference to `std::cout'
collect2.exe: error: ld returned 1 exit status

3.Q:task.json中的传递给编译器的参数行(args)中的-fdiagnostics-color=always参数是什么意思? A:-fdiagnostics-color=always 即总是输出颜色代码,由于vscode的任务栏中的输出不是真正的终端,是由js文件渲染的伪终端,需要将g++输出的信息渲染为带颜色的输出

1.CMakePresets.json:用于指定整个项目的构建细节,json中包含

name
预设的名称,一般用表示平台或编译期的版本名字;

vendor
可选内容,提供供应商的信息,Cmake一般不管除非有所谓映射(不用管)

displayName
此预设的个性化名词(无关紧要)一般有编译期名字代替如"GCC 15.0.0 x86_64-w64-mingw32"

description
自定义的描述(无关紧要)一般使用本地编译期所在路径描述

steps
A required array of objects describing the steps of the workflow. The first step must be a configure preset, and all subsequent steps must be non- configure presets whose configurePreset field matches the starting configure preset. Each object may contain the following fields:

type
A required string. The first step must be configure. Subsequent steps must be either build, test, or package.

name
A required string representing the name of the configure, build, test, or package preset to run as this workflow step.

2.CmakeLists.txt:告诉Cmake如何构建你的项目

构建CmakeLists

1.打开Vscode的命令面板 (Ctrl+Shift+P) 并运行CMake: Quick Start命令
2.输入项目名称,选择c++作为项目语言
3.暂时选择CTest作为测试支持
4.选择Executable作为项目类型时,创建包含main函数的mian.cpp文件 Note:当然想要创建头文件或基础资源时可选择Library

创建 CMakePresets.json

1.选择 添加新的预设值和从编译器创建
note:该扩展可自动扫描计算机上的工具包,并创建系统中发现的编译器列表。 2.根据你想要编译器选择 3.输入预设的名字 完成这些步骤后,您就拥有了一个完整的 hello world CMake 项目,其中包含以下文件: main.cpp, CMakeLists.txt, and CMakePresets.json.

创建一个项目

tasks.json (构建指导)
launch.json (debugger 设置)
c_cpp_properties.json (编译器路径与智能感知设置)

首次运行程序时,C++ 扩展会创建一个 tasks.json 文件,您可以在项目的 .vscode 文件夹中找到该文件。tasks.json 会存储您的构建配置

{
  "tasks": [
    {
      "type": "cppbuild",
      "label": "C/C++: g++.exe build active file",
      "command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
      "args": [
        "-fdiagnostics-color=always",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}\\${fileBasenameNoExtension}.exe"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ],
  "version": "2.0.0"
}

使用cmake

cmakelist配置

生成动态库

1.有如下目录结构

>cmake_study  
    |          
    |__lib  
    |__testFunc  
        |__testFunc.c  
        |__test2.h
# 新建变量SRC_LIST
set(SRC_LIST ${PROJECT_SOURCE_DIR}/testFunc/testFunc.c)

# 对 源文件变量 生成动态库 testFunc_shared
add_library(testFunc_shared SHARED ${SRC_LIST})
# 对 源文件变量 生成静态库 testFunc_static
add_library(testFunc_static STATIC ${SRC_LIST})

# 设置最终生成的库的名称
set_target_properties(testFunc_shared PROPERTIES OUTPUT_NAME "testFunc")
set_target_properties(testFunc_static PROPERTIES OUTPUT_NAME "testFunc")

# 设置库文件的输出路径
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

1.add_library:生成动态库或静态库
第1个参数:指定库的名字
第2个参数:决定是动态还是静态,如果没有就默认静态
第3个参数:指定生成库的源文件
2.set_target_properties:设置最终生成的库的名称,还有其它功能,如设置库的版本号等等
3.LIBRARY_OUTPUT_PATH:库文件的默认输出路径,这里设置为工程目录下的lib目录

前面使用set_target_properties重新定义了库的输出名称,如果不使用set_target_properties也可以,那么库的名称就是add_library里定义的名称,只是连续2次使用add_library指定库名称时(第一个参数),这个名称不能相同,而set_target_properties可以把名称设置为相同,只是最终生成的库文件后缀不同(一个是.so,一个是.a.win中为dll),这样相对来说会好看点

链接库

有如下文件路径

cmake_study
    |
    |__bin
    |__build
    |__src
    |__test
        |__inc
        |   |__test1.h
        |__lib
            |__test2.lib
            |__tets2.dll
   cmakelist.txt
# 输出bin文件路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

# 将源代码添加到变量
set(src_list ${PROJECT_SOURCE_DIR}/src/main.c)

# 添加头文件搜索路径
include_directories(${PROJECT_SOURCE_DIR}/testFunc/inc)

# 在指定路径下查找库,并把库的绝对路径存放到变量里
find_library(TESTFUNC_LIB testFunc HINTS ${PROJECT_SOURCE_DIR}/testFunc/lib)

# 执行源文件
add_executable(main ${src_list})

# 把目标文件与库文件进行链接
target_link_libraries(main ${TESTFUNC_LIB})

PRIVATE 关键字表明 fmt 仅在生成 HelloWorld 时需要,不应传播到其他依赖项目

cmake 命令速览

cmake -Bbuild -GNinja -S. 以ninja生成 以 当前目录为源码 构建目录为build(如果没有就新建)

cmake -Bbuild -GNinja -S.. 在build文件夹下执行

ninja 在build文件夹下执行


  1. 为什么选择第二个呢?我们创建的文件中使用了c++的标准库<iostream>所以需要创建以第二个任务编译器g++而不是gcc。如果你不小心点击了第一个任务并运行,则你肯定会在vscode下端的终端中获得如下报错,如果你不小心就是点击到了第一个任务,你可以选择编辑当前vscode打开的文件夹下的.vscode中的task.json文件,将'command'一行的最后一个gcc手动改为g++,并且为了避免混淆,将label行的C/C++: g++.exe 生成活动文件改为 g++或者你喜欢的名字` ↩︎ ↩︎