{"id":4228,"date":"2018-10-10T12:00:10","date_gmt":"2018-10-10T19:00:10","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=4228"},"modified":"2018-10-10T12:06:25","modified_gmt":"2018-10-10T19:06:25","slug":"debugging-cmake-scripts-with-visual-studio","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/cmake\/debugger\/","title":{"rendered":"Debugging CMake Scripts with Visual Studio"},"content":{"rendered":"<p>This tutorial shows how to use VisualGDB to\u00a0step through the CMake scripts while\u00a0analyzing CMake configuration problems. We will create a basic\u00a0CMake project using a Linux cross-toolchain,\u00a0add macros to read the version number from a text file, and will then step through the CMake statements in the debugger\u00a0and show how to modify the version read from the file on-the-fly.<\/p>\n<p>Before you begin, install VisualGDB 5.4 Preview 7 or later.<\/p>\n<ol>\n<li>Start Visual Studio and open the VisualGDB Linux Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-prj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4229\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-prj.png\" alt=\"01-prj\" width=\"893\" height=\"501\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-prj.png 893w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/01-prj-300x168.png 300w\" sizes=\"(max-width: 893px) 100vw, 893px\" \/><\/a><\/li>\n<li>Select &#8220;Create a new\u00a0project&#8221; -&gt; &#8220;Application&#8221; -&gt; &#8220;CMake&#8221;\u00a0and ensure that the &#8220;Use the\u00a0advanced CMake Project Subsystem&#8221; checkbox is set:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-newprj.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4230\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-newprj.png\" alt=\"02-newprj\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-newprj.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/02-newprj-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>On the next page select\u00a0the machine you want to target. You can\u00a0either build the code on the Windows machine using\u00a0a cross-toolchain, or build it\u00a0directly on the Linux machine, depending on your configuration. In this tutorial we will\u00a0build the code locally using the Raspberry Pi cross-toolchain:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-buildlocal.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4231\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-buildlocal.png\" alt=\"03-buildlocal\" width=\"886\" height=\"693\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-buildlocal.png 886w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/03-buildlocal-300x235.png 300w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/a><\/li>\n<li>Press &#8220;Finish&#8221; to create the project. VisualGDB will\u00a0generate a simple CMake project with\u00a0one target:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-created.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4232\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-created.png\" alt=\"04-created\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-created.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-created-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/04-created-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Open the\u00a0Visual Studio project properties for the target and\u00a0add &#8220;PROJECT_VERSION=1&#8221; to the preprocessor definitions:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-ver.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4233\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-ver.png\" alt=\"05-ver\" width=\"838\" height=\"599\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-ver.png 838w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/05-ver-300x214.png 300w\" sizes=\"(max-width: 838px) 100vw, 838px\" \/><\/a><\/li>\n<li>VisualGDB will automatically insert the\u00a0corresponding statement into the CMakeLists.txt file:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-updated.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4234\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-updated.png\" alt=\"06-updated\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-updated.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-updated-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/06-updated-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Now we will replace the hardcoded version with\u00a0a\u00a0CMake function that will read the version from a text file. First of all, create a file called <strong>version.txt<\/strong> in your project directory and ensure it contains a single character: &#8220;1&#8221;<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-ver.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4235\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-ver.png\" alt=\"07-ver\" width=\"786\" height=\"593\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-ver.png 786w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/07-ver-300x226.png 300w\" sizes=\"(max-width: 786px) 100vw, 786px\" \/><\/a><\/li>\n<li>Then add the following code to your CMakeLists.txt file:\n<pre class=\"\">function(set_version_from_file target)\r\n file(READ \"version.txt\" VERSION_FROM_FILE)\r\n\r\n if (${VERSION_FROM_FILE} LESS \"2\")\r\n  message(FATAL_ERROR \"Invalid version\")\r\n endif()\r\n\r\n target_compile_definitions(${target} PRIVATE PROJECT_VERSION=${VERSION_FROM_FILE})\r\nendfunction()\r\n\r\n&lt;...&gt;\r\nset_version_from_file(&lt;your target name&gt;)<\/pre>\n<\/li>\n<li>Save the CMakeLists.txt and see how CMake reports a configuration error (as the version stored in the file is less than the version checked in CMakeLists.txt):<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-readver.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4236\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-readver.png\" alt=\"08-readver\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-readver.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-readver-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/08-readver-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Now we will\u00a0use the CMake Script Debugger to step\u00a0through the CMakeLists.txt file and see what exactly CMake is doing\u00a0and also to\u00a0skip the error statement. Right-click on your project in Solution Explorer and select &#8220;Launch CMake Debugger&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4237\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-debug.png\" alt=\"09-debug\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-debug.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-debug-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/09-debug-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>VisualGDB will\u00a0stop at the first statement of the file:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/statement.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4247\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/statement.png\" alt=\"statement\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/statement.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/statement-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/statement-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>The easiest way to get to the error message would be to simply press F5 to continue debugging. Once CMake hits a fatal error, VisualGDB will automatically stop at that statement:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/stopped.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4248\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/stopped.png\" alt=\"stopped\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/stopped.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/stopped-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/stopped-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a>You can use the Call Stack and Watch windows to examine the program state, however as the message was already triggered, it is too late to change anything or skip the error line.<\/li>\n<li>Restart the CMake debugging an put a breakpoint on the line comparing VERSION_FROM_FILE. Wait for it to trigger:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/10-exception.png\"><br \/>\n<\/a> <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-ver1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4239\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-ver1.png\" alt=\"11-ver1\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-ver1.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-ver1-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/11-ver1-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Now instead of stepping\u00a0into the check, simply right-click on the &#8220;target_compile_definitions&#8221; line and select &#8220;Set Next Statement&#8221;:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-setnext.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4240\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-setnext.png\" alt=\"12-setnext\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-setnext.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-setnext-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/12-setnext-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Press F5 to continue the CMake configuration process. Once it is complete, the project will be configured with PROJECT_VERSION=1\u00a0as the error statement was successfully skipped:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-configured.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4241\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-configured.png\" alt=\"13-configured\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-configured.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-configured-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/13-configured-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Now we will show how to modify the version\u00a0after it was read from the file. Ensure the breakpoint on the VERSION_FROM_FILE\u00a0check is still set and start another debug session. Once the breakpoint triggers, hover the mouse over VERSION_FROM_FILE and change its value to 2:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-ver2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4242\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-ver2.png\" alt=\"14-ver2\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-ver2.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-ver2-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/14-ver2-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Step through the rest of the set_version_from_file() function to see that the error doesn&#8217;t trigger anymore:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-stepped.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4243\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-stepped.png\" alt=\"15-stepped\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-stepped.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-stepped-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/15-stepped-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>Now the project got configured with PROJECT_VERSION=2 as we have manually changed it during CMake configuration:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-ver2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4244\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-ver2.png\" alt=\"16-ver2\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-ver2.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-ver2-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/16-ver2-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a>Changing variable values manually and\u00a0setting next statement could be useful\u00a0to quickly\u00a0get past errors (e.g. missing tools) without\u00a0restarting the entire configuration process\u00a0each time. E.g. you\u00a0could also edit the version.txt file and then force CMake to re-run the <strong>file()<\/strong>\u00a0statement to read the updated version from the file.<\/li>\n<li>Finally we will show how to use the advanced CMake breakpoints to quickly locate the relevant parts of the\u00a0CMake scripts. Start another debug session and remove all breakpoints. Now instead of setting a breakpoint on a specific line, click &#8220;New Advanced CMake Breakpoint&#8221; -&gt; &#8220;Breakpoint on variable change&#8221; and enter &#8220;VERSION_FROM_FILE&#8221; as the variable name:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/17-bkpt.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4245\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/17-bkpt.png\" alt=\"17-bkpt\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/17-bkpt.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/17-bkpt-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/17-bkpt-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a><\/li>\n<li>The breakpoint will trigger when any statement anywhere in the CMake scripts will modify the VERSION_FROM_FILE variable in any scope:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/18-changed.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4246\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/18-changed.png\" alt=\"18-changed\" width=\"1063\" height=\"691\" srcset=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/18-changed.png 1063w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/18-changed-300x195.png 300w, https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2018\/10\/18-changed-1024x666.png 1024w\" sizes=\"(max-width: 1063px) 100vw, 1063px\" \/><\/a>Note that\u00a0when\u00a0an\u00a0advanced breakpoints triggers, CMake has already started processing a\u00a0statement, so you won&#8217;t be able to use the &#8220;Set next statement&#8221; command until you step to the next one, or stop at a regular breakpoint.<\/li>\n<\/ol>\n<p>If you are\u00a0running CMake on a remote Linux system,\u00a0ensure you build our <a href=\"http:\/\/visualgdb.com\/documentation\/cmake\/annotations\/\">open-source fork of CMake<\/a> that provides the script debugger functionality.\u00a0Our port is fully backward-compatible with the\u00a0regular CMake,\u00a0so you can keep on using the original CMake builds\u00a0on the machines where the script debugging functionality is not required.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial shows how to use VisualGDB to\u00a0step through the CMake scripts while\u00a0analyzing CMake configuration problems. We will create a<\/p>\n","protected":false},"author":1,"featured_media":4250,"comment_status":"closed","ping_status":"closed","sticky":true,"template":"","format":"standard","meta":{"footnotes":""},"categories":[172],"tags":[77,33],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4228"}],"collection":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/comments?post=4228"}],"version-history":[{"count":1,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4228\/revisions"}],"predecessor-version":[{"id":4249,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/4228\/revisions\/4249"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media\/4250"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=4228"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=4228"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=4228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}