39

IntelliSense uses c_cpp_properties.json >> includePath to find the headers for auto-completion, but I noticed I still need to specify the include path inside the task.json >> tasks >> args to build.

I found in the documentation that the includePath is pretty much the same path I would specify in "-I":

The paths that you specify for this setting are the same paths that you would send to your compiler via the -I switch. When your source files are parsed, the IntelliSense engine will prepend these paths to the files specified by your #include directives while attempting to resolve them. These paths are not searched recursively.*

link

  1. Am I setting up VSCode correctly by specifying all the libraries and the includes directories inside the args of the build taks ? Or should it be done differently ?
  2. Can someone explain using different words what's the difference between the includePath and browse ? The explanation link is not totally clear to me

Here is an example of my c_cpp_properties.json:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "D:/github/dependencies/SDL2-2.0.8/include"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "clang-x64",
            "browse": {
                "path": [
                    "${workspaceFolder}/**"
                ]
            }
        }
    ],
    "version": 4
}

and 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": "g++",
            "args": [
                "-g",
                "main2.cpp",
                "-ID:\\github\\dependencies\\SDL2-2.0.8\\include",
                "-LD:\\github\\dependencies\\SDL2-2.0.8\\lib\\x64",
                "-lSDL2main","-lSDL2", "-lopengl32",
                "-o",
                "test-sdl"
            ]
        }
    ],
    "group": {
        "kind": "build",
        "isDefault": true
    },
    "problemMatcher":"$gcc"
}

Is a simple question, but I am new to VSCode (sorry).

Diego Trazzi
  • 520
  • 2
  • 5
  • 9
  • I have the same situation and asking the same question. If you found an explanation for that, please share it, thank you :) – Imad May 28 '19 at 12:43
  • Does this answer your question? [#include errors detected in vscode](https://stackoverflow.com/questions/45583473/include-errors-detected-in-vscode) – JΛYDΞV Aug 20 '21 at 06:17

4 Answers4

32

1. Am I setting up VSCode correctly?

Mostly. The fact that you have to specify the include paths twice (once in c_cpp_properties.json and again in a file that describes your build) is unavoidable. In VSCode, the build system and the editor do not understand each other, and both need this information. In contrast, with Visual Studio (no "Code"), it would only be necessary to specify the paths once; that is one of the benefits of using a "true" Integrated Development Environment. (But there are drawbacks too; I'm not trying to discourage you from using VSCode.)

However, I do not recommend putting the include paths into tasks.json directly. Rather, one typically has a separate build system that can be invoked from the command line, and then tasks.json invokes that command too.

As a very common example, you could use GNU Make and replace your current tasks.json with this (untested!) Makefile:

test-sdl: main2.cpp
    g++ -g main2.cpp -ID:\\github\\dependencies\\SDL2-2.0.8\\include -LD:\\github\\dependencies\\SDL2-2.0.8\\lib\\x64 -lSDL2main -lSDL2 -lopengl32 -o test-sdl

This tells make how to build test-sdl from main2.cpp, namely by running the g++ command shown. (I have deliberately kept this Makefile very simple since the question isn't about Makefiles; just be aware that a real Makefile would break things up for better organization, and the backslashes are likely to need adjustment.)

In any case, then your tasks.json simplifies to:

{
    // 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": "make",   // <-- changed
            "args": []           // <-- changed
        }
    ],
    "group": {
        "kind": "build",
        "isDefault": true
    },
    "problemMatcher":"$gcc"
}

This is better because you don't have crucial build information locked away in a file that only VSCode understands.

2. Can someone explain ... includePath and browse?

VSCode has two different systems for understanding C++ code. There is the older "Tag Parser", which uses browse.path, and the newer "Intellisense", which uses includePath. At this point (2019-08-30, VSCode 1.37.1), my understanding is basically everyone should be using the newer Intellisense system, as it provides more accurate information and should be at least as mature. Consequently, you should be able to simply ignore browse.path.

To make sure you are using Intellisense rather than Tag Parser, go into File → Preferences → Settings → C/C++ → "C_Cpp: Intelli Sense Engine" and make sure that it is "Default" rather than "Tag Parser". Note that this setting is stored in settings.json rather than c_cpp_properties.json.

Scott McPeak
  • 8,803
  • 2
  • 40
  • 79
  • Using a `Makefile` is a great idea, unfortunately, when I click on the "run" button at the upper right, VSCode still tries to directly invoke `gcc` - not make. VScode-1.53.2 on MacOS. – Chris Wolf Mar 06 '23 at 14:11
  • Building with a `Makefile` didn't work until I added a specific extension: https://marketplace.visualstudio.com/items?itemName=ms-vscode.makefile-tools#review-details – Chris Wolf Mar 06 '23 at 14:37
12

I too have attempted to use libraries, and at least for now this works (I'm on Windows BTW): In c_cpp_properties.json, I have a reference to the include directory:

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "C:\\ProgrammingLibraries\\SDL2-2.0.10\\include\\SDL2",
                "${workspaceFolder}\\src\\include"
            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "compilerPath": "C:\\mingw-w64\\x86_64-8.1.0-win32-seh-rt_v6-rev0\\mingw64\\bin\\gcc.exe",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-x64"
        }
    ],
    "version": 4
}

And in tasks.json, I have A Compilation and a Linker task, and a task that runs both:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Compiler",
            "type": "shell",
            "command": "g++",
            "args": [
                "-c",
                "${workspaceFolder}\\src\\main.cpp",
                "-IC:\\ProgrammingLibraries\\SDL2-2.0.10\\include\\SDL2"
            ]
        },
        {
            "label": "Linker",
            "type": "shell",
            "command": "g++",
            "args": [
                "${workspaceFolder}\\main.o",
                "-o",
                "${workspaceFolder}\\bin\\HelloSDL.exe",
                "-LC:\\ProgrammingLibraries\\SDL2-2.0.10\\lib",
                "-lmingw32",
                "-lSDL2main",
                "-lSDL2"
            ]
        },
        {
            "label": "Build HelloSDL",
            "dependsOn": [
                "Compiler",
                "Linker"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
MemzIcon
  • 121
  • 1
  • 2
  • i tried this approach, and it seems to work. The only problem i had is that if you declare all the dependencies in the last task they will perform in parallel so that sometimes you end up linking .o files from previous builds. What i suggest instead is to declare only the "Linker" dependency in the last task and the "Compiler" dependency in the "Linker" task. That way the linker waits for the compiler to actually finish the job. – Francesco Rogo Oct 29 '20 at 11:00
2

I'm also new to VS Code. Additionally, I have never build larger C++ projects. At least for now, I solved the building like this. (SEE BELOW)

I ended up doing this in my tasks.json

 "tasks": [
    {
        "type": "shell",
        "label": "g++ build active file",
        "command": "${workspaceFolder}/buildMysorcery.sh",
        "options": {
            "cwd": "/usr/bin"
        }
    },

(Seems like you're not able to escape white-spaces within the args property, https://github.com/Microsoft/vscode/issues/36733),

I deleted the args property and set the command property to run a script(buildMysorcery.sh) which simply does

#!/bin/bash

g++ fullpathtodir/hello.cpp -Wall -g $(sdl2-config --cflags --libs) -o fullpathtodir/hello

Replace the fullpathtodir with your paths.

Urmzd
  • 682
  • 4
  • 17
planteater
  • 69
  • 6
0

This is the way I included OpenGL "GLWF" and and "glad" libraries in VS Code on Mac (MacBook Pro 2015, macOS Catalina) with clang. And I have intellisense, can build and debug.

include/glad/glad.h - library file to include

src/helloworld.cpp - main file

/* Ask for an OpenGL Core Context */
#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>
#include <glad/glad.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

int main(int argc, char **argv)
{
    GLFWwindow *window;

    /* Initialize the library */
    if (!glfwInit())
    {
        return -1;
    }

#ifdef __APPLE__
    /* We need to explicitly ask for a 3.2 context on OS X */
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif

    /* Create a windowed mode window and its OpenGL context */
    window = glfwCreateWindow(1280, 720, "Hello World", NULL, NULL);
    if (!window)
    {
        glfwTerminate();
        return -1;
    }

    /* Make the window's context current */
    glfwMakeContextCurrent(window);

    /* Loop until the user closes the window */
    while (!glfwWindowShouldClose(window))
    {
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the buffers

        /* Swap front and back buffers */
        glfwSwapBuffers(window);

        /* Poll for and process events */
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}

.vscode/c_cpp_properties.json

{
  "configurations": [
    {
      "name": "Mac",
      "includePath": ["${workspaceFolder}/src/", "${workspaceFolder}/include/"],
      "defines": [],
      "macFrameworkPath": [
        "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
      ],
      "compilerPath": "/usr/bin/clang",
      "cStandard": "c11",
      "cppStandard": "c++17",
      "intelliSenseMode": "${default}",
      "browse": {
        "limitSymbolsToIncludedHeaders": true,
        "databaseFilename": ""
      }
    }
  ],
  "version": 4
}

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb) Launch",
            "type": "lldb",
            "request": "launch",
            "program": "${workspaceFolder}/build/helloworld.out",
            "args": [],
            "cwd": "${workspaceFolder}"
        }
    ]
}

.vscode/tasks.json (you need to include implementation file include/glad.c, not only headers)

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build with Clang",
            "type": "shell",
            "command": "clang++",
            "args": [
                "-std=c++17",
                "-stdlib=libc++",
                "-lglfw3",
                "--include-directory=include/",
                "--include=include/glad.c",
                "-framework",
                "OpenGL",
                "-framework",
                "IOKit",
                "-framework",
                "Cocoa",
                "src/helloworld.cpp",
                "-o",
                "build/helloworld.out",
                "--debug"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
Michael Klishevich
  • 1,774
  • 1
  • 17
  • 17