Generate Plugin Description

This guide teaches you how to:

Basics

As you might already know, we are using a *.plugindescription file to describe an ADTF Component (e.g. Filter, Service, Streaming Source/Sink, ...) delivered within a corresponding *.adtfplugin. The containing information, such as for example pins, properties or default runlevel, will be used by ADTF Configuration Editor to provide the ADTF Component and its dependencies during configuration time without loading the binary itself. For more information please have a look at ADTF Plugin Description Generator, in this guide here we will focus which part of the API will be used for creation by using CMake and the post-build generation.

CMake setup

As you might already know from our different examples and guides, the "magic" CMake command for Plugin Description generation is called adtf_create_plugindescription:

          
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
project (filter_for_plugin_description)

find_package(ADTF COMPONENTS filtersdk)

# Adds the filter_for_plugin_description project to the Visual Studio solution, which when build
# creates a shared object called filter_for_plugin_description.adtfplugin
adtf_add_filter(filter_for_plugin_description 
    filter_for_plugin_description.h
    filter_for_plugin_description.cpp
)

# Adds the INSTALL project to the Visual Studio solution, which when build
# copies our Filter to the subdirectory given as the second argument into ${CMAKE_INSTALL_PREFIX}
adtf_install_filter(filter_for_plugin_description src/examples/bin)

# Generate a plugindescription for our Filter
# Note: The node <platform> will be generated automatically
adtf_create_plugindescription(
    TARGET filter_for_plugin_description 
    PLUGIN_SUBDIR "src/examples/bin"
    VERSION "0.8.15"                                        # this will fill the node <plugin_version> (0.0.0 if not defined)
    LICENSE "MPL"                                           # this will fill the node <license> (empty if not defined)
    SUPPORT_MAIL "support@mycompany.org"                    # this will fill the node <support_mail> (empty if not defined)
    HOMEPAGE_URL "www.mycompany.org"                        # this will fill the node <homepage_url> (empty if not defined)
    ISSUE_URL "www.mycompany.org/issues/1234"               # this will fill the node <issue_url> (empty if not defined)
    DEPENDENT_PLUGINS                                       # if required, a list of adtfplugins which have to be loaded before this adtfplugin at runtime
        "adtf_xsystem"
        "some_custom_plugin"
    DEPENDENT_DYNAMIC_LIBS                                  # if required, a list of shared libraries which have to be loaded before this adtfplugin (only for generating plugindescription)
        "${DEPENDENCY_DIR}/lib/library.dll"                 # macro with ${CMake} syntax, will be resolved for generation
    PLATFORM_DEPENDENCIES                                   # if required, this will fill the node <platform_dependency> (runtime only, empty if not defined)
        "=(MACRO_I_KNOW_AT_RUNTIME)/library.dll"            # macro with $(ADTF) syntax, won't be resolved, will be stored in plugindescription as is
        "=(MACRO_I_KNOW_AT_RUNTIME)/other_library.dll"      # Workaround to prevent CMake resolving: use macro with =(ADTF) syntax to be store as $(ADTF) in plugindescription, the '=' will be replaced with '$'
    PLATFORM_DEPENDENCIES_RELEASE                           # if required, this will fill the node <platform_dependency> for release only (runtime only, empty if not defined)
        "=(MACRO_I_KNOW_AT_RUNTIME)/bin/fancy.dll"          # Workaround to prevent CMake resolving: use macro with =(ADTF) syntax to be store as $(ADTF) in plugindescription, the '=' will be replaced with '$'
    PLATFORM_DEPENDENCIES_DEBUG                             # if required, this will fill the node <platform_dependency> for debug only (runtime only, empty if not defined)
        "=(MACRO_I_KNOW_AT_RUNTIME)/bin/debug/fancyd.dll"   # Workaround to prevent CMake resolving: use macro with =(ADTF) syntax to be store as $(ADTF) in plugindescription, the '=' will be replaced with '$'
    )
          
        

Generation for a Filter

Other Components than Filters

So this is all what you have to do to create the plugin description for your Filter.

But what if you want to implement a Streaming Source, Streaming Sink or ADTF Service ? The basics like <plugin_name>, <version> and stuff follow always the same rules, the variation might appear in the ADTF Component type itself. Let's have a look at it.

System or UI Service

The main difference is of course that a Service does not have any Pins. The rest works the same as shown in Filter example above. The information will be exported under the <service_descriptions> node instead of <filter_descriptions>.

Besides required interfaces a Service often provides one or more interface. To do so, have a look again at the Filter example and the macro ADTF_CLASS_DEPENDENCIES, but use it now with PROVIDE_INTERFACE instead of REQUIRE_INTERFACE. This works also in combination, for example:

            
// If use this macro, the Plugin Description Generator will add provided and required interfaces:
//      <provided_interfaces>
//          <interface_description>>
//              <iid>myinterface.ant.services.adtf.iid</iid>
//          </interface_description>
//          <interface_description>
//              <iid>myinterface.bat.services.adtf.iid</iid>
//          </interface_description>
//          <interface_description>
//              <iid>myinterface.elasto.services.adtf.iid</iid>
//          </interface_description>
//      </provided_interfaces>
//      <required_interfaces>
//          <interface_description>
//              <iid>reference_clock.giant.streaming.adtf.iid</iid>
//          </interface_description>
//          <interface_description>
//              <iid>kernel.devil.services.adtf.iid</iid>
//          </interface_description>
//      </required_interfaces>
ADTF_CLASS_DEPENDENCIES(REQUIRE_INTERFACE(adtf::services::IReferenceClock),
                        REQUIRE_INTERFACE(adtf::services::IKernel),
                        PROVIDE_INTERFACE(adtf::services::ant::IMyInterface),
                        PROVIDE_INTERFACE(adtf::services::bat::IMyInterface),
                        PROVIDE_INTERFACE(adtf::services::elasto::IMyInterface));
            
        

The second difference is the default runlevel for your System or UI Service, for that, just use SetDefaultRunlevel(tInt8 nDefaultRunlevel) in your constructor:

            
// constructor
cMyService::cMyService()
{
    // This will generate the description for the default runlevel:
    //     <runlevel>session</runlevel>
    SetDefaultRunlevel(tADTFRunLevel::RL_Session);
}
            
        

Streaming Service

The generation of the Plugin Description for Streaming Services follows exactly the rules as for Filters. The only difference is the node where the information will be exported, instead of <filter_descriptions> you will find the descriptions under <streaming_source_descriptions> (for Streaming Sources) and <streaming_sink_descriptions> (for Streaming Sinks).

Active Runner, Sample Stream and Binding Proxies

Yes, there are even more ADTF Components which can be implemented by you than Filters or Streaming/System/UI Services, but this might be the minor use case for this topic. Anyway, also these ADTF Components must be described to be used for example within ADTF Configuration Editor, but you can treat them almost like a System Service, except the not needed default runlevel. Of course, for each type there is a specified node, the Plugin Description will be generated under <activerunner_descriptions> (for Active Runners), <samplestream_descriptions> (for Sample Streams) and last but not least <bindingproxy_descriptions> (for Binding Proxies).

Where to go next?

Have a look at Data Processor Filter Tutorial to learn how to generate data samples in ADTF.