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

From Slicer Wiki
Jump to: navigation, search
(Moved to readthedocs)
Tags: 2017 source edit, Replaced
 
Line 1: Line 1:
 
<noinclude>{{documentation/versioncheck}}</noinclude>
 
<noinclude>{{documentation/versioncheck}}</noinclude>
<noinclude>__TOC__
 
={{#titleparts: {{PAGENAME}} | | -1 }}=
 
</noinclude><includeonly>
 
='''Developer FAQ: {{{1}}}'''=
 
</includeonly>
 
  
{{:Documentation/{{documentation/version}}/FAQ/Extensions}}
+
{{documentation/banner
 
+
| text  = [https://slicer.readthedocs.io/en/latest/developer_guide/extensions.html#frequently-asked-questions This page has been moved to read-the-docs.]
==What is an extension description file ?==
+
| background-color = 8FBC8F }}
 
 
See [[Documentation/{{documentation/version}}/Developers/Extensions/DescriptionFile|Description file description]]
 
 
 
==Can an extension contain different types of modules ?==
 
 
 
Yes. Extensions are used to package together all types of Slicer modules.
 
 
 
See also [[Documentation/{{documentation/version}}/Developers/FAQ#What_is_an_extension_.3F|What_is_an_extension ?]]
 
 
 
==Should the name of the source repository match the name of the extension ?==
 
 
 
Assuming your extension is named <code>AwesomeFilter</code>, generally, we suggest to name the extension repository <code>SlicerAwesomeFilter</code>. Note that the following variations are also possible <code>Slicer-AwesomeFilter</code>, <code>Slicer_AwesomeFilter</code>, <code>SlicerExtension-AwesomeFilter</code>, <code>SlicerExtension_AwesomeFilter</code>.
 
 
 
We suggest you keep the Slicer prefix in the extension name when the extension is a Slicer interface to some third-party library (SlicerOpenIGTLink, SlicerElastix, SlicerOpenCV, …).
 
 
 
Doing so will minimize confusion by clearly stating that the code base is associated with Slicer.
 
 
 
==What is the Extensions Index ?==
 
 
 
{{:Documentation/{{documentation/version}}/Developers/Extensions/Index}}
 
 
 
==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 ?==
 
{{:Documentation/{{documentation/version}}/Developers/Tutorials/ObtainExtensionServerApiKey}}
 
 
 
==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, <code>MIDAS_PACKAGE_EMAIL</code> and <code>MIDAS_PACKAGE_API_KEY</code>, you would simply need to configure your extension using:
 
 
 
{{pre2|<nowiki>
 
cd MyExtension-build
 
cmake -DCMAKE_BUILD_TYPE:STRING=Release -DSlicer_DIR:PATH=/path/to/Slicer-Superbuild/Slicer-build ../MyExtension
 
make ExperimentalUpload
 
</nowiki>}}
 
 
 
[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 [[Documentation/{{documentation/version}}/Developers/ExtensionWizard|Extension Wizard]], you could easily create a new extension without having to copy, rename and update manually every files.
 
 
 
==How to build an extension ?==
 
 
 
'''Note: to build C++ extensions you need to have built Slicer from source on your machine; they cannot be built against a binary download.'''
 
 
 
Assuming that the source code of your extension is located in folder <code>MyExtension</code>, this could be achieved doing:
 
 
 
{| width="100%"
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Linux or MacOSX (Makefile)
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Windows (Visual Studio)
 
|-
 
| valign="top" |
 
Start a terminal.
 
{{pre2|<nowiki>
 
$ mkdir MyExtension-build
 
$ cd MyExtension-build
 
$ cmake -DCMAKE_BUILD_TYPE:STRING=Release -DSlicer_DIR:PATH=/path/to/Slicer-Superbuild/Slicer-build ../MyExtension
 
$ make</nowiki>
 
}}
 
 
 
'''MaxOSX''': Extension '''must be configured''' specifying <code>CMAKE_OSX_*</code> variables matching the one used to configure Slicer:
 
 
 
*<code>-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64</code>
 
*<code>-DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=/same/as/Slicer</code>
 
*<code>-DCMAKE_OSX_SYSROOT:PATH=SameAsSlicer</code>
 
 
 
| valign="top" |
 
Run ''CMake (cmake-gui)'' from the Windows Start menu.
 
<ol start="1" style="list-style-type: decimal;">
 
<li>Select source and build directory</li>
 
<li>Add <code>Slicer_DIR</code> entry to the cache</li>
 
<li>Click on <code>Configure</code>, select generator, then click on <code>Generate</code> button.</li>
 
</ol>
 
 
 
Start Windows Explorer. [http://www.wikihow.com/Open-Windows-Explorer Need help?]
 
<ol>
 
<li>Open <code>MyExtension.sln</code> in Visual Studio</li>
 
<li>Select '''Release''' build configuration.</li>
 
<li>Select menu <code>Project -> Build Solution</code></li>
 
</ol>
 
|}
 
 
 
==Is there a way to automatically set CMAKE_OSX_* variables ?==
 
 
 
Within your extension, including the <code>ConfigurePrerequisites</code> component before the project statement should ensure it uses the same CMAKE_OSX_* variables as Slicer:
 
 
 
<pre>
 
find_package(Slicer COMPONENTS ConfigurePrerequisites REQUIRED)
 
 
 
project(Foo)
 
 
 
[...]
 
 
 
find_package(Slicer REQUIRED)
 
include(${Slicer_USE_FILE})
 
 
 
[...]
 
</pre>
 
 
 
Note: The <code>ConfigurePrerequisites</code> component should be considered experimental and could change without notice.
 
 
 
For more details, see [https://github.com/Slicer/Slicer/blob/75fc96bf05e65659eb5204f47b5205442cc6fd8e/CMake/SlicerConfig.cmake.in#L10-L38 here].
 
 
 
==How to run extension tests ?==
 
 
 
Assuming your extension has been built into folder <code>MyExtension-build</code>, this could be achieved doing:
 
 
 
{| width="100%"
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Linux or MacOSX (Makefile)
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Windows (Visual Studio)
 
|-
 
| valign="top" |
 
Start a terminal.
 
{{pre2|<nowiki>
 
$ ctest -j<NUMBEROFCORES>
 
</nowiki>
 
}}
 
 
 
| valign="top" |
 
To run all tests, start Windows Explorer. [http://www.wikihow.com/Open-Windows-Explorer Need help?]
 
<ol start="1" style="list-style-type: decimal;">
 
<li>Open <code>MyExtension.sln</code> in Visual Studio</li>
 
<li>Select <code>RUN_TESTS</code> project, then right click and select <code>Build</code></li>
 
</ol>
 
<br />
 
 
 
To run test individually, open  Command Line Prompt. [http://windows.microsoft.com/en-us/windows/command-prompt-faq Need help?]
 
{{pre2|<nowiki>
 
> cd C:\path\to\MyExtension-build
 
> ctest -R NameOfTest -V
 
</nowiki>
 
}}
 
<br />
 
 
 
To debug individual tests.
 
<ol start="1" style="list-style-type: decimal;">
 
<li>Launch Visual Studio from the Command Line Prompt: <code>C:\path\to\Slicer-build\Slicer.exe --VisualStudio --launcher-no-splash --launcher-additional-settings C:\path\to\MyExtension-build\AdditionalLauncherSettings.ini C:\path\to\MyExtension-build\MyExtension.sln</code></li>
 
<li>Find the project of the test you want to debug (e.g. ''qSlicerMODULE_NAMEModuleGenericCxxTests'').</li>
 
<li>Go to the project debugging properties (right-click -> Properties, then Configuration Properties / Debugging).</li>
 
<li>In ''Command Arguments'', type the name of the test you want to run (e.g. ''qSlicerMODULE_NAMEModuleGenericTest'').</li>
 
<li>If the test takes arguments, enter the arguments after the test name in ''Command Arguments''.</li>
 
<li>Set the project as the StartUp Project (right-click -> Set As StartUp Project).</li>
 
<li>Start debugging (F5).</li>
 
</ol>
 
<br />
 
 
 
|}
 
 
 
==How to package an extension ?==
 
 
 
Assuming your extension has been built into folder <code>MyExtension-build</code>, this could be achieved doing:
 
 
 
{| width="100%"
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Linux or MacOSX (Makefile)
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Windows (Visual Studio)
 
|-
 
| valign="top" |
 
Start a terminal.
 
{{pre2|<nowiki>
 
$ make package
 
</nowiki>
 
}}
 
 
 
| valign="top" |
 
Start Windows Explorer. [http://www.wikihow.com/Open-Windows-Explorer Need help?]
 
<ol start="1" style="list-style-type: decimal;">
 
<li>Open <code>MyExtension.sln</code></li> in Visual Studio
 
<li>Select <code>PACKAGES</code> project, then right click and select <code>Build</code></li>
 
</ol>
 
|}
 
 
 
==How are Superbuild extension packaged ?==
 
 
 
Extensions using the Superbuild mechanism build projects in two steps:
 
 
 
*First, the project dependencies are built in an outer-build directory.
 
*Then, the project itself is built in an inner-build directory
 
 
 
Extensions can use the Superbuild mechanism. However, developers have to be careful that the packaging macros clean the project before reconfiguring it. This means that if ones uses the Slicer extension packaging macros inside the inner-build directory, when packaging and uploading the extension package, the project will be reconfigured, and variables passed from the outer-build directory will be lost. If the project only depends on libraries that Slicer builds, this is not an issue. If the project has specific dependencies that Slicer does not compile on its own, the developer should be careful to instantiate the Slicer extension packaging macros only in the outer-build directory. This only means that in the latter case, tests should be instantiated in the outer-build directory to allow the Slicer extension building process to test the extension before uploading the extension and the tests results.
 
 
 
==How to upload an extension ?==
 
 
 
{{remark|red|{{:Documentation/{{documentation/version}}/Developers/Tutorials/BuildTestPackageDistributeExtensions/ExperimentalFolderAccess}} }}
 
 
 
Assuming your extension has been built and packaged into folder <code>MyExtension-build</code>, this could be achieved by first re-configuring the project providing your [[#How_to_obtain_an_API_key_to_submit_on_the_extension_server_.3F|midas credentials]] and then building the <code>packageupload</code> target:
 
 
 
{| width="100%"
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Linux or MacOSX (Makefile)
 
! width="50%" style="border-bottom: 1px solid darkgrey;font-size: 75%;" |Windows (Visual Studio)
 
|-
 
| valign="top" |
 
Start a terminal.
 
{{pre2|<nowiki>
 
$ cmake -DMIDAS_PACKAGE_EMAIL:STRING=<YOUR-MIDAS-LOGIN> -DMIDAS_PACKAGE_API_KEY:STRING=<YOUR-MIDAS-APIKEY> .
 
$ make packageupload
 
</nowiki>
 
}}
 
 
 
| valign="top" |
 
Run ''CMake (cmake-gui)'' from the Windows Start menu.
 
<ol start="1" style="list-style-type: decimal;">
 
<li>Select source and build directory</li>
 
<li>Add <code>MIDAS_PACKAGE_EMAIL</code> and <code>MIDAS_PACKAGE_API_KEY</code> entries to the cache</li>
 
</ol>
 
 
 
Start Windows Explorer. [http://www.wikihow.com/Open-Windows-Explorer Need help?]
 
<ol>
 
<li>Open <code>MyExtension.sln</code></li> in Visual Studio
 
<li>Select <code>Release</code> configuration</li>
 
<li>Select <code>packageupload</code> project, then right click and select <code>Build</code></li>
 
</ol>
 
|}
 
 
 
Alternatively, you could also [[#How_to_cache_API_credentials_.3F|cache your API credentials]].
 
 
 
==How to build Slicer bundling extensions ?==
 
 
 
Configuring Slicer specifying option <tt>EXTENSION_SOURCE_DIRS</tt> as a list of extension source directories will do it. Multiple extension source paths need to be separated using semicolons.
 
 
 
Note that Superbuild-type extensions expected to be bundled have to be updated to explicitly list Slicer dependencies. More specifically, the <tt>External_*.cmake</tt> files that were implicitly depending on project built by Slicer have to be updated.
 
 
 
For example, the file [https://github.com/KitwareMedical/SlicerVirtualReality/blob/master/SuperBuild/External_VTKRenderingOpenVR.cmake <tt>External_VTKRenderingOpenVR.cmake</tt>] available in the [https://github.com/KitwareMedical/SlicerVirtualReality <tt>SlicerVirtualReality</tt>] extension was updated to append <tt>VTKv9</tt> to the list of dependencies if bundled in Slicer:
 
 
 
<pre>
 
[...]
 
   
 
set(${proj}_DEPENDENCIES OpenVR)
 
if(DEFINED Slicer_SOURCE_DIR)
 
  list(APPEND ${proj}_DEPENDENCIES VTKv9)
 
endif()
 
   
 
[...]
 
</pre>
 
 
 
==Can an extension depend on other extensions ?==
 
 
 
Yes. An <code>ExtensionFoo</code> can depend on <code>ExtensionBar</code>
 
 
 
The dependency should be specified as a list by setting the variable <code>EXTENSION_DEPENDS</code> in the extension <code>CMakeLists.txt</code>.
 
 
 
For example, if you have <code>ModuleA</code>, <code>ModuleB</code> and <code>ModuleC</code> and <code>ModuleA</code> can be used as standalone one. You could create the following extensions:
 
 
 
*<code>Extension1</code> containing  <code>ModuleA</code>
 
*<code>Extension2</code> containing  <code>ModuleB</code> and <code>ModuleC</code>
 
 
 
and add the following variable to <code>Extension2/CMakeLists.txt</code>:
 
<pre>
 
set(EXTENSION_DEPENDS Extension1)
 
</pre>
 
 
 
'''User''':
 
 
 
*If user installs <code>Extension2</code>, <code>Extension1</code> will automatically be installed first.
 
 
 
'''Developer''':
 
 
 
*The generated extension description file have a <code>depends</code> field. See [[Documentation/{{documentation/version}}/Developers/Extensions/DescriptionFile|here]] for details.
 
*The extension framework will build the extension in order. When building <code>Extension2</code>, it will pass the CMake option <code>-DExtension1_DIR:PATH=/path/to/Extension1-build</code>.
 
 
 
==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.
 
 
 
<table class="alternate">
 
  <tr>
 
    <th>Target name</th>
 
    <th>Description</th>
 
  </tr>
 
  <tr>
 
    <td><code>test</code> or <code>BUILD_TESTS</code></td>
 
    <td>Locally execute the test</td>
 
  </tr>
 
  <tr>
 
    <td><code>package</code> or <code>PACKAGE</code></td>
 
    <td>Locally package the extension</td>
 
  </tr>
 
  <tr>
 
    <td><code>packageupload</code></td>
 
    <td>Locally package and upload the extension</td>
 
  </tr>
 
  <tr>
 
    <td><code>Experimental</code></td>
 
    <td>Configure, build, test the extension and publish result on CDash.</td>
 
  </tr>
 
  <tr>
 
    <td><code><s>ExperimentalUpload</s></code></td>
 
    <td><s>Equivalent to Experimental target followed by packaging and upload of the extension on the extension server.</s> Not available anymore. Removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26271 r26271]</td>
 
  </tr>
 
  <tr>
 
    <td><code><s>ExperimentalUploadOnly</s></code></td>
 
    <td><s>Only proceed to the upload of the extension on the extension server.</s>. Not available anymore. Superseded by <code>packageupload</code>. Removed in [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=26271 r26271]</td>
 
  </tr>
 
</table>
 
 
 
==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 <code>Slicer.app</code> is created. As explained [http://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFBundles/Introduction/Introduction.html 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 [http://www.cmake.org/cmake/help/v2.8.8/cmake.html#module:BundleUtilities BundleUtilities] module.
 
 
 
This module is used in two situations:
 
 
 
#Fixup of Slicer application itself. See [https://github.com/Slicer/Slicer/blob/master/CMake/SlicerCPack.cmake#L36-68 SlicerCPack.cmake#L36-68] and [https://github.com/Slicer/Slicer/blob/master/CMake/SlicerCPackBundleFixup.cmake.in SlicerCPackBundleFixup.cmake.in]
 
#Fixup of an extension package. See [https://github.com/Slicer/Slicer/blob/master/CMake/SlicerExtensionCPack.cmake#L126-143 SlicerExtensionCPack.cmake#L126-143] and [https://github.com/Slicer/Slicer/blob/master/CMake/SlicerExtensionCPackBundleFixup.cmake.in 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 <code>Documentation/Nightly/Modules</code>
 
*All extension documentation pages should be located under <code>Documentation/Nightly/Extensions</code>
 
 
 
 
 
For example, if an an extension named <code>DoSomethingGreat</code> bundles three modules <code>ModuleA</code>, <code>ModuleB</code> and <code>ModuleC</code>. The following pages should be created:
 
 
 
*<code>Documentation/Nightly/Extensions/DoSomethingGreat</code>
 
*<code>Documentation/Nightly/Modules/ModuleA</code>
 
*<code>Documentation/Nightly/Modules/ModuleB</code>
 
*<code>Documentation/Nightly/Modules/ModuleC</code>
 
 
 
 
 
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 <code>DoSomethingAwesome</code>, the associated module is expected to be named <code>DoSomethingAwesome</code>. The following pages will then be created:
 
 
 
*<code>Documentation/Nightly/Extensions/DoSomethingAwesome</code>
 
*<code>Documentation/Nightly/Modules/DoSomethingAwesome</code>
 
 
 
where page <code>Extensions/DoSomethingAwesome</code> redirect to page <code>Modules/DoSomethingAwesome</code>.
 
 
 
 
 
To setup a redirection, simply add the following text to page <code>Extensions/DoSomethingAwesome</code>:
 
<pre>
 
#REDIRECT [[Documentation/Nightly/Modules/DoSomethingAwesome]]
 
</pre>
 
For an example, see [http://www.slicer.org/slicerWiki/index.php?title=Documentation/Nightly/Extensions/SkullStripper&action=edit 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 <code>Nightly</code> documentation namespace. The corresponding URL should be associated with the <code>EXTENSION_HOMEPAGE</code> metadata.
 
 
 
For example:
 
 
 
*<code><nowiki>set(EXTENSION_HOMEPAGE "https://www.slicer.org/wiki/Documentation/Nightly/Extensions/DoSomethingGreat")</nowiki></code>* <code><nowiki>set(EXTENSION_HOMEPAGE "https://www.slicer.org/wiki/Documentation/Nightly/Extensions/DoSomethingAwesome")</nowiki></code> 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: https://www.slicer.org/wiki/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 [http://www.mediawiki.org/wiki/Help:Redirects #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:
 
<pre>
 
<ExtensionName>_BUILD_SLICER_EXTENSION
 
</pre>
 
 
 
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 [[Documentation/{{documentation/version}}/Developers/Extensions/Server|extensions server]] every day.
 
 
 
To be more specific, the frequency of extensions build and upload associated with:
 
 
 
*Slicer nightly package occurs '''every night''' <s>and also '''continuously''' during the day</s>.
 
*Slicer {{documentation/currentversion}} lastest stable release package occurs '''every night'''.
 
 
 
All extensions associated can be expected by mid-morning. Checking the dashboard will give a definite answer. Check [[Documentation/Nightly/Developers/Tutorials/BuildTestPackageDistributeExtensions#Continuous_Integration|this page]] to learn how to easily get the status of any given extension.
 
 
 
==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 [[Documentation/{{documentation/version}}/Developers/Extensions/Server|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. [https://help.github.com/articles/which-remote-url-should-i-use#cloning-with-ssh Need help ?]
 
 
 
3) Associate the remote URL with your local git source tree
 
 
 
<pre>
 
git remote add origin git://github.com/<username>/MyExtension
 
</pre>
 
 
 
==Which remote name is expected for extension git checkout ?==
 
 
 
When packaging an extension and generating the associated [[Documentation/{{documentation/version}}/Developers/Extensions/DescriptionFile|description file]], the system will look for a remote named <code>origin</code>.
 
 
 
In case you get the error reported below, you will have to either rename or add a remote. [http://git-scm.com/book/en/Git-Basics-Working-with-Remotes Need help ?]
 
 
 
<pre>
 
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)
 
</pre>
 
 
 
==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 [[Documentation/{{documentation/version}}/Developers/Tutorials/Contribute_Extension_Description_File|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 [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=22038 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 [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=22063 r22063], protecting call to <code>find_package(Slicer)</code> with <code>if(NOT Slicer_SOURCE_DIR)</code>
 
is optional and should be removed to keep code simpler and easier to maintain.
 
 
 
Before:
 
 
 
{{pre2|<nowiki>
 
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 "https://www.slicer.org/wiki/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://www.slicer.org/w/img_auth.php/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()
 
</nowiki>}}
 
 
 
After:
 
 
 
{{pre2|<nowiki>
 
cmake_minimum_required(VERSION 2.8.9)
 
 
 
find_package(Slicer COMPONENTS ConfigurePrerequisites)
 
 
 
project(EmptyExtensionTemplate)
 
 
 
set(EXTENSION_HOMEPAGE "https://www.slicer.org/wiki/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://www.slicer.org/w/img_auth.php/4/42/Slicer-r19441-EmptyExtensionTemplate-screenshot.png")
 
 
 
find_package(Slicer REQUIRED)
 
include(${Slicer_USE_FILE})
 
 
 
add_subdirectory(ModuleA)
 
 
 
include(${Slicer_EXTENSION_CPACK})
 
</nowiki>}}
 
 
 
==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 <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 that:
 
 
 
*(1) the extension build system configure the extensions in the right order
 
*(2) ExtensionB is configured with option <code>ExtensionA_DIR</code>.
 
 
 
==How to package third party libraries ?==
 
 
 
Extensions integrating third party libraries should follow the [https://github.com/Slicer/Slicer/tree/master/Utilities/Templates/Extensions/SuperBuild SuperBuild extension template].
 
 
 
Each third party libraries will be configured and built using a dedicated <code>External_MyLib.cmake</code> file, the install location of binaries and libraries should be set to <code>Slicer_INSTALL_BIN_DIR</code> and <code>Slicer_INSTALL_LIB_DIR</code>.
 
 
 
Also, starting with [http://viewvc.slicer.org/viewvc.cgi/Slicer4?view=revision&revision=25959 r25959], extension can package python modules and packages using <code>PYTHON_SITE_PACKAGES_SUBDIR</code> CMake variable to specify the install destination.
 
 
 
These relative paths are the one that the extensions manager will consider when generating the launcher and application settings for a given extension.
 
 
 
==Can I use C++11/14/17 language features ?==
 
 
 
We try to balance between compatibility and using new features. As a result, currently C++11 features are allowed, but usage of C++14/17 language features are discouraged in extensions (relying on C++14/17 features may lead to build errors on some build configurations).
 
 
 
If your extension can be compiled as a standalone project where you would like to use newer feature, you could rely on CMake detecting compile features. See [https://cmake.org/cmake/help/v3.5/manual/cmake-compile-features.7.html cmake-compile-features] for more details.
 
 
 
See the labs topic on [https://www.slicer.org/wiki/Documentation/Labs/UpgradingCompilerInfrastructure upgrading compiler infrastructure] for additional information/status.
 
 
 
==How do I publish a paper about my extension ?==
 
 
 
Consider publishing a paper describing your extension.  This link contains a list of journals that publish papers about software:
 
 
 
http://www.software.ac.uk/resources/guides/which-journals-should-i-publish-my-software
 
 
 
==How to force a different Slicer revision for downloading different extension ?==
 
 
 
Since extensions available from the [[Documentation/{{documentation/currentversion}}/SlicerApplication/ExtensionsManager|Extensions Manager]] are associated with a particular slicer revision, for testing purpose it is practical to override the current revision. This can be done by explicitly setting a revision number.
 
 
 
<pre>
 
>>> extensionManagerModel = slicer.app.extensionsManagerModel()
 
>>> extensionManagerModel.slicerRevision = "25742"
 
</pre>
 
 
 
On other approach is to re-configure Slicer setting the <tt>Slicer_FORCED_WC_REVISION</tt> option.
 
 
 
==How to address ITK test driver caught an ITK exception "Could not create IO object for reading file" ?==
 
 
 
If the following execption is reported when trying to run tests associated with a CLI modules:
 
 
 
<pre>
 
ITK test driver caught an ITK exception:
 
 
itk::ImageFileReaderException (0x1bd8430)
 
Location: "unknown"
 
File: /path/to/Slicer-SuperBuild/ITK/Modules/IO/ImageBase/include/itkImageFileReader.hxx
 
Line: 139
 
Description:  Could not create IO object for reading file /path/to/image.nrrd
 
  Tried to create one of the following:
 
    MRMLIDImageIO
 
  You probably failed to set a file suffix, or
 
    set the suffix to an unsupported type.
 
</pre>
 
 
 
It most likely means that the test driver is not linking against <tt>ITKFactoryRegistration</tt> library and/or registrering the ITK factories. To address this, the test driver should be updated:
 
 
 
*(1) to link against <tt>${SlicerExecutionModel_EXTRA_EXECUTABLE_TARGET_LIBRARIES}</tt>
 
*(2) to include <tt>itkFactoryRegistration.h</tt>
 
*(3) to call <tt>itk::itkFactoryRegistration();</tt> in its main function
 
 
 
For more details, read [[Documentation/Nightly/Developers/FAQ#What_is_the_ITKFactoryRegistration_library_.3F|What is the ITKFactoryRegistration library ?]]
 

Latest revision as of 05:54, 2 September 2021

Home < Documentation < Nightly < Developers < FAQ < Extensions