Build 4diac FORTE for Multiple Target on WSL
Eclipse 4diac™ provides an open source infrastructure for distributed industrial process measurement and control systems based on the IEC 61499 standard. 4diac includes: development environment (4diac IDE), runtime environment (4diac FORTE), function block library, and example projects.
The 4diac FORTE is a small portable implementation of an IEC 61499 runtime environment targeting small embedded control devices (16/32 Bit), implemented in C++. It supports online-reconfiguration of its applications and the real-time capable execution of all function block types provided by the IEC 61499 standard.
Supported communication layers: Ethernet (TCP/UDP), Ethernet PowerLink using openPOWERLINK V1.8.0, FBDK ASN.1 encoding, Modbus TCP client using libmodbus, MQTT using Eclipse Paho, OPC UA using open62541, OPC DA client using OPC Client library release 0.4, RS232.
Supported operating system: eCos, NET+OS 7, Posix: Cygwin, Linux (i386, PPC, ARM), rcX, VxWorks, PikeOS, Windows, freeRTOS.
Supported board: BeagleBone Black, Digi Connect ME (ARM7), emBRICK for Raspberry PI and BeagleBone Black, KIPR's CBC v2 robot controller, Lego Mindstorms EV3 (ARM7), NXH 51-ETM, Raspberry PI.
Supported Programmable Logic Controllers (PLCs): Bachmann electronic M1 PLC, Raspberry-SPS, WAGO PFC200, MicroControl uMIC.200, icom MR-router series.
Linux is a perfect environment for compiling programs for different machine targets and WSL is an easy way to set up a Linux environment on a Windows desktop. Another alternative is MSYS but it is limited to Windows targets and compilation is noticeably slow.
Windows Subsystem for Linux (WSL) is a feature of Windows that allows developers to run a Linux environment without the need for a separate virtual machine or dual booting.
Installing WSL is outside the scope here, please read the document from Microsoft regarding how to install WSL with the default Ubuntu Linux distribution. Let's start cross compiling FORTE on WSL for the Raspberry Pi 4B and/or Windows target.
Update:
A bash script for all of these tasks are included at the end of this post!
Install the additional software needed on WSL
For Raspberry Pi 4B target:
$ sudo apt-get install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu git make cmake automake autoconf libtool cmake-gui
$ mkdir $HOME/forte
For Windows target, the g++-mingw-w64 package built into Ubuntu 22.04 doesn't seem to work properly so we need a newer version of the package from another source, extract it in your $HOME directory:
$ cd
$ sudo apt-get install gcc-mingw-w64 g++-mingw-w64
$ wget -c https://github.com/xpack-dev-tools/mingw-w64-gcc-xpack/releases/download/v13.2.0-1/xpack-mingw-w64-gcc-13.2.0-1-linux-x64.tar.gz
$ tar xvf xpack-mingw-w64-gcc-13.2.0-1-linux-x64.tar.gz
$ export PATH=$HOME/xpack-mingw-w64-gcc-13.2.0-1/bin:$PATH
Update:
I decided to upgrade Ubuntu WSL from 22.04 LTS "Jammy Jellyfish" to 24.04 LTS "Noble Numbat" to use gcc-mingw-w64 and g++-mingw-w64 packages from Ubuntu distribution but had a problem with FORTE that compilation result did not run without any error message. In order for FORTE compilation results run successfully we have to change gcc and g++ thread model from default win32 to posix, do the following:
$ sudo do-release-upgrade -d # upgrade Ubuntu to 24.04
$ sudo update-alternatives --list x86_64-w64-mingw32-gcc
/usr/bin/x86_64-w64-mingw32-gcc-posix
/usr/bin/x86_64-w64-mingw32-gcc-win32
$ sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix
$ sudo update-alternatives --list x86_64-w64-mingw32-g++
/usr/bin/x86_64-w64-mingw32-g++-posix
/usr/bin/x86_64-w64-mingw32-g++-win32
$ sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
Update:
Upgrade to Ubuntu 24.04 make me feel stupid because the compilation result for Raspberry doesn't work anymore with an error message "/lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.38' not found" even though I compiled using gcc version 11. Incompatible libc version!
$ ldd --version
ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
I suggest sticking with Ubuntu version 22.04 or switch to GNU toolchain from Arm but then requires an adjustments in compilation: change compiler from aarch64-linux-gnu-* to aarch64-none-linux-gnu-*
$ cd
$ wget -c https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/11.3.rel1/binrel/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
$ tar xvf arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
$ export PATH=$HOME/arm-gnu-toolchain-11.3.rel1-x86_64-aarch64-none-linux-gnu/bin:$PATH
Download and build libmodbus static library
$ cd ~/forte
$ git clone https://github.com/stephane/libmodbus.git --depth=1
$ cd libmodbus
For Raspberry target:
$ ./autogen.sh
$ ./configure --with-pic --enable-static --enable-shared=no --host=aarch64-linux-gnu --prefix=$HOME/forte/install/aarch64
$ make -j3
$ make install
$ make clean
For Windows target:
$ ./autogen.sh
$ ./configure --with-pic --enable-static --enable-shared=no --host=x86_64-w64-mingw32 --prefix=$HOME/forte/install/x86_w64
$ make -j3
$ make install
$ make clean
Download and build LuaJIT shared library with Lua 5.2 compatibility enabled
$ cd ~/forte
$ git clone https://github.com/LuaJIT/LuaJIT.git --depth=1
$ cd LuaJIT
For Raspberry target:
$ make -j3 CROSS=aarch64-linux-gnu- CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT
$ make install CROSS=aarch64-linux-gnu- CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT PREFIX=$HOME/forte/install/aarch64
$ make clean
For Windows target:
$ make -j3 CROSS=x86_64-w64-mingw32- CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT TARGET_SYS=Windows
$ mv src/luajit.exe src/luajit # a trick to prevent `make install` failure
$ cp src/lua51.dll ~/forte/install/x86_w64/lib/ # manual copy lua shared library
$ make install CROSS=x86_64-w64-mingw32- CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT TARGET_SYS=Windows PREFIX=$HOME/forte/install/x86_w64
$ make clean
Download and build OpenSSL
$ cd ~/forte
$ git clone https://github.com/openssl/openssl.git --depth=1
$ cd openssl
Build OpenSSL shared library for Raspberry target:
$ ./Configure linux-aarch64 shared --cross-compile-prefix=aarch64-linux-gnu- --prefix=$HOME/forte/install/aarch64
$ make -j3
$ make install
$ make clean
Build OpenSSL static library for Windows target:
$ ./Configure mingw64 no-shared -static --cross-compile-prefix=x86_64-w64-mingw32- --prefix=$HOME/forte/install/x86_w64
$ make -j3
$ make install
$ cp $HOME/forte/install/x86_w64/lib64/libcrypto.a $HOME/forte/install/x86_w64/lib/ # create a duplicate copy to lib
$ cp $HOME/forte/install/x86_w64/lib64/libssl.a $HOME/forte/install/x86_w64/lib/ # create a duplicate copy to lib
$ make clean
Download and build Paho MQTT static library
$ cd ~/forte
$ git clone https://github.com/eclipse/paho.mqtt.c.git --depth=1
For Raspberry target:
$ cd ~/forte
$ mkdir -p build/paho/aarch64
$ which aarch64-linux-gnu-gcc # check where gcc location
/usr/bin/aarch64-linux-gnu-gcc
$ which aarch64-linux-gnu-++ # check where g++ location
/usr/bin/aarch64-linux-gnu-g++
Run CMake from inside Ubuntu sub menu on Windows start menu and set:
Source code: /home/user/forte/paho.mqtt.c
Build binaries: /home/user/forte/build/paho/aarch64
Run Configure and select Unix Makefiles for cross compiling and set:
C compiler: /usr/bin/aarch64-linux-gnu-gcc
C++ compiler: /usr/bin/aarch64-linux-gnu-g++
Click Finish and set the setup as follows, it may be necessary to generate repeatedly to fulfill all the setups without errors.
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/aarch64
PAHO_BUILD_SHARED=OFF
PAHO_BUILD_STATIC=ON
PAHO_ENABLE_TESTING=OFF
PAHO_WITH_SSL=ON
OPENSSL_INCLUDE_DIR=/home/user/forte/install/aarch64/include
OPENSSL_ROOT_DIR=/home/user/forte/install/aarch64
OPENSSL_CRYPTO_LIBRARY=/home/user/forte/install/aarch64/lib/libcrypto.so
OPENSSL_SSL_LIBRARY=/home/user/forte/install/aarch64/lib/libssl.so
Compile and install Paho MQTT:
make -j3
make install
make clean
For Windows target:
$ cd ~/forte
$ mkdir -p build/paho/x86_w64
$ which x86_64-w64-mingw32-gcc # check where gcc location
/home/user/xpack-mingw-w64-gcc-13.2.0-1/bin/x86_64-w64-mingw32-gcc
$ which x86_64-w64-mingw32-g++ # check where g++ location
/home/user/xpack-mingw-w64-gcc-13.2.0-1/bin/x86_64-w64-mingw32-g++
Run CMake from inside Ubuntu sub menu on Windows start menu and set:
Source code: /home/user/forte/paho.mqtt.c
Build binaries: /home/user/forte/build/paho/x86_w64
Run Configure and select Unix Makefiles for cross compiling and set:
C compiler: /home/user/xpack-mingw-w64-gcc-13.2.0-1/bin/x86_64-w64-mingw32-gcc
C++ compiler: /home/user/xpack-mingw-w64-gcc-13.2.0-1/bin/x86_64-w64-mingw32-g++
Click Finish and set the setup as follows, it may be necessary to generate repeatedly to fulfill all the setups without errors.
MINGW=ON # Manually added bool entry to tell CMake we are in a MINGW environment
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/x86_w64
PAHO_BUILD_SHARED=OFF
PAHO_BUILD_STATIC=ON
PAHO_ENABLE_TESTING=OFF
PAHO_WITH_SSL=ON
OPENSSL_INCLUDE_DIR=/home/user/forte/install/x86_w64/include
OPENSSL_ROOT_DIR=/home/user/forte/install/x86_w64
OPENSSL_CRYPTO_LIBRARY=/home/user/forte/install/x86_w64/lib/libcrypto.a
OPENSSL_SSL_LIBRARY=/home/user/forte/install/x86_w64/lib/libssl.a
Follow Raspberry step to compile and install Paho MQTT.
Download and build open62541 OPC UA static library
$ cd ~/forte
$ git clone https://github.com/open62541/open62541.git -b pack/v1.3.9 --depth=1
$ cd open62541
$ git submodule update --init --recursive --depth 1
For Raspberry target:
Run CMake and set:
Source code: /home/user/forte/open62541
Build binaries: /home/user/forte/build/open62541/aarch64
Follow previous CMake configuration step and set:
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/aarch64
UA_ARCHITECTURE=posix
UA_ENABLE_AMALGAMATION=ON
CMAKE_INSTALL_PREFIX=/home/user/forte/install/aarch64
UA_ENABLE_DISCOVERY=ON
UA_ENABLE_DISCOVERY_MULTICAST=ON
UA_ENABLE_ENCRYPTION=OPENSSL
OPENSSL_INCLUDE_DIR=/home/user/forte/install/aarch64/include
OPENSSL_CRYPTO_LIBRARY=/home/user/forte/install/aarch64/lib/libcrypto.so
OPENSSL_SSL_LIBRARY=/home/user/forte/install/aarch64/lib/libssl.so
Follow previous step to compile and install open62541.
For Windows target:
Run CMake and set:
Source code: /home/user/forte/open62541
Build binaries: /home/user/forte/build/open62541/x86_w64
Follow previous CMake configuration step and set:
MINGW=ON # Manually added bool entry to tell CMake we are in a MINGW environment
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/x86_w64
UA_ARCHITECTURE=win32
UA_ENABLE_AMALGAMATION=ON
CMAKE_INSTALL_PREFIX=/home/user/forte/install/x86_w64
UA_ENABLE_DISCOVERY=ON
UA_ENABLE_DISCOVERY_MULTICAST=ON
UA_ENABLE_ENCRYPTION=OPENSSL
OPENSSL_INCLUDE_DIR=/home/user/forte/install/x86_w64/include
OPENSSL_CRYPTO_LIBRARY=/home/user/forte/install/x86_w64/lib/libcrypto.a
OPENSSL_SSL_LIBRARY=/home/user/forte/install/x86_w64/lib/libssl.a
Follow previous step to compile and install open62541.
Download and build 4diac's FORTE development branch:
We will compile a development version of FORTE and therefore require a milestone version of the IDE which can be downloaded from 4diac's milestone software repository.
$ cd ~/forte
$ git clone https://git.eclipse.org/r/4diac/org.eclipse.4diac.forte.git -b develop --depth=100
$ cd org.eclipse.4diac.forte
$ git checkout -b local # a local branch to fix a compilation error
$ sed -i '39s/include )/include\/modbus )/' src/com/modbus/CMakeLists.txt
$ sed -i '41s/libmodbus.lib ) /modbus )/' src/com/modbus/CMakeLists.txt
For Raspberry target:
Run CMake and set:
Source code: /home/user/forte/org.eclipse.4diac.forte
Build binaries: /home/user/forte/build/forte/aarch64
Follow previous CMake configuration step and set:
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/aarch64
FORTE_ARCHITECTURE=posix
FORTE_COM_HTTP=ON
FORTE_COM_MODBUS=ON
FORTE_COM_OPC_UA=ON
FORTE_COM_PAHOMQTT=ON
FORTE_EXTERNAL_MODULES_DIRECTORY=/home/user/forte/ext_modules
FORTE_MODULE_CONVERT=ON
FORTE_MODULE_IEC61131=ON
FORTE_MODULE_RECONFIGURATION=ON
FORTE_MODULE_RT_Events=ON
FORTE_MODULE_UTILS=ON
FORTE_MODULE_SysFs=ON
FORTE_USE_LUATYPES=LuaJIT
FORTE_COM_MODBUS_LIB_DIR=/home/user/forte/install/aarch64
FORTE_COM_OPC_UA_ENCRYPTION=ON
FORTE_COM_OPC_UA_INCLUDE_DIR=/home/user/forte/install/aarch64/include
FORTE_COM_OPC_UA_LIB=libopen62541.a
FORTE_COM_OPC_UA_LIB_DIR=/home/user/forte/install/aarch64/lib
FORTE_COM_OPC_UA_MULTICAST=ON
FORTE_COM_PAHOMQTT_INCLUDE_DIR=/home/user/forte/install/aarch64/include
FORTE_COM_PAHOMQTT_LIB=libpaho-mqtt3as.a # MQTT asynchronous with SSL support
FORTE_COM_PAHOMQTT_LIB_DIR=/home/user/forte/install/aarch64/lib
FORTE_COM_SER=ON
LUAJIT_INCLUDE_DIR=/home/user/forte/install/aarch64/include/luajit-2.1
LUAJIT_LIBRARY=/home/user/forte/install/aarch64/lib/libluajit-5.1.so
FORTE_COM_OPC_UA_ENCRYPTION_MBEDTLS=OFF
FORTE_COM_OPC_UA_ENCRYPTION_INCLUDE_DIR=/home/user/forte/install/aarch64/include
FORTE_COM_OPC_UA_ENCRYPTION_LIB_DIR=/home/user/forte/install/aarch64/lib
Compile and install FORTE:
$ make -j3
$ make install
$ cd ~/forte/install/aarch64/
$ cp lib/libcrypto.so.3 lib/libssl.so.3 bin/
$ cp lib/libluajit-5.1.so.2.1.1703358377 bin/libluajit-5.1.so.2
$ aarch64-linux-gnu-strip bin/* # remove symbols and debugging information for a smaller binary size
For Windows target:
Run CMake and set:
Source code: /home/user/forte/org.eclipse.4diac.forte
Build binaries: /home/user/forte/build/forte/x86_w64
Follow previous CMake configuration step and set:
MINGW=ON # Manually added bool entry to tell CMake we are in a MINGW environment
CMAKE_C_STANDARD_LIBRARIES=-lws2_32 -lcrypt32 # Manually added for libmodbus and openssl
CMAKE_CXX_STANDARD_LIBRARIES=-lws2_32 -lcrypt32 # Manually added for libmodbus and openssl
CMAKE_BUILD_TYPE=Release
CMAKE_INSTALL_PREFIX=/home/user/forte/install/x86_w64
FORTE_ARCHITECTURE=win32
FORTE_COM_HTTP=ON
FORTE_COM_MODBUS=ON
FORTE_COM_OPC_UA=ON
FORTE_COM_PAHOMQTT=ON
FORTE_EXTERNAL_MODULES_DIRECTORY=/home/user/forte/ext_modules
FORTE_MODULE_CONVERT=ON
FORTE_MODULE_IEC61131=ON
FORTE_MODULE_RECONFIGURATION=ON
FORTE_MODULE_RT_Events=ON
FORTE_MODULE_UTILS=ON
FORTE_USE_LUATYPES=LuaJIT
FORTE_COM_MODBUS_LIB_DIR=/home/user/forte/install/x86_w64
FORTE_COM_OPC_UA_ENCRYPTION=ON
FORTE_COM_OPC_UA_INCLUDE_DIR=/home/user/forte/install/x86_w64/include
FORTE_COM_OPC_UA_LIB=libopen62541.a
FORTE_COM_OPC_UA_LIB_DIR=/home/user/forte/install/x86_w64/lib
FORTE_COM_OPC_UA_MULTICAST=ON
FORTE_COM_PAHOMQTT_INCLUDE_DIR=/home/user/forte/install/x86_w64/include
FORTE_COM_PAHOMQTT_LIB=libpaho-mqtt3as.a # MQTT asynchronous with SSL support
FORTE_COM_PAHOMQTT_LIB_DIR=/home/user/forte/install/x86_w64/lib
FORTE_COM_SER=ON
LUAJIT_INCLUDE_DIR=/home/user/forte/install/x86_w64/include/luajit-2.1
LUAJIT_LIBRARY=/home/user/forte/install/x86_w64/lib/lua51.dll
FORTE_COM_OPC_UA_ENCRYPTION_MBEDTLS=OFF
FORTE_COM_OPC_UA_ENCRYPTION_INCLUDE_DIR=/home/user/forte/install/aarch64/include
FORTE_COM_OPC_UA_ENCRYPTION_LIB_DIR=/home/user/forte/install/x86_w64/lib
Compile and install FORTE:
$ make -j3
$ cp src/forte.exe $HOME/forte/install/x86_w64/bin
$ $HOME/forte/install/x86_w64/lib/lua51.dll $HOME/forte/install/x86_w64/bin
$ x86_64-w64-mingw32-strip ~/forte/install/x86_w64/bin/*
Ubuntu WSL mount WSL drive on Explorer with the famous Tux the Penguin icon. For Windows target, we can run FORTE directly from WSL drive with a double click.
To make it easier, here is a long and dumb bash script to build 4diac's FORTE and all it's dependencies in single shot!
Update:
I found OpenSSL not working properly yet with Open62541 OPC UA library version 1.3.9 and updated below script use Mbed-TLS as encryption support to FORTE OPC UA client. I attach some patches for FORTE to 4diac forum, please check it.
#!/bin/bash
echo "----------------------------------------------------------------------------"
echo " Build FORTE for Raspberry Pi aarch64, Windows x86_w64, or Linux x86_64"
echo "----------------------------------------------------------------------------"
echo ""
echo " Includes Modbus, OPC UA, MQTT, OpenSSL, and LuaJIT support"
echo ""
echo "----------------------------------------------------------------------------"
install_if_not_exist() {
if dpkg -s "$1" &>/dev/null; then
PKG_EXIST=$(dpkg -s "$1" | grep "install ok installed")
if [[ -n "$PKG_EXIST" ]]; then
return
fi
fi
sudo apt install "$1" -y
}
#run this before execute this script
#sudo apt update -y
if [ $# -eq 0 ]; then
arch="aarch64"
else
arch=$1
fi
mkdir -p $HOME/toolchain/
if [ "$arch" == "x86_64" ]; then
forte_arch="x86_64"
forte_toolchain_dir=""
#comment out to install gcc and g++ compiler
#install_if_not_exist gcc-x86-64-linux-gnu
#install_if_not_exist g++-x86-64-linux-gnu
forte_compiler_prefix="x86_64-linux-gnu-"
forte_cmake_ua_arch="posix"
forte_cmake_arch="Posix"
forte_cmake_luajit_lib="libluajit-5.1.so"
elif [ "$arch" == "x86_w64" ]; then
forte_arch="x86_w64"
forte_toolchain_dir="$HOME/toolchain/xpack-mingw-w64-gcc-13.2.0-1"
# [ ! -d "$forte_toolchain_dir" ] && wget -c https://github.com/xpack-dev-tools/mingw-w64-gcc-xpack/releases/download/v13.2.0-1/xpack-mingw-w64-gcc-13.2.0-1-linux-x64.tar.gz -O $HOME/toolchain/xpack-mingw-w64-gcc-13.2.0-1-linux-x64.tar.gz
# [ ! -d "$forte_toolchain_dir" ] && tar xvf $HOME/toolchain/xpack-mingw-w64-gcc-13.2.0-1-linux-x64.tar.gz -C $HOME/toolchain/
forte_compiler_prefix="x86_64-w64-mingw32-"
forte_cmake_ua_arch="win32"
forte_cmake_arch="Win32"
forte_cmake_extra="-DMINGW:BOOL=ON"
forte_luajit_config="TARGET_SYS=Windows"
forte_cmake_luajit_lib="lua51.dll"
forte_cmake_libs="-lws2_32 -lcrypt32 -lbcrypt"
elif [ "$arch" == "aarch64" ]; then
forte_arch="aarch64"
forte_toolchain_dir="$HOME/toolchain/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu"
# [ ! -d "$forte_toolchain_dir" ] && wget -c https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.3.rel1/binrel/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -O $HOME/toolchain/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz
# [ ! -d "$forte_toolchain_dir" ] && tar xvf $HOME/toolchain/arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu.tar.xz -C $HOME/toolchain/
forte_compiler_prefix="aarch64-none-linux-gnu-"
forte_cmake_ua_arch="posix"
forte_cmake_arch="Posix"
forte_cmake_luajit_lib="libluajit-5.1.so"
#extra module for Raspberry
forte_cmake_extra="-DFORTE_MODULE_SysFs=ON"
elif [ "$arch" == "aarch64-musl" ]; then
forte_arch="aarch64-musl"
forte_toolchain_dir="$HOME/toolchain/aarch64--musl--stable-2023.11-1"
# [ ! -d "$forte_toolchain_dir" ] && wget -c https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--musl--stable-2023.11-1.tar.bz2
# [ ! -d "$forte_toolchain_dir" ] && tar xvf aarch64--musl--stable-2023.11-1.tar.bz2 -C $HOME/toolchain/
#disable musl toolchain python version to prevent mbedtls build failed
[ -L "$forte_toolchain_dir/bin/python" ] && mv $forte_toolchain_dir/bin/python $forte_toolchain_dir/bin/python.bak
[ -L "$forte_toolchain_dir/bin/python3" ] && mv $forte_toolchain_dir/bin/python3 $forte_toolchain_dir/bin/python3.bak
[ -f "$forte_toolchain_dir/bin/python3.11" ] && mv $forte_toolchain_dir/bin/python3.11 $forte_toolchain_dir/bin/python3.11.bak
[ -L "$forte_toolchain_dir/bin/python-config" ] && mv $forte_toolchain_dir/bin/python-config $forte_toolchain_dir/bin/python-config.bak
[ -L "$forte_toolchain_dir/bin/python3-config" ] && mv $forte_toolchain_dir/bin/python3-config $forte_toolchain_dir/bin/python3-config.bak
[ -f "$forte_toolchain_dir/bin/python3.11-config" ] && mv $forte_toolchain_dir/bin/python3.11-config $forte_toolchain_dir/bin/python3.11-config.bak
forte_compiler_prefix="aarch64-linux-"
forte_cmake_ua_arch="posix"
forte_cmake_arch="Posix"
forte_cmake_luajit_lib="libluajit-5.1.a"
forte_cmake_extra="-DFORTE_MODULE_SysFs=ON -DMUSL:BOOL=ON"
else
echo "!!!! Invalid argument! Please check https://blog.kiiota.com/4diacs-forte-cross-build-on-wsl/ "
exit
fi
export PATH=$forte_toolchain_dir/bin:$PATH
forte_root_dir="$PWD"
forte_sources_dir="$forte_root_dir/sources"
forte_build_dir="$forte_root_dir/build/$forte_arch"
forte_install_dir="$forte_root_dir/install/$forte_arch"
[ ! -d "$forte_sources_dir" ] && mkdir -p "$forte_sources_dir"
[ ! -d "$forte_build_dir" ] && mkdir -p "$forte_build_dir"
[ ! -d "$forte_install_dir" ] && mkdir -p "$forte_install_dir"
echo "==== Install package dependencies..."
install_if_not_exist git
install_if_not_exist make
install_if_not_exist cmake
#automake, autoconf, libtool for libmodbus
install_if_not_exist automake
install_if_not_exist autoconf
install_if_not_exist libtool
#python3-jsonschema for mbedtls
install_if_not_exist python3-jsonschema
echo "==== Dependecies install completed"
echo "==== Download dependencies and FORTE source codes..."
cd $forte_sources_dir
if [ ! -d "libmodbus" ]; then
echo "---- Download libmodbus source..."
git clone https://github.com/stephane/libmodbus.git --depth=1
fi
if [ ! -d "LuaJIT" ]; then
echo "---- Download LuaJIT source..."
git clone https://github.com/LuaJIT/LuaJIT.git --depth=1
fi
if [ ! -d "mbedtls" ]; then
echo "---- Download mbedtls source..."
git clone https://github.com/Mbed-TLS/mbedtls.git --depth=1
fi
if [ ! -d "paho.mqtt.c" ]; then
echo "---- Download paho.mqtt.c source..."
git clone https://github.com/eclipse/paho.mqtt.c.git --depth=1
fi
if [ ! -d "open62541" ]; then
echo "---- Download open62541 source..."
git clone https://github.com/open62541/open62541.git -b pack/v1.3.9 --depth=1
cd open62541
git submodule update --init --recursive --depth 1
cd ../
fi
if [ ! -d "org.eclipse.4diac.forte" ]; then
echo "---- Download org.eclipse.4diac.forte source..."
git clone https://git.eclipse.org/r/4diac/org.eclipse.4diac.forte.git -b develop --depth=1
fi
echo "==== Download source codes completed"
echo "==== Build FORTE for $forte_arch target begin..."
echo "==== Build dependencies from sources..."
cd $forte_sources_dir
#build libmodbus if static library not exists
if [ -d "libmodbus" ] && [ ! -e $forte_install_dir/lib/libmodbus.a ]; then
echo "---- Build libmodbus from source..."
cd libmodbus
./autogen.sh &>/dev/null
./configure --with-pic --enable-static --enable-shared=no --host=${forte_compiler_prefix:0:-1} --prefix=$forte_install_dir &>/dev/null
make clean &>/dev/null
make -j4 &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Build libmodbus succeeded"
else
echo "!!!! Build libmodbus failed!"
exit
fi
make install &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Libraries install completed"
else
echo "!!!! Install libmodbus failed!"
exit
fi
make clean &>/dev/null
fi
cd $forte_sources_dir
#build libluajit if shared library not exists
if [ -d "LuaJIT" ] && ([ ! -e $forte_install_dir/lib/libluajit-5.1.so ] && [ ! -e $forte_install_dir/lib/lua51.dll ]); then
echo "---- Build LuaJIT from source..."
cd LuaJIT
make clean &>/dev/null
make -j4 CROSS=$forte_compiler_prefix CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT $forte_luajit_config &>/dev/null
if [[ $? -eq 0 ]]; then
if [ "$forte_arch" == "x86_w64" ]; then
#special tricks for windows
mv src/luajit.exe src/luajit
cp src/lua51.dll $forte_install_dir/lib/
fi
echo "---- Build libluajit succeeded"
else
echo "!!!! Build libluajit failed!"
exit
fi
make install CROSS=$forte_compiler_prefix- CFLAGS=-DLUAJIT_ENABLE_LUA52COMPAT PREFIX=$forte_install_dir &>/dev/null
if [[ $? -eq 0 ]]; then
if [ "$forte_arch" == "x86_w64" ]; then
mv $forte_install_dir/bin/luajit $forte_install_dir/bin/luajit.exe
fi
echo "---- Libraries install completed"
else
echo "!!!! Install libluajit failed!"
exit
fi
make clean &>/dev/null
fi
cd $forte_sources_dir
CMAKE_ARGS=$(cat <<-END
-DCMAKE_C_COMPILER:FILEPATH=${forte_compiler_prefix}gcc \
-DCMAKE_CXX_COMPILER:FILEPATH=${forte_compiler_prefix}g++ \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INSTALL_PREFIX=$forte_install_dir \
-DENABLE_PROGRAMS=OFF \
-DENABLE_TESTING=OFF \
-DCMAKE_C_COMPILER_WORKS=ON \
$forte_cmake_extra
END
)
if [ -d "mbedtls" ] && [ ! -e $forte_install_dir/lib/libmbedcrypto.a ]; then
echo "---- Build libmbedcrypto, libmbedtls, libmbedx509 from source..."
mkdir -p $forte_build_dir/mbedtls
cd $forte_build_dir/mbedtls
#I have to run cmake twice to make it fully applied
cmake -G "Unix Makefiles" "-DCMAKE_C_STANDARD_LIBRARIES=$forte_cmake_libs" $CMAKE_ARGS $forte_sources_dir/mbedtls &>/dev/null
cmake -G "Unix Makefiles" "-DCMAKE_C_STANDARD_LIBRARIES=$forte_cmake_libs" $CMAKE_ARGS $forte_sources_dir/mbedtls &>/dev/null
make -j4 &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Build libmbedcrypto, libmbedtls, libmbedx509 succeeded"
else
echo "!!!! Build libmbedcrypto, libmbedtls, libmbedx509 failed!"
exit
fi
make install &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Libraries install completed"
else
echo "!!!! Install libmbedcrypto, libmbedtls, libmbedx509 failed!"
exit
fi
make clean &>/dev/null
unset CMAKE_ARGS
fi
cd $forte_sources_dir
CMAKE_ARGS=$(cat <<-END
-DCMAKE_C_COMPILER=${forte_compiler_prefix}gcc \
-DCMAKE_CXX_COMPILER=${forte_compiler_prefix}g++ \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INSTALL_PREFIX=$forte_install_dir \
-DPAHO_BUILD_SHARED=OFF \
-DPAHO_BUILD_STATIC=ON \
-DPAHO_ENABLE_TESTING=OFF \
-DPAHO_HIGH_PERFORMANCE=TRUE \
-DPAHO_WITH_SSL=OFF \
-DOPENSSL_INCLUDE_DIR=$forte_install_dir/include \
-DOPENSSL_ROOT_DIR=$forte_install_dir \
-DCMAKE_C_COMPILER_WORKS=ON \
$forte_cmake_extra
END
)
if [ -d "paho.mqtt.c" ] && [ ! -e $forte_install_dir/lib/libpaho-mqtt3a.a ]; then
echo "---- Build libpaho-mqtt from source..."
mkdir -p $forte_build_dir/paho.mqtt.c
cd $forte_build_dir/paho.mqtt.c
#I have to run cmake twice to make it fully applied
cmake -G "Unix Makefiles" $CMAKE_ARGS $forte_sources_dir/paho.mqtt.c &>/dev/null
cmake -G "Unix Makefiles" $CMAKE_ARGS $forte_sources_dir/paho.mqtt.c &>/dev/null
make -j4 &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Build libpaho-mqtt succeeded"
else
echo "!!!! Build libpaho-mqtt failed!"
exit
fi
make install &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Libraries install completed"
else
echo "!!!! Install libpaho-mqtt failed!"
exit
fi
make clean &>/dev/null
unset CMAKE_ARGS
fi
cd $forte_sources_dir
CMAKE_ARGS=$(cat <<-END
-DCMAKE_C_COMPILER=${forte_compiler_prefix}gcc \
-DCMAKE_CXX_COMPILER=${forte_compiler_prefix}g++ \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INSTALL_PREFIX=$forte_install_dir \
-DUA_ARCHITECTURE=$forte_cmake_ua_arch \
-DUA_ENABLE_AMALGAMATION=ON \
-DUA_ENABLE_DISCOVERY=ON \
-DUA_ENABLE_DISCOVERY_MULTICAST=ON \
-DUA_ENABLE_ENCRYPTION=MBEDTLS \
-DMBEDTLS_INCLUDE_DIR=$forte_install_dir/include \
-DMBEDCRYPTO_LIBRARY=$forte_install_dir/lib/libmbedcrypto.a \
-DMBEDTLS_LIBRARY=$forte_install_dir/lib/libmbedtls.a \
-DMBEDX509_LIBRARY=$forte_install_dir/lib/libmbedx509.a \
-DCMAKE_C_COMPILER_WORKS=ON \
$forte_cmake_extra
END
)
if [ -d "open62541" ] && [ ! -e $forte_install_dir/lib/libopen62541.a ]; then
echo "---- Build libopen62541 from source..."
mkdir -p $forte_build_dir/open62541
cd $forte_build_dir/open62541
#I have to run cmake twice to make it fully applied
cmake -G "Unix Makefiles" $CMAKE_ARGS "-DCMAKE_C_FLAGS_MINSIZEREL:STRING=-Wno-error -Os -DNDEBUG" $forte_sources_dir/open62541 &>/dev/null
cmake -G "Unix Makefiles" $CMAKE_ARGS "-DCMAKE_C_FLAGS_MINSIZEREL:STRING=-Wno-error -Os -DNDEBUG" $forte_sources_dir/open62541 &>/dev/null
make -j4 &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Build libopen62541 succeeded"
else
echo "!!!! Build libopen62541 failed!"
exit
fi
make install &>/dev/null
if [[ $? -eq 0 ]]; then
echo "---- Libraries installed in $forte_install_dir"
else
echo "!!!! Install libopen62541 failed!"
exit
fi
make clean &>/dev/null
unset CMAKE_ARGS
fi
echo "==== Dependencies build completed"
echo "==== Build 4diac's FORTE from sources..."
cd $forte_sources_dir
CMAKE_ARGS=$(cat <<-END
-DCMAKE_C_COMPILER=${forte_compiler_prefix}gcc \
-DCMAKE_CXX_COMPILER=${forte_compiler_prefix}g++ \
-DCMAKE_BUILD_TYPE=MinSizeRel \
-DCMAKE_INSTALL_PREFIX=$forte_install_dir \
-DFORTE_ARCHITECTURE=$forte_cmake_arch \
-DFORTE_COM_HTTP=ON \
-DFORTE_COM_SER=ON \
-DFORTE_COM_MODBUS=ON \
-DFORTE_COM_MODBUS_LIB_DIR=$forte_install_dir \
-DFORTE_COM_OPC_UA=ON \
-DFORTE_COM_OPC_UA_ENCRYPTION=ON \
-DFORTE_COM_OPC_UA_INCLUDE_DIR=$forte_install_dir/include \
-DFORTE_COM_OPC_UA_LIB=libopen62541.a \
-DFORTE_COM_OPC_UA_LIB_DIR=$forte_install_dir/lib \
-DFORTE_COM_OPC_UA_MULTICAST=ON \
-DFORTE_COM_PAHOMQTT=ON \
-DFORTE_COM_PAHOMQTT_INCLUDE_DIR=$forte_install_dir/include \
-DFORTE_COM_PAHOMQTT_LIB=libpaho-mqtt3a.a \
-DFORTE_COM_PAHOMQTT_LIB_DIR=$forte_install_dir/lib \
-DFORTE_EXTERNAL_MODULES_DIRECTORY=$forte_root_dir/ext_modules \
-DFORTE_MODULE_CONVERT=ON \
-DFORTE_MODULE_IEC61131=ON \
-DFORTE_MODULE_RECONFIGURATION=ON \
-DFORTE_MODULE_RT_Events=ON \
-DFORTE_MODULE_UTILS=ON \
-DFORTE_MODULE_KUMAJAYA=ON \
-DFORTE_USE_LUATYPES=LuaJIT \
-DLUAJIT_INCLUDE_DIR=$forte_install_dir/include/luajit-2.1 \
-DLUAJIT_LIBRARY=$forte_install_dir/lib/$forte_cmake_luajit_lib \
-DFORTE_COM_OPC_UA_ENCRYPTION_MBEDTLS=ON \
-DFORTE_COM_OPC_UA_ENCRYPTION_INCLUDE_DIR=$forte_install_dir/include \
-DFORTE_COM_OPC_UA_ENCRYPTION_LIB_DIR=$forte_install_dir/lib \
-DFORTE_IPLayerRecvBufferSize=25000 \
-DFORTE_TESTS=OFF \
$forte_cmake_extra
END
)
#let forte build multiple time
if [ -d "org.eclipse.4diac.forte" ]; then
echo "---- Build FORTE from source..."
mkdir -p $forte_build_dir/org.eclipse.4diac.forte
cd $forte_build_dir/org.eclipse.4diac.forte
#I have to run cmake twice to make it fully applied
cmake -G "Unix Makefiles" $CMAKE_ARGS "-DCMAKE_CXX_STANDARD_LIBRARIES:STRING=$forte_cmake_libs" $forte_sources_dir/org.eclipse.4diac.forte &>/dev/null
cmake -G "Unix Makefiles" $CMAKE_ARGS "-DCMAKE_CXX_STANDARD_LIBRARIES:STRING=$forte_cmake_libs" $forte_sources_dir/org.eclipse.4diac.forte
make -j4
if [[ $? -eq 0 ]]; then
if [ "$forte_arch" == "x86_w64" ]; then
#special tricks for windows
[ -f "src/CMakeFiles/CMakeRelink.dir/forte.exe" ] && mv src/CMakeFiles/CMakeRelink.dir/forte.exe src/CMakeFiles/CMakeRelink.dir/forte
fi
echo "---- Build forte succeeded"
else
echo "!!!! Build forte failed!"
exit
fi
make install
if [[ $? -eq 0 ]]; then
${forte_compiler_prefix}strip $forte_install_dir/bin/forte
if [ "$forte_arch" == "x86_w64" ]; then
mv $forte_install_dir/bin/forte $forte_install_dir/bin/forte.exe
#copy the only library needed by forte
cp $forte_install_dir/lib/lua51.dll $forte_install_dir/bin/
[ -f "src/CMakeFiles/CMakeRelink.dir/forte" ] && mv src/CMakeFiles/CMakeRelink.dir/forte src/CMakeFiles/CMakeRelink.dir/forte.exe
fi
echo "---- Binary installed in $forte_install_dir"
else
echo "!!!! Install forte failed!"
echo "!!!! Try run the script once again."
exit
fi
fi
echo "==== Build 4diac's FORTE completed"
echo "==== Build 4diac's FORTE for $forte_arch end"