launch.vs.json

Hi,

Is there any good way to get a PATH variable injected into the launch.vs.json file used for debugging a target. What I want is to avoid having to manually edit any configuration json files that Visual Studio uses. I would also like to have different environment for different executable cmake targets. (The actual environment differs between machines and operating systems, so I’d like to stay away from a CMakeSettings.json checked into the repository as well.)

Possible workarounds:

  • Copy all dll:s depending upon to the location of the executable target. This is not really an option, since we have a lot of third party libraries. We also have several executable targets, so copying into each and every intermediate directory of those is not a good option. Another similar approach used by Conan, is to generate symlinks, but that requires the developer to be administrator which is quite restricting (and this is really not a valid reason for that).
  • Setup the global PATH variable prior to starting Visual Studio. Not really good either. For one, each and every target will have the same environment and two, it will be cumbersome updating versions of the third party libraries. And what about libraries built by the project itself?
  • Prepopulate launch.vs.json files? How should that be done…? It doesn’t feel like a good option anyway and puts to way much effort into a specific development environment as well. It would probably be a fragile solution as well.
  • Install all project generated runtimes into a single folder. This has been a standard way when using solution files. (I have avoided that and injected the proper environment instead.) But doing this with the “Open Folder” approach doesn’t seem feasible anyway. But I’d like to here if it’s possible from cmake only.

Generating a solution file and loading that into VS2019 is no problem in itself (using the VS_* target properties works fine), but using msbuild is so awfully slow. Using the “Open Folder” approach allows using Ninja which is much faster.

I think this should be trivial, but it seems to even having a executable target using a library target built within the project is problematic without manually editing configuration files, which should not be needed, since that’s why we use cmake in the first place. (Building and installing is not a problem, it’s developing/debugging that doesn’t work.)

BR,
Daniel

I don’t know why you wouldn’t want to do that. It is meant for setting up things like this. The CMakePresets.json file is meant to be provided by the project. It is the CMakeUserPresets.json that shouldn’t be checked in, since it provides local, user-specific details.

Edit: Sorry just realised I missed the bit before that sentence, where you mention different values for different machines and operating systems. While it might be possible to handle that with conditions in the presets file, maybe that’s too complicated for your scenario.

Yes, I might be missing something out. But I really feel like all flexibility has been taken away using cmake from inside Visual Studio.

Having not been using CMakePresets.json, I get the impression that the primary idea is to eliminate the need to pass extra parameters when running the configuration in cmake (and possibly the install stage as well). For simple things that would be fine. But usually one would write cmake code to make it possible to externally customize some important things for the project, but still using sensible default value for the normal case. So the need for doing external customization is limited. The (more or less) requirement for those configuration files to exist and contain hardcoded paths and defines, changes all that.

I feel there are lots of cases where cmake is not consistent anymore:

  • LIBRARY_OUTPUT_DIRECTORY* and alas doesn’t seem to work.
  • CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT will always be false, even though it attempts to install to “C:\Program Files…”
  • My original issue; there is no way to run the debugger with an executable application dynamically loading a shared library (even built inside cmake), without hand-hacking hardcoded configuration files or changing those from the VS GUI manually.
  • … probably a lot more.

One huge benefit for using cmake is the flexibility and possibility to design data driven solutions. With hardcoded paths into configuration files, all that is lost!

(I really hope I have missed something vital, such as creating an “empty” CMakePreset.json, that will make cmake from VS work consistently with the way cmake with solution files, vscode and linux does.)

I began using this today because I liked the idea of working in one IDE at my worksatation, But I was really disappointed.
I am still hoping I can somehow get the debugging path set using all the dependency path variables. Id hate to have to copy things around just to get debug working.
But the user experience in VS is terrible compared to just opening the sln created by a Cmake project.
Not properties, No VS_DEBUGGING _…variables detected No access to the project, just the source, what about generated code?
Before I had a great integration with an old project that scp’ed and built remote on a linux vm and remote debugged.
Now it is all “improved” to useless.

Unless it is a simple demo.

In case someone still find this.

What I found that could be used for this is by using .env-files and envFile in launch.json
The .env file can be generated for each target using cmake as follows

add_custom_command(
    TARGET <<exe_target>> POST_BUILD
    COMMAND ${CMAKE_COMMAND} "-E" "echo" "PATH=${<<extra_paths>>}" ">" "$<TARGET_FILE_DIR: <<exe_target>> >/<<exe_target>>_Dev.env"
    WORKING_DIRECTORY "$<TARGET_FILE_DIR: <<exe_target>> >"
)

Then in launch.json I have "envFile": "${command:cmake.getLaunchTargetDirectory}/${command:cmake.buildTargetName}_Dev.env"

Select the build target to be your executable and it should work.

The keyword envFile is not supported in Visual Studio 2019 or 2022, it is only available in Visual Studio Code.