Source synchronization in Visual Studio CMake project and WSL - c++

I have a big solution where part of projects is a classic Visual C++ projects and other part is CMake type projects.
Previously I work with Windows 7 + VS 2017 + Ubuntu on virtual machine and before start building CMake project for linux, VS start rsync for synchronization source between PC and virtual machine.
For this I was create next rule in CMakeSettings.json file:
{
"name": "Linux-Debug",
"generator": "Unix Makefiles",
"remoteMachineName": "${defaultRemoteMachineName}",
"configurationType": "Debug",
"remoteCMakeListsRoot": "/var/tmp/src/Solution_dir/",
"cmakeExecutable": "/usr/bin/cmake",
"buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
"installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
"remoteBuildRoot": "/var/tmp/Solution_dir/build/x86_64_debug_unix",
"remoteInstallRoot": "/var/tmp/Solution_dir/install/x86_64_release_unix",
"remoteCopySources": true,
"remoteCopySourcesOutputVerbosity": "Normal",
"remoteCopySourcesConcurrentCopies": "10",
"remoteCopySourcesMethod": "rsync",
"remoteCopyBuildOutput": false,
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_x64" ],
"remoteCopySourcesExclusionList": [ "Debug", "Release", ".intermediate", ".vs", "Setup" ]
}
And now I have installed Windows 10 Pro and WSL.
By default WSL have mount my local drives(like /mnt/c, /mnt/d) and in my opinion there no more sense to make a copy of source code folder.
But if I will change remoteCMakeListsRoot property to "/mnt/d/Solution_dir" VS will start rsync that will remove my .git folder and all folders from remoteCopySourcesExclusionList property.
If I will remove remoteCopySourcesExclusionList property from CMakeSettings.json rsync will remove .git folder anyway.
What is the true way to work with WSL from Visual Studio? How can I say to VS that no need to start rsync?

Related

CMakePresets.json: Using (env-)variable in Visual Studio Remote Settings vendor map

A few weeks ago, we introduced the introduce the cmakepresets.json to our cpp cross platform project, which we code with Visual Studio. The setup was really straight forward and we are able to build and debug our project without any problems.
There is just one thing which is a little bit annoying. I would like to use a variable to secifiy the directory on the remote system. It's defined over the "sourceDir"-tag of the Visual Studio Remote Settings vendor map of the CMakePresets.json. There the HOME enviroment variable is used and the special visual studio variable $ms{projectDirName} which evaluates to the name of the open folder in Visual Studio.
{
"name": "linux-default",
"displayName": "Linux Debug",
"description": "Sets Ninja generator, compilers, build and install directory, debug build type",
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_INSTALL_PREFIX": "${sourceDir}/out/install/${presetName}"
},
"vendor": {
"microsoft.com/VisualStudioSettings/CMake/1.0": {
"hostOS": [ "Linux" ]
},
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
}
I tried to define a enviroment variable with the CMakeLists.txt but I think that the variable isn't in the scope of the CMakePresets.json. Are there any other possibilities to variable define the source directory?

Visual Studio compiling to wrong path AND trying to run wrong path when used with CMake

I'm very new to CMake (and new to C++ too, although that shouldn't matter here), and I am having a problem using CMake with Visual studio.
I have created a directory, let's say it's called Project, and put in it a simple project with the following structure:
Project/
build/ <empty>
src/
main.cpp
CMakeLists.txt
CMakePresets.json
Inside these files is just the most basic, default code:
CMakeLists.txt:
cmake_minimum_required (VERSION 3.8)
project (Project)
set (CMAKE_CXX_STANDARD 20)
set (CMAKE_CXX_STANDARD_REQUIRED True)
add_executable (Project src/main.cpp)
CMakePresets.json (this code is just the default that was generated):
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x64-debug",
"displayName": "x64 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x64-release",
"displayName": "x64 Release",
"inherits": "x64-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "x86-debug",
"displayName": "x86 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x86-release",
"displayName": "x86 Release",
"inherits": "x86-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}
src/main.cpp:
#include <iostream>
int main() {
std::cout << "Hello, world!" << std::endl;
return 0;
}
Then, I have used CMake to create a Visual Studio solution:
C:\...\Project\build> cmake ..
This has worked fine without any errors, and Visual Studio can open the solution. It can also build the project correctly...
But it cannot run the executable which it has built. After successfully building the project, it has written the executable to C:\...\Project\build\Debug\Project.exe, but it tries to open C:\...\Project\build\x64\Debug\ALL_BUILD instead, and I get an error popup.
I gather that there are two things wrong here:
The executable file should be written within the C:\...\Project\build\x64\Debug folder, not just the C:\...\Project\build\Debug folder. This is how it has worked whenever I have used Visual Studio before, and this is the folder it is trying to search in.
It should be searching for an executable called Project.exe, not one called ALL_BUILD.
When I run Project.exe manually from the command line, it works fine. But I cannot seem to make Visual Studio run it correctly.
What have I done wrong here, and how can I get this to work?
Default project is set to ALL_BUILD to change the default for the VS generators use the following CMake statement:
set_property(DIRECTORY PROPERTY VS_STARTUP_PROJECT Project)
Anywhere after the add_executable command.
You see several projects in the solution explorer. These projects are build targets. The default target is ALL_BUILD, that builds all configured targets, like cmake --build . does it.
Set required target as the startup project in the solution explorer. This will point the debugger what executable to run.

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

Build flatpak package from prebuild binaries (mono and gtk-sharp2 project)

I'm trying to pack my application with flatpak and currently I'm stuck:
How do I make shure, that the runtimes are installed on the target system? I need mono, gtk-sharp2, SFML, CSFML. I learned about the basic runtime, but what about my dependencies?
How do I run the application? I tried
[sven#localhost flatpak]$ flatpak-builder --run build net.sourceforge.audiocuesheet.json /app/AudioCuesheetEditor/./AudioCuesheetEditor
bwrap: execvp /app/AudioCuesheetEditor/./AudioCuesheetEditor: No such file or directory
Some more information about the project:
net.sourceforge.audiocuesheet.json:
{
"app-id": "net.sourceforge.audiocuesheet",
"runtime": "org.gnome.Platform",
"runtime-version": "3.26",
"sdk": "org.gnome.Sdk",
"command": "/AudioCuesheetEditor/AudioCuesheetEditor",
"modules": [
{
"name": "AudioCuesheetEditor",
"buildsystem": "simple",
"build-commands": [
"cp -r AudioCuesheetEditor /app/AudioCuesheetEditor",
"chmod +x /app/AudioCuesheetEditor/AudioCuesheetEditor"
],
"sources": [
{
"type": "archive",
"path": "AudioCuesheetEditor-linux-x64-v2.4.2.zip",
"dest": "AudioCuesheetEditor"
}
]
}
]
}
As you can see, the archive has prebuild binaries, which I would like to deploy to the target maschines. I'm new to flatpak and not really shure, if I'm doing right, so maybe some help from you would be perfect.
Thanks
Sven

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

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