前言

每次想用vscode写个代码,一到运行或者其它操作就报错, 希望能通过记录各种bug,加深自己对vscode的理解,最后,祝自己早日掌控它。



文章目录

  • 前言
  • 一、头文件的include问题
  • 1. 问题描述及原因
  • 2. 问题解决
  • 3. 总结与展望
  • 二、学习Vscode的一些网站
  • 1、预变量的学习
  • 三、.json配置文件
  • 1、`task.json`
  • 2、`launch.json`
  • 3、`c_cpp_configuration.json`
  • 4、优先级
  • 5、编译变量选项(`.json`文件下的args)
  • 四、预处理、编译、汇编、链接
  • 五、makefile文件的简单编写
  • 1、需要再看的
  • 伪目标



一、头文件的include问题

1. 问题描述及原因

vscode 找不到 axios_vscode 找不到 axios


从报错来看,基本上是因为编译器找不到对应的头文件,所以无法进行编译。

这两天看了网上大部分的解决方案,一个一个试了一下,这里给一个总结,因为有些方法并没有解决我的问题,但相信对看到这篇文章的人会有很大得帮助。


2. 问题解决

方法一: 在当前目录下的 .vscode 文件下找到tasks.json文件,在 “args” 下添加如下命令

"-I",
"E:\\vscode\\c_and_c++\\c++\\eigen-3.4.0"    //输入自己的Eigen路径,注意不要有中文

添加后如图所示

vscode 找不到 axios_学习_02

使用-I 参数可以告诉编译器在哪些目录中搜索头文件,当然若已经在c_cpp_properties.json文件中的IncludePath中配置了就不需要这个了,下一个办法也就是这个。

方法二: 在当前目录下的 .vscode 文件下找到c_cpp_properties.json文件,在 “includePath” 下添加如下命令

"E:/vscode/c_and_c++/c++/eigen-3.4.0"

添加后如图所示

vscode 找不到 axios_vscode 找不到 axios_03


这相当于告诉编译器可以在这些includePath下找到头文件,给了编译器寻找头文件的路径。

当然,以上两种方法对我的vscode没有效果,且多数人的博客记载的也是这两种方法。于是受到上面第二种方法的启发,就有了下面的两种方法。

方法三: 既然在c_cpp_properties.json文件中添加新的includePath路径没有用,那我就直接把这个Eigen文件夹复制到现有的includePath路径下,让编译器自己去现有的路径下寻找,这里我把它复制到了E:\MinGW\mingw64\lib\gcc\x86_64-w64-mingw32\8.1.0\include

vscode 找不到 axios_c++_04


最后成功运行。

方法四: 既然代码中可以允许出现#include <Eigen/Dense>的语句,那我干脆直接把这个头文件的绝对路径写进去,这样也是可以编译的。

#include <iostream>
#include <E:/vscode/c_and_c++/c++/eigen-3.4.0/Eigen/Dense>

3. 总结与展望

这里只是对于一个Eigen库而言,对于以后需要新的头文件,而路径下没有的情况,可以仿照这些办法解决。可惜的是方法一和方法二失败的原因还未找到,等找到了再更新。未完待续…


二、学习Vscode的一些网站

1、预变量的学习

Vscode官网的预变量学习(.json文件)

预变量的使用是配置文件具备迁移性的一个重要因素。


三、.json配置文件

1、task.json

任务配置文件:这个配置文件是用来执行你预定的任务的,比如说你修改了你的代码,调试之前,肯定要重新生成新的程序后再调试,那么你就可以配置它告诉vscode怎么重新生成这个新的程序。点击运行之后,VS Code将从tasks.json中查看如何构建并运行程序。

其中的args变量,顾名思义,执行的是命令行的操作,类似于将本可以在命令行中执行的操作移到这个里面。
args数组指定将传递给g++的命令行参数。这些参数按照编译器期望的特定顺序列在该文件中。

需要注意的是,tasks中可以有多个任务,在一个列表中保存,根据自己需要添加或删除。下面是官网中给出的一个task.json文件例子,tasks中只有一个任务。

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "cppbuild",//指定了任务的类型,即 C/C++ 构建任务
      "label": "C/C++: g++ build active file",//这是任务的标签,用于在 Visual Studio Code 中标识这个任务,可以随便命名。
      "command": "/usr/bin/g++",//这是要执行的命令,填写编译器的路径,即 g++ 编译器的路径。
      "args": ["-g", //在目标文件中添加调试信息,便于gdb调试或objdump反汇编
      			"${file}", //当前打开的文件
      			//你也可以通过更改 tasks.json来构建多个C++文件,只需要将${file}更改
      			//为"${workspaceFolder}/*.cpp"。
      			//这样更改参数将会构建当前文件夹下所有的.cpp文件,需要注意的是此时-o后的文件只能是下面这种情况。
      			
      			"-o", //指定生成文件的文件名
      			"${fileDirname}/${fileBasenameNoExtension}"//生成文件的文件名,命名规则可以参看预变量命名
      			//可以更改输出文件的文件名,
      			//例如将"${fileDirname}\\${fileBasenameNoExtension}"更改
      			//为"${workspaceFolder}\\${fileBasenameNoExtension}.exe"这样的命名。
      			//这样生成的就是一个带拓展.exe的编译文件。
      ],
      //command + args类似于在命令行中输入:
      // g++ -g ${file} -o ${fileDirname}/${fileBasenameNoExtension}
      
      "options": {
        "cwd": "/usr/bin"	//current work direct :指定了当前工作目录为 /usr/bin。
      },//options:这里指定了任务的选项。
      "problemMatcher": ["$gcc"],
      "group": {
        "kind": "build",//表示这是一个构建任务。
        "isDefault": true//表示这是默认的构建任务。
      },//group:定义了任务的分组信息。
      //注:如果需要更改默认编译器,可以通过删除group中的 "isDefault": true ,
      //这样在编译的时候vscode会重新弹出编译器选项。
      //换句话说,如果你想在每次编译的时候都希望vscode会重新弹出编译器选项,
      //那就将"isDefault": true改为"isDefault": false	
      
      "detail": "Task generated by Debugger."
    }
  ]
}

学习来自官网vscode一键配置C/C++多个C及CPP文件编译与tasks.json和launch.json原理

2、launch.json

这个配置文件是告诉vscode如何来启动调试你的代码程序的,这其中包括你的程序在哪个位置,你用什么工具来调试,调试的时候需要给调试工具传什么参数等。

需要注意的是,configurations中可以有多个调试配置的设置,在一个列表中保存,根据自己需要添加或删除。
下面是官网中给出的一个launch.json文件例子,configuration中只有一个调试配置设置。

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "C/C++: g++ build and debug active file",//这是调试配置的名称,用于在 Visual Studio Code 中标识这个调试配置,可以随便命名。
      "type": "cppdbg",//这指定了调试器的类型,即 C/C++ 调试器。
      "request": "launch",//这指定了调试器的请求类型,即启动调试。
      "program": "${fileDirname}/${fileBasenameNoExtension}",//这是要调试的程序的路径和名称,即当前活动文件的路径和名称。
      "args": [],//这是传递给程序的参数列表。在这里,为空列表,表示没有额外的启动参数。
      "stopAtEntry": false,//这指定了是否在程序入口处停止,这里设置为 false,表示不在程序入口处停止。
      "cwd": "${workspaceFolder}",//这是指定程序的当前工作目录,即工作区的根目录。
      "environment": [],
      "externalConsole": false,
      "MIMode": "gdb",
      "miDebuggerPath": "/usr/bin/gdb",//这是指定 GDB 调试器的路径。
      "setupCommands": [
        {
          "description": "Enable pretty-printing for gdb",
          "text": "-enable-pretty-printing",
          "ignoreFailures": true
        }
      ],
      "preLaunchTask": "C/C++: g++ build active file"//这是指定在启动调试之前运行的任务,即在启动调试之前会先运行名为 "C/C++: g++ build active file" 的构建任务。
    }
  ]
}

3、c_cpp_configuration.json

如果要更好地控制 C/C++ 扩展名,可以创建一个文件,该文件将允许您更改设置,例如编译器的路径、包含路径、C++ 标准(默认为 C++17)等。

您可以通过从命令面板 (Ctrl+Shift+P) 运行命令 C/C++:编辑配置 (UI) 来查看 C/C++ 配置 UI。

vscode 找不到 axios_c++_05


这将打开“C/C++ 配置”页。在此处进行更改时,VS Code 会将其写入c_cpp_configuration.json文件中。如果不习惯写代码修改配置,也可以直接在这样的一个交互页面进行配置修改。

vscode 找不到 axios_vscode 找不到 axios_06


仅当程序包含不在工作区或标准库路径中的头文件时,才需要修改“包含路径”设置。

vscode 找不到 axios_vscode 找不到 axios_07

Visual Studio Code 将这些设置放在c_cpp_configuration.json中。如果直接打开该文件,它应该如下所示:

{
    "configurations": [
        {
            "name": "Linux",
            "includePath": [
                "${workspaceFolder}/**" //表示包含工作区中所有文件的路径
                // 注意:/路径/**  表示的是 /路径 下的所有文件(也包括文件夹)
            ],//这是指定了包含文件的路径列表,可以看上图中的解释
            "defines": [],
            "compilerPath": "/usr/bin/gcc",//这是指定了编译器的路径,即 GCC 编译器的路径。
            "cStandard": "c17",
            "cppStandard": "gnu++14",//这是指定了 C++ 标准的版本,这里设置为 GNU++14。
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

4、优先级

这三个配置文件将统一放在.vscode文件夹里,位于当前运行的.cpp文件同级目录下的.vscode文件夹具有最高的优先级,运行的配置先看这里的配置,没有则往上级目录逐级寻找.vscode文件夹。

VS Code 现在配置为在 Linux 上使用 gcc。该配置适用于当前工作区。若要重复使用配置,只需将 JSON 文件复制到新项目文件夹(工作区)中的.vscode文件夹,并根据需要更改源文件和可执行文件的名称。

5、编译变量选项(.json文件下的args)

vscode 找不到 axios_vscode_08


vsode下多个文件的编译参看——GCC 同时编译多个 C/C++ 文件

注意,由于在程序预处理阶段,gcc / g++ 编译器会自行处理各个 .c/.cpp 文件内部引入的 .h 头文件(将 .h 文件中的代码直接拷贝到当前 .c / .cpp 源文件中),因此编译运行项目时,我们只需要提供所有的源文件即可,不需要处理头文件。

四、预处理、编译、汇编、链接

GCC 编译 C++ 程序分步骤流程

-o 选项用于指定要生成的文件名。
-c 编译、汇编指定的源文件,但不进行链接。

在此,我想多说关于程序编译的一些规范和方法。一般来说,无论是C还是C++,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即Object File,这个动作叫做编译(compile)(广义)。然后再把大量的Object File合成可执行文件,这个动作叫作链接(link)。

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件都应该对应于一个中间目标文件( .o 文件或 .obj 文件)。

链接时,主要是链接函数和全局变量。所以,我们可以使用这些中间目标文件( .o 文件或 .obj文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便。所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是.lib文件,在UNIX下,是Archive File,也就是 .a 文件。
摘自一起写makefile文件——概述

g++ -E main.cpp -o main.ii		//将main.cpp预处理成名为main.ii文件 
g++ -o main.ii -E main.cpp		//这样也是可以的,写makefile的时候发现的,
								//其他类似,基本就是引用文件前加带“-”的命令语句就行

g++ -S main.ii -o main.s		//将main.ii编译成名为main.s文件
g++ -S main.cpp -o main.s		//将main.cpp编译成名为main.s文件

g++ -c main.s -o main.o			//将main.s汇编成名为main.o文件
g++ -c main.cpp -o main.o		//将main.cpp直接经过前面几步汇编成名为main.o文件。-c (compile 编译) 

g++ main.o **.o -o main			//将main.o 、**.o文件链接成main这个可执行文件

####
g++ main.cpp **.cpp -o main			//将main.cpp 、**.cpp文件直接经过前面几步链接成main这个可执行文件
g++ -o main main.cpp **.cpp			//这样也是可以的,写makefile的时候发现的

五、makefile文件的简单编写

参看一起写makefile文件——makefile介绍

1、需要再看的

伪目标

vscode 找不到 axios_vscode 找不到 axios_09


vscode 找不到 axios_vscode_10