How to add the custom compile commands in VS Code? - bash

I usually do competitive programming in Geany IDE and have the following custom compile command to compile C++ programs -
g++ -std=c++17 -Wshadow -Wall -o "%e" "%f" -g -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG
The compile command is binded by f9 key. I just have to press f9, which saves and compiles the file and then I switch to bash terminal (f2 key shortcut) to execute the binary file.
The terminal also follows the path of the current file opened in editor.
I want the same settings in VS Code.
So far, I have managed to bring the editor and terminal side by side and to easily toggle the focus between them via f1 and f2.
But I am unable to set the custom compile command, bind it with f9 key and to configure the terminal so that it follows the path of file in editor currently in focus.
Please give me a complete solution. It would be much better to edit the json setting files directly.
Here is a snapshot of the settings in my Geany IDE :-
This is how my Geany looks and the Setting boxes

You can set a custom task in VS Code. Edit the tasks.json file in the .vscode folder of your workspace like:
{
"version": "2.0.0",
"tasks": [
{
"label": "My build task",
"type": "shell",
// Assign output file name with VSCode inner variables like ${fileBasename}
"command": "g++ -std=c++17 -Wshadow -Wall -o ${fileBasename} -g -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG",
"options": {
},
"problemMatcher": ["$gcc"],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
You can write the compile command directly into "command" attribute, or write it with more commands into a script then write the simple executing script command in the attribute instead.
And the "isDefault": true attribute make this default task which could be invoked simply binding with ctrl+shift+B.

Related

Shortcut for running terminal command in VS code

Is there a way to make a hotkey for running specific command in terminal? Say I want to compile my TypeScript files by hotkey and not to type to terminal "tsc" or any other variation of that command. (Edit: I know it is possible to recompile TS on save, but the question is still the same)
Typically you would set up a build or another task or an npm script and then trigger that with a hotkey.
There is another new way to do it with send text to the terminal.
For example, try this in your keybindings (Preferences: Open Keyboard Shortcuts (JSON)):
{
"key": "ctrl+alt+u",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "node -v\u000D"
}
}
for an npm script:
{
"key": "ctrl+alt+u",
"command": "workbench.action.terminal.sendSequence",
"args": {
"text": "npm run-script test\u000D"
}
}
The first will run the node -v command (the \u000D is a return so it runs). I still recommend actually setting up a build task though, and then there are keychords for running your build task: Ctrl-shift-B. Or an npm script.
For example, if you had a more complex script to run, see how to bind a task to a keybinding or how to keybind an external command.
EDIT: As of v1.32 you can now do something like this:
{
"key": "ctrl+shift+t",
"command": "workbench.action.terminal.sendSequence",
"args": { "text": "tsc '${file}'\u000D" }
}
You can now use the built-in variables, like ${file}, with the sendSequence command in a keybinding. I wrapped ${file} in single quotes in case your directory structure has a folder with a space in the name. And \u000D is a return.
You can accomplish this with VSCode tasks and then wire up your task to a keybinding. The downside to this approach is you have to have a tasks.json file in your workspace .vscode folder (it can't be global).
Here is an example where I wanted to open a file in a custom GitHub remote:
// tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "Open in remote",
"type": "shell",
"command": "open https://github.custom.com/org/repo/blob/master/${relativeFile}#L${lineNumber}"
}
]
}
// keybindings.json
{
"key": "ctrl+o",
"command": "workbench.action.tasks.runTask",
"args": "Open in remote"
},
Here are some more VS Code variables you can use if you are curious: https://code.visualstudio.com/docs/editor/variables-reference
There is a long standing issue open here which should make this easier to do without tasks: https://github.com/microsoft/vscode/issues/871
I don't think vscode by default can do this, but you can try this extension. That work for me.
https://marketplace.visualstudio.com/items?itemName=mkloubert.vs-script-commands
in addition to #mark ..
"args": { "text": "npm run-script test | tee /dev/null \u000D" }
this way it will run any script including bash scripts, that doesn't conflict to their arguments
(e.g try rsync without the tee)

Want ${workspaceFolder} to emit forward slashes on Windows?

I'm configuring a VSCode task in tasks.json, and I need to pass the ${workspaceFolder} to a 'make' command, however it needs to be forward slashes, not back slashes.
{
"version": "2.0.0",
"echoCommand": true,
"tasks": [
{
"label": "build",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"command": "make",
"args": [
"APPDIR=\"${workspaceFolder}\""
]
. . .
Is there any way to modify ${workspaceFolder} to emit forward slashes on Windows?
Or, is there such a thing as a macro, where I can search and replace?
EDIT:
My root issue is that GNU make seems to escape the backslashes incoming from APPDIR, for example: C:\somedirectory\someotherdirectory\athirddirectory.
I thought if I could switch to forward slashes, it would fix the issue.
I have no control over, and cannot edit, the make file.
Thanks
-John
Although not explicitly stated, it sounds like you're on Windows and using Cygwin make.
Basically using Johan's suggestion, here is a complete tasks.json that uses cygpath -m to pass forward slashes to make:
{
"version": "2.0.0",
"tasks": [
{
"label": "build hello world",
"type": "shell",
"command": "d:/cygwin64/bin/sh",
"args": [
"-c",
"make APPDIR=$(cygpath -m '${workspaceFolder}')"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
And here is a sample Makefile to be called:
$(info APPDIR is "$(APPDIR)")
helloworld.exe: helloworld.cpp
g++ -g -Wall -std=c++11 -o $# helloworld.cpp
When I press Ctrl+Shift+B to invoke this task, I see in the Terminal window:
> Executing task in folder cpphello: d:/cygwin64/bin/sh -c "make APPDIR=$(cygpath -m 'D:\wrk\learn\vscode\cpphello')" <
APPDIR is "D:/wrk/learn/vscode/cpphello"
make: 'helloworld.exe' is up to date.
Terminal will be reused by tasks, press any key to close it.
This uses the -m (mixed) switch to cygpath to get what looks like a Windows path but using forward slashes. cygpath has other options; see cygpath --help.
Two subtleties here:
I specify the path to sh explicitly. That is because I also
have git for Windows on my $PATH,
and it comes before my Cygwin path so that vscode will use that
git. But git for Windows also has sh.exe, and if that one
is used here, make blows up with a Cygwin DLL error.
I had to change the default VSCode shell to cmd.exe, whereas
the default is powershell.exe. The problem with powershell
here is that VSCode uses single quotes when passing arguments to
it, whereas my solution requires that VSCode use double-quotes,
which it does with cmd.exe. To change the shell, use the
"Terminal: Select Default Shell" command from the palette
(Ctrl+Shift+P).
Finally, I'll note that all of this nonsense can be avoided if, in your situation, you can create an intermediate bash shell script rather than invoking make directly. The tasks.json language is not very powerful, and the quirky shells VSCode knows how to invoke on Windows (namely cmd.exe and powershell.exe) add extra complexity and fragility.
Use variable extension.commandvariable.workspace.workspaceFolderPosix from extension command-variable where you need ${workspaceFolder} with forward slashes. There are also other useful substitutions in this extension.

NetBeans: change compiler/linker parameters with command line

I want to change the compiler/linker parameters without using NetBeans GUI, i.e. I want every new project I make has already set gcc parameters (like -I and -l -L) in makefile without enter in the project properties window by user interface. I need it for an installation script which already set netbeans for working with fixed library (for example openCV) at first boot. I already tried changing toolchain file like GNU_c.xml and GNU_cpp.xml but without results. Same thing making a GCC alias/bash function before starting netbeans (no inerithance between subshell that netbeans creates for compiling/linking files), also modifying .bashrc file with alias same results.
Is there a way to do this?
You could define an alias in your .bashrc, for example :
$ echo "alias gcc='gcc -l -Wall -Wextra" >> ~/.bashrc
$ source ~/.bashrc
In the case of NetBeans, I don't know if it launches an instance of bash to run gcc but if not, you could define a script as an executable that contains something like (for example):
#!/bin/bash
gcc -l -Wall -Wextra "$#"
# or [gcc "$#"] only if you have define the previous alias in your bashrc

Creating a Vala Sublime Text build system

I can't seem to make a Vala build system in Sublime Text 2... Here's what I have so far:
{
"cmd": ["valac", "--pkg", "gtk+-3.0", "'$file'"]
}
Unfortunately, this only compiles the code with valac, but doesn't run it.
How can I make it run the compiled program straight after?
Use vala instead of valac. However, keep in mind that this will not keep the resulting executable. To do that you would need to chain multiple command together—I don't know how to do that with Sublime Text, but on the command line you could do something like
valac -o foo --pkg gtk+-3.0 file.vala && ./foo
This works for me in Sublime Text 3 ( by the introduction of "shell_cmd" ) :
{
"shell_cmd": "valac --pkg gtk+-3.0 $file -o app.vala && ./app.vala"
}
app.vala will be the filename of the compiled build-file.
The simplest build system to run Vala code from Sublime Text 2 would be:
{ "cmd": ["vala", "--pkg=gtk+-3.0", "$file"] }
This was my first attempt to create a build system for Vala on Windows, and I wasn't quite satisfied with the result. Several annoying windows popped up during compilation, and after, host window remained visible. To solve this, I ran vala in a minimized window:
{ "cmd": ["cmd", "/c start /min vala --pkg=gtk+-3.0 $file"] }
It worked, but now, compiler output was not visible to Sublime Text.
Since I'm just playing around with Vala and my programs are of Hello World complexity, I can solve both problems by simply compiling the code twice. First to C code to get build results, and then to run the code from a minimized window.
{ "cmd": ["cmd", "/c valac --ccode --pkg=gtk+-3.0 $file && start /min vala --pkg=gtk+-3.0 $file"] }
Compiling to C only does have its drawbacks, and C-compiler errors won't be shown in build results, but I can live with that.
Here is what I ended up with:
{
"cmd": ["cmd", "/c valac --ccode --pkg=gtk+-3.0 $file && start /min /wait valac -X -mwindows --pkg=gtk+-3.0 $file -o $file_base_name && $file_base_name"],
"file_regex": "^(?<filename>(?:[A-Z]:)?[^:]+):(?<line>[0-9]+).(?<column>[0-9]+)[^:]+: (?<message>.+)",
"selector": "source.vala"
}
I used valac instead of vala here to save the compiled program and run it after compilation (the trick described by Roman Fischer and nemequ, but with $file_base_name variable instead of static file name).
Also I added two more fields: file_regex for build results navigation and selector for build system auto-selection.

Is there a way to make a c++ compiler flag as default

Just like we specify input flags in the settings of the project in Xcode
Can I make few flags like -O3 or -fopenmp as default flags in command line when I use Terminal.
So that I dont have to type them everytime I compile some c++ fies. Is there a file in the installed gcc or C++ that I can edit to make them default.
Please let me know
thanks
For situations like this you'd probably use a makefile if it's project specific (or other similar automated build management like scons or cmake).
If you want it always on the terminal, you can alias your command to always specify those options, i.e.
alias g++='g++ -O3 -fopenmp'
Note that you said 'terminal' so I assume this is a type of *nix. If that is the case you can also set this into your terminal profile, like ~/.bashrc if you use bash, or ~/.zshrc if you use zsh, etc.

Resources