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:
Option | Description |
---|---|
MCL_STATICLIB | If set to ON , MCL is built as static library.If set to OFF (Default), MCL is built as dynamic library. |
MCL_USE_LIBCURL | If 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_OPENSSL | If 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_TESTING | If 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_DOXYGEN | If 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_LEVEL | The 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:
Target | Description |
---|---|
mc | target for building the MCL |
mcl_doc | target for building the Doxygen documentation of the MCL project |
package | target 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¶
- Create
/usr/customAgentExample
directory. This will be the parent directory for the whole process. - Create
/usr/customAgentExample/build
directory. This will be the parent directory for build outputs. - Create
/usr/customAgentExample/build/openssl
directory for openssl build outputs. - Create
/usr/customAgentExample/build/curl
directory for curl build outputs. - Create
/usr/customAgentExample/build/mcl
directory for mcl build outputs. - Create
/usr/customAgentExample/build/agent
directory for agent build outputs. - 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¶
- Create /usr/customAgentExample/agent directory for agent application.
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})
Make sure the provided MCL headers are in
/usr/customAgentExample/build/mcl/include/mcl
.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:
Modules | Description |
---|---|
memory.h | Implements 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.h | If not specified otherwise, MCL uses the random generator from the standard library. You can replace this module by a custom implementation. |
security.h | This 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.h | This 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.