1

I am learning C++ and I want to use VS Code as my code editor. I created a simple project that has a file with the main method and 2 other files to define a class (a .h and a .cpp). I created the default build task in VS Code to compile my code (g++ build active file), only to get a compile error: undefined reference for the class constructor. I saw that it was related to the linker not finding the implementation because it wasn't included in the build. So I modified my build task to build all .cpp :

 "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "g++ build active file",
            "command": "/usr/bin/g++",
            "args": [
                "-g",
                "${fileDirname}/*.cpp",
                "-o",
                "${fileDirname}/${fileBasenameNoExtension}"
            ],
            "options": {
                "cwd": "/usr/bin"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

But now when I build the project, I get this error: /path/to/project/*.cpp": No such file or directory. Meaning that *.cpp wasn't interpreted as a wildcard. I am using the default C++ extension for VS Code if is relevant. Am I missing some configuration in my task? How can I make this work? For a large project the method in which I manually add all cpp files as arguments is obviously not appropriate so I would like to make this method to work. Thanks in advace!

Adrian Pascu
  • 949
  • 5
  • 20
  • 48
  • For C++ 'building the active file' doesn't make any sense, unless the source file you are building contains the entire implementation of all included symbols. If you want to build your application/library/project from VS Code, I'd advise against doing it directly as its task system is extremely primitive. You're better off using a 'real' C++ build system, such as CMake or Meson, and then triggering that from VS Code. This will also make your project far more portable. VS Code has extensions that provide very good CMake integration too. – cmannett85 Apr 05 '20 at 10:36
  • Does the compiler accept the path, if you specify 1 (existing) cpp file (inside this directory) instead of the wildcard? – Sebastian Apr 05 '20 at 10:40
  • @Sebastian yes, it does – Adrian Pascu Apr 05 '20 at 10:49
  • So g++ does not handle wildcards itself? So VS Code has to do the wilcard glob resolution or you have to call a shell instead of /usr/bin/g++ which calls g++ in turn – Sebastian Apr 05 '20 at 10:54
  • Perhaps try to find another compiler build, cf. https://stackoverflow.com/questions/39360051/mingw-gcc-wildcard – Sebastian Apr 05 '20 at 10:56
  • The compiler is not the problem. It's VS Code that doesn't interpret the wildcard – Adrian Pascu Apr 05 '20 at 11:11
  • What do you mean by 'call a shell' – Adrian Pascu Apr 05 '20 at 11:12
  • Either should interpret the wildcards, currently neither does. The compiler has a compile flag, whether it should do the wildcard expansion internally. Some gccs are compiled with, some without. You can replace "command": "/usr/bin/g++" with "command": "/usr/bin/sh" and let the shell do wildcard expansion and call g++ (use the -c option of sh) – Sebastian Apr 05 '20 at 12:13
  • @cmannett85 I added CMake and the vscode extension, but I see that some configuration still needs to be done to compile more that one file. Can you please help me with that? – Adrian Pascu Apr 05 '20 at 12:50
  • @AdrianPascu create a different SO question. – cmannett85 Apr 06 '20 at 08:24

1 Answers1

0

This is a tough question to deal with because everyone's computers have different programs, files etc... For reference, I am on windows 10.

This worked for me and it's worth trying...

in tasks.json, either add a new task or modify the existing one to look as follows:

{
        "label": "g++.exe build active file",
        "args": [
            "-g",
            "${fileDirname}\\*.cpp",
            "-o",
            "${fileDirname}\\${fileBasenameNoExtension}.exe",
        ],
        "command": "g++.exe",
        "options": {
            "cwd": "${workspaceFolder}",
        },
        "group": "build",
        "type": "shell"
    }

Make a new file under .vscode called c_cpp_properties.json: The following may be different if you are using another compiler or OS

{
"configurations": [
    {
        "name": "Win32",
        "includePath": [
            "C:\\msys64\\mingw64\\include\\c++",  
            "C:\\msys64\\mingw64\\lib\\gcc\\x86_64-w64-mingw32\\11.2.0\\include",  "${workspaceFolder}/**"
        ],
        "defines": [
            "_DEBUG",
            "UNICODE",
            "_UNICODE"
        ],
        "compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
        "cStandard": "c11",
        "cppStandard": "c++20",
        "intelliSenseMode": "gcc-x64"
    }
],
"version": 4
}

Now in launch.json, you need to change the "preLaunchTask" to match the task's name we just created in tasks.json. This will tell vscode to first compile/build the program... then to run it:

Mine now looks like this:

{

"version": "0.2.0",
"configurations": [
    {
        "name": "g++.exe - Build and debug active file",
        "type": "cppdbg",
        "request": "launch",
        "program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
        "args": [],
        "stopAtEntry": false,
        "cwd": "${fileDirname}",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "miDebuggerPath": "C:\\msys64\\mingw64\\bin\\gdb.exe",
        "setupCommands": [
            {
                "description": "Enable pretty-printing for gdb",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
            }
        ],
        "preLaunchTask": "g++.exe build active file" 
    }
]
}

Note that the name we chose is not exactly describing what the new task actually does, feel free to change it, but if you do... make sure to update both the "label" in tasks.json and "preLaunchTask" in launch.json to be identical.

A P
  • 2,131
  • 2
  • 24
  • 36