Wednesday, October 5, 2022

[SOLVED] Debugging CMake Visual Studio project with PATH environment set by VS_DEBUGGER_ENVIRONMENT

Issue

I've created a CMake project using visual studio 2019. It has one executable target, which links to some shared libraries (DLL). I cannot directly set the system environment variable PATH because the DLL path is determined by find_package. Therefore, set VS_DEBUGGER_ENVIRONMENT target property is my choice to debug that executable target.

However, the VS_DEBUGGER_ENVIRONMENT property is not working when I directly open the CMake project and debug that target. I've checked the .vsproj it has the correct LocalDebuggerEnvironment tag generated.

But if I run cmake -G "Visual Studio 16 2019" ../ and open the generated visual studio solution and then debug the subproject from there, everything turns out to be ok.

I think maybe the visual studio doesn't support LocalDebuggerEnvironment when opening project as a CMake project. Or perhaps I didn't debug it the right way. Is there anything else I can do to change the visual studio debug runtime PATH environment using CMake?

Any suggestion would be greatly appreciated!


Solution

This is just to share what I finally ended up with after some painful hours of digging through the web.

  1. First, a variable to store the required debugging paths is needed (example):
list(APPEND VS_DEBUGGING_PATH "%PATH%")
list(APPEND VS_DEBUGGING_PATH "${PostgreSQL_ROOT}/bin")
  1. The next step is to create a ${CMAKE_PROJECT_NAME}.vcxproj.user template file for C/C++ and in my case also a ${CMAKE_PROJECT_NAME}.vfproj.user template for FORTRAN (just for the record):
    file(
        WRITE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.vcxproj.user"
"<?xml version=\"1.0\" encoding=\"utf-8\"?>
<Project ToolsVersion=\"15.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">
    <PropertyGroup Condition=\"'\$(Configuration)'=='Release'\">
        <LocalDebuggerEnvironment>PATH=@VS_DEBUGGING_PATH@</LocalDebuggerEnvironment>
    </PropertyGroup>
    <PropertyGroup Condition=\"'\$(Configuration)'=='MinSizeRel'\">
        <LocalDebuggerEnvironment>PATH=@VS_DEBUGGING_PATH@</LocalDebuggerEnvironment>
    </PropertyGroup>
    <PropertyGroup Condition=\"'\$(Configuration)'=='RelWithDebInfo'\">
        <LocalDebuggerEnvironment>PATH=@VS_DEBUGGING_PATH@</LocalDebuggerEnvironment>
    </PropertyGroup>
    <PropertyGroup Condition=\"'\$(Configuration)'=='Debug'\">
        <LocalDebuggerEnvironment>PATH=@VS_DEBUGGING_PATH@</LocalDebuggerEnvironment>
    </PropertyGroup>
</Project>"
    )
    file(
        WRITE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.vfproj.user"
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<VisualStudioUserFile>
    <Configurations>
        <Configuration Name=\"Release|x64\" Environment=\"PATH=@VS_DEBUGGING_PATH@\"/>
        <Configuration Name=\"MinSizeRel|x64\" Environment=\"PATH=@VS_DEBUGGING_PATH@\"/>
        <Configuration Name=\"RelWithDebInfo|x64\" Environment=\"PATH=@VS_DEBUGGING_PATH@\"/>
        <Configuration Name=\"Debug|x64\" Environment=\"PATH=@VS_DEBUGGING_PATH@\"/>
    </Configurations>
</VisualStudioUserFile>"
    )

As you might see, both template files are just dumped into the root of ${CMAKE_BINARY_DIR} in this case. The base name ${CMAKE_PROJECT_NAME} is also arbitrary.

  1. Those templates can then finally be "configured" (copied) into each target folder of your setup. Either for C/C++
configure_file(
    "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.vcxproj.user"
    "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.vcxproj.user"
    @ONLY
)

or FORTRAN

configure_file(
    "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.vfproj.user"
    "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.vfproj.$ENV{USERNAME}.user"
    @ONLY
)

or even both if necessary. The variable ${target_name} needs to replaced with your target name of course. :-)

This should suffice. It is however important to close VS 2019 before (re-)configuring/(re-)generating with CMake. Otherwise VS 2019 might simply overwrite those files for each target.

I strongly hope this is helpful. Please let me know if you need more details.

Here is the result for C/C++ targets Debugging environment for C/C++ and here for FORTRAN targets Debugging environment for FORTRAN



Answered By - P. B.
Answer Checked By - Clifford M. (WPSolving Volunteer)