{"id":5270,"date":"2019-11-13T15:03:11","date_gmt":"2019-11-13T23:03:11","guid":{"rendered":"https:\/\/visualgdb.com\/w\/?p=5270"},"modified":"2020-04-29T11:14:20","modified_gmt":"2020-04-29T18:14:20","slug":"using-custom-cmake-target-properties-with-visualgdb","status":"publish","type":"post","link":"https:\/\/visualgdb.com\/tutorials\/cmake\/targets\/","title":{"rendered":"Using Custom CMake Target Properties with VisualGDB"},"content":{"rendered":"<p>Large CMake-based codebases often use custom macros or functions for defining executables and libraries instead of the regular <strong>add_executable()<\/strong> and <strong>add_library()<\/strong> statements. This tutorial shows how to configure VisualGDB to automatically recognize those custom statements and automatically edit them in response to adding\/removing source files in Solution Explorer or changing properties via the Target Properties window.<\/p>\n<p>We will create a CMake-based project, add 2 CMake functions for defining custom targets using the semantics similar to the <a href=\"https:\/\/github.com\/espressif\/esp-idf\">ESP-IDF<\/a> framework and the <a href=\"https:\/\/github.com\/mysql\">MySQL codebase<\/a> and show how to configure VisualGDB to recognize those statements.<\/p>\n<p>Before you begin, install VisualGDB 5.5 or later.<\/p>\n<ol>\n<li>Start Visual Studio and locate the VisualGDB Linux Project Wizard:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/01-newprj-1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5272\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/01-newprj-1.png\" alt=\"\" width=\"1024\" height=\"710\" \/><\/a><\/li>\n<li>Specify the name and location for your project:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/02-prjname.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5273\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/02-prjname.png\" alt=\"\" width=\"1024\" height=\"710\" \/><\/a><\/li>\n<li>On the first page of the Linux Project Wizard select &#8220;Application -&gt; CMake -&gt; Use the Advanced CMake Project Subsystem&#8221;: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/03-type.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5274\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/03-type.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a><\/li>\n<li>On the next page of the wizard select your target. In this tutorial we will build the project on the Windows machine using the Raspberry Pi cross-toolchain, however the steps described here will also apply for projects built on the Linux side:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/04-raspi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5275\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/04-raspi.png\" alt=\"\" width=\"886\" height=\"693\" \/><\/a>Click &#8220;Finish&#8221; to finish generating the project. VisualGDB will create a basic CMake project with one target.<\/li>\n<li>Now we will add 4 library targets to the project and will later convert them to use the custom macros. Select &#8220;<strong>Add-&gt;New Item&#8221;<\/strong> in Solution Explorer:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/05-addnew.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5276\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/05-addnew.png\" alt=\"\" width=\"1282\" height=\"823\" \/><\/a><\/li>\n<li>Pick &#8220;<strong>Static Library<\/strong>&#8221; and click &#8220;<strong>Add<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/06-lib1.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5277\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/06-lib1.png\" alt=\"\" width=\"1282\" height=\"823\" \/><\/a><\/li>\n<li>Add 3 more libraries until the main <strong>CMakeLists.txt<\/strong> file declares 4 different libraries:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/07-4libs.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5278\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/07-4libs.png\" alt=\"\" width=\"1282\" height=\"823\" \/><\/a><\/li>\n<li>Create a new text file and save it under <strong>&lt;Project Directory&gt;\\functions.cmake<\/strong>. Then add the following content to it:\n<pre class=\"\">function(register_static_library NAME)\r\n\tadd_library(Static${NAME} ${ARGN})\r\nendfunction(register_static_library)\r\n\r\nfunction(set_static_library_cflags NAME)\r\n\ttarget_compile_options(Static${NAME} PRIVATE ${ARGN})\r\nendfunction(set_static_library_cflags)\r\n\r\nfunction(register_shared_library)\r\n\tcmake_parse_arguments(_ \"\" \"NAME\" \"SOURCES;CFLAGS\" ${ARGN})\r\n\r\n\tadd_library(Shared${__NAME} SHARED ${__SOURCES})\r\n\ttarget_compile_options(Shared${__NAME} PRIVATE ${__CFLAGS})\r\nendfunction(register_shared_library)<\/pre>\n<p>This defines 3 custom CMake functions:<\/p>\n<ul>\n<li><strong>register_static_library()<\/strong> will create a new static library with the given name and sources (prepending &#8216;Static&#8217; to the name)<\/li>\n<li><strong>set_static_library_cflags()<\/strong> will set the compilation flags for the static library<\/li>\n<li><strong>register_shared_library()<\/strong> will register a shared library and set the flags for it at the same time<\/li>\n<\/ul>\n<\/li>\n<li>Include <strong>functions.cmake<\/strong> from your main CMakeLists.txt file and replace the direct target definitions with the following lines:\n<pre class=\"\">register_static_library(Library1 Library1.cpp)\r\nregister_static_library(Library2 Library2.cpp)\r\nset_static_library_cflags(Library1 -DTESTMACRO)\r\n\r\nregister_shared_library(NAME Library3 SOURCES Library3.cpp CFLAGS -DTESTMACRO)\r\nregister_shared_library(NAME Library4 SOURCES Library4.cpp)<\/pre>\n<p><a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/08-functions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5279\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/08-functions.png\" alt=\"\" width=\"1282\" height=\"823\" \/><\/a>Note that <strong>register_static_library()<\/strong> and <strong>register_shared_library()<\/strong> use different syntax. While <strong>register_static_library()<\/strong> expects the target name followed by a list of sources, <strong>register_shared_library()<\/strong> uses CMake argument groups to separate name, source list and CFLAGS.<\/li>\n<li>Try opening any source file belonging to the project. VisualGDB will detect that the targets are defined using custom functions or macros and will advise to define a custom target schema:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/09-hint.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5280\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/09-hint.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a>You can disable this warning via <strong>Tools-&gt;Options-&gt;VisualGDB-&gt;CMake-&gt;Detect Ambiguous Target Definitions<\/strong>.<\/li>\n<li>Also editing target properties or adding sources to the targets defined with those functions will not work unless a schema is defined: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/10-ambiguous.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5281\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/10-ambiguous.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>If your project structure is more complex than this tutorial shows, you can use the &#8220;Step into Target Definition&#8221; command to launch VisualGDB&#8217;s Cmake debugger:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/11-stepinto.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5282\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/11-stepinto.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>This will allow stepping through the CMake files, viewing call stack and variable values just as if it was a regular program:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/12-stepped.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5283\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/12-stepped.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>Now we will show how to define the custom property schema that will allow VisualGDB to automatically edit the calls to the custom CMake functions. Create a subdirectory called &#8220;TargetDefinitions&#8221; inside your project directory and add the following files there:<br \/>\n<strong>custom.tgt:<\/strong><\/p>\n<pre class=\"\">CustomStaticLibrary\r\n\tmatch\t\tregister_static_library()\r\n\tpriority\t1000\r\n\tprops\t\tcustom.prop\r\n\tstatements\tcustom.stmt<\/pre>\n<p><strong>custom.stmt:<\/strong><\/p>\n<pre class=\"\">register_static_library()\r\n\tfrom: register_static_library()\r\n\tformat: register_static_library(@*)\r\n\tsubformat: %name @sources<\/pre>\n<p><strong>custom.prop:<\/strong><\/p>\n<pre class=\"\">@internal\r\n\ttarget.decl: register_static_library()\r\n\ttarget.name = target.decl.name\r\n\ttarget.sources = target.decl.sources<\/pre>\n<p>The <strong>custom.tgt<\/strong> file defines a rule that will be used for all targets that have &#8216;register_static_library()&#8217; in their backtrace (i.e. the call stack when the target was registered). It specifies a priority (in case the backtrace has multiple statements matching different targets) and links to properties and statements files.<br \/>\nThe <strong>custom.stmt<\/strong> file tells VisualGDB how to interpret various statements. In this example, it defines the <strong>register_static_library()<\/strong> statement that exposes 2 properties: <strong>name<\/strong> (1 token) and <strong>sources<\/strong> (0 or more tokens).<br \/>\nFinally, <strong>custom.prop<\/strong> file defines one property category (@internal) and 3 properties:<\/p>\n<ul>\n<li><strong>target.decl<\/strong> is defined as an instance of the <strong>register_static_library()<\/strong> statement (that internally exposes the <strong>name<\/strong> and <strong>sources<\/strong> properties per the <strong>custom.stmt<\/strong> file).<\/li>\n<li><strong>target.name<\/strong> and <strong>target.sources<\/strong> are special statement names expected by VisualGDB. They are defined as shortcuts to the <strong>name<\/strong> and <strong>sources<\/strong> subproperties of <strong>target.decl<\/strong>.<\/li>\n<\/ul>\n<\/li>\n<li>Open VisualGDB Project Properties and set the Custom Target Definitions Directory to &#8220;<strong>TargetDefinitions<\/strong>&#8220;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/13-subdir.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5285\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/13-subdir.png\" alt=\"\" width=\"893\" height=\"622\" \/><\/a><\/li>\n<li>Press OK to apply the settings. Locate the StaticLibrary1 target in Solution Explorer and verify that the <strong>Matching layout rule<\/strong> for it is <strong>CustomStaticLibrary<\/strong>:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/14-rule.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5286\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/14-rule.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>Try adding a new source to the static library:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/15-addsrc.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5287\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/15-addsrc.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>VisualGDB will automatically update the <strong>register_static_library()<\/strong> statement:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/16-added.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5288\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/16-added.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a>This happens because VisualGDB will internally locate the &#8220;target.sources&#8221; property, confirm that it&#8217;s defined in a unique way (i.e. no other target shares the same definition) and will then edit it according to the rules we specified.<\/li>\n<li>You can now also rename the target (VisualGDB will automatically read and write the &#8220;target.name&#8221; property we defined):<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/17-rename.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5289\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/17-rename.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>Now we will show how to map the<strong> set_static_library_cflags()<\/strong> statement to the Visual Studio properties GUI. Add the following text to the schema files:<br \/>\n<strong>custom.tgt:<\/strong><\/p>\n<pre class=\"\">CustomStaticLibrary\r\n\t&lt;...&gt;\r\n\tspelling_regex  Static(.*)\r\n<\/pre>\n<p><strong>custom.stmt:<\/strong><\/p>\n<pre class=\"\">set_static_library_cflags()\r\n\tfrom: register_static_library().file\r\n\tformat: set_static_library_cflags(%target @*)\r\n\tinsert: after register_static_library()<\/pre>\n<p><strong>custom.prop:<\/strong><\/p>\n<pre class=\"\">C\/C++\r\n\tGeneral\r\n\t\tCFLAGS: set_static_library_cflags()\r\n\t\t\thelp = Compiler Flags for this target<\/pre>\n<p>This defines a new statement called <strong>set_static_library_cflags()<\/strong>. VisualGDB will search the CMakeLists.txt where the <strong>register_static_library()<\/strong> was called for the target for all <strong>set_static_library_cflags()<\/strong> statements where the first argument matches the spelling name of the target (that is defined by stripping the &#8220;Static&#8221; prefix via the <strong>spelling_regex<\/strong> property). If none are found, VisualGDB will insert one right after the <strong>register_static_library()<\/strong> call.<\/li>\n<li>Reopen the project and open Visual Studio properties for the target. The custom CFLAGS property will now appear there:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/18-props.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5291\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/18-props.png\" alt=\"\" width=\"838\" height=\"581\" \/><\/a><\/li>\n<li>Select multiple targets at once and set CFLAGS to <strong>-DANOTHERMACRO<\/strong>: <a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/19-multi.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5292\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/19-multi.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>See how VisualGDB edited the first <strong>set_static_library_cflags()<\/strong> statement and inserted another one for <strong>Library2<\/strong>:<br \/>\n<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/20-edited.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5293\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/20-edited.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>As the CFLAGS property typically contains many different compiler options, you can define flag filters to display them in a reasonable way. Replace the <strong>C\/C++<\/strong> group contents in custom.prop with the following code:\n<pre class=\"\">C\/C++\r\n\tGeneral\r\n\t\tCFLAGS[self.cflags]: set_static_library_cflags()\r\n\t\t\thelp = Compiler Flags for this target\r\n\t\tPreprocessor Definitions[cc.defines] -&gt; self.cflags\r\n\t\t\thelp \t = Defines a preprocessing symbols for the source files\r\n\t\t\ttype \t = list\r\n\t\t\tprefix   = -D\r\n\t\t\tpretoken = -D<\/pre>\n<p>This will move all -D&lt;MACRO&gt; and -D&lt;space&gt;&lt;MACRO&gt; flags into a separate property called &#8220;Preprocessor Definitions&#8221;:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/21-structured.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5295\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/21-structured.png\" alt=\"\" width=\"838\" height=\"581\" \/><\/a><\/li>\n<li>VisualGDB comes with predefined filters for common flags used by popular compilers, so you can replace the entire <strong>custom.prop<\/strong> file with the following code instead:\n<pre class=\"\">@internal\r\n\ttarget.decl: register_static_library()\r\n\ttarget.name = target.decl.name\r\n\ttarget.sources = target.decl.sources\r\n\tself.cflags: set_static_library_cflags()\r\n\r\n%include $(VISUALGDB_DIR)\\rules\\PropertyEngine\\common\\cflags.prop<\/pre>\n<p>This will result in a regular-looking set of properties for the target:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/22-struct2.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5296\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/22-struct2.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>Editing them will transparently modify the <strong>set_static_library_cflags()<\/strong> statements so you won&#8217;t need to interpret the flags manually:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/23-values.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5297\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/23-values.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a><\/li>\n<li>The <strong>register_shared_library()<\/strong> statement combines sources and CFLAGS in the same statement, so the schema for it will look slightly different. Create\/update the schema files as shown below:<br \/>\n<strong>custom.tgt:<\/strong><\/p>\n<pre class=\"\">CustomSharedLibrary\r\n\tmatch\t\t\tregister_shared_library()\r\n\tpriority\t\t1000\r\n\tprops\t\t\tshared.prop\r\n\tstatements\t\tcustom.stmt\r\n<\/pre>\n<p><strong>custom.stmt:<\/strong><\/p>\n<pre class=\"\">CustomSharedLibrary\r\n\tmatch\t\t\tregister_shared_library()\r\n\tpriority\t\t1000\r\n\tprops\t\t\tshared.prop\r\n\tstatements\t\tcustom.stmt<\/pre>\n<p><strong>shared.prop <\/strong>(note that it&#8217;s a separate file from <strong>custom.prop<\/strong>)<strong>:<\/strong><\/p>\n<pre class=\"\">@internal\r\n\ttarget.decl: register_shared_library()\r\n\ttarget.name = target.decl.NAME\r\n\ttarget.sources = target.decl.SOURCES\r\n\tself.cflags = target.decl.CFLAGS\r\n\r\n%include $(VISUALGDB_DIR)\\rules\\PropertyEngine\\common\\cflags.prop<\/pre>\n<\/li>\n<li>Now you can use the same convenient GUI to edit the properties of shared libraries, or add files to them and VisualGDB will know how to edit the register_shared_library() statements:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/24-shared.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5298\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/09\/24-shared.png\" alt=\"\" width=\"1297\" height=\"763\" \/><\/a>You can find detailed reference for the CMake statement definition syntax in the <strong>&lt;VisualGDB Directory&gt;\\Rules\\PropertyEngine\\CMake\\cmake.stmt<\/strong> file as well as the schema used by VisualGDB to edit regular CMake targets and files.<\/li>\n<li>Finally we will show how to add custom target templates for your project. Go to the custom target definitions directory and create a <strong>templates\/target\/MyCustomTarget <\/strong>subdirectory with the following contents:\n<ul>\n<li><strong>template.xml<\/strong>:\n<pre class=\"\">&lt;?xml version=\"1.0\"?&gt;\r\n&lt;CMakeTargetTemplate xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xmlns:xsd=\"http:\/\/www.w3.org\/2001\/XMLSchema\"&gt;\r\n\t&lt;Name&gt;Sample Custom Target Template&lt;\/Name&gt;\r\n\t&lt;FileNameBase&gt;MyCustomTarget&lt;\/FileNameBase&gt;\r\n\t&lt;CMakeStatementTemplate&gt;register_static_library($$TARGETNAME$$ $$TARGETSOURCES$$)&lt;\/CMakeStatementTemplate&gt;\r\n\t&lt;SourceFileTemplates&gt;\r\n\t\t&lt;string&gt;$$TARGETNAME$$.cpp&lt;\/string&gt;\r\n\t&lt;\/SourceFileTemplates&gt;\r\n\t&lt;ExtraFileTemplates&gt;\r\n\t\t&lt;string&gt;$$TARGETNAME$$.h&lt;\/string&gt;\r\n\t&lt;\/ExtraFileTemplates&gt;\r\n\t&lt;Icon&gt;wizard.png&lt;\/Icon&gt;\r\n&lt;\/CMakeTargetTemplate&gt;<\/pre>\n<\/li>\n<li><strong>$$TARGETNAME$$.cpp<\/strong>:\n<pre class=\"\">#include &lt;stdio.h&gt;\r\n\r\nvoid Sample$$TARGETNAME$$Function()\r\n{\r\n\tprintf(\"Hello from $$TARGETNAME$$!\\n\");\r\n}<\/pre>\n<\/li>\n<li><strong>$$TARGETNAME$$.h<\/strong>:\n<pre class=\"\">#pragma once\r\n\r\nvoid Sample$$TARGETNAME$$Function();<\/pre>\n<\/li>\n<li><strong>wizard.png<\/strong>:<br \/>\n(any 32&#215;32 icon, e.g. <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/blob\/master\/visualgdb\/CMake\/CustomCMakeTargetDemo\/TargetDefinitions\/templates\/target\/MyCustomTarget\/wizard.png\">this one<\/a>)<\/li>\n<\/ul>\n<\/li>\n<li>Right-click on the project node in Solution Explorer and select Add-&gt;New Item. VisualGDB will show &#8220;<strong>Sample Custom Target Template<\/strong>&#8221; after the regular target templates:<a href=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/custom.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-5953\" src=\"https:\/\/visualgdb.com\/w\/wp-content\/uploads\/2019\/11\/custom.png\" alt=\"\" width=\"812\" height=\"420\" \/><\/a>Selecting the custom template will insert the contents of the <strong>CMakeStatemenTtemplate<\/strong> into <strong>CMakeLists.txt <\/strong>in the selected folder (if a new folder was selected, it will be automatically included from your main CMakeLists.txt). It will also create the source and other files based on the template. The only difference between <strong>SourceFileTemplates<\/strong> and <strong>ExtraFileTemplates <\/strong>is that the extra files won&#8217;t be included in the <strong>$$TARGETSOURCES$$<\/strong> variable.<\/li>\n<\/ol>\n<p>The project shown in this tutorial is available on our <a href=\"https:\/\/github.com\/sysprogs\/tutorials\/tree\/master\/visualgdb\/CMake\/CustomCMakeTargetDemo\">Github repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Large CMake-based codebases often use custom macros or functions for defining executables and libraries instead of the regular add_executable() and<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[77,38],"_links":{"self":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5270"}],"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=5270"}],"version-history":[{"count":8,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5270\/revisions"}],"predecessor-version":[{"id":5954,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/posts\/5270\/revisions\/5954"}],"wp:attachment":[{"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/media?parent=5270"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/categories?post=5270"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/visualgdb.com\/w\/wp-json\/wp\/v2\/tags?post=5270"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}