Difference between revisions of "Documentation/Nightly/Developers/FAQ/Extensions"

From Slicer Wiki
Jump to: navigation, search
m
m
Line 383: Line 383:
  
 
To build Slicer with SSL support, you need to build (or download) Qt with SSL support and configure Slicer with <code>-DSlicer_USE_PYTHONQT_WITH_OPENSSL:BOOL=ON</code>
 
To build Slicer with SSL support, you need to build (or download) Qt with SSL support and configure Slicer with <code>-DSlicer_USE_PYTHONQT_WITH_OPENSSL:BOOL=ON</code>
 +
 +
== How dependent extensions are configured and built ? ==
 +
 +
If an ExtensionB depends on an ExtensionA, ExtensionA should be listed as dependency in the metadata of ExtensionB.
 +
 +
This can be done setting <code>EXTENSION_DEPENDS</code> in the <code>CMakeLists.txt</code> or by specifying <code>depends</code> field in the [[Documentation/{{documentation/version}}/Developers/Extensions/DescriptionFile|description file]].
 +
 +
Doing so will ensure:
 +
* (1) the extension build system configure the extensions in the right order
 +
* (2) configure ExtensionB passing the <code>ExtensionA_DIR</code> option.

Revision as of 17:36, 6 December 2014

Home < Documentation < Nightly < Developers < FAQ < Extensions


For the latest Slicer documentation, visit the read-the-docs.


Contents

Extensions

What is an extension description file ?

See Description file description

Can an extension contain different type of modules ?

Yes. Extensions are used to package together all type of Slicer modules.

See also What_is_an_extension ?

Should the name of the source repository match the name of the extension ?

Assuming your extension is named AwesomeFilter, generally, we suggest to name the extension repository either SlicerAwesomeFilter, Slicer-AwesomeFilter, Slicer_AwesomeFilter, SlicerExtension-AwesomeFilter, SlicerExtension_AwesomeFilter.

Doing so will minimize confusion by clearly stating that the code base is associated with Slicer.

What is the Extensions Index ?

This page has been moved to read-the-docs.

What is an API Key ?

See http://en.wikipedia.org/wiki/Application_programming_interface_key

How to obtain an API key to submit on the extension server ?

In order to upload extensions on the slicer extensions server, it is required to:


  1. Create an account on the extension server: http://slicer.kitware.com by clicking on the Register link in the top right corner

  2. Slicer-midas-extensions-server-registration.png

    This image shows the top portion of http://slicer.kitware.com after it has been expanded by clicking the Register button.

  3. Go to NA-MIC community and click on Join community

  4. Retrieve your API key looking at your account details:

    1. Go to http://slicer.kitware.com. If needed, signin by clicking on Login in the top right corner.
    2. Click on your name in the top right corner.
    3. Click on My account.
    4. Click on API tab.
    5. Copy the API Key associated with Default application.

      1. There is currently a bug preventing api key containing non alpanumeric characters from being used.
        If your Default api key contain for example a /, try to delete the api key and regenerate one that is not containing "/" and is named Default.
        We are working on the issue to update the build system so that it properly escape "/" and also get in touch with Midas team so that api key containing just number and letter are generated.

  5. Slicer-midas-extensions-server-obtaining-api-key.png

How to cache API credentials ?

There is now a new feature that allow you to "cache" your credential [1]. If you set the two environment variables, MIDAS_PACKAGE_EMAIL and MIDAS_PACKAGE_API_KEY, you would simply need to configure your extension using:

cd MyExtension-build
cmake -DCMAKE_BUILD_TYPE:STRING=Release -DSlicer_DIR:PATH=/path/to/Slicer-Superbuild/Slicer-build ../MyExtension
make ExperimentalUpload

[1] http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=22457

Where can I find the extension templates ?

The module and extension templates are available in the Slicer source tree: https://github.com/Slicer/Slicer/tree/master/Utilities/Templates/

Using the Extension Wizard, you could easily create a new extension without having to copy, rename and update manually every files.

How to build an extension ?

Assuming that the source code of your extension is located in folder MyExtension, this could be achieved doing:

Makefile Visual Studio
$ mkdir MyExtension-build
$ cd MyExtension-build
$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DSlicer_DIR:PATH=/path/to/Slicer-Superbuild/Slicer-build ../MyExtension
$ make
  1. Start CMake, select source and build directory
  2. Add Slicer_DIR entry to the cache
  3. Click on Configure, select generator, then click on Generate button.
  4. Open MyExtension.sln, select Release configuration, then menu Project -> Build Solution.

How to package an extension ?

Assuming your extension has been built into folder MyExtension-build, this could be achieved doing:

Makefile Visual Studio
$ make package
  1. Open MyExtension.sln
  2. Select PACKAGES project, then right click and select Build

How to upload an extension ?

  1. If not already done, send an email on the slicer developers list asking to be granted write permission on the experimental folder.

    To: slicer-devel@bwh.harvard.edu
    Subject: Extension NAME-OF-YOUR-EXTENSION - Asking permission to write to the Experimental folder
    Hi, 
    
    This extension will allow to [...]
    
    Could you grant user YourUserName write access to the Experimental folder ?
    
    

Assuming your extension has been built and packaged into folder MyExtension-build, this could be achieved by first re-configuring the project providing your midas credentials and then building the ExperimentalUploadOnly target:

Makefile Visual Studio
$ cmake -DMIDAS_PACKAGE_EMAIL:STRING=<YOUR-MIDAS-LOGIN> -DMIDAS_PACKAGE_API_KEY:STRING=<YOUR-MIDAS-APIKEY> .
$ make ExperimentalUploadOnly
  1. Start CMake, select source and build directory
  2. Add MIDAS_PACKAGE_EMAIL and MIDAS_PACKAGE_API_KEY entries to the cache
  3. Open MyExtension.sln
  4. Select Release configuration
  5. Select ExperimentalUploadOnly project, then right click and select Build

Can an extension depend on other extensions ?

Yes. An ExtensionFoo can depend on ExtensionBar

The dependency should be specified as a list by setting the variable EXTENSION_DEPENDS in the extension CMakeLists.txt.

For example, if you have ModuleA, ModuleB and ModuleC and ModuleA can be used as standalone one. You could create the following extensions:

  • Extension1 containing ModuleA
  • Extension2 containing ModuleB and ModuleC

and add the following variable to Extension2/CMakeLists.txt:

set(EXTENSION_DEPENDS Extension1)

User:

  • If user installs Extension2, Extension1 will automatically be installed first.

Developer:

  • The generated extension description file have a depends field. See here for details.
  • The extension framework will build the extension in order. When building Extension2, it will pass the CMake option -DExtension1_DIR:PATH=/path/to/Extension1-build.

What are the extension specific targets: ExperimentalUpload, ExperimentalUploadOnly, ... ?

Slicer extension build system provides the developer with a set of convenient targets allowing to build and upload extensions.

Target name Description
Experimental Configure, build, test the extension and publish result on CDash.
ExperimentalUpload Equivalent to Experimental target followed by packaging and upload of the extension on the extension server.
ExperimentalUploadOnly Only proceed to the upload of the extension on the extension server.
test or BUILD_TESTS Locally execute the test
package or PACKAGE Locally package the extension

Is --launch flag available for a MacOSX installed Slicer.app ?

On MacOSx, running Slicer with the --help argument does NOT list the usual launcher related options.

$ ./Slicer.app/Contents/MacOS/Slicer --help
Usage
 Slicer [options]
 
 Options
   --, --ignore-rest                     Ignores the rest of the labeled arguments following this flag. (default: false)
   -h, --help                            Display available command line arguments.
   [...]
   --version                             Displays version information and exits.

To provide some background information, when generating the package that will be distributed, an application bundle Slicer.app is created. As explained here, a bundle is a directory with a standardized hierarchical structure that holds executable code and the resources used by that code. It means that since all libraries contained within a bundle are referenced relatively to the location of either the CLI or the Slicer executable, the use of launcher does NOT make sens.

To help fixing-up the libraries, executables and plugins so that they reference each other in a relative way, CMake provides us with the BundleUtilities module.

This module is used in two situations:

  1. Fixup of Slicer application itself. See SlicerCPack.cmake#L36-68 and SlicerCPackBundleFixup.cmake.in
  2. Fixup of an extension package. See SlicerExtensionCPack.cmake#L126-143 and SlicerExtensionCPackBundleFixup.cmake.in


What is the difference between Documentation/Nightly/Modules and Documentation/Nightly/Extensions ?

As suggested by the namespace names:

  • All module documentation pages should be located under Documentation/Nightly/Modules
  • All extension documentation pages should be located under Documentation/Nightly/Extensions


For example, if an an extension named DoSomethingGreat bundles three modules ModuleA, ModuleB and ModuleC. The following pages should be created:

  • Documentation/Nightly/Extensions/DoSomethingGreat
  • Documentation/Nightly/Modules/ModuleA
  • Documentation/Nightly/Modules/ModuleB
  • Documentation/Nightly/Modules/ModuleC


In case your extension bundles only one module, the extension name is expected to match the module name. For example, if your extension is named DoSomethingAwesome, the associated module is expected to be named DoSomethingAwesome. The following pages will then be created:

  • Documentation/Nightly/Extensions/DoSomethingAwesome
  • Documentation/Nightly/Modules/DoSomethingAwesome

where page Extensions/DoSomethingAwesome redirect to page Modules/DoSomethingAwesome.


To setup a redirection, simply add the following text to page Extensions/DoSomethingAwesome:

#REDIRECT [[Documentation/Nightly/Modules/DoSomethingAwesome]]

For an example, see here

More details about redirection are available here: http://www.mediawiki.org/wiki/Help:Redirects


Which URL should be associated with EXTENSION_HOMEPAGE metadata ?

Extensions available through the Slicer Extensions Catalog are expected to have a page created under the Nightly documentation namespace. The corresponding URL should be associated with the EXTENSION_HOMEPAGE metadata.

For example:

  • set(EXTENSION_HOMEPAGE "http://slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DoSomethingGreat")
  • set(EXTENSION_HOMEPAGE "http://slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DoSomethingAwesome")

Note that this also apply for extension bundling only one module. Indeed, in this case the page will redirect to the appropriate module page. For example: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/SkullStripper

How to rename an extension to add new features ?

If you created an extension to perform Task1, but later on, your module is getting more generic and you add some other tasks, the name of your extension might change. In order to rename, your extension, you should:

  • Remove your old extension from the ExtensionsIndex
  • Then, submit your extension again (including new features) with a new name
  • Make also sure to add redirection from the "deprecated" module documentation to the "new" pages. On the Slicer wiki, this could be using the #REDIRECT instruction.

How to check if an extension is built by Slicer Extensions build system ?

Sometimes an extension could be built either as a standalone package or as a Slicer extension.

To differenciate the two cases, the developer could check for the value of:

<ExtensionName>_BUILD_SLICER_EXTENSION

This variable will be set to ON when the extension is built by the Slicer Extensions build system.

For details: https://github.com/Slicer/Slicer/blob/ff5f5a866d8afcaa0f2e6f615cc8f8cf07361741/Extensions/CMake/SlicerBlockBuildPackageAndUploadExtension.cmake#L95

How often extensions are uploaded on the extensions server ?

Slicer extensions are built and uploaded on the extensions server every day.

To be more specific, the frequency of extensions build and upload associated with:

  • Slicer nightly package occurs every night and also continuously during the day.
  • Slicer 4.10 lastest stable release package occurs every night.

Will an extension be uploaded if associated tests are failing ?

Independently of the extension test results, if the extension could be successfully packaged, it will be uploaded on the extensions server.

How do I associate a remote with my local extension git source directory ?

1) Start a terminal (or Git Bash on Windows)

2) Get the associated SSH remote url. Need help ?

3) Associate the remote URL with your local git source tree

git remote add origin git://github.com/<username>/MyExtension

Which remote name is expected for extension git checkout ?

When packaging an extension and generating the associated description file, the system will look for a remote named origin.

In case you get the error reported below, you will have to either rename or add a remote. Need help ?

CMake Warning at /path/to/Slicer/CMake/FindGit.cmake:144 (message):
No remote origin set for git repository: /path/to/MyExtension
Call Stack (most recent call first):
/path/to/Slicer/CMake/SlicerMacroExtractRepositoryInfo.cmake:99 (GIT_WC_INFO)
/path/to/Slicer/CMake/SlicerExtensionCPack.cmake:55 (SlicerMacroExtractRepositoryInfo)
CMakeLists.txt:25 (include)

Why ExtensionWizard failed to describe extension: "script does not set 'EXTENSION_HOMEPAGE'" ?

The issue is that the your extension has a "non standard" layout and the wizard was now way of extracting the expected information.

Similar issue has been discussed and reported for the "SPHARM-PDM" or UKF extension.

First half of the solution would be to move the metadata from Common.cmake to CMakeLists.txt as it is done in [1]

Then, you could make sure there is a project() statement by following what is suggested in [2]

If you prefer not to re-organize your extension, you could still contribute extension description file. See here for details.

[1] http://www.nitrc.org/plugins/scmsvn/viewcvs.php?view=rev&root=spharm-pdm&revision=228

[2] http://www.na-mic.org/Bug/view.php?id=3737#c12081

Is project() statement allowed in extension CMakeLists.txt ?

Following Slicer r22038, the project statement is required.

Is call to "if(NOT Slicer_SOURCE_DIR)" required to protect "find_package(Slicer)" in extension CMakeLists.txt ?

Following Slicer r22063, protecting call to find_package(Slicer) with if(NOT Slicer_SOURCE_DIR) is optional and should be removed to keep code simpler and easier to maintain.

Before:

cmake_minimum_required(VERSION 2.8.9)

if(NOT Slicer_SOURCE_DIR)
  find_package(Slicer COMPONENTS ConfigurePrerequisites)
endif()

if(NOT Slicer_SOURCE_DIR)
  set(EXTENSION_NAME EmptyExtensionTemplate)
  set(EXTENSION_HOMEPAGE "http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/EmptyExtensionTemplate")
  set(EXTENSION_CATEGORY "Examples")
  set(EXTENSION_CONTRIBUTORS "Jean-Christophe Fillion-Robin (Kitware)")
  set(EXTENSION_DESCRIPTION "This is an example of extension bundling N module(s)")
  set(EXTENSION_ICONURL "http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Extensions/Testing/EmptyExtensionTemplate/EmptyExtensionTemplate.png?revision=21746&view=co")
  set(EXTENSION_SCREENSHOTURLS "http://wiki.slicer.org/slicerWiki/images/4/42/Slicer-r19441-EmptyExtensionTemplate-screenshot.png")
endif()

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

add_subdirectory(ModuleA)

if(NOT Slicer_SOURCE_DIR)
  include(${Slicer_EXTENSION_CPACK})
endif()

After:

cmake_minimum_required(VERSION 2.8.9)

find_package(Slicer COMPONENTS ConfigurePrerequisites)

project(EmptyExtensionTemplate)

set(EXTENSION_HOMEPAGE "http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/EmptyExtensionTemplate")
set(EXTENSION_CATEGORY "Examples")
set(EXTENSION_CONTRIBUTORS "Jean-Christophe Fillion-Robin (Kitware)")
set(EXTENSION_DESCRIPTION "This is an example of empty extension")
set(EXTENSION_ICONURL "http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Extensions/Testing/EmptyExtensionTemplate/EmptyExtensionTemplate.png?revision=21746&view=co")
set(EXTENSION_SCREENSHOTURLS "http://wiki.slicer.org/slicerWiki/images/4/42/Slicer-r19441-EmptyExtensionTemplate-screenshot.png")

find_package(Slicer REQUIRED)
include(${Slicer_USE_FILE})

add_subdirectory(ModuleA)

include(${Slicer_EXTENSION_CPACK})

Why is the --contribute option is not available with the ExtensionWizard ?

Wizard contribute option is available only (1) if Slicer is built with OpenSSL support or (2) directly from the nightly.

To build Slicer with SSL support, you need to build (or download) Qt with SSL support and configure Slicer with -DSlicer_USE_PYTHONQT_WITH_OPENSSL:BOOL=ON

How dependent extensions are configured and built ?

If an ExtensionB depends on an ExtensionA, ExtensionA should be listed as dependency in the metadata of ExtensionB.

This can be done setting EXTENSION_DEPENDS in the CMakeLists.txt or by specifying depends field in the description file.

Doing so will ensure:

  • (1) the extension build system configure the extensions in the right order
  • (2) configure ExtensionB passing the ExtensionA_DIR option.