Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VS Code: Running Tasks with WSL/Bash

WSL makes it easy to get gcc and other Linux tools. You can use a script to quickly configure a WSL development environment, so if you mess something up you can quickly destroy it and start over again with minimal cost. Thus I would like to run tasks on WSL instead of on Windows itself.

In Sublime3 for example, I can build C code using the WSL installation of GCC by simply creating a new build system with the following code:

{
  "cmd" : ["bash", "-c", "gcc ${file_name} -o ${file_base_name} && ./${file_base_name}"],
  "shell": true,
  "working_dir": "${file_path}",
}

I have been trying to figure out how to replicate this on VS Code with no luck so far. It seems as if at least one other person has managed to get this working so it should be possible.

It seems that the proper way is to configure a tasks.json file. The relevant lines seem to be:

"command": "bash.exe",
    "args": ["-c", "'insert code here'"]

It seems that this tells the powershell to run bash -c 'insert code here'. Can anyone come up with the right command?


Some Background:

${file} is a a variable representing the active file in VSCode. Here is the list of all predefined variables.

wslpath is a new bash command shipping in Windows 1803 which takes a Windows path and returns the wsl path e.g.:

$ wslpath "c:\Users\Evan\Google Drive\Development\Programming Languages\file.c"
/mnt/c/Users/Evan/Google Drive/Development/Programming Languages/file.c

My Attempts:

I tried writing a script to do it, but ran into issues. The tasks.json syntax to call myscript should be something like this (note that we pass the file name to the script so that the script can pass it to GCC).

"args": ["-c", "'myscript.sh \"${file}\"'"]

or as per this answer

"command": "/path/to/script.sh"
"args": ["\"${file}\""]

myscript might look something like this:

#!/bin/bash
echo "File Path is here $1"
x=$(wslpath "$1")
gcc "$x" -o a.out
./a.out

VS Code Docs

like image 941
Evan Rosica Avatar asked Jul 31 '26 14:07

Evan Rosica


2 Answers

It can be done without the script:

 "command": "gcc '$(wslpath '${file}')' && ./a.out"

${file} would be parsed before the command parsed in bash.

like image 103
idanp Avatar answered Aug 03 '26 18:08

idanp


here is another quick solution of how to solve the problem using the bash command in the task.json file in vscode. You can pretty much take this and insert the commands that you need. You can also chain and nest commands if you need that.

{
    "version": "2.0.0",
    "tasks": [
        {
            // link current file. Uses one or more object.o files
            "label": "link_only_cpp_17",
            "type": "shell",
            "command": "bash", // call bash
            "args": [
                "-c", // read commands from string
                "\"g++ -g -o a $(ls | grep -F .o | tr '\\n' ' ')\"" // link all files ending with .o
            ],
            "problemMatcher": []
        }
    ]
}

This is an example from my task.json file. It shows that you can use the bash command and pass arbitrary code to it. For this you have to use the -c flag (read code from a string) and then pass your code as a string (next argument). In this example, the g++ links all files that contain .o. These files are found with the help of $(ls | grep -F .o | tr '\\n' ' '). Be aware that you have to use $(), otherwise, your code will not be evaluated.

As far as I know, you cannot use a vscode macro (e.g. ${file}) in the command that you pass to bash, since this is a string literal. This is why I am using a and not the file name. If you know a way to do this, let me know :)

Works on vscode version 1.38.1.

like image 22
User12547645 Avatar answered Aug 03 '26 20:08

User12547645



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!