Documentation/4.2/Developers/Tutorials/BundleModulesIntoExtension

From Slicer Wiki
Jump to: navigation, search
Home < Documentation < 4.2 < Developers < Tutorials < BundleModulesIntoExtension

For the latest Slicer developers documentation, visit the Nightly page.

Extensions in the Extension manager.

An extension could be seen as a delivery package bundling together one or more Slicer modules. After installing an extension, the associated modules will be presented to the user as built-in ones

The Slicer community maintains a website referred to as the Slicer Extensions Catalog to support finding, downloading and installing of extensions. Access to this website is integral to Slicer and facilitated by the Extensions Manager functionality built into the distributed program.

The Catalog classifies extensions into three levels of compliance:

  1. Category 1: Fully compliant Slicer Extensions: Slicer license, open source, maintained.
  2. Category 2: Open source, contact exists.
  3. Category 3: All other extensions (work in progress, beta, closed source etc).

To publish extensions, developers should consider reading the following pages:

Extensions are packaged against a specific version of Slicer, to be distributed and available for a revision X of Slicer, extensions have to be build against that same revision of Slicer. Otherwise, an extension will be considered as incompatible.


Extension bundles N modules

CMake variables

In case an extension is expected to bundle more than one module, the following CMake variables could be defined:

CMake variable Description Mandatory
EXTENSION_NAME Name of the extension Check.svg
EXTENSION_HOMEPAGE Url of the web page describing the extension Check.svg
EXTENSION_CATEGORY Extension category Check.svg
EXTENSION_CONTRIBUTORS Extension contributor specified as Firstname1 Lastname1 ([SubOrg1, ]Org1), Firstname2 Lastname2 ([SubOrg2, ]Org2)
EXTENSION_DESCRIPTION One line describing what is the purpose of the extension
EXTENSION_ICONURL Url to an icon (png, size 128x128 pixels)
EXTENSION_SCREENSHOTURLS Space separated list of urls to images
EXTENSION_DEPENDS List of extensions required to build this extension. Specify "NA" if there are no dependency.


List of partially supported CMake variables:

CMake variable Description
EXTENSION_STATUS Give people an idea what to expect from this code

Project layout

The code should be organized as illustrated below:


  MyExtension  <- - - - - - - - - - - - - - - - - - - - - - Top-level folder of the extension project
       |
       |-- CMakeLists.txt
       |
       |-- MyExtension.png
       |
       |-- MyCLIModule
       |        |
       |        |-- CMakeLists.txt
       |        |
       |        |-- MyCLIModule.cxx
       |        |
       |        |-- MyCLIModule.xml
       .        .
       .        .
       |
       |-- MyLoadableModule
                |
                |-- CMakeLists.txt
                |
                |-- qSlicerMyLoadableModuleModule.cxx
                |
                |-- qSlicerMyLoadableModuleModule.h
                .
                .

Top-level CMakeLists.txt

The top-level CMakeLists.txt could be organized as reported below:

cmake_minimum_required(VERSION 2.8.8)

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_NAME MyExtension)  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_HOMEPAGE "http://www.slicer.org/wiki/Documentation/4.1/Extensions/${EXTENSION_NAME}")  <- - - - EXTENSION SPECIFIC
  set(EXTENSION_CATEGORY "Examples")  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  EXTENSION SPECIFIC
  set(EXTENSION_CONTRIBUTORS "Jean-Christophe Fillion-Robin (Kitware)")  <- - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_DESCRIPTION "This is an example of extension bundling a CLI, a loadable and a scripted module")  <- - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_ICONURL "http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Extensions/Testing/LoadableExtensionTemplate/Resources/Icons/LoadableExtensionTemplate.png?revision=19437&view=co")
endif()  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)
  find_package(Slicer REQUIRED)
  include(${Slicer_USE_FILE})
endif()

#-----------------------------------------------------------------------------
add_subdirectory(MyCLIModule)
add_subdirectory(MyLoadableModule)
[...]

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)  <- - - - - - - - - - - EXTENSION SPECIFIC
  include(${Slicer_EXTENSION_CPACK})  <- - - - -  EXTENSION SPECIFIC
endif()  <- - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC

Possible tweak of Module level CMakeLists.txt

During the development process, it could be useful to be able to build each module against a given slicer build tree without having to build the complete extensions, to do so the CMakeLists.txt of each module could include find_package(Slicer REQUIRED).

For example, the CMakeLists.txt of MyCLIModule module that would be bundled into MyExtension could include the following code:

cmake_minimum_required(VERSION 2.8.8)

#-----------------------------------------------------------------------------
set(MODULE_NAME MyCLIModule) # Do not use 'project()'

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)
  find_package(Slicer REQUIRED)
  include(${Slicer_USE_FILE})
endif()

[...]

Extension bundles 1 module

This section describes how a developer could write (or update) the CMakeLists.txt of a regular Slicer module so that it could be packaged and published as an extension.

CMake variables

In case an extension is expected to bundle exactly one module, the CMake variables to define an extension are detailed above.


Project layout

In this case the extension should be organized as illustrated below:


 MyLoadableModuleExtension <- - - - - - - - - - - - - - - - - - - - - - Top-level folder of the extension project
       |
       |-- CMakeLists.txt
       |
       |-- qSlicerMyLoadableModuleExtensionModule.cxx
       |
       |-- qSlicerMyLoadableModuleExtensionModule.h
       .
       .

Top-level CMakeLists.txt

The top-level CMakeLists.txt could be organized as reported below:

cmake_minimum_required(VERSION 2.8.8)

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_NAME MyLoadableModuleExtension)  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_HOMEPAGE "http://www.slicer.org/wiki/Documentation/4.1/Extensions/${MODULE_NAME}")  <- - - - -  EXTENSION SPECIFIC
  set(EXTENSION_CATEGORY "Examples")  <- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  EXTENSION SPECIFIC
  set(EXTENSION_CONTRIBUTORS "Jean-Christophe Fillion-Robin (Kitware)")  <- - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_DESCRIPTION "This is an example of Qt loadable module built as an extension")  <- - - - - - - - - - - - - - - - EXTENSION SPECIFIC
  set(EXTENSION_ICONURL "http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Extensions/Testing/LoadableExtensionTemplate/Resources/Icons/LoadableExtensionTemplate.png?revision=19437&view=co")
endif()<- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC

#-----------------------------------------------------------------------------
set(MODULE_NAME MyLoadableModuleExtension)
set(MODULE_TITLE ${MODULE_NAME})

string(TOUPPER ${MODULE_NAME} MODULE_NAME_UPPER)

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR) 
  find_package(Slicer REQUIRED)
  include(${Slicer_USE_FILE})
endif()

#-----------------------------------------------------------------------------
add_subdirectory(Logic)

#-----------------------------------------------------------------------------
set(MODULE_EXPORT_DIRECTIVE "Q_SLICER_QTMODULES_${MODULE_NAME_UPPER}_EXPORT")

[...]

#-----------------------------------------------------------------------------
slicerMacroBuildQtModule(
  NAME ${MODULE_NAME}
  TITLE ${MODULE_TITLE}
  EXPORT_DIRECTIVE ${MODULE_EXPORT_DIRECTIVE}
  INCLUDE_DIRECTORIES ${MODULE_INCLUDE_DIRECTORIES}
  SRCS ${MODULE_SRCS}
  MOC_SRCS ${MODULE_MOC_SRCS}
  UI_SRCS ${MODULE_UI_SRCS}
  TARGET_LIBRARIES ${MODULE_TARGET_LIBRARIES}
  RESOURCES ${MODULE_RESOURCES}
  )

#-----------------------------------------------------------------------------
if(BUILD_TESTING)
  add_subdirectory(Testing)
endif()

#-----------------------------------------------------------------------------
if(NOT Slicer_SOURCE_DIR)  <- - - - - - - - - - - EXTENSION SPECIFIC
  include(${Slicer_EXTENSION_CPACK})  <- - - - -  EXTENSION SPECIFIC
endif()  <- - - - - - - - - - - - - - - - - - - - EXTENSION SPECIFIC

Additional documentation