На новом месте работы мне поставили задачу запустить продукт на NAS от производителей Synology и QNAP. Продукт написан на C++ с применением C++11, Boost и Qt5. За неимением свободного веб разработчика, интерфейс был написан наWt, который в свою очередь для сборки использует CMake. Под катом будет сборка этого зоопарка и создания простого пакета.
Основной источник информации официальное руководство DSM Developer Guide,
описывающий в общих чертах работу с toolchain(установка, компиляция open source проектов, пакетирование). Т.к. был куплен бюджетный вариант DS 114, который имеет под капотом Marvell Armada 370 и версию прошивки DSM 5.2, то все будет собираться под arm.
Для подготовки окружения буду использовать package toolkit, который можно скачать со страницы проекта Synology Open Source Project. Это немного удобней, потому что устройства в разных ценовых категориях поставляются с разными процессорами, что требует скачивания нескольких наборов инструментов.
Подробней можно посмотреть на странице What kind of CPU does my NAS have.
распаковываем package toolkit
выкачиваем окружение и инструменты
Boost на удивление собирается довольно просто. В фай ~/user-config.jam прописываем
и собираем:
Для настройки CMake использую toolchain-файл toolchain-arm-marvell.cmake
Дальше:
Собираю пример, который буду пакетировать:
Проверяю полученный файл:
В каталоге исходников Qt идем в qtbase/mkspecs/devices.
Создаем каталог armada370, с содержимым
qmake.conf
-mfpu=vfpv3-d16 — это оптимизация fpu, а DISTRO_OPTS отвечает за hard-float/soft-float.
qplatformdefs.h взял стандартным из конфигурации для других ARM.
При вызове configure необходимо передать:
Пакет имеет расширение spk, представляет из файловый архив. Структура минимального пакета имеет вид:
INFO — текстовый файл с описанием пакета:
scripts — скрипты выполняемые на разных этапах установки/удаления пакета, и скрипт запуска демона;
package.tgz — сжатый архив содержащий исполняемые файлы, библиотеки, ресурсы и т. д.
Собранный пакет composer.skp имеет структуру:
composer.wt, composer.xml, composer.css и paperclip.png взяты из примера Wt и интереса не вызывают.
dsmuidir опциональная переменная, необходимая для автоматической создания ссылки с /volumeX/@appstore/[packge name]/[dsmuidir] на /usr/syno/synoman/webman/3rdparty/[package name]. /volumeX/@appstore/[packge name], где X=1,2..N — путь по которому будет находится установленное приложение. /usr/syno/synoman/webman/3rdparty/[package name] путь для интеграции в UI DSM.
Для интеграции в UI DSM нужно создать каталог /usr/syno/synoman/webman/3rdparty/[package name] и поместить туда файл config примерного содержания:
composer_{0}.png — плейсхолдер заменяется на composer_48.png/composer_64.png/composer_72.png/composer_256.png.
url — путь к html/cgi который будет открываться в новом окне, при нажатии на приложение. В /usr/syno/synoman/webman/3rdparty/[package name] допускается html, js, css, cgi, изображения. А вот подсунуть php не получилось.
Простой cgi скрипт перенаправляющий на приложение написанный на Wt.
Запуск остановка приложения.
В случае с Synology использование toolchain имеет свои плюсы и минусы.
Возможные плюсы:
Возможные минусы:
У QNAP toolchain оказался древним и пришлось идти в обход, но это другая история.
Основной источник информации официальное руководство DSM Developer Guide,
описывающий в общих чертах работу с toolchain(установка, компиляция open source проектов, пакетирование). Т.к. был куплен бюджетный вариант DS 114, который имеет под капотом Marvell Armada 370 и версию прошивки DSM 5.2, то все будет собираться под arm.
Для подготовки окружения буду использовать package toolkit, который можно скачать со страницы проекта Synology Open Source Project. Это немного удобней, потому что устройства в разных ценовых категориях поставляются с разными процессорами, что требует скачивания нескольких наборов инструментов.
Подробней можно посмотреть на странице What kind of CPU does my NAS have.
распаковываем package toolkit
$ mkdir -p ~/synology/toolkit
$ tar xvf pkgscripts.tgz -C ~/synology/toolkit
выкачиваем окружение и инструменты
$ cd ~/synology/toolkit/pkgscripts/
$ sudo ./EnvDeploy -v 5.2 -p armada370
Boost
Boost на удивление собирается довольно просто. В фай ~/user-config.jam прописываем
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
Для настройки CMake использую toolchain-файл 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)
Дальше:
$ 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
Собираю пример, который буду пакетировать:
$ cd examples/composer
$ make
Проверяю полученный файл:
$ 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
В каталоге исходников Qt идем в qtbase/mkspecs/devices.
Создаем каталог armada370, с содержимым
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 — это оптимизация fpu, а DISTRO_OPTS отвечает за hard-float/soft-float.
qplatformdefs.h взял стандартным из конфигурации для других ARM.
При вызове configure необходимо передать:
- -device armada370
- -device-option CROSS_COMPILE=arm-marvell-linux-gnueabi-
- -sysroot .../arm-marvell-linux-gnueabi/arm-marvell-linux-gnueabi/libc
Собирал в chroot'е
conf.sh:
#!/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
Пакетирование
Пакет имеет расширение spk, представляет из файловый архив. Структура минимального пакета имеет вид:
INFO — текстовый файл с описанием пакета:
scripts — скрипты выполняемые на разных этапах установки/удаления пакета, и скрипт запуска демона;
package.tgz — сжатый архив содержащий исполняемые файлы, библиотеки, ресурсы и т. д.
Собранный пакет composer.skp имеет структуру:
composer.wt, composer.xml, composer.css и paperclip.png взяты из примера Wt и интереса не вызывают.
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 опциональная переменная, необходимая для автоматической создания ссылки с /volumeX/@appstore/[packge name]/[dsmuidir] на /usr/syno/synoman/webman/3rdparty/[package name]. /volumeX/@appstore/[packge name], где X=1,2..N — путь по которому будет находится установленное приложение. /usr/syno/synoman/webman/3rdparty/[package name] путь для интеграции в UI DSM.
config
Для интеграции в UI DSM нужно создать каталог /usr/syno/synoman/webman/3rdparty/[package name] и поместить туда файл config примерного содержания:
{
".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 — плейсхолдер заменяется на composer_48.png/composer_64.png/composer_72.png/composer_256.png.
url — путь к html/cgi который будет открываться в новом окне, при нажатии на приложение. В /usr/syno/synoman/webman/3rdparty/[package name] допускается html, js, css, cgi, изображения. А вот подсунуть php не получилось.
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
Простой cgi скрипт перенаправляющий на приложение написанный на 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
Запуск остановка приложения.
Выводы
В случае с Synology использование toolchain имеет свои плюсы и минусы.
Возможные плюсы:
- не надо собирать и класть необходимые системные библиотеки;
- можно включить дополнительные оптимизации по cpu.
Возможные минусы:
- возможно придется делать сборки под каждый toolchain.
У QNAP toolchain оказался древним и пришлось идти в обход, но это другая история.