Working with external software

## Contents

- Your rights

- Introduction

- Component model

- Component description file

- GenoM IDL mappings

- Running GenoM

- Tutorials

  - Genom workflow

  - Simple service

  - IDS (Internal Data Structure)

  - Working with external software

- Templates

## Working with external software

This tutorial covers how to use external software in your component.

Depending on how the external software is packaged, two methods must be considered:

- using `pkg-config`

- manually describing the dependency

If the external software provides `pkg-config` files, the first method is simpler to setup and should be used. The second method is more general, but requires a bit more code to be added to your component build system.

### Using pkg-config

Adding a `pkg-config` dependency is achieved by declaring a `codels-require` attribute in your component description.

For instance, to add a dependency on `eigen3` with a version greater than `3.2`, add the following line to the `.gen` file of the component:

example.gen

            component example {
              [...]
              codels-require "eigen3 >= 3.2";
              [...]
            };

Simple and effective, that is all what is required.

To check that a dependency can be found by `pkg-config` you can either check its documentation, or just run:

            $ pkg-config --modversion eigen3
            3.2.92
            $

If this succeeds, you can use the pkg-config method.

### Manually describing the dependency

When the external software cannot be discovered by `pkg-config`, it is necessary to manually amend the component build system so that it can locate where the dependency is installed. How this can be done highly depends on the software in question, but this section provides some general guidelines that should be useful for a majority of software.

#### Simple scenario

Usually, you need to locate both header files, that are to be included in your code, and libraries to link with. In `autoconf` syntax, this can be achieved by adding the following bits to the `configure.ac` file generated by the skeleton template.

configure.ac

            [...]
            # Dependency on 'foo'. Check that header.h and function foo_init() in
            # libdependency.so are present.
            AC_CHECK_HEADER([header.h],,[
              AC_MSG_ERROR([Could not find foo header.h file.])])
            AC_CHECK_LIB([dependency], [foo_init],,[
              AC_MSG_ERROR([Could not find foo dependency library.])])
            [...]

Then, in the automake file `codels/Makefile.am`, you need to link with the library:

codels/Makefile.am

            [...]
            libexample_codels_la_LDFLAGS+=        -ldependency
            [...]

If the dependency is installed in a non-standard location, you may need to pass additional flags to the `configure` script when compiling your component.

For instance, if the 'foo' dependency is installed in `/opt/foo`, you may run the `configure` script of your component like so:

    $ ../configure CPPFLAGS="-I/opt/foo/include" \
                   LDFLAGS="-L/opt/foo/lib -R/opt/foo/lib"

Tip | The `-R/opt/foo/lib` sets the runtime library path in the component binary, so that you can run it without bothering with runtime variables such as `LD_LIBRARY_PATH`.

#### Using an external C++ library with no C symbol

The previous method works well for depencencies in which you can call a `C` function. If you need to link with a `C++` library that exports no `C` symbol, you should use something similiar to the following snippet in your `configure.ac` file:

configure.ac

            [...]
            # Dependency on 'tinyxml'. Check that libtinyxml.h and class
            # TiXmlDocument in C++ libtinyxml.so are present.
            AC_LANG([C++])
            AC_CHECK_HEADER([tinyxml.h],,[
              AC_MSG_ERROR([Could not find tinyxml.h file.])])

            AC_MSG_CHECKING([TiXmlDocument in libtinyxml])
            SAVED_LDFLAGS="$LDFLAGS"
            LDFLAGS="$LDFLAGS -ltinyxml"
            AC_LINK_IFELSE(
              [AC_LANG_PROGRAM([#include <tinyxml.h>], [TiXmlDocument dummy()])],
              [AC_MSG_RESULT([yes])],
              [AC_MSG_RESULT([no])
               AC_MSG_ERROR([Could not find libtinyxml dependency library.])])
            LDFLAGS="$SAVED_LDFLAGS"
            [...]

The `codels/Makefile.am` shoud be modified like in the simple scenario above:

codels/Makefile.am

            [...]
            libexample_codels_la_LDFLAGS+=        -ltinyxml
            [...]