Reference a variabled in tasks.json that was defined in launch.json - json

I'm trying to configure my project in Visual Studio Code.
I am using CMake+make to build my project. CMake needs to know the project configuration (Debug/Release) and architecture (x64/x86) before it can generate the make files.
I could define 4 tasks and 4 launch configurations to achieve this (each hardcoding both options), but that is a lot of duplication.
Instead, I would like to use environment variables to basically "pass down" the parameters from the launch configuration to a single task.
However, VScode doesn't seem to forward what I define in the launch configuration to the task.
Here is what I have:
// launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug (x64)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/debug/x64/executable",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [
{
"name": "proj_configuration",
"value": "Debug"
},
{
"name": "proj_platform",
"value": "x64"
}
],
// "variables": {
// "proj_configuration": "Debug",
// "proj_platform": "x64"
// },
"externalConsole": true,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "Make Project",
}
]
}
// tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Project",
"type": "shell",
"command": "cmake",
"args": [
"-B${workspaceFolder}/build",
"-H${workspaceFolder}",
"-DCMAKE_BUILD_TYPE=${proj_configuration}",
"-DCMAKE_GENERATOR_PLATFORM=${proj_platform}"
],
"group": {
"kind": "build",
"isDefault": false
}
},
{
"label": "Make Project",
"type": "shell",
"command": "make",
"group": {
"kind": "build",
"isDefault": true
},
"dependsOn": ["Build Project"],
}
]
}
When I try to run my project, I get
Executing task: cmake -B/home/user/project/build -H/home/user/project/ -DCMAKE_BUILD_TYPE=${proj_configuration} -DCMAKE_GENERATOR_PLATFORM=${proj_platform}
As you can see, the 2 variables are not replaced.
I've also tried using the property "variables", but no luck using that either.
So, is it possible to do what I described, or do I have to define multiple tasks instead?

with the extension Command Variable you can save a number of strings in a store and use these in launch.json and task.json. See example in the link

Related

Can I use ${file} to generate a output "arg" for a task in vscode?

I'm trying to build files in vscode with an "unsupported" compiler. Therefore I've created a task to start the compiler and this works perfectly, as long as the source and destination files are given. I give my source file as ${file} and vscode correctly substitutes this with the source file. For the destination file I have to use the same filename but change it's extension.
Is it possible for me to create a string variable in .json, copy the value of my ${file} string into that and use change its extension before using it as an argument?
My tasks.json is below, my sourcefile ${file} = "C:\_projects\Customer\Logging\LogAsync\ASyncLog\Server.kl"
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": ".\\ktrans.exe",
"problemMatcher": [],
"options": {
"cwd": "C:\\Program Files (x86)\\FANUC\\WinOLPC\\bin\\"
},
"args": [
"${file}",
"C:\\_projects\\Customer\\Logging\\LogAsync\\ASyncLog\\Server.pc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Thanks all for helping. My working code is below for other peaple who came here searching for how to compile Fanuc Karel in vscode:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": ".\\ktrans.exe",
"problemMatcher": [],
"options": {
"cwd": "C:\\Program Files (x86)\\FANUC\\WinOLPC\\bin\\"
},
"args": [
"${file}",
"${fileDirname}\\${fileBasenameNoExtension}.pc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Yes, you can use ${file} to generate an output "arg" for a task in vscode. To do so, simply add the following line to your tasks.json file:
"args": ["${file}"]

Configure Visual Studio Code task to execute multiple shell commands in sequence

Is there a possibility, to add multiple shell commands in sequence to a Visual Studio Code task with separate arguments and options? I managed to execute multiple commands using && to chain then together to a single command, as you could in any Linux shell. But i guess, there has to be a better way to do this.
I use Visual Studio Code on Ubuntu 18.04 LTS.
Here is the example of how i currently chained the commands for a build task in a task.json file to build a c++ project using cmake:
{
"tasks": [
{
"type": "shell",
"label": "build",
"command": "cd ${workspaceFolder}/build && cmake .. && make clean && make",
"group": {
"kind": "build",
"isDefault": true
}
}
],
"version": "2.0.0"
}
Update: -------------------------------------------------------------------
I tried to use the dependsOn: property to start the 4 separatly defined tasks. However, this resulted in all 4 commands being executed at the same time in different shell instances instead of in sequence as needed:
{
"tasks": [
{
"type": "shell",
"label": "build project",
"dependsOn": [
"Go to build folder",
"Cmake",
"make clean",
"make",
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Go to build folder",
"type": "shell",
"command": "cd ${workspaceFolder}/build",
"presentation": {
"group": "cmake-complile"
}
},
{
"label": "Cmake",
"type": "shell",
"command": "cmake ..",
"presentation": {
"group": "cmake-complile"
}
},
{
"label": "make clean",
"type": "shell",
"command": "make clean",
"presentation": {
"group": "cmake-complile"
}
},
{
"label": "make",
"type": "shell",
"command": "make",
"presentation": {
"group": "cmake-complile"
}
}
],
"version": "2.0.0"
}
Thanks to the many comments i found a solution which works well by setting "dependsOrder" to "sequence":
{
"tasks": [
{
"type": "shell",
"label": "build project",
"dependsOrder": "sequence",
"dependsOn": [
"Cmake",
"make clean",
"make",
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Cmake",
"type": "shell",
"command": "cmake ..",
"options": {
"cwd": "${workspaceFolder}/build",
},
},
{
"label": "make clean",
"type": "shell",
"command": "make clean",
"options": {
"cwd": "${workspaceFolder}/build",
},
},
{
"label": "make",
"type": "shell",
"command": "make",
"options": {
"cwd": "${workspaceFolder}/build",
},
}
],
"version": "2.0.0"
}

VS code, c++ extension, task.json is there a way to group args in a array and reference in a task

Im using VS code with c++ extesion, on my task.json i have a debug task and runwithoutdebug task, this tasks have common arguments and i instead of have to add those arguments in both, i was trying to reference a array, and write those common argument in that array.
Is that possible? is there any alternative
Example: --->task.json
"version": "2.0.0",
"tasks": [
{ ----------------------> TASK 1
"label": "compilewithoutDeb",
"type": "shell",
"command": "g++",
"args": [
"main.cpp",
"header.cpp",
"-o",
"main.exe"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{ ----------------------> TASK 2
"label": "compileDeb",
"type": "shell",
"command": "g++",
"args": [
"-g",
"main.cpp",
"header.cpp",
"-o",
"main.exe"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Has you can see i have on task "compilewithoutDeb" and "compileDeb" this common arguments
"main.cpp",
"header.cpp",
"-o",
"main.exe"
Is there a away that i could do like:
"paramArg":[
"main.cpp",
"header.cpp",
"-o",
"main.exe"
]
"tasks": [
{
"label": "compilewithoutDeb",
"type": "shell",
"command": "g++",
"args": [
"${paramArg}" <-----------------
],
"group": {
"kind": "build",
"isDefault": true
}
}
You can create an input. It would be a promptString with the arguments as the default. For your other task you'd add the "-g" parameter before the input.
"tasks": [
{
"label": "compilewithoutDeb",
"type": "shell",
"command": "g++",
"args": [
"${input:paramArg}"
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "compileDeb",
"type": "shell",
"command": "g++",
"args": [
"-g",
"${input:paramArg}"
],
"group": {
"kind": "build",
"isDefault": true
}
},
],
"inputs": [
{
"id": "paramArg",
"description": "Just hit the Enter key",
"type": "promptString",
"default": "main.cpp header.cpp -o main.exe"
},
]
Yes, there's an (ugly) way to do this. While tasks.json can only define tasks (that is what is is for) it can reference different kind of variables.
The two options that would be reasonable to use: env (if you want to set it outside of vscode which doesn't seem to be the case here) or config.
To apply it to your sample:
settings.json (either in your user's settings or in the workspace [folder .vscode])
{
"personalSettings.commonArgs": [
"-o",
"main.exe",
"header.cpp",
"main.cpp"
]
}
and then your tasks.json would be
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{ // ----------------------> TASK 1
"label": "compilewithoutDeb",
"type": "shell",
"command": "g++ ${config:personalSettings.commonArgs}",
"group": {
"kind": "build",
"isDefault": true
}
},
{ // ----------------------> TASK 2
"label": "compileDeb",
"type": "shell",
"command": "g++ ${config:personalSettings.commonArgs}",
"args": [
"-g"
],
"group": "build"
}
]
}
(additional changes: only one build task can be the default, used inline comments)
Note: to get the most out of your build tasks I'd suggest to add a problem matcher to your task definition, something like
// use this or similar when cpptools or a similar libre/free extension
// is installed providing an appropriate matcher
// "problemMatcher": "$gcc"
// remark: ms-vscode.cpptools is "gratis", but comes with telemetry + usage-restrictions
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
Note: I'd suggest to not hard-wire the file names, instead use either a "general task" which uses ${file} or change the tool you run to make where you have all the arguments defined clean, can build outside of vscode, too and because of dependency tracking only compile what is actually necessary.

Property args is not allowed in launch.json in vscode

I am just trying to add some basic configuration to my launch.json file in vscode, but I am getting an error as Property args is not allowed. Below is my configuration.
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "index",
"args": [
"src/index.ts"
],
"cwd": "${workspaceFolder}"
}
],
"compounds": []
}
That was a silly mistake. According to this doc
VS Code debuggers typically support launching a program in debug mode
or attaching to an already running program in debug mode. Depending on
the request (attach or launch) different attributes are required and
VS Code's launch.json validation and suggestions should help with
that.
So when I changed my request to launch from attach, everything was perfect. Only the request type launch supports the configuration args.
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "index",
"args": [
"src/index.ts"
],
"cwd": "${workspaceFolder}"
}
],
"compounds": []
}

vs code to run c code

I have an existing code base that builds with a makefile and I'd like to use Visual Studio Code to run it.
There are my launch.json and tasks.json.
{
"version": "0.2.0",
"configurations": [{
"name": "C Launch (GDB)",
"type": "cppdbg",
"request": "launch",
"launchOptionType": "Local",
"targetArchitecture": "x64",
"cwd": "${workspaceRoot}",
"program": "E:/code/c",
"miDebuggerPath": "E:/Program Files/TDM-GCC-64/bin/gdb64.exe",
"args": [""],
"stopAtEntry": false,
"externalConsole": true,
"preLaunchTask": "gcc"  
}]
}
{
"version": "0.1.0",
"command": "gcc",
"args": ["${file}", "-o", "${fileBasenameNoExtension}.exe", "-g3", "-Og", "-Wall", "-static-libgcc", "-std=c11", "-fexec-charset=GBK", "-finput-charset=UTF-8"],
"showOutput": "always",
"problemMatcher": {
"owner": "c",
"fileLocation": ["relative", "${workspaceRoot}"],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
}
then when I run Hello world,then will have some problems.
Try changing your paths to use \ instead of / on Windows. Since you have to escape \ in json strings, the actual value would be:
"program": "E:\\code\\c\\${fileBasenameNoExtension}.exe"
provided the built executable is actually at E:\code\c