Cross-compiling and building a package for Synology DSM
The main source of information is the official DSM Developer Guide , which
outlines how to work with the toolchain (installation, compilation of open source projects, packaging). Because A budget version of the DS 114 was purchased , which has a Marvell Armada 370 and a DSM 5.2 firmware version under the hood, then everything will be assembled under arm.
To prepare the environment I will usepackage toolkit , which can be downloaded from the Synology Open Source Project project page . This is a little more convenient, because devices in different price categories come with different processors, which requires downloading several sets of tools.
See the What kind of CPU does my NAS have page for more details .
unpack package toolkit pump out the environment and tools
$ mkdir -p ~/synology/toolkit
$ tar xvf pkgscripts.tgz -C ~/synology/toolkit
$ cd ~/synology/toolkit/pkgscripts/
$ sudo ./EnvDeploy -v 5.2 -p armada370
Boost
Boost is surprisingly easy to build. In the file ~ / user-config.jam we register and collect:
using gcc : arm : arm-marvell-linux-gnueabi-g++ ;
$ ./bootstrap.sh --prefix=/home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/arm-marvell-linux-gnueabi/libc
$ export PATH=~/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/bin:$PATH
$ ./b2 toolset=gcc-arm link=static threading=multi install
Webtoolkit
To configure CMake, I use the toolchain-file toolchain-arm-marvell.cmake
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_C_COMPILER /home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabi-g++)
SET(CMAKE_LINKER /home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabi-ld.gold)
SET(CMAKE_FIND_ROOT_PATH /home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/arm-marvell-linux-gnueabi/libc)
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)
Further:
$ tar xvf wt-3.3.4.tar.gz
$ cd wt-3.3.4
$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=~/toolchain-arm-marvell.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DSHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX=/home/dmitry/synology/toolkit/build_env/ds.armada370-5.2/usr/local/arm-marvell-linux-gnueabi/arm-marvell-linux-gnueabi/libc \
..
$ make
$ make install
I am collecting an example that I will package:
$ cd examples/composer
$ make
I check the received file:
$ file Home.wt
Home.wt: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, BuildID[sha1]=228a30c3dab0572993e41468aa0862fc93e11487, not stripped
Qt5
In the Qt source directory, go to qtbase / mkspecs / devices .
Create the armada370 directory, with the contents of
qmake.conf
include(../common/linux_device_pre.conf)
QMAKE_INCDIR += $$[QT_SYSROOT]/usr/include
QMAKE_LIBDIR += $$[QT_SYSROOT]/lib
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_LINK = $${CROSS_COMPILE}g++
QMAKE_LINK_SHLIB = $${CROSS_COMPILE}g++
QMAKE_AR = $${CROSS_COMPILE}ar cqs
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
QMAKE_STRIP = $${CROSS_COMPILE}strip
QMAKE_CFLAGS += -march=armv7-a -mfpu=vfpv3-d16
QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
DISTRO_OPTS += hard-float
QT_QPA_DEFAULT_PLATFORM = eglfs
include(../common/linux_arm_device_post.conf)
load(qt_config)
-mfpu = vfpv3-d16 is fpu optimization , and DISTRO_OPTS is responsible for hard-float / soft-float.
qplatformdefs.h is standard from the configuration for other ARMs.
When calling configure, you must pass:
- -device armada370
- -device-option CROSS_COMPILE = arm-marvell-linux-gnueabi-
- -sysroot ... / arm-marvell-linux-gnueabi / arm-marvell-linux-gnueabi / libc
#!/bin/bash
CFG=''
CFG+=' -opensource'
CFG+=' -confirm-license'
CFG+=' -v'
CFG+=' -static'
CFG+=' -device armada370'
CFG+=' -make libs'
CFG+=' -device-option CROSS_COMPILE=/usr/local/arm-marvell-linux-gnueabi/bin/arm-marvell-linux-gnueabi- '
CFG+=' -sysroot /usr/local/arm-marvell-linux-gnueabi/arm-marvell-linux-gnueabi/libc'
CFG+=' -release'
CFG+=' -nomake tools'
CFG+=' -nomake examples'
CFG+=' -no-compile-examples'
CFG+=' -no-dbus'
CFG+=' -no-gui'
CFG+=' -no-widgets'
CFG+=' -qt-sql-sqlite'
CFG+=' -D QT_NO_GRAPHICSVIEW'
CFG+=' -D QT_NO_GRAPHICSEFFECT'
CFG+=' -D QT_NO_STYLESHEET'
CFG+=' -D QT_NO_STYLE_CDE'
CFG+=' -D QT_NO_STYLE_CLEANLOOKS'
CFG+=' -D QT_NO_STYLE_MOTIF'
CFG+=' -D QT_NO_STYLE_PLASTIQUE'
CFG+=' -no-qml-debug'
CFG+=' -no-alsa'
CFG+=' -no-cups'
CFG+=' -no-dbus'
CFG+=' -no-directfb'
CFG+=' -no-evdev'
CFG+=' -no-gtkstyle'
CFG+=' -no-kms'
CFG+=' -no-libudev'
CFG+=' -no-linuxfb'
CFG+=' -no-mtdev'
CFG+=' -no-nis'
CFG+=' -no-pulseaudio'
CFG+=' -no-sm'
CFG+=' -no-xcb'
CFG+=' -no-xcb-xlib'
CFG+=' -no-xinerama'
CFG+=' -no-xinput2'
CFG+=' -no-xkb'
CFG+=' -no-xrender'
CFG+=' -no-icu'
CFG+=' -no-use-gold-linker'
CFG+=' -no-eglfs'
CFG+=' -no-cups'
CFG+=' -no-fontconfig'
CFG+=' -no-sse2'
CFG+=' -no-sse3'
CFG+=' -no-sse4.1'
CFG+=' -no-avx'
CFG+=' -no-opengl'
cd qtbase
./configure $CFG "$@"
$ sudo chroot ~/synology/toolkit/build_env/ds.armada370-5.2/
$ cd /root/qt-everywhere-opensource-src-5.5.0/
$ ./conf.sh
$ cd qtbase
$ make
$ make install
Packaging
The package has the extension spk, represents from a file archive. The structure of the minimal package looks like:

INFO - a text file with a description of the package:
scripts - scripts executed at different stages of installing / uninstalling the package, and a script to run the daemon;
package.tgz - compressed archive containing executable files, libraries, resources, etc.
The composer.skp package compiled has the structure:

composer.wt , composer.xml , composer.css and paperclip.png taken from the Wt example and are not of interest.
INFO
package="composer"
displayname="Mail composer"
version="1.0.0"
arch="armada370"
description="This example implements a GMail-like mail composer and shows among other things how to upload files asynchronously, showing a cross-browser upload progress bar and with support for multiple files."
maintainer="Wt"
dsmuidir=ui
dsmuidir is an optional variable needed to automatically create a link from / volumeX / @ appstore / [packge name] / [dsmuidir] to / usr / syno / synoman / webman / 3rdparty / [package name] . / volumeX / @ appstore / [packge name] , where X = 1,2..N is the path where the installed application will be located. / usr / syno / synoman / webman / 3rdparty / [package name] path for integration into the DSM UI.
config
To integrate into the DSM UI, you need to create the directory / usr / syno / synoman / webman / 3rdparty / [package name] and place the config file with approximate contents there:
{
".url": {
"eu.webtoolkit.composer": {
"type": "url",
"allUsers": true,
"title": "Mail composer",
"desc":"This example implements a GMail-like mail composer and shows among other things how to upload files asynchronously, showing a cross-browser upload progress bar and with support for multiple files.",
"icon":"composer_{0}.png",
"url": "3rdparty/composer/index.cgi"
}
}
}
composer_ {0} .png - the placeholder is replaced by composer_48.png / composer_64.png / composer_72.png / composer_256.png.
url - the path to html / cgi that will open in a new window, when you click on the application. In / usr / syno / synoman / webman / 3rdparty / [package name] html, js, css, cgi, images are allowed. But slipping php did not work.
index.cgi
#!/bin/sh
if [ `ifconfig | grep bond0 | awk '{print $1}'` ]
then
IP_ADDR=`ifconfig bond0 | grep "inet addr" | awk '{print $2}' | awk -F: '{print $2}'`
else
IP_ADDR=`ifconfig eth0 | grep "inet addr" | awk '{print $2}' | awk -F: '{print $2}'`
fi
echo Location: http://$IP_ADDR:8585
echo ""
exit
A simple cgi script redirecting to an application written in Wt.
start-stop-status
#!/bin/sh
case $1 in
start)
${SYNOPKG_PKGDEST}/composer.wt --docroot=${SYNOPKG_PKGDEST} --approot=${SYNOPKG_PKGDEST} --http-address=0.0.0.0 --http-port=8585 &
exit 0
;;
stop)
pkill composer.wt
exit 0
;;
restart)
exit 0;
;;
status)
if [ "$?" = "0" ]; then
exit 0
else
exit 1
fi
;;
log)
exit 0
;;
esac
Start stop application.
conclusions
In the case of Synology, the use of the toolchain has its pros and cons.
Possible advantages:
- no need to collect and put the necessary system libraries;
- You can enable additional cpu optimizations.
Possible cons:
- You may have to do builds for each toolchain.
The QNAP toolchain turned out to be ancient and had to be bypassed, but that's a different story.