Documentation/CTK Plugin Framework: Setting up a project
This tutorial will show you how to set-up your own project using the CMake build system and how to integrate it with the CTK Plugin Framework.
The described set-up will allow for an arbitrary number of applications and CTK plug-ins, contained in one project.
Project Layout
A possible project layout is shown in Fig. 1. It contains one application (UseCTKPlugin) and one plugin (org.mydomain.serviceeventlistener). The code for the application and different plugins is explained in other tutorials. We will cover only the four CMake files seen in Fig. 1.
Top-Level CMake File
The top-level CMake file is in charge of finding CTK and Qt4. You can add any CMake commands you want, the only requirement for a CTK Plugin integration is the availability of CTK and Qt4 (by using FIND_PACKAGE). You can have a look at an example file by clicking on the CMakeLists.txt link below. We will discuss one important part of this file in more detail:
https://github.com/saschazelzer/CTKPluginTutorials/raw/master/CMakeLists.txt
To be able to take advantage of CTKs sophisticated dependency checking system inside your own build system, you need to write a small CMake macro called GetMyTargetLibraries. It is used as a callback inside CTKs own CMake macros and functions to distinguish between targets being build in your project and targets external to your project (e.g. targets coming from CTK). It works by taking a list of target names and filtering out the names belonging to your own project using regular expressions. You can use as many regular expressions as you want in the call to ctkMacroListFilter, between _tmp_list and OUTPUT_VARIABLE.
Together with the FIND_PACKAGE commands for CTK and Qt4, that is all you need in your top-level CMake file.
Application Integration
The CMakeLists.txt file inside the Apps directory is not required to use any CTK specific CMake code. In the described set-up it just adds a build option for our CTKUsePlugin application and adds its directory to be parsed by CMake.
Here is an example CMake file for our CTKUsePlugin application which needs to call methods in the CTK Plugin Framework library:
https://github.com/saschazelzer/CTKPluginTutorials/raw/master/Apps/UseCTKPlugin/CMakeLists.txt
This is standard CMake code, adding the CTK include directories and linking the application to the CTK Plugin Framework library CTKPluginFramework.
Plugin Integration
In contrast to the CMake file in the Apps directory, the CMakeLists.txt file in the Plugins directory makes use of some dependency checking from the CTK build system:
https://github.com/saschazelzer/CTKPluginTutorials/raw/master/Plugins/CMakeLists.txt
The first step is to create a list containing one entry for each plug-in in the Plugins directory. Each entry consists of the directory name containing the plug-in followed by a : and the default build option value. This list is then passed to the ctkFunctionSetupExternalPlugins function, which executes the following steps:
- Create a CMake option for each given plugin. You can customise the option name with a prefix by supplying "BUILD_OPTION_PREFIX MyPrefix" as the last arguments to the function (MyPrefix defaults to BUILD_).
- Generate a dependency graph of your plugins and external dependencies (other plugins and libraries).
- Validate the dependencies of enabled plugins. If one of your own plugins depends on other plugins in your project, they will be automatically enabled. Unsatisfied external dependencies will result in a CMake configuration error.
- Add the subdirectories of enabled plugins.
Plugin CMake File
Plugins external to CTK are build exactly the same way as plugins contained within the CTK project itself. An example CMakeLists.txt file for a plugin named org.mydomain.serviceeventlistener is shown below:
https://github.com/saschazelzer/CTKPluginTutorials/raw/master/Plugins/org.mydomain.serviceeventlistener/CMakeLists.txt
The PROJECT command in line one sets the name for your plugin sub-project. Additionally, this name is used as the target name for the shared library and should be globally unique. A good convention is to use the reverse domain scheme for the project name and also for the directory containing the plugin code. Note that the project name must not contain periods.
Calling the macro ctkMacroBuildPlugin will do the heavy lifting and set-up all include paths and library dependencies. The definition of plugin dependencies and the usage of this macro is covered in the Creating a new CTK Plugin tutorial.