Vscode

Published: by Creative Commons Licence

  • Tags:

今天手痒,想写点C代码。但是我的机器装的是Windows系统,写C似乎有点复杂,需要安装一个十几个G的Visual Studio Community。但是好在找到了它的一个轻量级的替代IDE,Visual Studio Code。

Visual Studio Code(简称VS Code)是一个由微软开发的,同时支持Windows、Linux、和macOS系统且开放源代码的代码编辑器,它支持测试,并内置了Git 版本控制功能,同时也具有开发环境功能,例如代码补全(类似于 IntelliSense)、代码片段、和代码重构等,该编辑器支持用户个性化配置,例如改变主题颜色、键盘快捷方式等各种属性和参数,还在编辑器中内置了扩展程序管理的功能。

IDE安装

安装VS Code

在官网https://code.visualstudio.com/上下载最新的windows版本VS Code。之后安装即可。

C/CPP开发

安装MinGW

MinGWMinimalist GNU for Windows),又称mingw32,是将GCC编译器和GNU Binutils移植到Win32平台下的产物,包括一系列头文件(Win32API)、库和可执行文件。 另有可用于产生32位及64位Windows可执行文件的MinGW-w64项目,是从原本MinGW产生的分支。如今已经独立发展。

虽然VS Code是一个轻量快速的一款IDE,但是并没有提供大部分语言需要的开发环境。因此我们需要自行提供C语言开发必须的编译器、调试器、头文件、静态库等。好在MinGW为我们提供上述所有内容。

由于我的系统是64位的,因此选择的是MinGW-w64,可有在官网https://mingw-w64.org/doku.php下载最新版本的MinGW并自行安装。由于GFW的原因,可能无法正常下载,需要自行使用梯子或者寻找国内的镜像。

注意MinGW不会自行将自己的bin目录加入到环境变量PATH中,因此需要手动添加。

安装插件

VS Code如果没有插件的加持,可能只是一个美观快捷的文本编辑器,但是有了插件,VS Code就成了一个万能的开发环境。

打开VS Code,在Extensions下搜索并安装以下插件:

  • C/C++:微软自家提供的插件,用于提供对C/C++语法的智能感知、调试和代码浏览等特性。
  • Code Runner:用于直接运行代码文件,支持C、C++、Java、Js、Python、Go、Ruby、C#等多种语言。

  • Include Autocomplete:提供C++头文件的自动补全特性。
  • Bracket Pair Colorizer:为不同层级的花括号使用不同的着色。

第一个项目helloworld

创建一个空目录helloworld,并在启动页面点击Open Folder,之后在文件选择框选择之前创建的helloworld文件夹。这样我们就以helloworld目录为工作目录创建了一个项目。

现在我们的项目空空如也,让我们新建一个文件main.c。

#include<stdio.h>

int main(){
    printf("Hello, world!");
    return 0;
}

使用Code Runner运行

由于我们之前安装了Code Runner,因此可以右键选择运行(Run Code,Ctrl+Alt+N )。或者可以使用VS Code上的三角形按钮。

可以看到下面创建了一个output面板输出了具体执行的命令和执行结果。如果报错,你可以手动复制命令并执行来排查。执行结果中输出了代码中main方法的返回值(或者显式exit提供的结束码)和总共花费时间。

但是现在我们仅能直接执行应用,假如应用执行结果不如人意,那么我们还是需要进行调试的,当然我们的helloworld应用实在太简单了,根本不需要调试,但是还是让我们手把手来试试看具体怎么进行调试。

手工构建项目

在我们使用Code Runner自动运行时,会为我们创建一个名为main.exe的可执行文件。我们这一节将讲述如何手动创建这个文件,当然不是通过命令行而是配置的方式。

点击Terminal->Config Tasks,之后选择Other模板,VS Code会自动为你创建一个.vscode/tasks.json文件。你需要在这个文件中配置一个任务,并之后在其它的配置文件中引用这个任务。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "gcc",
            "args": [
                "*.c",
                "-o", "manual.exe"
            ]
        }
    ]
}

这里我们创建了一个编译工作目录下所有以.c后缀名结尾的文件,并生成一个main.exe可执行文件。这里的命令等价于

$ gcc *.c -o manual.exe

接下来,我们Terminal->Run Task,并在下拉框中选择build任务。下面的TERMINAL框输出

> Executing task: gcc *.c -o manual.exe <


Terminal will be reused by tasks, press any key to close it.

之后左边文件栏可以看到刚刚构建的manual.exe可执行文件。接下来验证文件确实可以正常执行。

$ .\manual.exe
Hello, world!

假如大家引入了外部的库和头文件,比如像OpenGL的库和头文件,我们可以利用gcc的-I和-L选项指定额外的头文件目录和库目录。比如我们将头文件放在/usr/external/include下面,而库放在/usr/external/lib下面。修改我们tasks.json文件。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "gcc",
            "args": [
                "*.c",
                "-o", "manual.exe",
                "-I", "/usr/external/include",
                "-L", "/usr/external/lib"
            ]
        }
    ]
}

调试项目

上一节,我们了解过了如何手动建立和执行编译任务。这一节我们将使用编译得到的可执行文件进行调试。为了能正常进行调试我们需要在task.json中增加额外的参数-g以在构建输出的可执行文件中夹带gdb调试所需的信息。

...
            "args": [
                "*.c",
                "-o", "manual.exe",
                "-g"
            ]
...

点击Debug->Start Debugging,选择使用GDB/LLDB进行调试。可以看到VS Code又一次自动为我们创建了一个.vscode/launch.json文件。对其进行修改得到

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/manual.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "D:/software/mingw/mingw64/bin/gdb.exe",
            "preLaunchTask": "build",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

简单说明一下上面这个json文件。preLaunchTask指定了在启动应用之前执行的额外命令,这里我们执行了build命令来构建用于启动的manual.exe文件,之后设置program,表示需要进行调试的可执行文件,最后还修改了miDebuggerPath,指定了用于调试的gdb的绝对地址。有了这些信息,VS Code就可以为我们提供调试的能力。

在调试之前,我们先点击代码行号左侧标记断点。现在我们点击Debug->Start Debugging,就可以愉快地进行调试了。

多个主函数

一个项目可以同时又多个入口。这个在Java项目中非常常见,每个类都可以有自己的一个main函数,而每一个main函数都可以作为项目的入口。当然一般在C/CPP项目中只会有一个main函数,因为函数不允许重复定义。但是仅仅用于测试或练习,我们可能会希望多个文件都有自己的main函数,而我们只需要直接执行就可以了。这类似于Code Runner所做的,但是Code Runner不能为我们提供调试的能力。我们这一节将讲述如何实现Code Runner的效果(仅将当前活跃文件进行编译和执行),同时能够进行调试。

我们需要使用VS Code中预定义的变量。VS Code的支持的变量以及含义可以在官网文档https://code.visualstudio.com/docs/editor/variables-reference找到,这里我简单翻译。

预定义变量 解释
${workspaceFolder} VS Code打开的文件夹路径
${workspaceFolderBasename} VS Code打开的文件夹的名称去除斜线(/)
${file} 当前打开的文件
${relativeFile} 当前打开的文件相对于${workspaceFolder}的路径
${fileBasename} 当前打开的文件的基础名称
${fileBasenameNoExtension} ${fileBasename}去除后缀名
${fileDirname} 当前打开文件所在的目录名称
${fileExtname} 当前打开的文件的后缀名
${cwd} 任务执行者所在工作目录
${lineNumber} 当前活跃文件选中行号
${selectedText} 当前活跃文件选中文本
${execPath} 执行VS Code可执行文件的路径

我们需要用到${relativeFile}${fileBasenameNoExtension}来根据当前活跃文件进行编译和调试。

task.json如下:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "gcc",
            "args": [
                "${relativeFile}",
                "-o", "${fileBasenameNoExtension}.exe",
                "-g"
            ]
        }
    ]
}

launch.json如下:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/${fileBasenameNoExtension}.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "gdb",
            "miDebuggerPath": "D:/software/mingw/mingw64/bin/gdb.exe",
            "preLaunchTask": "build",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

同时为了测试,我们建立另外一个源文件other.c:

#include<stdio.h>

int main(){
    printf("Hello, other!");
    return 0;
}

之后分别在激活main.c和other.c时执行调试,就可以发现调试的是不同的main函数。

LaTeX

安装TeX Live

打开http://www.tug.org/texlive/acquire-netinstall.html,选择合适自己系统的文件下载即可。

安装插件

要在VSCode上操作LaTeX,你需要安装LaTeX Workshop插件。

简单的项目

我们创建一个空目录。在VSCode中打开该目录作为工作目录。创建一个文件foo2.tex。

\documentclass{article}

\begin{document}
\title{A sample project}
\maketitle

Hello, world!

\end{document}

预览

要实时预览当前tex文件,你需要利用LaTeX Workshop插件提供的预览能力。 首先编译当前文件,点击Recipe.latexmk选项。

编译完成后,我们就可以进行预览了,点击View in VSCode tab。

之后的每次文件的修改后都会实时地显示在预览页面上。