Debugging DLL, CMake, and Visual Studio 2019

Debugging DLL, CMake, and Visual Studio 2019

One of the reasons why you want to use Visual Studio is because it has nice debugging interface.  Support has been around for a while and now it is much easier to construct a cross-platform project using CMake.  But if your project is like mine where you build a DLL for Windows and an executable that make use of that DLL, you may run into this error when you start debugging the executable:

The code execution cannot proceed because blah.dll was not found. Reinstalling the program may fix this problem.

Adding Install Target

Not finding DLLs on Windows is commonly fixed by putting all the required DLLs in the same directory as the executable.  So we do that by adding:

install(TARGETS blah-dll-target

This copy the built DLL that you add_library() with into ${CMAKE_INSTALL_DIR}/dir when you click on the menu item Build > Install...; your executable and DLLs are now in the same directory.  Actual location is determined by the build configuration, which you can change by editing CMakeSettings.json.  Specifically properties buildRoot and installRoot, so you may put your debug and release binaries in separate directories.

More importantly, if you now try to select a target to debug, you will see for the same executable there are now 2 targets: app.exe and app.exe (install).  Clicking on the first one will continue to give you the same missing DLL error dialog.  But the target with (install) suffix will work just as you expect.  You can then hide the useless debug targets by selecting Show/Hide Debug Targets... from the drop-down list you'd use to start debugger.

Launch Debugger With Arguments

Sometimes your program depends on command-line arguments, and so you want to supply those automatically when debugging.  This is done by selecting from menu Debug > Debug And Launch Setting for...  This will bring up launch.vs.json that you can edit, and all you need to do is add a new property with key args and an array of strings that make up the arguments you'd normally type on command line to invoke the program.