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=""$(toolchain)/"" />
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=""$(toolchain)/"" />
</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