This article applies to PLCnext CLI version 22.0.0 LTS.
If you program PLCnext Control devices using C++, you have probably used code templates that are installed with the PLCnext CLI.
In Visual Studio and Eclipse, you must pick the project template you want to use when creating a new project with the PLCnext project wizard (installed with the PLCnext IDE extension).
When generating a new C++ project on the command-line with the PLCnext CLI, you must also specify a project template.
The three default project templates are:
project The project is a template for user programs.
They are managed by the PLM (Program Library Manager).
acfproject The acfproject is a template for component based platform development.
The resulting component will be managed by the ACF
(Application Component Framework).
consumablelibrary The consumable library is a template, that creates a library
which can be used by other projects.
The above information can be seen by executing the plcncli new
command. More information on these types of projects can be found in the PLCnext Info Center:
This article describes how to activate and use additional project templates that are installed with the PLCnext CLI, and how to create and use your own project template.
But first, let's look at how the PLCnext CLI Template system works.
The PLCnext CLI Template system
The PLCnext CLI includes a default setting called TemplateLocations
, that tells it where to find code templates. You can see the value of this setting with the following command:
user@machine:~$ plcncli get setting TemplateLocations
{
"setting": {
"TemplateLocations": "./Templates/Templates.xml"
}
}
The path to the xml file is relative to the plcncli
installation path.
If you browse to the ./Templates
directory, you will see the Templates.xml
file, and a number of sub-directories.
Listing the contents of the Templates.xml
file ...
user@machine:~/plcncli/Templates$ cat Templates.xml
<?xml version="1.0" encoding="utf-8"?>
<Templates xmlns="http://www.phoenixcontact.com/schema/clitemplates">
<Include type="Template">ProjectTemplate/TemplateDescription.xml</Include>
<Include type="Template">ProgramTemplate/TemplateDescription.xml</Include>
<Include type="Format">ProjectTemplate/FormatTemplates.xml</Include>
<Include type="Template">ComponentTemplate/TemplateDescription.xml</Include>
<Include type="Template">BaseTemplates/BaseTemplateDescription.xml</Include>
<Include type="Template">BaseTemplates/CodeTemplateDescription.xml</Include>
<Include type="Fields">BaseTemplates/FieldTemplates.xml</Include>
<Include type="Types">BaseTemplates/TypeTemplates.xml</Include>
<Include type="Format">BaseTemplates/FormatTemplates.xml</Include>
<Include type="Template">AcfProjectTemplate/TemplateDescription.xml</Include>
<Include type="Template">BaseProjectTemplate/TemplateDescription.xml</Include>
<Include type="Template">AcfComponentTemplate/TemplateDescription.xml</Include>
<Include type="Template">BaseComponentTemplate/TemplateDescription.xml</Include>
<Include type="Template">ConsumableLibraryTemplate/TemplateDescription.xml</Include>
</Templates>
... you can see that there are references to TemplateDescription.xml
files of various types in the directories below the Templates
directory. These contain instructions that tell the PLCnext CLI what to do when that template is used.
The template description files shown above implement the three default project templates that you are already familiar with.
How to activate additional templates
There is one "hidden" project template installed by default with the PLCnext CLI, which is not available by default:
minimumproject This is the same as acfproject, but without the capability to create
Port variables in the Global Data Space.
We can make this template available to the PLCnext CLI by adding the MinimalAcfTemplates.xml
file - which you may have already noticed in the Templates
directory - to the template locations setting:
user@machine:~$ plcncli set setting TemplateLocations ./Templates/MinimalAcfTemplates.xml --add
The new XML file has now been added to the template locations:
user@machine:~$ plcncli get setting TemplateLocations
{
"setting": {
"TemplateLocations": "./Templates/Templates.xml;./Templates/MinimalAcfTemplates.xml"
}
}
... and when the plcncli new
command is executed, minimumproject
now appears in the list of options. This template can now be used to create a new C++ project from the command line.
Note: Adding a project template to the PLCnext CLI does not automatically add the project template to the Visual Studio or Eclipse project wizards.
How to create your own PLCnext CLI template
The creation of custom PLCnext CLI templates will be demonstrated using a simple example. A PLCnext CLI template will be created that generates a "Hello World!" console application in C++.
The procedure is as follows:
-
Create a directory for the new PLCnext CLI project template.
On Linux:
user@machine:~/plcncli/Templates$ mkdir ExeTemplate && cd ExeTemplate
-
Create a file containing template C++ code, which can be used as a starting point for every new project of this type.
user@machine:~/plcncli/Templates/ExeTemplate$ touch Main.cpp
The C++ code used in this example is:
#include int main() { std::cout << "Hello World!" << std::endl; return 0; }
-
Create a template cmake source file.
user@machine:~/plcncli/Templates/ExeTemplate$ touch CMakeLists.txt
The CMake code used in this example is:
cmake_minimum_required(VERSION 3.13) project($(name)) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release) endif() ################# create target ####################################################### file(GLOB_RECURSE Headers CONFIGURE_DEPENDS src/*.h src/*.hpp src/*.hxx) file(GLOB_RECURSE Sources CONFIGURE_DEPENDS src/*.cpp) add_executable(${CMAKE_PROJECT_NAME} ${Headers} ${Sources}) ####################################################################################### ################# set install directories ############################################# string(REGEX REPLACE "^.*\\(([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*$" "\\1" _ARP_SHORT_DEVICE_VERSION ${ARP_DEVICE_VERSION}) set(BIN_INSTALL_DIR ${ARP_DEVICE}_${_ARP_SHORT_DEVICE_VERSION}/${CMAKE_BUILD_TYPE}) ####################################################################################### ################# project include-paths ############################################### target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE $) ####################################################################################### ################# include arp cmake module path ####################################### list(INSERT CMAKE_MODULE_PATH 0 "${ARP_TOOLCHAIN_CMAKE_MODULE_PATH}") ####################################################################################### ################# set link options #################################################### # WARNING: Without --no-undefined the linker will not check, whether all necessary # # libraries are linked. When a library which is necessary is not linked, # # the firmware will crash and there will be NO indication why it crashed. # ####################################################################################### target_link_options(${CMAKE_PROJECT_NAME} PRIVATE LINKER:--no-undefined) ####################################################################################### ################# add link targets #################################################### find_package(ArpDevice REQUIRED) find_package(ArpProgramming REQUIRED) target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ArpDevice ArpProgramming) ####################################################################################### ################# install ############################################################# install(TARGETS ${CMAKE_PROJECT_NAME} RUNTIME DESTINATION ${BIN_INSTALL_DIR}) unset(_ARP_SHORT_DEVICE_VERSION) #######################################################################################
Note that the CMake code includes the placeholder
$(name)
, which will be replaced with the name of the project that is passed to theplcncli new
command. -
Optional: Add a README file to the new template directory, which can also be used to create a README file in each new project created from this template.
-
Create a PLCnext CLI project configuration file.
This file is used to store project configuration information for the PLCnext CLI, e.g. the list of targets that the project should be built for.
For this example, the
.proj
file was copied from theConsumableLibraryTemplate
directory and edited to produce the following:<?xml version="1.0" encoding="utf-8"?> <ProjectSettings xmlns="http://www.phoenixcontact.com/schema/cliproject"> <Type>exeproject</Type> <Version>0.1</Version> <Name>$(name)</Name> </ProjectSettings>
The
Type
field should contain the unique name of this project template, which will also be included in the template description file in the next step.The
Name
field contains the placeholder$(name)
, which will be substituted with the project name during the creation of each new project. -
Create a template description file.
For this example, the
TemplateDescription.xml
file was copied from theConsumableLibraryTemplate
directory and edited to produce the following:<?xml version="1.0" encoding="utf-8"?> <TemplateDescription name="exeproject" isRoot="true" basedOn="baseproject" supportedFirmwareVersions="19.0.0.16199" requiredCliVersion="19.0.0.660" version="1.0" xmlns="http://www.phoenixcontact.com/schema/clitemplates" identifier="ProjectSettingsIdentifier"> <File name="plcnext.proj" template=".proj"/> <File name="CMakeLists.txt" template="CMakeLists.txt"/> <File name="README.md" template="README.md"/> <File name="$(name)Main.cpp" template="Main.cpp" path="src"/> <Description>Create a new stand-alone executable project.</Description> <Example> <Arguments> <Argument name="name" value="MyExe"/> </Arguments> <Description>creates a new stand-alone executable project in the directory 'MyExe'</Description> </Example> </TemplateDescription>
The fields in the template description include:
-
name="exeproject"
: Enables projects to be created from this template using the commandplcncli new exeproject
. -
File name="A" template="B" path="C"
: Creates a file in the new project, in the specified path, based on the specified template file. The file name can also include placeholders like$(name)
, which will be substituted with the project name during the creation of each new project. -
Description
andExample
fields, which are displayed in the relevant sections of theplcncli
help system.
-
-
Create a new Templates file, which will be used to tell the PLCnext CLI about our new template(s).
For this example, the
MinimalAcfTemplates.xml
file in theTemplates
directory was copied to a file namedCustomTemplates.xml
, and that file was edited to produce the following:<?xml version="1.0" encoding="utf-8"?> <Templates xmlns="http://www.phoenixcontact.com/schema/clitemplates"> <Include type="Template">ExeTemplate/TemplateDescription.xml</Include> </Templates>
-
Register the custom templates with the PLCnext CLI
user@machine:~$ plcncli set setting TemplateLocations ./Templates/CustomTemplates.xml --add
The path is relative to the PLCnext CLI installation directory.
-
Try it out!
The following list of bash commands demonstrate the features of the new template:
plcncli new # The help text includes the new template and description plcncli new exeproject --help # Displays the example showing how to use this template plcncli new exeproject --name "HelloWorld" # Creates a new project based on the template cd HelloWorld plcncli set target -n AXCF2152 -v 2022 --add # Sets the build target plcncli build # Builds the project with the default template code scp bin/AXCF2152_22.0.3.129/Release/HelloWorld admin@192.168.1.10:~ # Copies the executable to the device ssh admin@192.168.1.10 ./HelloWorld # Runs the executable!
Contribute
In the future, it is planned that contributions to the PLCnext CLI Templates project on Github will be possible. Until then, you can open an issue with ideas for new templates, or with examples of templates that you have created yourself.
Questions or comments?
Post a comment below, or ask questions in the PLCnext Community Forum.
Leave a Reply
You must be logged in to post a comment.