Recent changes to the tasks.json
seem to have made a command available for each of the tasks listed. See https://code.visualstudio.com/docs/editor/tasks which makes a lot of this moot.
This answer was originally aimed at a more complex solution, but the simple shell runner task format as presented in the accepted answer proved more useful. See below for what that looks like now.
The limitation here is that VS Code is limited to a single high level build task/command for a given workspace. Multiple sub-tasks are allowed, but they are limited to using the top level "command" but can provide different "arguments". This would be well suited to an environment that uses a build system akin to make, ant or msbuild. E.g.;
{
"version": "0.1.0",
"command": "make", // command must appear here
"tasks" : [
{
"taskName": "clean",
"suppressTaskName": false, // false by default
//"command": "somethingelse", // not valid here
"args": ["${file}"] // if required
},
{
"taskName": "install"
// ...
}
]
}
Two alternatives are available;
Have a custom script attempt to run the compile/execution solely given the arguments in task.json.
-- the shell file would be a simple
"$@" # run what I get
-- the tasks.json
"args": ["clang++", "-std=c++14", "-O2", "${file}"]
Getting the exectuable to run (./a.out
) was more effort. Simply adding it as an argument didn't work, the shell script was required to execute it if it was there.
Shell out the switching and the execution of the output to a custom script, given the file extension and filename. This proved easier to implement and offered more control in the shell script.
{
"version": "0.1.0",
"isShellCommand": true,
"taskName": "generic build",
"showOutput": "always",
"args": ["${fileExtname}", "${file}"]
"command": "./.vscode/compileme.sh", // expected in the "local settings" folder
//"command": "~/compileme.sh", // if in HOME folder
}
And the shell script, compileme.sh;
#!/bin/sh
# basic error checking not shown...
echo "compilation being executed with the arguments;"
echo "$@"
filetype=$1
file=$2
if [ $filetype = ".cpp" -o $filetype = ".cxx" ] ; then
clang++ -std=c++14 -Wall -Wextra -pedantic -pthread $file && ./a.out
elif [ $filetype = ".c" ]
then
clang -std=c11 -Wall -Wextra -pedantic -pthread $file && ./a.out
elif [ $filetype = ".sh" ]
then
$file
elif [ $filetype = ".py" ]
then
python $file
else
echo "file type not supported..."
exit 1
fi
Given the options listed above, the second option is preferable. This implementation works on OS X, but it could be easily ported to Linux and Windows as needed. I'll keep on eye on this and try track changes to the VS Code build tasks, file based builds or support for multiple commands could be a welcome addition.
My tasks.json supports a few runners, and a default for the build that prints message as a reminder. It uses the shell as the runner and now looks like...
{
"version": "0.1.0",
"isShellCommand": true,
"taskName": "GenericBuild",
"showOutput": "always",
"command": "sh",
"suppressTaskName": false,
"args": ["-c"],
"tasks": [
{
"taskName": "no build",
"suppressTaskName": true,
"isBuildCommand": true,
"args": [
"echo There is no default build task, run a task by name..."
]
},
{
"taskName": "cpp",
"suppressTaskName": true,
"args": [
"clang++ -std=c++14 -Wall -Wextra -pedantic -pthread \"${file}\" && ./a.out"
]
},
{
"taskName": "shell",
"suppressTaskName": true,
"args": [
"\"${file}\""
]
},
{
"taskName": "python",
"suppressTaskName": true,
"args": [
"python \"${file}\""
]
},
{
"taskName": "c",
"suppressTaskName": true,
"args": [
"clang -std=c11 -Wall -Wextra -pedantic -pthread \"${file}\" && ./a.out"
]
}
]
}