How to compile c language with different options with vscode? - c++

Some c language codes use dynamic libraries, so I need to use the -ldm option. Some include other static libraries and need to use -I to specify the directory. But in vscode, the common configuration is directly gcc sourcefile -o targetfile, so it can't be executed normally? Is there a way to make vscode execute according to Makefile?
And such a setting can automatically use this method when I use SSH to add a folder on the server to the workspace, without having to reconfigure it every time?

Indeed it is possible to have VSCode work with make on linux or msbuild.exe on windows. You can have different configurations within these as well so that you have have a Debug build or a Release build. All you need to do is to have suitable tasks defined in tasks.json. For instance, consider:
{
"label": "lindbgbuild",
"type": "shell",
"command": "make",
"args": [
"CONF=Debug",
"-C",
"./.vscode"
],
"group": "build",
"problemMatcher": []
},
{
"label": "linreleasebuild",
"type": "shell",
"command": "make",
"args": [
"CONF=Release",
"-C",
"./.vscode"
],
"group": "build"
},
{
"label": "winbuilddebug",
"type": "shell",
"command": "msbuild",
"args": [
".vscode/windows.vcxproj",
"/property:GenerateFullPaths=true",
"/property:Configuration=Debug",
"/property:Platform=x64",
"/t:build",
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
},
{
"label": "winbuildrelease",
"type": "shell",
"command": "msbuild",
"args": [
".vscode/windows.vcxproj",
"/property:GenerateFullPaths=true",
"/property:Configuration=Release",
"/property:Platform=x64",
"/t:build",
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": {
"reveal": "silent"
},
"problemMatcher": "$msCompile"
}
There are 4 tasks in the tasks.json. In turn, they are:
lindbgbuild which executes command make CONF=Debug -C ./.vscode
What this command assumes is the existence of Makefile in the ./.vscode subdirectory of the current (project) directory. Then, it executes the Debug configuration within it. The next, linreleasebuild does the same for the Release configuration. So, what we have accomplished is that we can run an abstract command make and then this command will call the appropriate configuration specified within Makefile. All commands like g++ -c -o -g -I, etc., are configurable outside of VSCode in a separate makefile that VSCode only calls.
Then, you have a task winbuilddebug. This assumes the existence of a .vcxproj project configuration file in ./.vscode. It then executes the appropriate configuration with the options provided (in this case, the configuration is Debug on x64). Similarly, winbuildrelease for Release configuration under Windows. .vcxproj is automatically generated by Visual Studio IDE and makefiles on linux can be created by getting the project built using an IDE such as Netbeans. Or else, you can modify pre-existing makefiles/.vcxproj from other pre-existing projects to suit your current project. (I suggest against this, and using an IDE for your initial build since that automates without error many settings.)
With this given tasks.json, how do you access these tasks? On hitting CtrlShiftB, it opens up Select Build Tasks to Run dialog box where you can choose which task you want to run depending on which OS/Platform/compiler you are on.
Is there a way to automate this step and launch? Indeed, following is an example of launch.json. Consider the following configuration:
{
"name": "(Windows)RelLaunch",
"type": "cppvsdbg",
"request": "launch",
"program": ".vscode/x64/Release/windows.exe",
"args": [],
"preLaunchTask": "winbuildrelease",
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"internalConsoleOptions": "openOnSessionStart",
}
This will build then launch the application (assuming there are no build errors). Which build configuration does it choose? It will choose the winbuildrelease configuration that has been specified. Like this, if you are debugging and want to step through the code, you will have a different configuration.
How do you choose which configuration to launch? Hit CtrlShiftD. This opens up the Run sidebar, where on top, you can choose from amongst the configurations you have specified in your launch.json.

Related

Configure vscode to build and run c++ in one terminal

I installed mingw64 toolchain with MSYS2, and managed to successfully run my code from vscode. However, running it creates two terminals, one for building and one for running the generated file: C/C++: g++.exe build active file and cppdbg: main.exe.
cppdbg: main.exe leaves the text from the previous runs and "presentation" { "clear": true } in launch.json doesn`t help.
since build and run are not related, it's possible that the build will fail and the old .exe will be launched without me noticing it.
So I'm looking for a way to configure vscode to build and run the app in one terminal, or maybe redirect the compiler output to the output tab. Anything similar to how it's done in other languages.
Also, how can I configure it to run without debugging by default? In launch.json, "configurations" require a "type" parameter, which has only one option, "cppdbg" - why is there no release option?
You are asking two questions and I can answer both.
How do I build and debug the application, by making sure that it is launched only when the build is successful?
How do I configure it to run the application similarly?
Let me answer 2 first.
To solve this, you need the dependsOn property of tasks. For example, this is the content of my tasks.json file:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks":
[
{
"label": "Debug_Build",
"type": "shell",
"command": "g++ -g ./src/main.cpp -o ./bin/a.out",
},
{
"label": "Run main()",
"type": "shell",
"command": "./bin/a.out",
"dependsOn":"Debug_Build" //Previous task is run first, and then this one if previous was successful.
}
]
}
Notice that the second task (which is responsible for running the program) has dependsOn property which behaves exactly as you require: It will run only when the dependsOn task is successful (Which here is the build task)
To run the tasks, you can use the Command Palette to Run
Tasks>Run main()
to launch your task. Personally, I prefer using the extension Tasks, which creates a button for each task in the tasks.json file on the status bar of VS Code.
Now to answer 1, we use a similar property in the launch configuration json file: preLaunchTask
This will be exactly what you need: It will run the debugging only if the preLaunchTask was successful.
My launch.json file is as follows:
{
// 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}/bin/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "Debug_Build", //This is the part you need
}
]
}
So to summarize, you will need to create tasks.json and launch.json files in your workspace. In the tasks.json file, declare a "build" task, declare the "run" task which depends on the "build" task using the dependsOn property. Finally, in the launch.json file, refer the "build" task in the preLaunch property.

how do I configure VS code to build in Release mode (clang + macOS)

I am new to VS code. I have configured it using Clang on macOS using the provided [VS code documentation] (https://code.visualstudio.com/docs/cpp/config-clang-mac)
It works, I can build and debug. Great!
My question is: how do I configure VS Code to build in Release mode? I don't seem to be able to find any info in the documentation or a tutorial on how to do it
In case it helps, this is the way tasks.json looks right now
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "clang++ build active file",
"command": "/usr/bin/clang++",
"args": [
"-std=c++17",
"-stdlib=libc++",
"-g",
"-v",
"${file}",
"${workspaceFolder}/source/*.cpp",
"${workspaceFolder}/FFTreal/*.cpp",
"-I.",
"-L",
"${workspaceFolder}/BassLibrary",
"-lbass",
"-o",
"${workspaceFolder}/final.out",
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Any idea? Thanks!
Sorry, for the last answer...
So first of all, I need to claim that I'm not really familiar to Clang Family, but I did some research and found that there are two special groups out in tasks.json which VSCode provides: Build and Test. So, I guess that we need to build it in release mode manually where again I don't have any confidence on me...
I found that you can build your Clang scripts using CMake. CMake is simply a builder tool to help you reassemble your whole code, including libraries, dependencies, modules etc.
So, I'm not sure if that'll be possible but you can change your tasks.json configuration from Clang++ to CMake, maybe?
First of all, for a quick answer, I edited your tasks.json snippet to this:
{
"tasks": [
{
"label": "cmake init",
"type": "shell",
"options": {
"cwd": "${workspaceRoot}"
},
"command": "/path/to/cmake",
"args": [
"-S",
"${cwd}",
"-B",
"${cwd}/build"
],
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "cmake release builder",
"type": "shell",
"options": {
"cwd": "${workspaceRoot}"
},
"command": "/path/to/cmake",
"args": [
"--build",
"${workspaceRoot}/build",
"--config",
"Release"
],
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
What it does is, basically CMake scans your project folder and create configuration files via the cmake init task. After that, when you run cmake release builder, the task will assume that you have a build folder - which you can change easily - and creates a compact executable file, in build/Release.
But also, in order to use CMake, you need to create a CMakeLists.txt file whose baseName is case-sensitive. So, I created a really simple CMake configuration file which you can add your source files manually, unfortunately, like this:
cmake_minimum_required(VERSION 3.13) # CMake version check
project(simple_example) # Create project "simple_example"
set(CMAKE_CXX_STANDARD 14) # Enable c++14 standard
set(SOURCE_FILES test.cpp add.cpp) # Append source files
# Add executable target with source files listed in SOURCE_FILES variable
add_executable(simple_example ${SOURCE_FILES})
Finally, to make this process REAL, you need to go Terminal > Run Build Task in VSCode.
I'm not really sure that you can use Clang compiler to build a whole application, like an .exe file in Windows. During the research, I focused a lot on the difference between compiler and builder which I recommend to look it up!
I hope that I used English in a comprehensible way and not made confused.

Why is "C/C++:" being inserted into the label of my tasks.json file in Visual Studio Code?

I am using Visual Studio Code with MinGW-w64. This involves creating two files (launch.json and tasks.json) that allow me to build and debug my C++ code. I select my tasks.json file by going to Terminal --> Configure Default Build Task... and then selecting "C/C++: g++.exe build active file."
Normally, the tasks.json file appears as follows:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
However, in the last few days, it has appeared as follows:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": "build"
}
]
}
When the file is in this format, I'm not able to debug my code. Instead, I get the message "Could not find the task 'g++.exe build active file'.
The only apparent difference is that C/C++is now preceding g++.exe build active file in the "label" line. Once I delete this label, I'm able to get the code to compile and/or debug.
This leads me to ask two questions: first, why is C/C++ being inserted in the label? It doesn't appear in the Microsoft documentation for setting up MinGW with Visual Studio Code: https://code.visualstudio.com/docs/cpp/config-mingw
Secondly, how am I able to permanently remove C/C++ from my label so that I don't have to manually delete it each time? I have tried choosing Configure Task next to C/C++:g++.exe build active file in the Configure Default Build Tasks in the dropdown menu; removing C/C++, and then saving the tasks.json file, but this doesn't appear to cause the build task to change permanently.
Thank you as always for your help.
It took me a while to read the source code of the cpptools extension, and then I found some problems. Under different conditions, the extension has different response
If there is ".vscode" folder in the folder root directory, then when adding the debug configuration, it will only guide the creation of launch.json.The user needs to be guided to configure "tasks.json" again.But the name of the task created at this time is not consistent with value of "preLaunchTask". This is a problem with this extension. I think the reason is that the ".vscode" folder was not found when initializing the debug configuration, some conditions are missing when the extension's code is executed
If there is a empty ".vscode" folder in the root directory of the folder, "launch.json" and "tasks.json" will be created at the same time when initializing the debug configuration.The two files are exactly matched and do not need any modification
If the user configures the task as first.When initializing the debug configuration, the extension will recreate a task called "g++.exe build active file" which is not start with "C/C++".This of course works, but you may need to delete the task created at the beginning whichhas not been used
This design is reasonable because "C/C++: g++.exe build active file" is actually a task template built into cpptools (there are two others). The built-in templates can be referenced by "preLaunchTask", but the user cannot see them in "tasks.json"
If you delete the file "tasks.json" and change the value of "preLaunchTask" to "C:C++: g++.exe build active file".It also works,but this is not a standard usage
I think this is a mistake of them, it started to appear after a recent version

How to get debugging c++ to work in VSCode on a mac?

Can someone explain how to get building and debugging to work in VSCode on a Mac?
Let's assume we successfully installed cpp tools:
-Including creating a proper task file that works on a mac.
-The required changes to launch.json
-Any other step required.
(Don't get me wrong, I'm not lazy, I have been trying for more then 2 hours now and it seems that a proper answer for this question can help a lot of people.)
Once you have the C/C++ extension downloaded, you can use the configurations to generate a project.json in debug window of VsCode. If you do not currently have a project.json under the project's .vscode folder, hit F5 and a dropdown list should show up. There you can select C++ (GDB/LLDB), and this should generate a project.json for you to use.
If you want to just hit F5 so it automatically compiles and debugs your program, you will need to add a tasks.json. This can be done by hitting F1 and selecting Tasks: Configure Task Runner and select Other. Replace "echo" with "gcc" (or clang) and replace the args with your .cpp files and don't forget to add -g.
You can find more information in their documentation: https://code.visualstudio.com/docs/languages/cpp
I don't count the time I lost looking for an answer to this question!
I found the vscode-lldb extension and it works fine, all other solutions I found don't work for me.
You still have to create configuration files, here are mine to debug my unit tests:
I'm using googletest and extension c++14 in this example
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build & debug tests",
"type": "shell",
"command": "g++",
"args": [
"-g",
"-std=c++14",
"-I/src",
"-lgtest",
"tests/MainTest.cpp",
"-o",
"bin/testMain"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
}
]
}
launch.json
{
"version": "0.2.0",
"configurations":
[
{
"name": "Debug Tests C/C++",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/bin/testMain",
"args": [],
"cwd": "${workspaceFolder}/tests",
"preLaunchTask": "build & debug tests"
}
]
}

How to build and run C++ code in Visual Studio Code?

I have a tasks.json script that currently compiles the code
{
"version": "0.1.0",
"command": "gcc",
"isShellCommand": true,
"args": ["-Wall", "${relativeFile}", "-o", "${relativeFile}.exe", "-pedantic"],
"echoCommand": true,
"showOutput": "always",
"problemMatcher": {
"owner": "cpp",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
}
This works fine, but when I want to run the file I have to run the exe from command line. Is it possible to do this in the task as well? So if it finishes building succesfully it then runs a different task?
If anyone else comes across this when searching like I did, you can now set the property preLaunchTask in your launch.json to your build task's name property and it will run before your launch.
For Example
"name": "Debug (gdb) Launch",
"preLaunchTask": "Build All",
Will run the "name": "Builld All" in your tasks.json before launching your program.
You can read the information on this on the Debugging in Visual Code docs page.
You can configure multiple tasks in Visual Studio Code, one of which will allow you to build your executable, and the other will run your executable.
Optionally, you could also look into Visual Studio Code's "Run Mode" (see here). If you use "Run Mode", you should be able to configure Visual Studio Code to build your executable, and then launch it.
I'm not extremely familiar with "Run Mode", thus I will detail how to define multiple tasks to achieve a similar result.
Disclaimer: Visual Studio Code does not support tasks that use different shell commands (see here).
That's right. At its current state, Visual Studio Code doesn't have "native" support for defining tasks that use different shell commands.
Disclaimer: Visual Studio Code's task-output pane will not allow you to pass input to your program interactively.
If your program relies on user-input (for example, from stdin), you're probably better off not using Visual Studio Code to run your executable.
Basically, what we'll need to do, is define two tasks, one of which will be a build task, the other will be our launch task.
Seeing as Visual Studio Code doesn't have great support for defining multiple tasks that each use different shell commands, we'll need to change our tasks.json's "command" property to cmd (or sh, if on Linux/macOS). We'll also need to set the "args" property to [/C] ([-c] if on Linux/macOS).
The reason behind us doing this, is because we want each of the tasks we're about to define, to be passed as arguments to a new shell instance.
The next step, is to define our build and launch tasks. When we do so, we'll need to make sure we place the command we want to run, as a task argument. For example:
{
"taskName": "build",
"args": ["gcc", "-Wall", "${relativeFile}", "-o", "${relativeFile}.exe", "-pedantic"]
}
Finally, what we'll do, is add the "isBuildCommand" property to our build task (and make sure it's true), as well as add the "isTestCommand" property to our launch task (and, again, make sure it's true).
After all of that, our tasks.json file could look something like this:
{
"version": "0.1.0",
"command": "cmd",
"args": ["/C"],
"isShellCommand": true,
"showOutput": "always",
"suppressTaskName": true,
"tasks": [
{
"taskName": "build",
"args": ["gcc", "-Wall", "${relativeFile}", "-o", "${relativeFile}.exe", "-pedantic"],
"isBuildCommand": true
},
{
"taskName": "run",
"args": ["${relativeFile}.exe"],
"isTestCommand": true
}
]
}
Note: If placing each task argument in their own string within the args array doesn't work, you can also try placing all of the arguments in a single string within the args array. Example:
["gcc -Wall ${relativeFile} -o ${relativeFile}.exe -pedantic"]
Note: If you would like to be able to invoke your task(s) via keyboard shortcuts, you have the "workbench.action.tasks.build" and "workbench.action.tasks.test" editor commands at your disposal.
If you need an example of binding keys to those commands, here's an example of how I have them mapped in my keybindings.json file:
[
{
"key": "f6",
"command": "workbench.action.tasks.build"
},
{
"key": "f7",
"command": "workbench.action.tasks.test"
}
}
Edit: You probably only need to define a keyboard shortcut for the test task, as the build task probably already has one defined. Check here before you take the time to define a different keyboard shortcut.
You can create a task for build and as the arguments of it you can pass the commands for running. As an example the task I use to compile and run c++ is shown below.
{
"version": "2.0.0",
"tasks": [
{
"label": "g++ build and run",
"type": "shell",
"command": "g++",
"args": [
"-g",
"-o",
"out.exe",
"\"${file}\"",
"&&",
"./out.exe",
"<",
"input.in",
">",
"output.out"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
In the above task I compile my source file (the name of the file could be anyone here as ${file} is used) into out.exe and the run out.exe while getting input from input.in and outputting the output to output.out.