Converting a BlueBerry bundle to a CTK plugin

Jump to navigation Jump to search

This is a step-by-step guide to convert your existing BlueBerry bundle into a proper CTK plugin. It is assumed that your build system can already handle CTK-based plug-ins.

Overview of the necessary changes

Some files in your BlueBerry bundle will need modifications, some will be obsolete and a few new ones have to be created.

Files needing modification:
  • CMakeLists.txt
  • files.cmake
  • Classes and interfaces you use in your plugin.xml file
  • Your BlueBerry activator class (if you have one)
  • A top-level CMakeLists.txt file, listing all available plug-ins

New files:
  • manifest_headers.cmake
  • mitkPluginActivator.[h|cpp] (if you do not already have a BlueBerry activator class)

Obsolete files and directories:
  • META-INF directory (replaced by manifest_headers.make)
  • manifest.cpp (replaced by calls to BERRY_REGISTER_EXTENSION_CLASS)
  • includes.cmake (replaced by providing a list in MACRO_CREATE_MITK_CTK_PLUGIN)
  • src/*Dll.h (this will be auto-generated)


1. Adapt your plug-ins build system

1.1 Your CMakeLists.txt file must conatin a PROJECT command and a MACRO_CREATE_MITK_CTK_PLUGIN command, i.e.:

<syntaxhighlight lang="cmake">

  1. The project name must correspond to the directory name of your plug-in
  2. and must not contain periods.



 EXPORT_DIRECTIVE <export-directive>
 EXPORTED_INCLUDE_SUFFIXES <list-of-include-subdirs>
 MODULE_DEPENDENCIES <list-of-mitk-modules>

) </syntaxhighlight>

Only the first argument - EXPORT_DIRECTIVE - is mandatory. You should use the same token as in your src/*Dll.h file, usually located at line 32: #define <export-directive> _declspec(dllexport) .

The EXPORTED_INCLUDE_SUFFIXES argument is optional. For usual BlueBerry bundles, you would just add your src directory to the list, i.e. "EXPORTED_INCLUDE_SUFFIXES src". This list is equivalent to the list defined in the obsolete includes.cmake file plus your src directory.

If your original MACRO_CREATE_MITK_PLUGIN command contained a list of MITK modules as arguments, add the same module names as arguments to MODULE_DEPENDENCIES.

1.2 Create a new file called manifest_headers.cmake in the root directory of your plug-in. This file replaces the META-INF/MANIFEST.MF file and should contain the same information, just in a different format. Here is a template you can use:

<syntaxhighlight lang="cmake"> set(Plugin-Name "A human readable name for your plug-in") set(Plugin-Version "x.x.x") set(Plugin-Vendor "A human readable name for the vendor of the plug-in") set(Plugin-ContactAddress "Could be a web page, a email adress, etc.") set(Require-Plugin <list-of-plugin-symbolic-names>) </syntaxhighlight>

Here are examples for each entry:

  • set(Plugin-Name "MITK Image Cropper")
  • set(Plugin-Version "0.9")
  • set (Plugin-Vendor "DKFZ, Medical and Biological Informatics")
  • set(Plugin-ContactAddress "")
  • set(Require-Plugin org.blueberry.ui

Use the same list of required plug-ins as in your old MANIFEST.MF file, but this time separated with spaces (usual CMake syntax).

If your old MANIFEST.MF file contains a "Bundle-ActivationPolicy" header, be sure to create an equivalent entry in your new manifest_headers.cmake file: "set(Plugin-ActivationPolicy eager)".

1.3 Adapt your files.cmake file.

  • Change the variable named RESOURCE_FILES to CACHED_RESOURCE_FILES. If you don't have one but you have a plugin.xml file, create an empty variable: SET(CACHED_RESOURCE_FILES ).
  • If you have a plugin.xml file, add it to the CACHED_RESOURCE_FILES variable.
  • If you have a RES_FILES variable, rename it to QRC_FILES.
  • If you don't have a MOC_H_FILES variable, add an empty one: SET(MOC_H_FILES ).
  • Delete all occurences of manifest.cpp.

1.4 Adapt your plugin.xml file.

  • Some people use the global namespace identifier "::" in class names for executable extensions. This will not work anymore, so remove any occurence of ::, as for example in class="::QmitkDeformableRegistrationView".

2. Code changes

2.1 Create a CTK plugin activator class. If you already have a BlueBerry activator class (you can check in your old META-INF/MANIFEST.MF file if it contains a line starting with Bundle-Activator and having a non-empty value) you can reuse the source code and just modify it.

Your CTK plugin activator class must be a QObject derived class implementing the interface ctkPluginActivator. Below you find the header and implementation file, which you should copy into your src/internal directory. You can rename the file and the class if you have a good reason to do so, but it also works if you leave the class and filename unchanged.


<syntaxhighlight lang="cpp">

  1. include <ctkPluginActivator.h>

namespace mitk {

class PluginActivator :

 public QObject, public ctkPluginActivator




 void start(ctkPluginContext* context);
 void stop(ctkPluginContext* context);

}; // PluginActivator





<syntaxhighlight lang="cpp">

  1. include "mitkPluginActivator.h"
  1. include <QtPlugin>

namespace mitk {

void PluginActivator::start(ctkPluginContext* context) {



void PluginActivator::stop(ctkPluginContext* context) {




Q_EXPORT_PLUGIN2(<replace-with-cmake-project-name>, mitk::PluginActivator) </syntaxhighlight>

The string <replace-with-cmake-project-name> must be replaced with your plug-ins base library name, which is the same as the argument to the CMake command PROJECT in your CMakeLists.txt file (i.e. org_mitk_gui_common).

Finally, add the mitkPluginActivator.h file to the MOC_H_FILES variable and the mitkPluginActivator.cpp file to the INTERNAL_CPP_FILES variable in your files.cmake file.

2.2 Register your BlueBerry extension classes. If your plug-in does not contain a plugin.xml file or this file does not contain "extension" XML tags, skip to step 3.

In the old BlueBerry bundle system, the implementation classes you declare in your plugin.xml file are "registered" in your (now obsolete) manifest.cpp file. This registration is now done in the start() method of your CTK plugin activator class.

Further, these classes need to derive from QObject (directly or indirectly) and need to implement a public default constructor and destructor.

Suppose your plug-in contributes a view, implemented in the class QmitkImageCropperView. The old code in the manifest.cpp file would look like this:

<syntaxhighlight lang="cpp">

  1. include <berryIViewPart.h>
  2. include "src/internal/QmitkImageCropperView.h"

POCO_BEGIN_NAMED_MANIFEST(berryIViewPart, berry::IViewPart)


POCO_END_MANIFEST </syntaxhighlight>

This registration has now to be done in your activator's start method, i.e.

<syntaxhighlight lang="cpp">

  1. include "QmitkImageCropperView.h"

void ImageCropperPluginActivator::start(ctkPluginContext* context) {

 BERRY_REGISTER_EXTENSION_CLASS(QmitkImageCropperView, context)

} </syntaxhighlight >

The QmitkImageCropperView class would look something like

<syntaxhighlight lang="cpp"> class QmitkImageCropperView : public QmitkFunctionality {



 QmitkImageCroperView() {}
 ~QmitkImageCropperView() {}

}; </syntaxhighlight>

Last, add the header file of your extension class to the CMake variable MOC_H_FILES in your files.cmake file.

3. Remove obsolete files

Remove the following files or directories, if they exist:

  • manifest.cpp
  • includes.cmake
  • src/*Dll.h

After removing the last file (*Dll.h), you may have to replace #include "...Dll.h" directives in your source files with #include <org_my_plugin_name_Export.h>, i.e.

<syntaxhighlight lang="cpp">

  1. include <org_mitk_gui_common_Export.h>


!Important! You must remove the old BlueBerry bundle directory in the bin dir of your build directory. For example for a bundle named org.mitk.gui.qt.imagecropper (shipped with MITK) delete the directory <MITK-build>/bin/ExtBundles/org.mitk.gui.qt.imagecropper . If you fail to do so, the BlueBerry framework will discover both the old legacy BlueBerry version of your plug-in and the new CTK-based version which will result in undefined behavior.

4. Add your new CTK plug-in to the list of known plug-ins

Ask your build-system guru in which CMakeLists.txt file you must add a reference to your plug-in.