Eclipse CDT Plug-ins – New C/C++ Project Templates

A C/C++ New Project Template in Eclipse CDT can be seen as a set of template files that form the new project source code and other resources, and a description how to copy the files and setup the project. The latter is in the template.xml file. The template files can be source code (.c, .c++, .gcc, .g++), include files (.h, h++), libraries, makefiles, icons, etc. It can be actually any file in complete folder structures.

Macro’s

One of the interesting properties is that the new project files can contain macros that get replaced upon copying. This can be used to add a copyright notice, a file name or a specifc refrence to a header named as the project.

//============================================================================
// Name : $(projName).cpp
// Author : $(author)
// Copyright : $(copyright)
// Description : Send RFM69 packets. Report received data on the serial port
//============================================================================ 

#include "$(projName).h"
int main () {

When the template is selected in the New C/C++ Project Wizard, the templateEngine expands the macro’s:

//============================================================================
// Name : rf_ping.cpp
// Author : sevenwatt
// Copyright : (c) 2015 All rights reserved.
// Description : Send RFM69 packets. Report received data on the serial port
//============================================================================

#include "rf_ping.h"
int main () {

This is actually a cool feature.

For makefiles the same mechanism exist. But as in makefiles the same syntax $(MACRO) is already extensively used, for the templates a new syntax is introduced: {{macro}}. There is one  restriction: the source template file has to be named MakeFile, just like the target.

LINK = {{LPCType}}.ld
OBJS = {{baseName}}.o system_LPC8xx.o gcc_startup_lpc8xx.o uart.o

Macro’s can originate from:

  • Eclipse C/C++ build variables (user defined and built-in)
  • Eclipse C/C++ environment variables
  • Properties on the New C/C++ project wizard pages
  • Template-defined properties in the wizard pages

Adding wizard pages

The template language has propertyGroups and properties. PropertyGroups represent a newly added wizard page, while the properties represent the UI input fields and the underlying variable the property is stored in:

<property-group id="advanced" label="%LPC8xxHello.advanced.label"
  description="%LPC8xxHello.advanced.description" type="PAGES-ONLY" help="help.html">
     <property id="toolchain" label="%LPC8xxHello.toolchain.label"
       description="%LPC8xxHello.toolchain.description" type="browsedir"
       mandatory="false" default="%LPC8xxHello.toolchain.default" persist="false" />
</property-group>

The property has an id="toolchain". This property id can be used as macro $(toolchain) in the process steps in the template for example as a include file location.

The following UI widgets are available as property UI, by assigning the value to attribute type:

  • input: If you want a text input box.
  • multiline: If you want a multi-line input box.
  • select: If you want a drop-down combo box.
  • boolean: If you want an option button.
  • stringlist: If you want a list box.
  • speciallist: If you want a list box with buttons to add and delete items to it.
  • browse: If you want a browse button which opens a file (not directory) selection dialog
  • browsedir: If you want a browse button which opens a directory selection dialog

Performing actions in templates: Processes

In templates, processes can be defined. Processes take actions such as creating a project and copying files to those projects. Examples of predefined processes are:

  • org.eclipse.cdt.core.CreateResourceIdentifier
  • org.eclipse.cdt.core.ExcludeResources
  • org.eclipse.cdt.core.Copy
  • org.eclipse.cdt.core.AddLink
  • org.eclipse.cdt.core.AppendCreate
  • org.eclipse.cdt.core.Append
  • org.eclipse.cdt.core.AddFiles
  • org.eclipse.cdt.core.AddFile
  • org.eclipse.cdt.core.CreateIncludeFolder
  • org.eclipse.cdt.core.CreateSourcefolder
  • org.eclipse.cdt.managedbuilder.core.NewManagedProject
  • org.eclipse.cdt.managedbuilder.core.GenerateMakeFileWithBuildDescription
  • org.eclipse.cdt.managedbuilder.core.SetMBSStringOptionValue
  • org.eclipse.cdt.managedbuilder.core.SetMBSStringListOptionValues
  • org.eclipse.cdt.managedbuilder.core.SetMBSBooleanOptionValue
  • org.eclipse.cdt.managedbuilder.core.AppendToMBSStringOptionValue
  • org.eclipse.cdt.managedbuilder.core.AppendToMBSStringListOptionValues
  • org.eclipse.cdt.ui.OpenFiles
  • org.eclipse.cdt.managedbuilder.gnu.ui.SimpleGNUMakefileGenerator

A simple example of process specification is:

<process type="org.eclipse.cdt.managedbuilder.gnu.ui.SimpleGNUMakefileGenerator">
    <simple name="projectName" value="$(projectName)"/>
<code></process></code>

Prevent macro replacement

Sometimes it is unwanted to have the macro’s expanded. For example you want to expand the $(projName) in main.cpp, but do not want to expand an included make file rules.mk, because it is in the make language and includes several make macro’s. There is a solution for this in the template language. A parameter of several process, like AddFiles and Copy is replaceable. The primary semantics of replaceable = "true" is:

Expand the macro’s

However the eclipse CDT documentation gives it the semantics:

Use this flag to specify whether the file should be replaced or not, if it is found in the target location

This is mostly incorrect. AddFile and AddFiles only process the macro’s. the Copy process also processes the macros’s conditionally, but has a quirk. When replaceable = "false" it fails to create target folder structure when needed. If the target folder exists, it just copies the files. The actual syntax in the process step is: <simple name="replaceable" value="true" />.

Available macro’s and syntaxes

There are some predefined macro’s in the CDT system:

projName, baseName, ........

Also some special eclipse syntax can be used:

${workspace_loc:<resource path>} for example ${workspace_loc:$(projName)/lib}

Those built-in variables and special syntax is used in the specification of a Process step:

<process type="org.eclipse.cdt.core.AddFiles">
   <simple name="projectName" value="$(projectName)" />
   <complex-array name="files">
       <element>
            <simple name="source" value="rf69.cpp" />
            <simple name="target" value="{$(workspace_loc:$(projectName)/lib}/rf69.cpp" />
            <simple name="replaceable" value="true" />
       </element>
   </complex-array>
 </process>
 

When dealing with Windows, paths may contain spaces. To indicated a path string with  spaces, double quotes can be used in the template.xml file. The problem with double quotes is that it belongs to XML syntax. The following will work in the template.xml file:

<element value="&quot;$(toolchain)/&quot;" />

Setting project properties

Project properties can be set by pressing Alt-Enter in the project navigator. What can be set through the UI can also be set by the template. An example of setting additional include search paths is:

<process
  type="org.eclipse.cdt.managedbuilder.core.AppendToMBSStringListOptionValues">
      <simple name="projectName" value="$(projectName)" />
      <complex-array name="resourcePaths">
          <element>
              <simple name="id"
                value="org.eclipse.cdt.build.core.settings.holder.incpaths" />
              <simple-array name="values">
                  <element value="&quot;$(toolchain)/&quot;" />
              </simple-array>
              <simple name="path" value="" />
          </element>
      </complex-array>
</process>

The property that is set in this example is: org.eclipse.cdt.build.core.settings.holder.incpaths.  The difficult part is to figure out what the internal name of the property is that needs to be set. One way to figure out is to set a property in the property of project pages and give it a value that can be easily searched on, such as COME_FIND_ME. Then search with your favorite tool within files in the active workspace folder. I normally do this in windows with Notepad++. Most settings are by the way stored in the .cproject file, but sometimes it is stored in preferences of core components or plug-ins. This stackoverflow.com question (second answer) gives some strategies to find the built-in properties.

List of “known” properties

Paths and symbols – includes org.eclipse.cdt.build.core.settings.holder.incpaths
Paths and symbols – symbols org.eclipse.cdt.build.core.settings.holder.symbols
Settings – Tool settings – Optimization gnu.c.compiler.option.optimization.flags
 gnu.c.link.option.libs
 gnu.c.link.option.nostdlibs
gnu.cpp.link.option.libs

Selecting the project type for the template

The plugin.xml file defines which templates are provided by a plugin or core module. It also specifies the C/C++ project type category. This can be

EXE org.eclipse.cdt.build.core.buildArtefactType.exe
Shared Lib org.eclipse.cdt.build.core.buildArtefactType.sharedLib
Static Lib org.eclipse.cdt.build.core.buildArtefactType.staticLib
Makefile org.eclipse.cdt.build.makefile.projectType

By setting the projectType attribute in the template element, the proper category the template shows is selected: projectType="org.eclipse.cdt.build.makefile.projectType". A full specification of a plugin delivering one template would look like this in plugin.xml:

<plugin>
  <extension point="org.eclipse.cdt.core.templates">
      <template
        filterPattern=".*g\+\+"
        id="com.sevenwatt.templates.LPC8xxHelloWorld"
        location="templates/projecttemplates/LPC8xxHelloWorld/template.xml"
        projectType="org.eclipse.cdt.build.makefile.projectType">
      </template>
  </extension>
</plugin

3 thoughts to “Eclipse CDT Plug-ins – New C/C++ Project Templates”

  1. Hi,
    Good post. Please suggest a solution for the below.
    I wanted to know how to execute/run the Makefile using CDT commands.. Lets assume that I am having a button in my own GUI and on click of the button CDT build command should be executed. I wanted to feed the makefile to CDT manually. The script which executes the build is what I want.

  2. Hi,

    Thanks for writing the post. I have a question about the templates, do you know if it’s possible to associate multiple build configurations with a template, more than the default Debug/Release? Any idea how I should go about doing it? [I have already defined the configurations under buildDefinitions, but don’t know how to link them up to a template manifest]

Leave a Reply

Your email address will not be published. Required fields are marked *