Developers Toolkit

Development of plugins and extensions for FogLAMP does not always require the user to have access to the source code or to have built a FogLAMP from source code. A developers toolkit exists that includes all of the header files and libraries required to develop plugins for a FogLAMP distribution. The developers toolkit is installed using the package manager in the same way that binary packages are installed.

Choosing Developers Toolkit Version

In general it is best to choose the develop toolkit version which is the same as the version of FogLAMP you are running. However if you wish to develop a plugin that supports multiple versions of FogLAMP you should choose the toolkit for the minimum version you wish to support. FogLAMP offers compatibility with newer versions but does not guarantee that a plugin developed on newer version of FogLAMP will run on an older version.

Installation

The first step in installing the developers toolkit via the package manager is to configuration the repository archive from which to obtain the package. If you have already installed FogLAMP from a package you can skip this section as it uses the same package repository.

Ubuntu or Debian

On a Ubuntu or Debian system, including the Raspberry Pi, the package manager that is supported is apt. You will need to add the Dianomic Systems archive server into the configuration of apt on your system. The first thing that most be done is to add the key that is used to verify the package repository. To do this run the command

wget -q -O - http://archives.dianomic.com/KEY.gpg | sudo apt-key add -

Once complete you can add the repository itself into the apt configuration file /etc/apt/sources.list. The simplest way to do this is the use the add-apt-repository command. The exact command will vary between systems;

  • Raspberry Pi does not have an apt-add-repository command, the user must edit the apt sources file manually

    sudo vi /etc/apt/sources.list
    

    and add the line

    deb  http://archives.dianomic.com/foglamp/latest/buster/armv7l/ /
    

    to the end of the file.

    Note

    Replace buster with stretch or bullseye based on the OS image used.

  • Users with an Intel or AMD system with Ubuntu 18.04 should run

    sudo add-apt-repository "deb http://archives.dianomic.com/foglamp/latest/ubuntu1804/x86_64/ / "
    
  • Users with an Intel or AMD system with Ubuntu 20.04 should run

    sudo add-apt-repository "deb http://archives.dianomic.com/foglamp/latest/ubuntu2004/x86_64/ / "
    

    Note

    We do not support the aarch64 architecture with Ubuntu 20.04 yet.

  • Users with an Arm system with Ubuntu 18.04, such as the Odroid board, should run

    sudo add-apt-repository "deb http://archives.dianomic.com/foglamp/latest/ubuntu1804/aarch64/ / "
    
  • Users of the Mendel operating system on a Google Coral create the file /etc/apt/sources.list.d/foglamp.list and insert the following content

    deb http://archives.dianomic.com/foglamp/latest/mendel/aarch64/ /
    

Once the repository has been added you must inform the package manager to go and fetch a list of the packages it supports. To do this run the command

sudo apt -y update

You are now ready to install the FogLAMP packages. You do this by running the command

sudo apt -y install *package*

Developer Toolkit Package

You are now ready to install the developer toolkit package

$ sudo apt install -y foglamp-dev
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  autoconf automake autotools-dev binutils binutils-common binutils-x86-64-linux-gnu build-essential cpp cpp-7
  dh-python dpkg-dev fakeroot g++ g++-7 gcc gcc-4.8-base gcc-7 gcc-7-base libalgorithm-diff-perl
  libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan0 libasan4 libatomic1 libbinutils
  libboost-atomic1.65-dev libboost-atomic1.65.1 libboost-chrono1.65-dev libboost-chrono1.65.1
  libboost-date-time1.65-dev libboost-date-time1.65.1 libboost-dev libboost-serialization1.65-dev
  libboost-serialization1.65.1 libboost-system-dev libboost-system1.65-dev libboost-system1.65.1
  libboost-thread-dev libboost-thread1.65-dev libboost-thread1.65.1 libboost1.65-dev libc-dev-bin libc6 libc6-dev
  libcc1-0 libcilkrts5 libdpkg-perl libexpat1-dev libfakeroot libfile-fcntllock-perl libgcc-4.8-dev libgcc-7-dev
  libgomp1 libisl19 libitm1 liblsan0 libltdl-dev libltdl7 libmpc3 libmpx2 libpq-dev libpq5 libpython3-dev
  libpython3.6-dev libquadmath0 libsensors4 libstdc++-4.8-dev libstdc++-7-dev libtool libtsan0 libubsan0
  linux-libc-dev m4 make manpages-dev postgresql postgresql-10 postgresql-client-10 postgresql-client-common
  postgresql-common python-pip-whl python3-crypto python3-dev python3-distutils python3-keyring
  python3-keyrings.alt python3-lib2to3 python3-pip python3-secretstorage python3-setuptools python3-wheel
  python3-xdg python3.6-dev sqlite3 ssl-cert sysstat
Suggested packages:
  autoconf-archive gnu-standards autoconf-doc gettext binutils-doc cpp-doc gcc-7-locales debian-keyring
  g++-multilib g++-7-multilib gcc-7-doc libstdc++6-7-dbg gcc-multilib flex bison gdb gcc-doc gcc-7-multilib
  libgcc1-dbg libgomp1-dbg libitm1-dbg libatomic1-dbg libasan4-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg
  libcilkrts5-dbg libmpx2-dbg libquadmath0-dbg libboost-doc libboost1.65-doc libboost-container1.65-dev
  libboost-context1.65-dev libboost-coroutine1.65-dev libboost-exception1.65-dev libboost-fiber1.65-dev
  libboost-filesystem1.65-dev libboost-graph1.65-dev libboost-graph-parallel1.65-dev libboost-iostreams1.65-dev
  libboost-locale1.65-dev libboost-log1.65-dev libboost-math1.65-dev libboost-mpi1.65-dev
  libboost-mpi-python1.65-dev libboost-numpy1.65-dev libboost-program-options1.65-dev libboost-python1.65-dev
  libboost-random1.65-dev libboost-regex1.65-dev libboost-signals1.65-dev libboost-stacktrace1.65-dev
  libboost-test1.65-dev libboost-timer1.65-dev libboost-type-erasure1.65-dev libboost-wave1.65-dev
  libboost1.65-tools-dev libmpfrc++-dev libntl-dev glibc-doc bzr libtool-doc postgresql-doc-10 lm-sensors
  libstdc++-4.8-doc libstdc++-7-doc gfortran | fortran95-compiler gcj-jdk m4-doc make-doc postgresql-doc
  locales-all libjson-perl python-crypto-doc gnome-keyring libkf5wallet-bin gir1.2-gnomekeyring-1.0
  python-secretstorage-doc python-setuptools-doc sqlite3-doc openssl-blacklist isag
...
Setting up foglamp-dev (1.9.2) ...
Processing triggers for ureadahead (0.100.0-21) ...
Processing triggers for install-info (6.5.0.dfsg.1-2) ...
Processing triggers for libc-bin (2.27-3ubuntu1.5) ...
Processing triggers for systemd (237-3ubuntu10.52) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
$

At the end of this command all of the packages needed to build plugins for FogLAMP will have been installed and the FogLAMP header files and libraries will also be installed. FogLAMP itself will not be installed.

The FogLAMP header files can be found in the directory /usr/include/foglamp and the libraries in /usr/lib/foglamp.

Building Plugins

FogLAMP uses the cmake system to build plugins and other components. In order to find the various libraries and header files there is a standard FindFoglamp.cmake file that is used. This will allow the cmake system to find the libraries and header files when FogLAMP has either been installed as source code or via the developer package. The content of the FindFoglamp.cmake file is reproduced below.

# This CMake file locates the Foglamp header files and libraries
#
# The following variables are set:
# FOGLAMP_INCLUDE_DIRS - Path(s) to Foglamp headers files found
# FOGLAMP_LIB_DIRS - Path to Foglamp shared libraries
# FOGLAMP_SUCCESS - Set on succes
#
# In case of error use SEND_ERROR and return()
#

# Set defaults paths of installed Foglamp SDK package
set(FOGLAMP_DEFAULT_INCLUDE_DIR "/usr/include/foglamp" CACHE INTERNAL "")
set(FOGLAMP_DEFAULT_LIB_DIR "/usr/lib/foglamp" CACHE INTERNAL "")

# CMakeLists.txt options
set(FOGLAMP_SRC "" CACHE INTERNAL "")
set(FOGLAMP_INCLUDE "" CACHE INTERNAL "")
set(FOGLAMP_LIB "" CACHE INTERNAL "")

# Return variables
set(FOGLAMP_INCLUDE_DIRS "" CACHE INTERNAL "")
set(FOGLAMP_LIB_DIRS "" CACHE INTERNAL "")
set(FOGLAMP_FOUND "" CACHE INTERNAL "")

# No options set
# If FOGLAMP_ROOT env var is set, use it
if (NOT FOGLAMP_SRC AND NOT FOGLAMP_INCLUDE AND NOT FOGLAMP_LIB)
        if (DEFINED ENV{FOGLAMP_ROOT})
                message(STATUS "No options set.\n"
                        "   +Using found FOGLAMP_ROOT $ENV{FOGLAMP_ROOT}")
                set(FOGLAMP_SRC $ENV{FOGLAMP_ROOT})
        endif()
endif()

# -DFOGLAMP_SRC=/some_path or FOGLAMP_ROOT path
# Set return variable FOGLAMP_INCLUDE_DIRS
if (FOGLAMP_SRC)
        unset(_INCLUDE_LIST CACHE)
        file(GLOB_RECURSE _INCLUDE_COMMON "${FOGLAMP_SRC}/C/common/*.h")
        file(GLOB_RECURSE _INCLUDE_SERVICES "${FOGLAMP_SRC}/C/services/common/*.h")
        list(APPEND _INCLUDE_LIST ${_INCLUDE_COMMON} ${_INCLUDE_SERVICES})
        foreach(_ITEM ${_INCLUDE_LIST})
                get_filename_component(_ITEM_PATH ${_ITEM} DIRECTORY)
                list(APPEND FOGLAMP_INCLUDE_DIRS ${_ITEM_PATH})
        endforeach()
        unset(INCLUDE_LIST CACHE)

        list(REMOVE_DUPLICATES FOGLAMP_INCLUDE_DIRS)

        string (REPLACE ";" "\n   +" DISPLAY_PATHS "${FOGLAMP_INCLUDE_DIRS}")
        if (NOT DEFINED ENV{FOGLAMP_ROOT})
                message(STATUS "Using -DFOGLAMP_SRC option for includes\n   +" "${DISPLAY_PATHS}")
        else()
                message(STATUS "Using FOGLAMP_ROOT for includes\n   +" "${DISPLAY_PATHS}")
        endif()

        if (NOT FOGLAMP_INCLUDE_DIRS)
                message(SEND_ERROR "Needed Foglamp header files not found in path ${FOGLAMP_SRC}/C")
                return()
        endif()
else()
        # -DFOGLAMP_INCLUDE=/some_path
        if (NOT FOGLAMP_INCLUDE)
                set(FOGLAMP_INCLUDE ${FOGLAMP_DEFAULT_INCLUDE_DIR})
                message(STATUS "Using Foglamp dev package includes " ${FOGLAMP_INCLUDE})
        else()
                message(STATUS "Using -DFOGLAMP_INCLUDE option " ${FOGLAMP_INCLUDE})
        endif()
        # Remove current value from cache
        unset(_FIND_INCLUDES CACHE)
        # Get up to date var from find_path
        find_path(_FIND_INCLUDES NAMES plugin_api.h PATHS ${FOGLAMP_INCLUDE})
        if (_FIND_INCLUDES)
                list(APPEND FOGLAMP_INCLUDE_DIRS ${_FIND_INCLUDES})
        endif()
        # Remove current value from cache
        unset(_FIND_INCLUDES CACHE)

        if (NOT FOGLAMP_INCLUDE_DIRS)
                message(SEND_ERROR "Needed Foglamp header files not found in path ${FOGLAMP_INCLUDE}")
                return()
        endif()
endif()

#
# Foglamp Libraries
#
# Check -DFOGLAMP_LIB=/some path is valid
# or use FOGLAMP_SRC/cmake_build/C/lib
# FOGLAMP_SRC might have been set to FOGLAMP_ROOT above
#
if (FOGLAMP_SRC)
        # Set return variable FOGLAMP_LIB_DIRS
        set(FOGLAMP_LIB "${FOGLAMP_SRC}/cmake_build/C/lib")

        if (NOT DEFINED ENV{FOGLAMP_ROOT})
                message(STATUS "Using -DFOGLAMP_SRC option for libs \n   +" "${FOGLAMP_SRC}/cmake_build/C/lib")
        else()
                message(STATUS "Using FOGLAMP_ROOT for libs \n   +" "${FOGLAMP_SRC}/cmake_build/C/lib")
        endif()

        if (NOT EXISTS "${FOGLAMP_SRC}/cmake_build")
                message(SEND_ERROR "Foglamp has not been built yet in ${FOGLAMP_SRC}  Compile it first.")
                return()
        endif()

        # Set return variable FOGLAMP_LIB_DIRS
        set(FOGLAMP_LIB_DIRS "${FOGLAMP_SRC}/cmake_build/C/lib")
else()
        if (NOT FOGLAMP_LIB)
                set(FOGLAMP_LIB ${FOGLAMP_DEFAULT_LIB_DIR})
                message(STATUS "Using Foglamp dev package libs " ${FOGLAMP_LIB})
        else()
                message(STATUS "Using -DFOGLAMP_LIB option " ${FOGLAMP_LIB})
        endif()
        # Set return variable FOGLAMP_LIB_DIRS
        set(FOGLAMP_LIB_DIRS ${FOGLAMP_LIB})
endif()

# Check NEEDED_FOGLAMP_LIBS in libraries in FOGLAMP_LIB_DIRS
# NEEDED_FOGLAMP_LIBS variables comes from CMakeLists.txt
foreach(_LIB ${NEEDED_FOGLAMP_LIBS})
        # Remove current value from cache
        unset(_FOUND_LIB CACHE)
        # Get up to date var from find_library
        find_library(_FOUND_LIB NAME ${_LIB} PATHS ${FOGLAMP_LIB_DIRS})
        if (_FOUND_LIB)
                # Extract path form founf library file
                get_filename_component(_DIR_LIB ${_FOUND_LIB} DIRECTORY)
        else()
                message(SEND_ERROR "Needed Foglamp library ${_LIB} not found in ${FOGLAMP_LIB_DIRS}")
                return()
        endif()
        # Remove current value from cache
        unset(_FOUND_LIB CACHE)
endforeach()

# Set return variable FOGLAMP_FOUND
set(FOGLAMP_FOUND "true")

This should be placed in the base directory of your plugin, along with the plugins CMakeLists.txt file. In that file simply add the lines

# Find Foglamp includes and libs, by including FindFoglamp.cmake file
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
find_package(Foglamp)
include_directories(${FOGLAMP_INCLUDE_DIRS})

This will enable cmake to find the header files and libraries that you include. It will also enable you to add the FogLAMP libraries using directives such as

target_link_libraries(${PROJECT_NAME} common-lib)

The above example will add the FogLAMP common-lib to the build, this will give access to readings objects and other common objects needed for a FogLAMP plugin.

The convention for any plugins built for FogLAMP is to provide a script called requirements.sh that will install any dependencies required by the plugin. If such a script exists then this should be run as the first step in building a plugin or service.

Building then becomes a case of

  • creating the build directory,

  • changing to that directory,

  • running cmake,

  • followed by make

  • and optionally make install.

$ mkdir build
$ cd build
$ cmake ..
-- The C compiler identification is GNU 7.5.0
-- The CXX compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using Foglamp dev package includes /usr/include/foglamp
-- Using Foglamp dev package libs /usr/lib/foglamp
-- Configuring done
-- Generating done
-- Build files have been written to: /home/mark/foglamp-south-etherip/build
$ make
[ 25%] Generating version header
Scanning dependencies of target etherip
[ 50%] Building CXX object CMakeFiles/etherip.dir/plctag.o
[ 50%] Building CXX object CMakeFiles/etherip.dir/plugin.o
[ 75%] Linking CXX shared library libetherip.so
[100%] Built target etherip
$