Compile C++ with Docker on Visual Studio Code for macOS - c++

I start a new project of a C++ application working on a BeagleBone Black (Ubuntu 14.04 (Trusty Tahr), ARM v7), but in the future I will do to port the application to Linux or Windows.
I want to set up a development environment who can be cross platform (especially for macOS)
For now, I use:
Visual Studio Code: I like this editor, and it is crossplatform.
CMake: I'm new to it, but I want to learn.
Docker with following things: I'm also new to Docker
arm-linux-gnueabihf-g++-4.8 as compiler
Libraries: like Poco
The goal is to build my application with my Docker image, transfer the binary on my BeagleBone Black and debug on target from my macOS Visual Studio Code instance.
Also, I try to install Visual Studio Code on my Docker image, but it's a little sluggish, and my keyboard doesn't work correctly.
I'm open to change my development setup, and I don't know the best practice.

Finally I use a "workaround" with Visual Studio Code tasks
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"showOutput": "always",
"runner": "terminal",
"command": "bash",
"args": [
"-c"
],
"isShellCommand": true,
"tasks": [
{
"taskName": "docker-cmake-configure",
"suppressTaskName": true,
"args": [
"docker exec -it ${config:custom.docker.defaultName} cmake --no-warn-unused-cli -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/arm-linux-gnueabihf-gcc-4.8 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/arm-linux-gnueabihf-g++-4.8 -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -H/home/developer/project -B/home/developer/project/build"
]
},
{
"taskName": "docker-cmake-build",
"suppressTaskName": true,
"isBuildCommand": true,
"args": [
"docker exec -it ${config:custom.docker.defaultName} cmake --build /home/developer/project/build --config Debug -- -j 6"
]
}
]
}
Maybe when this issue will be solved, I can use a more integrated solution: https://github.com/vector-of-bool/vscode-cmake-tools/issues/111

Related

How to Launch and Debug WSL C++ Binary from Within Visual Studio

I want to be able to launch and debug a WSL Linux binary from within Visual Studio.
EDIT:
Please note that I want to build within WSL, i.e. gcc -g test.cpp -o test and only use Visual Studio to launch and debug the binary. Ideally I would like something like: devenv.exe /debugexe <binary> for a Linux binary. This would probably equate to something like DebugAdapterHost.Launch /LaunchJson:c:\wsl\vs\launch.json inside the command-window.
Taking the approach from this article, the following is a launch.json that acheives this for .NET:
{
"version": "0.2.0",
"adapter": "c:\\tools\\plink.exe",
"adapterArgs": "-ssh -pw <password> chrisnas#DBGDQPZ1 -batch -T ~/vsdbg/vsdbg --interpreter=vscode",
"configurations": [
{
"name": ".NET Core Launch",
"type": "coreclr",
"cwd": "/mnt/d/wsl/TestConsole/TestConsole/bin/Debug/netcoreapp2.1/publish",
"program": "TestConsole.dll",
"request": "launch"
}
]
}
I have seen articles that use GDBServer, however this a lot more cumbersome than the approach outlined above.
How could this be modified to work with C++?

Compiling C/C++ in VS Code

I'm trying to compile C/C++ code in VS Code using cl (installed via visual studio 2019). I've set up the json files like the MS website suggests,
https://code.visualstudio.com/docs/cpp/config-msvc,
but I still get the error:
cl.exe : The term 'cl.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Here are my json files:
{
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.17763.0",
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.21.27702/bin/Hostx64/x64/cl.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "msvc-x64"
}
],
"version": 4
}
{
"version": "2.0.0",
"tasks": [
{
"label": "msvc build",
"type": "shell",
"command": "cl.exe",
"args": [
"/EHsc",
"/Zi",
"/Fe:",
"helloworld.exe",
"test.c"
],
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal":"always"
},
"problemMatcher": "$msCompile"
}
]
}
cl.exe : The term 'cl.exe' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Your "msvc build" task only specifies "cl.exe" for its command, with no leading path. The problem is that cl.exe isn't on your PATH, or anywhere that VS Code can see when it goes to run your build task.
One solution to this is to open VS Code using the "Developer Command Prompt" for whatever Visual Studio version you have. This version of the command prompt defines the location of the Visual Studio build tools so that any program or command that is run from that cmd prompt will be able to find the programs like "cl.exe".
There is another solution that I prefer to use, which is to write a batch script for your build task.
Put this script in the root of your VSCode workspace and call it build.bat:
:: set the path to your visual studio vcvars script, it is different for every version of Visual Studio.
set VS2017TOOLS="C:\Program Files(x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
:: make sure we found them
if not exist %VS2017TOOLS% (
echo VS 2017 Build Tools are missing!
exit
)
:: call that script, which essentially sets up the VS Developer Command Prompt
call %VS2017TOOLS%
:: run the compiler with your arguments
cl.exe /EHsc /Zi /Fe: helloworld.exe test.c
exit
Then your task has to be changed to run the batch script:
{
"label": "msvc build",
"type": "shell",
"command": "${workspaceFolder}/build.bat",
"group": {
"kind": "build",
"isDefault": true
},
"presentation": {
"reveal":"always"
},
"problemMatcher": "$msCompile"
}
The advantage to using the batch script this way is that you do not need to run VS Code from the Developer Command Prompt, and the $msCompile problem matcher will still be able to display errors and warnings inside VS Code.
Another note is that the batch script in this answer is specific to just your project. You can continue to update that script to build your project as it gets larger, or you could take advantage of a tool like CMake to handle the generation of the actual build scripts from a configuration file.
Then your build.bat may look more like this:
:: set the path to your visual studio vcvars script, it is different for every version of Visual Studio.
set VS2017TOOLS="C:\Program Files(x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"
:: make sure we found them
if not exist %VS2017TOOLS% (
echo VS 2017 Build Tools are missing!
exit
)
:: call that script, which essentially sets up the VS Developer Command Prompt
call %VS2017TOOLS%
:: Set some variables for the source directory and the build directory
set SrcDir=%CD%
set BuildDir=%CD%\build
:: Make the build directory if it doesn't exist
if not exist "%BuildDir%" mkdir "%BuildDir%"
:: Make sure you configure with CMake from the build directory
cd "%BuildDir%"
:: Call CMake to configure the build (generates the build scripts)
cmake %SrcDir%^
-D CMAKE_C_COMPILER=cl.exe^
-D CMAKE_CXX_COMPILER=cl.exe^
:: Call CMake again to build the project
cmake --build %BuildDir%
exit
I have struggled in the same problem as following the instructions in Configure VS Code for Microsoft C++. Thankfully I found this question and #Romen's great answer.
However, here are some itchy points in his solution:
He hard-coded the executable name and the file name so that you have to change it every time you make a new project.
He put the .bat in the folder of the compiled file but not the .vscode folder so that we couldn't copy one folder directly while making new projects.
For this two flecks, I modified his codes a little bit so that it's more convenient to make new projects debugging with Microsoft C++.
In the build.bat file, change the command
cl.exe /EHsc /Zi /Fe: helloworld.exe helloworld.cpp
to
cl.exe /EHsc /Zi /Fe: %1.exe %1.cpp
Move the build.bat to .vscode folder and change "command": "build.bat" to "command": ".\\.vscode\\build.bat ${fileBasenameNoExtension}".
This is trivial, but I hope it could help some newbies like me and inspire better solutions for more complicated cases :)
For anyone comming here thinking the best solution would be to set the path environment variables, so cl.exe could be run in any command prompt, or power shell terminal, this is not recommended, as per documentation:
The MSVC command-line tools use the PATH, TMP, INCLUDE, LIB, and
LIBPATH environment variables, and also use other environment
variables specific to your installed tools, platforms, and SDKs. Even
a simple Visual Studio installation may set twenty or more environment
variables. Because the values of these environment variables are
specific to your installation and your choice of build configuration,
and can be changed by product updates or upgrades, we strongly
recommend that you use a developer command prompt shortcut or one of
the customized command files to set them, instead of setting them in
the Windows environment yourself.
https://learn.microsoft.com/en-us/cpp/build/setting-the-path-and-environment-variables-for-command-line-builds?view=vs-2019
What worked for me:
Following this guide, I made this change in task.json:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "cl.exe build active file",
"command": "build.bat", //calling build.bat instead
"args": [
"/Zi",
"/EHsc",
"/Fe:",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"${file}"
],
"problemMatcher": [
"$msCompile"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Then my build.bat (sDevCmd.bat is called when the developer terminal is opened):
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat"
echo Building...
cl.exe %*
Then Ctrl + Shift + B.
Default terminal of VSCode does not have cl.exe PATH, you need to use Developer Command Prompt :
Open Developer Command Prompt
https://code.visualstudio.com/docs/cpp/config-msvc:
To open the Developer Command Prompt for VS, start typing 'developer' in the Windows Start menu, and you should see it appear in the list of suggestions. The exact name depends on which version of Visual Studio or the Visual Studio Build Tools you have installed. Click on the item to open the prompt.
Go to project parent folder
Lets say it is D:\workspace and project name is myproject
Ctrl+Shift+B to build

Can't compile code "launch: program <program_path> does not exist "

I have simple console application in C++ that I succeed to compile with Visual Studio.
I wanted to try Visual Studio Code so I copied the directory to the computer with Visual Studio Code installed.
I installed the C++ extension:
I put break point at the beginning and press F5 and I received an error:
launch: program 'enter program name, for example
c:\Users\student1\Desktop\ConsoleApp\a.exe' does not exist.
Of course the the program does not exist, I am compiling it in order for the code to become the program.
I followed the instruction and I went to the launch.json file:
I changed the "program" value to: "${workspaceRoot}/a.exe" instead of "enter program name, for example ${workspaceRoot}/a.exe".
But the same problem still exist.
Any idea ?
Spent 2 hours on this.
Ideally, VS Code shouldn't make so difficult for beginners
VS Code can give prompts for each installation, etc. automatically, in a step by step manner, like Idea editors, so that it wont be so long procedure for beginners.
Sequence of steps to do (most of the things are one time):
one time:
install a C/C++ complier, add to PATH environment variable
install C/C++ plugin for visual studio code
tell visual studio code where the compiler is and what is the short cut to build and run
these are files under ".vscode" (see below)
every project:
crate a project
build project
run project
Detailed:
One time:
Note: Point 'A' below can be skipped if you already have a compiler.
A. Install a compiler (if you don't have one already)
Example below, installs MinGW c++ compiler on Windows:
Download from here: https://sourceforge.net/p/mingw-w64/mailman/message/36103143/
1. For windows, I downloaded https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-v5.0.3.zip
2. unzip mingw-w64-v5.0.3.zip
3. rename unzipped folder to MinGW, Move it to C:\MinGW\
4. verify that you have "C:\MinGW\bin\gcc.exe" director/file, otherwise make necessary change to folder
B. Add your compiler to PATH environment variable
1. Add "C:\MinGW\bin" to PATH > user environment variable
2. verify gcc command works from cmd
restart your cmd
run below command in 'cmd'
where gcc
The output should be: C:\MinGW\bin\gcc.exe
C. Restart your visual studio code
1. install C/C++ plugin, as below:
From Menu
View > Extension
Search & Install below extension
C/C++
Every project:
Note: You can copy paste the .vscode folder every time
A. Create a below "myproj" folder & files, like below in below structure:
C:\myproj\myfile.cpp
C:\myproj\.vscode\
C:\myproj\.vscode\c_cpp_properties.json
C:\myproj\.vscode\launch.json
C:\myproj\.vscode\settings.json
C:\myproj\.vscode\tasks.json
B. Download & overwrite the above ((5 files)), from below link
https://github.com/manoharreddyporeddy/my-programming-language-notes/tree/master/vscode-c%2B%2B
C. Restart your visual studio/vs code
D. Open project in vs code & run project:
Drag and drop "myproj" folder into visual studio code
BUILD PROJECT: press "Ctrl + Shift + B" to build your myfile.exe
RUN PROJECT: press "Ctrl + F5" to run your myfile.exe
Thats all, hope that helped.
More info: https://code.visualstudio.com/docs/languages/cpp
Optional
To format C++ better
C++ formatting
1. Install Clang:
Download from: http://releases.llvm.org/download.html#5.0.2
I have downloaded for windows
"Pre-Built Binaries:" > Clang for Windows (64-bit) (LLVM-6.0.0-win64.exe)
2. Select Add to PATH while installing.
3. Install vs code plugin "Clang-Format" by xaver, this wraps above exe.
4. Restart visual studio code.
Note:
Issue: As of June 2018, Clang does not format the newer C++17 syntax correctly.
Solution: If so, move that code to another file/ comment & restart the vs code.
That's all. Now press Alt+Shift+F to format (similar key combination in other OS)
The error ".exe file does not exist" in vscode can occur because of the following reasons:
If the file name contains white spaces
If there is re-declaration of variables or other kind of compilation errors
This problem is mainly due file name , as per below table the name of the binary will be audioMatrixBin in windows folder not audioMatrixBin.exe, but we have to mention filename.exe here.
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "audioMatrixBin.exe",
"args": ["AudioMxrMgr4Subaru.conf"],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true
}
]
}
Go to launch.json(we've encounter problem with .json file that's why we're here)
Change 'cwd' & 'miDebuggerPath' where your 'gdb' is(mine is default).
"cwd": "C:\\MinGw\\bin",
"miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
(you can copy-paste if yours is default too).
Now run with 'gcc.exe-Build and debug active file'
(run your file with this option, this should run)
Make sure your "program" and "cwd" properties are actually correct. Check the path it tells you and compare with the path you want them to be.
BUILD your PROJECT .exe file : press "Ctrl + Shift + B" to build your example.exe
It seems that launch.json file needs to have the correct configs.
please check the configurations as per the below link, if you are using VS build tools
https://code.visualstudio.com/docs/cpp/config-msvc
or delete the launch.json file, gotoRun > Add Configuration... and then choose C++ (Windows), Choose cl.exe build and debug active file. Check the new name in launch.json and try again.
This video explain it very well how to setup vscode for c, I did it on Ubuntu.
https://www.youtube.com/watch?v=9pjBseGfEPU
Then I use this reference to setup c++,
https://code.visualstudio.com/docs/cpp/config-linux
I just had to replace "command": "/usr/bin/gcc" with
"command": "/usr/bin/g++",
from the example on the video.
and you can update the label on both tasks and launch if you want it.
this is how my c++ setup ended up.
tasks.json for c++
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
// "command": for classic c, "command": "/usr/bin/gcc",
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}/bin/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"isDefault": true,
"kind": "build"
}
}
]
}
launch.json for c++{
// 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": "${fileDirname}/bin/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++ build active file"
}
]
}
In your launch.json file check the "miDebuggerPath" and see if the same path is defined in your environment variables.
To resolve this proble one has to make sure three things are in order:
You have successfully downloaded and install the gcc (compiler) and gdb (debugger). To check this you should be able to type
gcc --version
and
gdb --version
and get the correct results
Once done with this step compile the myfile.c using this command.Make sure that your file has a main() function ,otherwise the produced myfile.exe will not be recognised by the debugger.
gcc -c myfile.c -o myfile.exe
Add a launch configuration using gcc.
In the launch configuration
manually add the path to the executable "program": "${workspaceFolder}/myfile.exe"
In the launch configuration
manually add the path to the debugger "miDebuggerPath": "C:/MinGW/bin/gdb.exe"
Nuke everything and use the build active file tasks:
Delete all files within the .vscode folder.
Select Terminal > Configure Tasks
Select appropriate system task (i.e. for Mac, C/C++: clang build active file).
Open .vscode/tasks.json
Configure C++ language standard by specifying the std flag (i.e. "-std=c++17") at the top of the args array.
the problem for me was an error during the run time that the compiler didn't notice before. then the .exe file didn't built, therefore the .exe file does not exist so you have to check if your script is fine even if no error is found by the debugger.
{In launch.json file where name : (Gdb) launch ,
step 1: enter the complete address of program for eg, c:/users/.....xyz.exe.
step 2: In Mi-debugger path complete address of bin in mingw folder which contains the Gdb debugger so the address would be c:/mingw/....gdb.exe repeat step 2 for the first configuration in launch.JSON
step 3 IN CWD , copy the same path but only till /bin
That should work }

Setup VSCode for C++ on Windows (MSVC)

I'm a little befuddled that I'm not able to setup Visual Studio Code to do C++ development on Windows using MSVC. All over the web people say how pleased they are with how easy everything is to set up and use, but I don't find any straightforward guides; most of them just skip the setup part and show how nice everything works including code completion/intellisense and debugging support.
I have installed Visual Studio 2015 Community Edition (including the debugging tools etc.), Visual Studio Code and the C++ extension by Microsoft.
What do I need to do next?
Edit:
Intellisense works out of the box these days, that's great. But my auto-generated tasks.json doesn't seem to do the trick for building, here's what it looks like:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"taskName": "build",
"type": "process",
"command": "msbuild",
"args": [
// Ask msbuild to generate full paths for file names.
"/property:GenerateFullPaths=true",
"/t:build"
],
"group": "build",
"presentation": {
// Reveal the output only if unrecognized errors occur.
"reveal": "always"
},
// Use the standard MS compiler pattern to detect errors, warnings and infos
"problemMatcher": "$msCompile"
}
]
}
When I run this task it seems to run infinitely and only outputs to the following:
Executing task: msbuild /property:GenerateFullPaths=true /t:build <
Any ideas?
For MSVC 2017 version:
add these to your include path:
"D:/Program Files/Microsoft/MSVC2017/VC/Tools/MSVC/14.12.25827/include/*",
"C:/Program Files (x86)/Windows Kits/10/Include/10.0.10240.0/ucrt",
"C:/Program Files (x86)/Windows Kits/10/Lib/10.0.10240.0/ucrt/x64",
You may change the drive name and folder name accordingly.
2.change your shell setting in settings.json:
"terminal.integrated.shell.windows": "C:\WINDOWS\System32\cmd.exe",
"terminal.integrated.shellArgs.windows": ["/k", "D:/Program Files/Microsoft/MSVC2017/Common7/Tools/VsDevCmd.bat"]
which will enable the cl command in your integrated terminal.
3.Press ctrl+` to enable integrated terminal, type cl /EHsc your_cpp_program.cpp to compile.
I think easiest way to get it - open visual studio 2017 command prompt console and run Visual Studio Code IDE from there so it will pick all necessary compiler environment variables

How to define the task.json to compile C/C++ code in vscode by using the cl.exe on windows?

I have installed the Microsoft Visual C++ Build Tools 2015 on my 64bit win10 , and can use the cl.exe to compile and link the C/C++ program in a plain Command Prompt window by the following steps (some instructions from Setting the Path and Environment Variables for Command-Line Builds):
1. cd "\Program Files (x86)\Microsoft Visual Studio 14.0\VC"
2. vcvarsall amd64
3. cl helloworld.c
The helloworld.c is just a simple C source file to print "Hello world!". I aslo try to congfigure the task.json to directly compile and link C/C++ programs in the vs code. Here is my task.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "vcvarsall amd64 && cl",
"isShellCommand": true,
"args": ["${file}"],
"showOutput": "always"
}
And the path of vsvarsall and cl have been added in the PATH. But it still doesn't work (the output is put at the end of the post). So my question is that: how can I to define the task.json which can first run the vcvarsall amd64 to set system variables and then execute the cl command to compile and link programs.
As Rudolfs Bundulis said, make a batch file and just call it, inside it do everything you need to do.
tasks.json:
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "build.bat",
"isShellCommand": true,
"args": [],
"showOutput": "always"
}
And in your project have the build.bat goodness.
build.bat:
#echo off
call "E:\programs\VS2015\VC\vcvarsall.bat" x64 <----- update your path to vcvarsall.bat
..
cl %YourCompilerFlags% main.cpp %YourLinkerFlags%
..
I would mention that you'd like to have another visual studio code bootstraper batch that would set the vcvars environment and then starts up the editor so you don't set the vcvars for every build. Like so:
#echo off
call "E:\programs\VS2015\VC\vcvarsall.bat" x64 <----- update your path to vcvarsall.bat
code
This way you can omit setting the vcvarsall.bat every time you compile the code. Minimal rebuild flag will also help you a lot so you only compile changed files.