Commit f8a8202d authored by fw4splbot's avatar fw4splbot
Browse files

merge(dev): release 16.1.0

parents af12c235 f90ba330
****************************
How to use CMake with Fw4spl
****************************
.. toctree::
:maxdepth: 2
src/introduction
src/Cmake_Tutorials
Tutorials
==========
How can I add a new dependency
------------------------------
You may want to add a new dependency into fw4spl-deps or you may want to add your own folder of dependencies.
.. tip::
You need to know that the main CMakeLists.txt is in fw4spl-deps, and you can add as many additional folders as you want.
Use the *ADDITONNAL_DEPS* option in cmake to set the path of your custom deps.
Add a new deps in fw4spl-deps
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Adding a new deps is quite easy, the only things to do is to add a new folder *myNewDeps* and put a CMakeLists.txt file into it.
The CMakeLists.txt should contain at least:
- cmake_minimum_required()
- project()
- include(ExternalProject)
- ExternalProject_Add(...)
For example:
.. code:: cmake
cmake_minimum_required(VERSION 2.8)
project(myDepsBuilder)
include(ExternalProject)
getCachedUrl(http://myDeps.com/myDeps.zip CACHED_URL)
ExternalProject_Add(
myDeps
URL ${CACHED_URL}
DOWNLOAD_DIR Path/To/Your/Download/dir
PATCH_COMMAND your_patch_command (optional)
CONFIGURE_COMMAND your_configure_command (optional)
BUILD_COMMAND your_build_command (optional)
INSTALL_COMMAND your_install_command (optional)
INSTALL_DIR your_install_dir
CMAKE_ARGS cmake_arguments
)
Add a custom deps repository
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You may want to add your own folder of dependencies (as fw4spl-ext-deps or fw4spl-ar-deps).
In this case your main need to create a CMakeLists.txt in the root of your folder (myDepsFolder/CMakeLists.txt) in order to list the subdirectories of your deps.
.. code:: cmake
cmake_minimum_required(VERSION 2.8)
project(CustomDeps)
list(APPEND SUBDIRECTORIES myDeps1)
list(APPEND SUBDIRECTORIES myDeps2)
...
Then when you do a *ccmake* or *cmake-gui* in the build of your deps, you need to add the path to your custom repository in the *ADDITONNAL_DEPS* option.
Then cmake will automaticaly parsed your folder.
How can I add a custom bundle in fw4spl
----------------------------------------
You may want to add a new bundle/lib/app in an existing repository or you may want to add your custom repository to fw4spl.
.. tip::
You need to know that the main CMakeLists.txt is in fw4spl repository, and you can add as many additional repository as you want.
Use the *ADDITIONAL_PROJECTS* option in cmake to add path of your custom folders.
Add a new bundle/lib/app in fw4spl
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The only thing to do is to write a CMakeLists.txt and a Properties.cmake (see section Cmake for Fw4spl for more informations).
Add a custom repository to fw4spl
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
As the main CMakeLists.txt is in fw4spl repository,you need to add the path of your folder in *ADDITIONAL_PROJECTS* option when you launch *ccmake* of *cmake-gui* on the build folder of fw4spl.
Then your folder will automaticaly be parsed by cmake.
.. note::
All your bundle/lib/application need to respect the fw4spl-cmake conventions and have a CMakeLists.txt and a Properties.cmake.
CMake for fw4spl
================
Introduction
-------------
Fw4spl and it's dependencies are based on `CMake <http://www.cmake.org/>`_ .
Note that the minimal version of cmake to have is 3.1.
CMake files for dependencies
-----------------------------
fw4spl dependencies are based on the `ExternalProject <http://www.cmake.org/cmake/help/v3.0/module/ExternalProject.html>`_ concept from lastest versions of cmake.
The concept is to create custom targets to build projects in external trees.
Each project has custom steps for download, update/patch, configure, build and install.
Here is a simple example from camp :
.. code:: cmake
cmake_minimum_required(VERSION 2.8)
project(campBuilder)
include(ExternalProject)
set(CAMP_CMAKE_ARGS ${COMMON_CMAKE_ARGS}
-DBUILD_DOXYGEN:BOOL=OFF
-DBOOST_INCLUDEDIR:PATH=${CMAKE_INSTALL_PREFIX}/include/boost-1_57
)
getCachedUrl(https://github.com/greenjava/camp/archive/0.7.1.1.tar.gz CACHED_URL)
ExternalProject_Add(
camp
URL ${CACHED_URL}
DOWNLOAD_DIR ${ARCHIVE_DIR}
DEPENDS boost
INSTALL_DIR ${CMAKE_INSTALL_PREFIX}
CMAKE_ARGS ${CAMP_CMAKE_ARGS}
STEP_TARGETS CopyConfigFileToInstall
)
ExternalProject_Add_Step(camp CopyConfigFileToInstall
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/cmake/findBinpkgs/FindCAMP.cmake ${CMAKE_INSTALL_PREFIX}/FindCAMP.cmake
COMMENT "Install configuration file"
The important parts are in the *ExternalProject_Add* fonction:
- URL: is the download link of the sources
- DOWNLOAD_DIR: The folder where the sources will be stored (set globaly for all deps)
- DEPENDS: The dependencies of the current library (will be compiled before)
- INSTALL_DIR: The folder in which the library will be installed (set globaly for all deps)
- CMAKE_ARGS: CMake options for library which have a cmake build system
- STEP_TARGETS: Custom command (in this example it will copy a script in the install folder)
Note that in other script you can have much more options like:
- PATCH_COMMAND
- CONFIGURE_COMMAND
- BUILD_COMMAND
- INSTALL_COMMAND
Refer you to the documentation of `ExternalProject <http://www.cmake.org/cmake/help/v3.0/module/ExternalProject.html>`_ for more informations.
CMake files for fw4spl
-----------------------
Each project (apps, bundles, libs) have two "CMake" files:
- CMakeLists.txt
- Properties.cmake
The CMakeLists.txt file
^^^^^^^^^^^^^^^^^^^^^^^
The CMakeLists.txt should contain at least the function *fwLoadProperties()* to load the Properties.cmake.
But it can also contain others functions useful to link with external libraries.
Here is an example of CMakeLists.txt from guiQt Bundle :
.. code:: cmake
fwLoadProperties()
find_package(Qt5 COMPONENTS Core Gui Widgets REQUIRED)
fwForwardInclude(
${Qt5Core_INCLUDE_DIRS}
${Qt5Gui_INCLUDE_DIRS}
${Qt5Widgets_INCLUDE_DIRS}
)
fwLink(
${Qt5Core_LIBRARIES}
${Qt5Gui_LIBRARIES}
${Qt5Widgets_LIBRARIES}
)
set_target_properties(${FWPROJECT_NAME} PROPERTIES AUTOMOC TRUE)
The first line *fwLoadProperties()* will load the properties.cmake (see explanation in the next section).
The next lines are for the link with an external libraries (fw4spl-deps), in this example it is Qt.
The first thing to do is to call *find_package(The_lib COMPONENTS The_component)*.
The use *fwForwardInclude* to add includes directories to the target,
and *fwLink* to link the libraries with your target.
You can also add custom properties to your target with *set_target_properties*.
The Properties.cmake file
^^^^^^^^^^^^^^^^^^^^^^^^^
Properties.cmake should contain informations like name, version, dependencies and requirements of the current target.
Here is an example of Properties.cmake from fwData library:
.. code:: cmake
set( NAME fwData )
set( VERSION 0.1 )
set( TYPE LIBRARY )
set( DEPENDENCIES fwCamp fwCom fwCore fwMath fwMemory fwTools )
set( REQUIREMENTS )
- NAME: Name of the target
- VERSION: Version of the target
- TYPE: Type of the target (can be library, bundle or executable)
- DEPENDENCIES: Link the target with the given libraries (see `target_link_libraries <http://www.cmake.org/cmake/help/v3.0/command/target_link_libraries.html?highlight=target_link_libraries>`_ )
- REQUIREMENTS: Ensure that the depends are build before target (see `add_dependencies <http://www.cmake.org/cmake/help/v3.0/command/add_dependencies.html?highlight=add_dependencies>`_ )
......@@ -5,7 +5,7 @@ CMakeLists coding
Standard CMake functions and macros should be written in lower case. Each word is generally separated by an underscore (this is a rule of CMake anyway).
.. code-block :: cmake
.. code-block:: cmake
add_subdirectory("library/")
include_directories(SYSTEM "/usr/local")
......@@ -14,7 +14,7 @@ CMakeLists coding
Custom macros should be written in camel case.
.. code-block :: cmake
.. code-block:: cmake
fwLoadProperties()
fwLink("boost")
......@@ -23,7 +23,7 @@ CMakeLists coding
Variables should be written in upper case letters separated if needed by underscores.
.. code-block :: cmake
.. code-block:: cmake
set(VARIABLE_NAME "")
......@@ -31,7 +31,7 @@ CMakeLists coding
In the past, CMake enforced to specify the label or expression in block ending, for instance :
.. code-block :: cmake
.. code::
function(name arg1 arg2)
...
......@@ -45,7 +45,7 @@ CMakeLists coding
This is no longer needed in latest CMake versions, and we recommend to use this possibility for the sake of simplicity.
.. code-block :: cmake
.. code::
function(name arg1 arg2)
...
......@@ -56,4 +56,3 @@ CMakeLists coding
endif()
...
endfunction()
.. _Documentation:
Documentation
=============
.. rule :: Document the code
.. rule:: Document the code
The code must be documented with **Doxygen**, an automated tool to generate documentation.
.. rule :: Location of the documentation
.. rule:: Location of the documentation
Every documentation that can be useful to a user must be placed inside the header files. Thus a user of a module can
find the declaration of a class and its documentation at the same place. Inside the implementation file, the
......@@ -14,7 +16,7 @@ Documentation
Moreover, every documentation must be placed next to the entity it is refering to, in order to help searching inside
the code.
.. recommendation :: Lightweight documentation
.. recommendation:: Lightweight documentation
Inside a documentation block, only use necessary tags. This will avoid to overload the documentation and makes it
readable. By the way, empty tags will be presented inside the generated documentation and will be useless.
......@@ -79,15 +81,15 @@ Example 3 : Function documentation
std::string m_thing;
};
.. recommendation :: Structured documentation
.. recommendation:: Structured documentation
Doxygen provides a default structure when you generate the documentation. However, when dealing with a big
documented entity, it is often recommended to use the group feature (``@name``). With this feature you will build a
logical view of the class interfaces.
.. rule :: Document service
.. rule:: Document service
The service must be properly documented.
The service must be properly documented.
This should include first a brief description, then a long description if necessary.
......@@ -95,7 +97,7 @@ Example 3 : Function documentation
/**
* @brief This is the short description.
*
*
* This is the long description.
*
......@@ -103,22 +105,24 @@ Example 3 : Function documentation
.. code-block:: cpp
*
/**
* ...
* @section Signals Signals
* - \b signal2(::fwData::Mesh::sptr) : Emitted when the mesh has changed.
* - \b signal1(std::int64_t) : Emitted when ...
*
* @section Slots Slots
* - \b modified() : Modify the data.
*
*/
Last the xml configuration of the service must be described into a dedicated section.
Last the xml configuration of the service must be described into a dedicated section.
It should indicate first the input, input/outputs and outputs in three subsections. The type and the name of the data should appear along with a short description.
A fourth subsection describes the rest of the parameters, and tells if it they are optional or not.
.. code-block:: cpp
*
/**
* ...
* @section XML XML Configuration
*
* @code{.xml}
......@@ -144,5 +148,11 @@ Example 3 : Function documentation
*
*/
Please follow the template above as much as possible to keep the documentation as clear and homogeneous as possible.
**The XML documentation is important**, it is parsed to register properly the service.
The `Input`, `Output` and `InOut` sections must follow the defined format:
\\- \\b ``key_name`` [``object_type``]: ``description``
- *key_name*: the name of the key (used to retrieve the object in the service)
- *object_type*: class of the object with the full namespace (don't forget the ``::``)
- *description*: the purpose of this input/output
********************************
Frequently Asked Questions (FAQ)
********************************
What is fw4spl?
===============
......@@ -110,16 +107,17 @@ In this latter case, do you need to share this object between different services
- If the answer is yes, then you need create a new object like fwData::Image and a wrapping with fwData::Image<=>itk::Image and fwData::Image<=>vtkImage.
- Otherwise, you can just encapsulated an itk::Image in fwData::Image and create an accessor on it. ( however, this choice implies that all applications that use fwData::Image need ITK library for running. )
.. _campPath:
What is a sesh@ path ?
What is a camp path ?
======================
A **sesh@ path** is a path used to browse an object (and sub-object) using the introspection (see fwDataCamp and :ref:`Serialization`). The path begins
A **camp path** (also called sesh@ path) is a path used to browse an object (and sub-object) using the introspection (see fwDataCamp and :ref:`Serialization`). The path begins
with a '@' or a '!'.
- ``@`` : the returned string is the fwID of the sub-object defined by the path.
- ``!`` : the returned string is the value of the sub-object, it works only on String, Integer, Float and Boolean object.
Sadly, we do not have yet a document giving the paths for all existing data. To know how an object can be accessed with a sesh@ path, you canal
Sadly, we do not have yet a document giving the paths for all existing data. To know how an object can be accessed with a sesh@ path, you can
have a look at the corresponding fwDataCamp implementation of the object. For instance, the file *fwDataCamp/Image.cpp* shows :
.. code:: c++
......@@ -141,22 +139,23 @@ have a look at the corresponding fwDataCamp implementation of the object. For in
;
}
Which means that each property is a possible **sesh@ path**. For instance the height of the image can be retrieved using:
Which means that each property is a reachable by a **camp path**. This is notably used by services in the ``ctrlCamp`` bundle, like ``SExtractObjObj`` or ``SCopy``.
For instance the height of the image can be retrieved using:
.. code:: xml
@values.size.1
@size.1
Other examples:
----------------
To get the fwID of an image contained in a Composite with the key "myImage"
To get the image contained in a ``::fwData::Composite`` with the key ``myImage``
.. code:: xml
@values.myImage
To get the fwID of the first reconstruction of a ModelSeries contained in a Composite with the key "myModel"
To get the first reconstruction of a ModelSeries contained in a ``::fwData::Composite`` with the key ``myModel``
.. code:: xml
......
********************************
Frequently Asked Questions (FAQ)
********************************
.. toctree::
:maxdepth: 2
FAQ-FW4SPL.rst
.. _xmlApplication:
****************************************
How to create a XML based application ?
****************************************
In the Tutorials, we explain how to create simple applications.
A XML based application, is defined by an "application bundle" (like a bundle but with some differences that we will
describe further).
Application bundle
-------------------
This "application bundle" contains a base configuration to run when the application is launched and lists the required
bundles for this configuration.
Like a bundle, the application folder needs the CMake files and a plugin.xml file. The first difference, is that the
*Properties.cmake* ``TYPE`` is ``APP`` instead of ``BUNDLE``.
The second difference is the line:
.. code-block:: cmake
bundleParam(appXml PARAM_LIST config PARAM_VALUES tutoDataServiceBasicConfig)
It defines the main configuration to be launched by the application (see :ref:`Properties.cmake`).
The main configuration should be written in the ``plugin.xml`` file in a ``<extension implements="::fwServices::registry::AppConfig">``
tag (see :ref:`tuto01`).
.. _profile.xml:
profile.xml
------------
To launch an application, we use:
.. code::
bin/fwlauncher share/<myApplication>_<version>/profile.xml
This ``profile.xml`` file, used as an input of the fwlauncher command, holds a list of all bundles
necessary to run an application. We describe the content of this file here for reference, but hopefully you do **not** have to write it yourself.
The Properties.cmake of an application generates automatically a ``profile.xml``.
Here is for example the ``profile.xml`` generated for :ref:`tuto01`.
.. code-block:: xml
<!-- WARNING, this file is GENERATED by FW4SPL CMake-based build system from CMake/build/profile.xml.in -->
<!-- DO NOT EDIT MANUALLY !!! -->
<profile name="Tuto01Basic" version="0.1" check-single-instance="false">
<activate id="Tuto01Basic" version="0.1" />
<activate id="appXml" version="0.2" >
<param id="config" value="tutoBasicConfig" />
</activate>
<activate id="dataReg" version="0.1" />
<activate id="gui" version="0.1" />
<activate id="guiQt" version="0.1" />
<activate id="servicesReg" version="0.1" />
<start id="appXml" />
<start id="guiQt" />
</profile>
activate:
List of bundles used in this application. We see the parameter given to *appXML* bundle that we wrote in the *Properties.cmake*.
start:
List of bundles to start when the application is launched. Basically, there are a few bundles to start at the beginning:
- *appXML*: to launch the configuration
- *guiQt*: to launch the qt event loop for applications with a GUI
- *memory*: to manage image and mesh buffers
The other bundles will be started according to the XML <requirement> tags of the bundles, or when a service is used in
an XML configuration and its bundle is not started. That way we only have the minimum number of shared libraries loaded.
*******************************************************************
How to create a bundle, a lib, an executable or an application ?
*******************************************************************
In fw4spl, the bundles, libraries, applications and executables are folders containing:
- [required] two files to generate the *CMake* target: ``CMakeLists.txt`` and ``Properties.cmake`` (see :ref:`HowCMake`).
- [optional] *include* and *src* folder to contain the header and source files.
- [optional] *rc* folder to contain resources and XML configuration files
- [optional] *test* folder to contain the unit tests
.. _bundleCreation:
How to create a bundle ?
==========================
In fw4spl, you will encounter two types of bundles:
- the bundles containing only XML configurations
- the bundles containing services or other cpp code
It is possible to contain at the same time configurations and services (or C++ code), but for the sake of clarity and
reusability we recommend to separate the two.
.. _configBundle:
XML configurations bundles
--------------------------
These bundles does not contain C++ code, they only contain XML files and the required *CMake* files.
In the bundle folder, there is only the *CMake* files and the *rc* folder.
CMake files
~~~~~~~~~~~~
The CMakeLists.txt contains only ``fwLoadProperties()`` to load the Properties.cmake
The Properties.cmake defines the bundles needed to launch the configuration (ie. the bundle of all the services present
in the configurations).
Example:
.. code-block:: cmake
set( NAME dataManagerConfig )
set( VERSION 0.1 )
set( TYPE BUNDLE )
set( DEPENDENCIES ) # no dependency
set( REQUIREMENTS # required bundle
gui
guiQt
uiMedDataQt
uiReconstructionQt
ctrlSelection
media
)
Configurations
~~~~~~~~~~~~~~~
A bundle could contain several configurations, they are in the ``plugin.xml`` file in the *rc* folder.
.. code-block:: xml
<plugin id="dataManagerConfig" version="@PROJECT_VERSION@" >
<requirement id="dataReg" />
<requirement id="servicesReg" />
<!-- ... extensions ... -->
</plugin>
The ``@PROJECT_VERSION@`` will be automatically replaced by the version defined in the Properties.cmake.
The ``<requirement>`` tags contain the bundles that must be started before to start your bundle (see https://rawgit.com/fw4spl-org/fw4spl-dox/dev/group__requirement.html).
Then the extensions are defined. There are different types of extensions, the most common are:
- ``::fwServices::registry::AppConfig`` to define configurations for applications (see :ref:`tuto01`)
- ``::fwActivities::registry::Activities`` to define activities
- ``:fwServices::registry::ServiceConfig`` to define configurations of services (mostly used to configure readers/writers)
- ``::fwServices::registry::ServiceFactory`` to define services
.. TODO add links to documentation for the extensions
.. note::
To separate the configuration in several files, you can use ``<xi:include href="..." />``
.. _serviceBundle:
Service bundles
----------------
You don't need to create the ``plugin.xml`` file for the bundle that contains only services, it will be automatically generated.
A ``CMake`` script parses the services macro and doxygen to generate the ``::fwServices::registry::ServiceFactory`` extension
(see :ref:`serviceCreation` and :ref:`serviceNotFound`)
The bundle contains the service header files in the `include` folder and the `source` files in the `src` folder.
It must also contain a ``Plugin`` class used to register the bundle.
The ``Plugin.hpp`` in the *include* folder should look like:
.. code-block:: cpp
#pragma once
#include <fwRuntime/Plugin.hpp>
namespace myBundle
{
class MYBUNDLE_CLASS_API Plugin : public ::fwRuntime::Plugin
{
public: