{"id":5912,"date":"2020-04-20T20:44:59","date_gmt":"2020-04-21T03:44:59","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5912"},"modified":"2021-07-01T08:40:53","modified_gmt":"2021-07-01T15:40:53","slug":"advanced-cmake-project-structure","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/documentation\/projects\/cmake\/","title":{"rendered":"Advanced CMake Project Structure"},"content":{"rendered":"<p>This page describes the Advanced CMake Projects and outlines their differences from the regular VC++-based projects.<\/p>\n<h2>Contents<\/h2>\n<p><a href=\"#overview\">Overview<\/a><br \/>\n<a href=\"#structure\">Structure<\/a><br \/>\n<a href=\"#settings\">Settings<\/a><br \/>\n<a href=\"#targets\">Managing Targets<\/a><br \/>\n<a href=\"#tools\">Underlying Build Tools<\/a><br \/>\n<a href=\"#debugging\">Debugging CMake Scripts<\/a><br \/>\n<a href=\"#troubleshooting\">Troubleshooting Build Problems<\/a><br \/>\n<a href=\"#solexp\">Customizing Solution Explorer View<\/a><br \/>\n<a href=\"#vfolders\">Using Virtual Folders<\/a><br \/>\n<a href=\"#conditionals\">Defining Conditional Settings<\/a><\/p>\n<h2><a id=\"overview\"><\/a>Overview<\/h2>\n<p>Unlike the <a href=\"https:\/\/visualgdb.com\/documentation\/projects\/msbuild\/\">MSBuild-based<\/a> projects, Advanced CMake projects are completely independent from the regular Visual C++ Project Subsystem and are fully managed by VisualGDB. This enables a much deeper integration with the underlying build tools and also allows having multiple targets (e.g. executables or libraries) per project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/nodes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5913\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/nodes.png\" alt=\"\" width=\"514\" height=\"335\" \/><\/a><\/p>\n<h2><a id=\"structure\"><\/a>Structure<\/h2>\n<p>A typical Advanced CMake project consists of the following parts:<\/p>\n<ul>\n<li>One or more <strong>CMakeLists.txt<\/strong> files (and <strong>*.cmake<\/strong> files included from them) that actually describe the project structure (targets, files, build settings, etc.).<\/li>\n<li>The <strong>.vgdbcmake<\/strong> file that contains VisualGDB-level settings (e.g. how to transfer source files to the target, or how to debug the project).<\/li>\n<\/ul>\n<p>The project structure (targets, source files, etc) are not duplicated in the <strong>.vgdbsettings<\/strong> file. Instead, they are queried directly from CMake and rendered in Solution Explorer. Using Solution Explorer to add new files, or change any settings will directly update the necessary statements in <strong>CMakeLists.txt<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/lists.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5914\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/lists.png\" alt=\"\" width=\"768\" height=\"388\" \/><\/a><\/p>\n<h2><a id=\"settings\"><\/a>Settings<\/h2>\n<p>The Advanced CMake Projects have 4 types of settings shown below:<\/p>\n<table style=\"border-collapse: collapse; width: 100%;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 33.3333%;\">Settings<\/td>\n<td style=\"width: 33.3333%;\">What covers<\/td>\n<td style=\"width: 33.3333%;\">How to edit<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">VisualGDB Project Properties<\/td>\n<td style=\"width: 33.3333%;\">File transfer settings, most debugging settings, custom steps, IntelliSense.<\/td>\n<td style=\"width: 33.3333%;\">Select &#8220;VisualGDB Project Properties&#8221; in the project&#8217;s context menu.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">VS Project Properties for the project<\/td>\n<td style=\"width: 33.3333%;\">Sorting\/grouping of targets and other nodes in Solution Explorer.<\/td>\n<td style=\"width: 33.3333%;\">Select &#8220;Properties&#8221; in the <strong>project<\/strong>&#8216;s context menu or press Alt+Enter.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">VS Project Properties for a specific target<\/td>\n<td style=\"width: 33.3333%;\">Include directories, preprocessor macros, CFLAGS, target-specific debug and deployment settings.<\/td>\n<td style=\"width: 33.3333%;\">Select &#8220;Properties&#8221; in the <strong>target<\/strong>&#8216;s context menu or press Alt+Enter.<\/td>\n<\/tr>\n<tr>\n<td style=\"width: 33.3333%;\">VS Project Properties for a specific file<\/td>\n<td style=\"width: 33.3333%;\">Include directories, preprocessor macros, CFLAGS for a specific file. These settings override target-level settings.<\/td>\n<td style=\"width: 33.3333%;\">Select &#8220;Properties&#8221; in the <strong>file<\/strong>&#8216;s context menu or press Alt+Enter.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2><a id=\"targets\"><\/a>Managing Targets<\/h2>\n<p>You can add new targets to the project by selecting Add-&gt;New Item in the <strong>project&#8217;s<\/strong> context menu:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/new-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5915\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/new-1.png\" alt=\"\" width=\"812\" height=\"420\" \/><\/a>Selecting the same command in the <strong>target&#8217;s<\/strong> menu will add source files to the target instead.<\/p>\n<h2><a id=\"tools\"><\/a>Underlying Build Tools<\/h2>\n<p>CMake relies on external tools (such as GNU Make) to find outdated files and do the actual build. VisualGDB supports 2 build tools for the CMake projects:<\/p>\n<ul>\n<li>GNU Make<\/li>\n<li>Ninja<\/li>\n<\/ul>\n<p>You can switch between the build tools via VisualGDB Project Properties:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/ninja.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5917\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/ninja.png\" alt=\"\" width=\"1080\" height=\"759\" \/><\/a>We recommend using Ninja instead of GNU Make, if your project and target supports its. Ninja works much faster on multi-core systems and is better integrated with the &#8220;project is out-of-date&#8221; check.<\/p>\n<h2><a id=\"debugging\"><\/a>Debugging CMake Scripts<\/h2>\n<p>VisualGDB supports debugging CMake scripts by stepping into them (with breakpoints, watches and other regular debug functionality). You can start a CMake debug session by selecting &#8220;Launch CMake Debugger&#8221; in the <strong>project&#8217;s<\/strong> context menu:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/debug.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5916\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/debug.png\" alt=\"\" width=\"1145\" height=\"292\" \/><\/a><\/p>\n<h2><a id=\"troubleshooting\"><\/a>Troubleshooting Build Problems<\/h2>\n<p>If building a project with VisualGDB results in strange errors that don&#8217;t appear when building it manually, you can extract the exact command lines used by VisualGDB to configure and build the project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/export.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5921\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/export.png\" alt=\"\" width=\"1196\" height=\"307\" \/><\/a>First, reload the project via Solution Explorer. Then check the VisualGDB Build window. If it shows both configuration and build logs, make sure you select <strong>Configuration<\/strong>. Finally, locate the build command line <span style=\"color: #00aaaa;\">shown in cyan<\/span> and dump it into a batch file. Repeat last step for the build command line to dump it to another batch file.<\/p>\n<p>Running the configuration and build <strong>.bat<\/strong> files manually will result in the same behavior as you observe with VisualGDB. If it is still different from the manual build, try modifying the batch files to 100% match the original build command.<\/p>\n<p>If you discover that the project requires some environment variables or CMake Definitions that were not specified when importing it into VisualGDB, you can add them via <strong>VisualGDB Project Properties -&gt; CMake Project Settings<\/strong> as shown below:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/vars.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5922\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/vars.png\" alt=\"\" width=\"872\" height=\"469\" \/><\/a><\/p>\n<h2><a id=\"solexp\"><\/a>Customizing Solution Explorer View<\/h2>\n<p>You can customize the way items are shown in Solution Explorer by opening VS properties for the project-level node (with CMake icon) in Solution Explorer:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/group.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7057\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/group.png\" alt=\"\" width=\"1144\" height=\"528\" \/><\/a>There you can set the following options:<\/p>\n<ul>\n<li><strong>Combine Trivial Folder Nodes. <\/strong>If grouping by paths is enabled, VisualGDB will combine multiple folder nodes where possible. E.g. if the &#8220;<strong>level2<\/strong>&#8221; folder only contains a &#8220;<strong>level3<\/strong>&#8221; subfolder and no files inside &#8220;level2&#8221;, both nodes will be merged into &#8220;<strong>level2\/level3<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/levels.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7058\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/levels.png\" alt=\"\" width=\"508\" height=\"242\" \/><\/a><\/li>\n<li><strong>Follow CMake Source Groups.<\/strong> If enabled, VisualGDB will rely on CMake-reported source groups instead of built-in groups like &#8220;<strong>Source Files<\/strong>&#8221; or &#8220;<strong>Header Files<\/strong>&#8220;. CMake source groups can be defined via the <a href=\"https:\/\/cmake.org\/cmake\/help\/latest\/command\/source_group.html\">source_group()<\/a> statement.<\/li>\n<li><strong>Group Sources by Paths. <\/strong>If enabled, VisualGDB will automatically group file nodes in Solution Explorer by their paths relative to the main source directory of each target. If disabled, all files will appear together as if they were located in the same directory:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/paths.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7059\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/paths.png\" alt=\"\" width=\"628\" height=\"222\" \/><\/a><\/li>\n<li><strong>Group Sources by Types. <\/strong>If enabled, VisualGDB will show files of different types (e.g. <strong>Source Files<\/strong> vs. <strong>Header Files<\/strong>) separately:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/types.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7060\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/types.png\" alt=\"\" width=\"558\" height=\"380\" \/><\/a>Note that this setting does not affect built-in nodes like <strong>Embedded Resources<\/strong> or <strong>Linker Scripts<\/strong>.<\/li>\n<li><strong>Group Targets by Paths. <\/strong>If enabled, VisualGDB will automatically group targets (executables and libraries) based on the directory path where they are defined, relatively to the top-level <strong>CMakeLists.txt<\/strong> file. If disabled, VisualGDB will show all targets as if they were defined in the same directory:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/targets.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7061\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/targets.png\" alt=\"\" width=\"585\" height=\"274\" \/><\/a><\/li>\n<li><strong>Sort Sources\/Targets <\/strong><strong>by Name.<\/strong> If enabled, VisualGDB will sort all source files\/targets in Solution Explorer alphabetically. If disabled, it will show them in the order reported by CMake.<\/li>\n<\/ul>\n<h2><a id=\"vfolders\"><\/a>Using Virtual Folders<\/h2>\n<p>You can create virtual target\/source folders in Solution Explorer using context menu commands in the <strong>Add<\/strong> menu:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/newfolder-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7063\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/newfolder-1.png\" alt=\"\" width=\"1006\" height=\"681\" \/><\/a>After the folder is created, you can drag targets or sources into it, and VisualGDB will remember it next time you open the project. The mappings between the target\/source paths and virtual folders are stored in the <strong>.vgdbcmake<\/strong> files.<\/p>\n<h2><a id=\"conditionals\"><\/a>Defining Conditional Settings<\/h2>\n<p>You can change various target settings (e.g. add preprocessor macros) via VS Properties window for the target. However, it will affect all configurations and platforms:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/macro-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7073\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/macro-1.png\" alt=\"\" width=\"1004\" height=\"502\" \/><\/a>Note that each time you change these settings, VisualGDB will create or update a statement in one of the <strong>CMakeLists.txt<\/strong> files. You can make this statement conditional by wrapping it in <a href=\"https:\/\/cmake.org\/cmake\/help\/latest\/command\/if.html\">if()\/endif() commands<\/a>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/dbg.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-7074\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2020\/04\/dbg.png\" alt=\"\" width=\"868\" height=\"289\" \/><\/a>E.g. the following code will add the MYMACRO definition to debug configuration only:<\/p>\n<pre class=\"\">if (\"${CMAKE_BUILD_TYPE}\" STREQUAL \"DEBUG\")\r\ntarget_compile_definitions(LinuxProject10 PRIVATE MYMACRO)\r\nendif()<\/pre>\n<p>Note that the VS Properties windows will show conditionally defined settings together with the unconditional ones.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This page describes the Advanced CMake Projects and outlines their differences from the regular VC++-based projects. Contents Overview Structure Settings<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[201],"tags":[],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5912"}],"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=5912"}],"version-history":[{"count":8,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5912\/revisions"}],"predecessor-version":[{"id":7363,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5912\/revisions\/7363"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5912"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5912"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5912"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}