Skip to content

MindConnect Library – Getting started for Linux

Prerequisites

  • CMake 3.5.2 or newer is required for to building the MindConnect Library.
  • OpenSSL 1.1.x and libcurl are required.
    Note that MindConnect Library has been tested with OpenSSL 1.1.1d and LibCurl 7.68.0.
    Make sure that libcurl is configured to use OpenSSL as the TLS v1.2 implementation.
    To use OpenSSL with your implementation one of following ciphers must be supported and configured for SSL handshaking:

    AES128-SHA256
    AES256-SHA256
    AES128-GCM-SHA256
    AES256-GCM-SHA384
    ECDHE-RSA-AES128-SHA256
    ECDHE-RSA-AES256-SHA384
    ECDHE-RSA-AES128-GCM-SHA256
    ECDHE-RSA-AES256-GCM-SHA384
    

    Enable host and peer verification in order to verify the correctness of Insights Hub's certificate. - For building unit and integration test executables, ensure that ruby is installed and available for CMake (optional).

Preparing and Building

The following steps describe each build process and show how to import and use the MCL inside a client application.

Creating a Build Directory

Create a working directory {MCL_build_dir} where CMake can generate required files, e.g. ~/MCL_build_linux or C:\\Temp\\MCL_build_windows and change into the new directory:

mkdir {MCL_build_dir}
cd {MCL_build_dir}

All following build steps are executed in this working directory. Source files of the MindConnect Library are not affected by these operations. Build files are located at:

{MCL_build_dir}\build\{build_type}\

Preparing the Build Folder with CMake

Build the MindConnect Library from inside MCL_build_dir. The placeholder {MCL_project_dir} specifies the location of the source code directory containing CMakeLists.txt.

cmake {MCL_project_dir}

When creating the build files, CMake looks for a suitable compiler and linker within the environment. In Windows with Visual Studio's toolchain, you need to run vcvarsall.bat (located in your VS installation) in order to set all environment variables.

Selecting a CMake Generator (optional)

Depending on which IDE you use for development you can have CMake create project and makefiles for the MCL. Use the help documentation of CMake to see the list of available generators depending on your environment.

cmake --help

You should see an output which may look like:

The following generators are available on this platform:
  Visual Studio 14 2015 [arch]  = Generates Visual Studio 2015 project files. Optional [arch] can be "Win64" or "ARM".
  ...
  Unix Makefiles                = Generates standard UNIX makefiles.
  ...
  Eclipse CDT4 - Unix Makefiles = Generates Eclipse CDT 4.0 project files with Unix Makefiles.

Each of the listed generators can be used to create project and makefiles in your build directory MCL_build_dir.

If you want to use one of the above generators, change the cmake call to:

cmake -G "name of the generator" {MCL_project_dir}

For example, here are the CMake calls using the generators listed above:

cmake -G "Unix Makefiles" {MCL_project_dir}
cmake -G "Visual Studio 14 2015 Win64" {MCL_project_dir}
cmake -G "Eclipse CDT4 - Unix Makefiles" {MCL_project_dir}

If you choose the generator for Visual Studio or Eclipse, CMake also generates project files (like solutions for VS) which can be opened by the respective IDE.

If you want to have an output for a specific build type, use the parameter CMAKE_BUILD_TYPE. For example:

cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_BUILD_TYPE={Debug|Release|..} {MCL_project_dir}

Specifying MCL Options for the Build Process

There are other options you can enable or disable in order to modify how MCL is built. Each option is provided to CMake with the following command:

cmake -D{MCL_OPTION}[={selection}] {MCL_project_dir}

The part [={selection}] is optional and can be omitted, if the MCL_OPTION has no value.

The following options are allowed options:

OptionDescription
MCL_STATICLIBIf set to ON, MCL is built as static library.
If set to OFF (Default), MCL is built as dynamic library.
MCL_USE_LIBCURLIf set to ON (Default), MCL is built with libcurl.
If set to OFF, MCL is built without libcurl. In this case the user has to provide a module which implements an HTTPS client. Users must make sure that libcurl is available in the path environment.
MCL_USE_OPENSSLIf set to ON (Default), MCL is built with OpenSSL.
If set to OFF, MCL is built without OpenSSL. In this case the user has to provide a module which implements the security layer (SHA256, MD5 calculation etc.) of MCL. Make sure that OpenSSL 1.1.1d is available in the path.
MCL_TESTINGIf set to ON (Default) and Ruby is found in the path, MCL is built with tests.
If set to OFF, MCL is built without tests.
MCL_CREATE_DOXYGENIf set to ON (Default) and Doxygen is found in the path, MCL is built with target mcl_doc for generating Doxygen documentation.
If set to OFF, MCL is built without target mcl_doc.
MCL_LOG_UTIL_LEVELThe value of this option is used to set the log level for compilation.
Possible values from lowest to highest level are:
MCL_LOG_UTIL_LEVEL_VERBOSE
MCL_LOG_UTIL_LEVEL_DEBUG
MCL_LOG_UTIL_LEVEL_INFO
MCL_LOG_UTIL_LEVEL_WARN
MCL_LOG_UTIL_LEVEL_ERROR
MCL_LOG_UTIL_LEVEL_FATAL
MCL_LOG_UTIL_LEVEL_NONE

Invoking Cross Build with CMake (optional)

CMake can cross build the MindConnect Library for a different target system. The build system must support the required toolchain and a toolchain setup file must be provided. The CMake call for building with a toolchain setup looks like this:

cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-i586-poky-linux.cmake {MCL_project_dir}

Any required system root folders must be available in your path, so CMake can find any includes for the target system. The following example shows the Toolchain-i586-poky-linux.cmake for building MCL for an IoT2040 device with Intel's toolchain on a Debian OS:

SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSROOT ~/iss-iot-linux/devkit-x86/sysroots/i586-poky-linux)

SET(CMAKE_C_COMPILER i586-poky-linux-gcc)

SET(tools ~/iss-iot-linux/devkit-x86/sysroots/x86_64-pokysdk-linux/usr/bin/i586-poky-linux)
SET(CMAKE_FIND_ROOT_PATH ${tools})

SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

Another example for building MCL for embedded devices may look like:

SET(CMAKE_SYSTEM_NAME Generic)
INCLUDE(CMakeForceCompiler)
CMAKE_FORCE_C_COMPILER(arm-none-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-none-eabi-g++ GNU)
SET(CMAKE_C_FLAGS "-Wall -ffunction-sections -fdata-sections -fno-builtin-memcpy -gdwarf-2 -mthumb-interwork -mcpu=arm926ej-s  -O0 -g3 -c -MMD -MP")
SET(CMAKE_EXE_LINKER_FLAGS "-nostdlib -nostartfiles -Wl,--gc-sections -Wl,--wrap=malloc -Wl,--wrap=calloc -Wl,--wrap=realloc -Wl,--wrap=free -Wl,--wrap=_malloc_r -Wl,--wrap=_calloc_r -Wl,--wrap=_realloc_r -Wl,--wrap=_free_r -Wl,--defsym -Wl,PAGE_SIZE=0 -Wl,--start-group -lgcc -lc -lm -lstdc++ -Wl,--end-group")

Invoking a build with CMake

After setting the folder structure you should be able to build the MCL project. If the command make e.g. is in your toolchain then you could call it in your build folder directly, but for other toolchain setups you may want to call (builds all targets):

cmake --build .

It is possible to choose only one of the targets. The following table lists the different targets:

TargetDescription
mctarget for building the MCL
mcl_doctarget for building the Doxygen documentation of the MCL project
packagetarget for generating the distribution package of MCL
test_{module_name}target for building a unit test executable for given module of the MCL

Use the following command structure to build only one target:

cmake --build . --target {target_name}

Creating the Doxygen documentation

The documentation of the MCL is built by Doxygen. The project contains a Doxygen configuration file which can be adapted to your needs. You can build the documentation by calling the CMake target as follows:

cmake --build . --target mcl_doc

Generating a Distribution Package

The distribution package of the MCL is generated using CPack. CPack is configured in the CMake files. You can generate the distribution package MCL-{mcl_version}-{target_system}.zip by calling the CMake target as follows:

cmake --build . --target package

Executing Unit and Integration Tests

If you build all targets with including tests you may run tests with the following command:

ctest .

Refer to the help of CTest (ctest --help) for running or excluding specific tests using regular expressions.

The build process stores all outputs in the subfolder {MCL_build_dir}/build/{Debug|Release|...

Building and Running a Custom Agent for Linux

Perform the following steps to build and run a custom agent using MCL for Linux from scratch.

Creating the Directory Structure

  1. Create /usr/customAgentExample directory. This will be the parent directory for the whole process.
  2. Create /usr/customAgentExample/build directory. This will be the parent directory for build outputs.
  3. Create /usr/customAgentExample/build/openssl directory for openssl build outputs.
  4. Create /usr/customAgentExample/build/curl directory for curl build outputs.
  5. Create /usr/customAgentExample/build/mcl directory for mcl build outputs.
  6. Create /usr/customAgentExample/build/agent directory for agent build outputs.
  7. Copy MCL source code .../MCL_Core into /usr/customAgentExample.

Note

Change the modes of directories if needed using:

sudo chmod 755 {directory_path}

Building OpenSSL

Download the OpenSSL package openssl-1.1.1d.tar.gz. Unzip openssl-1.1.1d.tar.gz to /usr/customAgentExample. Enter the following commands:

cd /usr/customAgentExample/{downloaded_openssl_dir}
./config --openssldir=/usr/customAgentExample/build/openssl shared -fPIC
sudo make install

Building Libcurl

Download curl-7.68.0.zip. Unzip curl-7.68.0.zip to /usr/customAgentExample. Enter the following commands:

cd /usr/customAgentExample/{downloaded_curl_dir}
LDFLAGS="-Wl,-R/usr/customAgentExample/build/openssl/lib" ./configure --enable-http --with-ssl=/usr/customAgentExample/build/openssl --prefix=/usr/customAgentExample/build/curl --without-libssh2 --disable-ftp --disable-tftp --disable-file --disable-ldap --disable-rtsp --disable-dict --disable-telnet --disable-pop3 --disable-imap --disable-smb --disable-scp --disable-sftp --disable-smtp --disable-gopher --disable-manual
sudo make install

Building MCL

Create a bash file /usr/customAgentExample/build_mcl with the following content:

#!/bin/bash
OPENSSL_DIR="/usr/customAgentExample/build/openssl"
CURL_DIR="/usr/customAgentExample/build/curl"
MCL_SOURCE_DIR="/usr/customAgentExample/MCL_Core"
MCL_BUILD_DIR="/usr/customAgentExample/build/mcl"
if [ -d ${MCL_BUILD_DIR} ]; then
    sudo rm -rf ${MCL_BUILD_DIR}
fi
sudo mkdir ${MCL_BUILD_DIR}
sudo chmod 777 ${MCL_BUILD_DIR}
cd ${MCL_BUILD_DIR}
cmake -DCMAKE_PREFIX_PATH="${OPENSSL_DIR};${CURL_DIR}" -DCMAKE_BUILD_TYPE=Release -DMCL_STATICLIB=OFF -DMCL_USE_LIBCURL=ON -DMCL_USE_OPENSSL=ON -DMCL_CREATE_DOXYGEN=OFF -DMCL_TESTING=OFF -DMCL_LOG_UTIL_LEVEL=MCL_LOG_UTIL_LEVEL_NONE ${MCL_SOURCE_DIR}
cmake --build . --target mc

Build MCL using:

sudo ./build_mcl

Make sure the correct libraries are linked using the following command:

ldd /usr/customAgentExample/build/mcl/build/Release/libmc.so

Building a Custom Agent Application

  1. Create /usr/customAgentExample/agent directory for agent application.
  2. Create CMakeLists.txt file in /usr/customAgentExample/agent with the following content:

    CMAKE_MINIMUM_REQUIRED(VERSION 3.5 FATAL_ERROR)
    PROJECT(CustomAgentApplication LANGUAGES C)
    SET(CMAKE_C_STANDARD 99)
    SET(CMAKE_C_STANDARD_REQUIRED ON)
    FILE(GLOB SOURCES *.c)
    LIST(APPEND AGENT_SOURCES ${SOURCES})
    SET(MCL "/usr/customAgentExample/build/mcl/build/Release/libmc.so" CACHE INTERNAL "MCL" FORCE)
    SET(MCL_INCLUDE_DIRECTORIES "/usr/customAgentExample/build/mcl/include/" CACHE INTERNAL "MCL_INCLUDE_DIRECTORIES" FORCE)
    SET(AGENT_OUTPUT_DIR ${CMAKE_BINARY_DIR}/build)
    SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${AGENT_OUTPUT_DIR})
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${AGENT_OUTPUT_DIR})
    SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${AGENT_OUTPUT_DIR})
    ADD_EXECUTABLE(${PROJECT_NAME} ${AGENT_SOURCES})
    TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PUBLIC ${MCL_INCLUDE_DIRECTORIES})
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${MCL})
    
  3. Make sure the provided MCL headers are in /usr/customAgentExample/build/mcl/include/mcl.

  4. Write the source code for your custom agent application in /usr/customAgentExample/agent and run the following commands:

    cd /usr/customAgentExample/build/agent
    cmake /usr/customAgentExample/agent
    cmake --build . --clean-first
    ./build/CustomAgentApplication
    

Replacing MCL Modules with Custom Implementations

The following table list the modules of the MCL project, which can be replaced by custom implementations:

ModulesDescription
memory.hImplements memory related functions. If not specified otherwise, alloc, calloc, realloc and free are used from the standard library. You can replace this module by a custom implementation which handles the memory management for your target device and build environment.
random.hIf not specified otherwise, MCL uses the random generator from the standard library. You can replace this module by a custom implementation.
security.hThis module provides several functions which implements calculations like SHA256, MD5, RSA key generation. If not specified otherwise, these calculations are performed by OpenSSL's crypto library. Replace this module to provide your own hardware specific implementation.
http_client.hThis module is used by MCL in order to send an HTTP request to Insights Hub. If not specified otherwise, libcurl is used to realize the communication. You can replace this module by a custom implementation. Your implementation has to fulfill the same security requirements with respect to TLS v1.2. Insights Hub's certificate must be validated by your implementation during the SSL handshaking procedure.

For replacing a module, keep the original *.h file and replace its implementation file *.c with the same name.