How to write a remote module

From OTBWiki
Jump to: navigation, search

A list of existing remote modules is maintained here: https://www.orfeo-toolbox.org/external-projects/

Components of a module

The otb-module.cmake file

This file is mandatory. It follows the CMake syntax, and has two purposes:

  • Declare dependencies to other modules,
  • Provide a short description of the module purpose.

These purposes are fulfilled by a single CMake Macro call:

otb_module(TheModuleName DEPENDS OTBModule1 OTBModule2 ... OTBModuleN DESCRIPTION "A description string")

Notes: You can use the TEST_DEPENDS keyword to declare module dependencies that only applies to the tests.

The CMakeLists.txt file

The CMakeLists.txt file is mandatory. It contains only a few things.

First, it declares a new CMake project with the name of the module.

project(TheModuleName)

Second, if the module contain a library (see src folder section bellow), it initializes the TheModuleName_LIBRARIES CMake variable (if your module only contains headers or template code, skip this line):

set(TheModuleName_LIBRARIES OTBTheModuleName)

You can build your remote module inside or outside the OTB source tree. The configuration below will handle both cases and take care of all the CMake plumbing of the module:

 if(NOT OTB_SOURCE_DIR)
   find_package(OTB REQUIRED)
   list(APPEND CMAKE_MODULE_PATH ${OTB_CMAKE_DIR})
   include(OTBModuleExternal)
 else()
   otb_module_impl()
 endif()


The overall file should look like this:

 cmake_minimum_required(VERSION 2.8.9)
 project(TheModuleName)
 set(ExternalTemplate_LIBRARIES OTBTheModuleName)
 if(NOT OTB_SOURCE_DIR)
   find_package(OTB REQUIRED)
   list(APPEND CMAKE_MODULE_PATH ${OTB_CMAKE_DIR})
   include(OTBModuleExternal)
 else()
   otb_module_impl()
 endif()

The include folder

The include folder will contain all your headers (*.h files) and template method boy files (*.txx or *.hxx). It does not require any additional file (in particular, no CMakeLists.txt file is required).

The src folder

The src folder contains the internal implementation of your module :

  • It typically contains cxx source files that will be compiled into a library.
  • It can contain header files for classes used only within the implementation files of your module. Any header file present in the src folder will not be installed, and will not be available to other modules depending on your module.

If your modules is made of template only code, you do not need a src folder at all.

If present, the src folder requires a CMakeLists.txt file.


The first part of the CMakeLists.txt file is classical, as it builds the library and links it:

set(OTBTheModuleName_SRC
    sourceFile1.cxx
    sourceFile2.cxx
    sourceFile3.cxx
    ...
    sourceFileN.cxx)

add_library(OTBTheModuleName ${OTBTheModuleName_SRC})

target_link_libraries(OTBTheModuleName ${OTBModule1_LIBRARIES} ${OTBModule2_LIBRARIES} ... ${OTBModuleN_LIBRARIES})

Notes:

  • Library name should match the one declared in the root CMakeLists.txt when setting CMake variable TheModuleName_LIBRARIES,
  • Linked libraries should match the dependencies of your module declared in the root otb-module.cmake file.

The last line of CMake code takes care of installation instructions:

otb_module_target(OTBTheModuleName)

The overall CMakeLists.txt file should look like:

set(OTBTheModuleName_SRC
    sourceFile1.cxx
    sourceFile2.cxx
    sourceFile3.cxx
    ...
    sourceFileN.cxx)

add_library(OTBTheModuleName ${OTBTheModuleName_SRC})

target_link_libraries(OTBTheModuleName ${OTBModule1_LIBRARIES} ${OTBModule2_LIBRARIES} ... ${OTBModuleN_LIBRARIES})

otb_module_target(OTBTheModuleName)

The app folder

The app folder contains the code of applications shipped with your module. If your module has no application, you do not need the app folder.

Notes: If your module contains application (and an app folder), do not forget to add the ApplicationEngine in the dependencies listed in the otb-module.cmake file.

In addition to the applications source code, the app folder should contain a CMakeLists.txt file as follows.

For each application, a single call otb_create_application is required:

otb_create_application(
 NAME           TheModuleApplication1
 SOURCES        TheModuleApplication1.cxx
 LINK_LIBRARIES ${OTBModule1_LIBRARIES} ${OTBModule2_LIBRARIES} ... ${OTBModuleN_LIBRARIES})

The test folder

This folder contains tests of the module. If your module has no test in it (which is not recommended, you do not need it).

The test folder should contain the source files of tests, as well as a CMakeLists.txt file. This file will contain the following.

First, indicate that this folder contains tests.

otb_module_test()

Then, build the test driver:

set(OTBTheModuleNameTests
    testFile1.cxx
    testFile2.cxx
    ...
    testFileN.cxx)

add_executable(otbTheModuleNameTestDriver ${OTBTheModuleNameTests})

target_link_libraries(otbTheModuleNameTestDriver ${OTBTheModuleName-Test_LIBRARIES})
 
otb_module_target_label(otbTheModuleNameTestDriver)

Finally, you can add your tests:

otb_add_test(NAME nameOfTheTest COMMAND otbTheModuleNameTestDriver
             --compare-image ${EPSILON_8} ... # baseline comparison if needed
             nameOfTheTestFunction
             testParameters)

If your module contains one or more application in the app folder, you should also write tests for them, in the test folder. Running an application test is easily done with the helper macro otb_test_application:

 otb_test_application(NAME   nameofApplication1Test1
                      APP  TheModuleApplication1
                      OPTIONS -in1 ${INPUTDATA}/input1.tif
                              -in2 ${INPUTDATA}/input2.tif
                              -out ${TEMP}/nameofApplication1Test1_result.tif
                      VALID   --compare-image ${EPSILON_8}
                              ${BASELINE}/nameofApplication1Test1_result.tif
                              ${TEMP}/nameofApplication1Test1_result.tif)

ToDo: Add instructions for test naming and input/baseline data inclusion.

You overall CMakeLists.txt file should look like:

otb_module_test()

set(OTBTheModuleNameTests
    testFile1.cxx
    testFile2.cxx
    ...
    testFileN.cxx)

add_executable(otbTheModuleNameTestDriver ${OTBTheModuleNameTests})

target_link_libraries(otbTheModuleNameTestDriver ${OTBTheModuleName-Test_LIBRARIES})
 
otb_module_target_label(otbTheModuleNameTestDriver)

otb_add_test(NAME nameOfTheTest COMMAND otbTheModuleNameTestDriver
             --compare-image ${EPSILON_8} ... # baseline comparison if needed
             nameOfTheTestFunction
             testParameters)

Including a remote module in OTB

Local build of a remote module

To build your new remote module, simply copy the folder containing the module component to Modules/Remote, then run CMake configuration. you should see a new CMake option named MODULE_TheModuleName. Simply turn this option to ON, and finish CMake configuration. Your module will be built with the rest of the OTB project.

Sharing your remote module

To make your remote module available to others when building OTB, you should provide a CMake file name TheModuleName.remote.cmake file for inclusion in the Modules/Remote folder in OTB source tree.

This file should contain the following:

#Contact: Author name <author email adress>

otb_fetch_module(TheModuleName
  "A description of the module, to appear during CMake configuration step"
  GIT_REPOSITORY http_link_to_a_git_repository_hosting_the_module
  GIT_TAG the_git_revision_to_checkout
  )

This file should be provided along with your remote module inclusion proposal email to the otb-developers list. Please refer to the contributors guidelines for more information.

Advanced remote modules

Handling new third parties in remote modules

To be done.