TL;DR: Новичок увидел Haiku в первый раз, пробует портировать некоторые программы из мира Linux.



Моя первая портированная для Haiku программа, упакованная в ее формат hpkg


Недавно я открыл для себя Haiku, неожиданно хорошую операционную систему для ПК.
Сегодня я буду учиться переносить новые программы на эту операционку. Основной упор — описание первого опыта перехода на Haiku с точки зрения разработчика для Linux. Прошу прощения за глупые ошибки, совершенные в процессе, ведь с тех пор, как я впервые загрузил Haiku, не прошло и недели.


Я хочу достичь трех целей:


  • Портировать простое CLI приложение
  • Портировать приложение с GUI на Qt
  • Упаковать их потом в формат hpkg (поскольку я все еще думаю об адаптации AppDir и AppImage для Haiku...)

Приступим. В разделах документация и разработка, а также в wiki от HaikuPorts я нашел нужное направление. Есть даже онлайн книга PDF BeOS: Портирование приложения Unix.
467 страниц — и это с 1997 года! Заглядывать внутрь страшно, но надеюсь на лучшее. Обнадеживают слова разработчика: "долго, потому что BeOS не была POSIX-совместимой", зато Haiku "по большей части» уже такая.


Портирование простого приложения CLI


Первой мыслью было портировать приложение avrdude, но, как оказалось, это уже сделали давным-давно.


Первая попытка: нечего смотреть


Чего мне никак не понять, так это того, что уже более 10 лет приложения портируются для Haiku — при том, что самой ОС еще даже версии 1.0 нет.


Вторая попытка: нужно переписать


Итак, я буду использовать ptouch-770, CLI для управления принтером Brother P-Touch 770, на котором я печатаю этикетки.
Я на нем печатаю различные этикетки, и вы его, возможно, уже видели в прошлой статье. Чуть ранее я написал небольшую программу-обертку с GUI на Python (поскольку она на Gtk+ — придется переписать, а это хороший повод подучиться).



Принтер для этикеток Brother P-Touch 770. Заработает ли под Haiku?


Менеджер пакетов Haiku знает о библиотеках и командах, поэтому если я получаю сообщение "can't find libintl" при запуске configure — просто запускаю pkgman install devel:libintl и нужный пакет будет найден. Аналогично pkgman install cmd:rsync. Ну, и т.д.


За исключением случаев, когда это не работает:


/Haiku/home> git clone https://github.com/probonopd/ptouch-770
Cloning into 'ptouch-770'...
remote: Enumerating objects: 134, done.
remote: Total 134 (delta 0), reused 0 (delta 0), pack-reused 134
Receiving objects: 100% (134/134), 98.91 KiB | 637.00 KiB/s, done.
Resolving deltas: 100% (71/71), done./Haiku/home> cd ptouch-770//Haiku/home/ptouch-770> make
gcc -Wall -O2 -c -o ptouch-770-write.o ptouch-770-write.c
ptouch-770-write.c:28:10: fatal error: libudev.h: No such file or directory
 #include <libudev.h>
          ^~~~~~~~~~~
compilation terminated.
Makefile:16: recipe for target 'ptouch-770-write.o' failed
make: *** [ptouch-770-write.o] Error 1/Haiku/home/ptouch-770> pkgman install devel:libudev
100% repochecksum-1 [65 bytes]
Validating checksum for Haiku...done.
100% repochecksum-1 [64 bytes]
Validating checksum for HaikuPorts...done.
*** Failed to find a match for "devel:libudev": Name not found/Haiku/home/ptouch-770> pkgman install devel:udev
100% repochecksum-1 [65 bytes]
Validating checksum for Haiku...done.
100% repochecksum-1 [64 bytes]
Validating checksum for HaikuPorts...done.
*** Failed to find a match for "devel:udev": Name not found

Возможно udev слишком линуксячий, поэтому не существует для Haiku. Что означает необходимость правки исходного кода, который я пытаюсь скомпилировать.
Эх, выше головы не прыгнешь, и я даже не знаю, с чего начать.


Третья попытка


Было бы неплохо иметь tmate для Haiku, тогда я разрешил бы разработчикам Haiku подключаться к моей терминальной сессии — на случай, если что-то пойдет не так. Инструкции достаточно простые:


./autogen.sh
./configure
make
make install

Выглядит неплохо, ну так почему бы и не попробовать это на Haiku?


/Haiku/home> git clone https://github.com/tmate-io/tmate/Haiku/home> cd tmate//Haiku/home/tmate> ./autogen.sh
(...)/Haiku/home/tmate> ./configure
(...)
checking for libevent... no
checking for library containing event_init... no
configure: error: "libevent not found"/Haiku/home/tmate> pkgman install devel:libevent
(...)
The following changes will be made:
  in system:
    install package libevent21-2.1.8-2 from repository HaikuPorts
    install package libevent21_devel-2.1.8-2 from repository HaikuPorts
Continue? [yes/no] (yes) :
100% libevent21-2.1.8-2-x86_64.hpkg [965.22 KiB]
(...)
[system] Done.checking for ncurses... no
checking for library containing setupterm... no
configure: error: "curses not found"/Haiku/home/tmate> pkgman install devel:libcurses
(...)
*** Failed to find a match for "devel:libcurses": Name not found/Haiku/home/tmate> pkgman install devel:curses
(...)
*** Failed to find a match for "devel:curses": Name not found

На этом шаге я открываю HaikuDepot и ищу curses.
Что-то таки нашлось, что и дало мне подсказку для более грамотного запроса:


/Haiku/home/tmate> pkgman install devel:libncurses
(...)
100% ncurses6_devel-6.1-1-x86_64.hpkg [835.62 KiB]
(...)./configure
(...)
checking for msgpack >= 1.1.0... no
configure: error: "msgpack >= 1.1.0 not found"/Haiku/home/tmate> pkgman install devel:msgpack
(...)
*** Failed to find a match for "devel:msgpack": Name not found/Haiku/home/tmate> pkgman install devel:libmsgpack
(...)
*** Failed to find a match for "devel:libmsgpack": Name not found

Опять пошел в HaikuDepot, и, конечно же, нашел devel:msgpack_c_cpp_devel. Что за странные имена?


/Haiku/home/tmate> pkgman install devel:msgpack_c_cpp_devel
100% repochecksum-1 [65 bytes]
Validating checksum for Haiku...done.
100% repochecksum-1 [64 bytes]
Validating checksum for HaikuPorts...done.
*** Failed to find a match for "devel:msgpack_c_cpp_devel": Name not found# Why is it not finding it? To hell with the "devel:".../Haiku/home/tmate> pkgman install msgpack_c_cpp_devel
(...)
The following changes will be made:
  in system:
    install package msgpack_c_cpp-3.1.1-1 from repository HaikuPorts
    install package msgpack_c_cpp_devel-3.1.1-1 from repository HaikuPorts
Continue? [yes/no] (yes) :
(...)/Haiku/home/tmate> ./configure
(...)
checking for libssh >= 0.8.4... no
configure: error: "libssh >= 0.8.4 not found"/Haiku/home/tmate> pkgman install devel:libssh/Haiku/home/tmate> make
(...)
In file included from /boot/system/develop/headers/msgpack.h:22,
                 from tmate.h:5,
                 from cfg.c:29:
/boot/system/develop/headers/msgpack/vrefbuffer.h:19:8: error: redefinition of struct iovec'
 struct iovec {
        ^~~~~
In file included from tmux.h:27,
                 from cfg.c:28:
/boot/system/develop/headers/posix/sys/uio.h:12:16: note: originally defined here
 typedef struct iovec {
                ^~~~~
Makefile:969: recipe for target 'cfg.o' failed
make: *** [cfg.o] Error 1

На этом шаге я осознал, что перенос программы на Haiku требует значительно больше знаний, чем нужно для простой пересборки.
Я поговорил с дружелюбными разработчиками Haiku, оказалось, что есть ошибка в msgpack, а через несколько минут я вижу patch, в HaikuPorts. Воочию наблюдаю, как исправленный пакет собирается здесь (buildslave — виртуальные машины).



Сборка исправленного msgpack на buildmaster


Между делом отправляю patch в upstream для добавления поддержки Haiku в msgpack.


Пять минут спустя обновленный msgpack уже доступен в Haiku:


/Haiku/home/tmate> pkgman update
(...)
The following changes will be made:
  in system:
    upgrade package msgpack_c_cpp-3.1.1-1 to 3.2.0-2 from repository HaikuPorts
    upgrade package msgpack_c_cpp_devel-3.1.1-1 to 3.2.0-2 from repository HaikuPorts
Continue? [yes/no] (yes) : y
100% msgpack_c_cpp-3.2.0-2-x86_64.hpkg [13.43 KiB]
(...)
[system] Done.

Неожиданно хорошо. Это я сказал?!


Возвращаюсь обратно к исходной задаче:


/Haiku/home/tmate> make
(...)
In file included from tmux.h:40,
                 from tty.c:32:
compat.h:266: warning: "AT_FDCWD" redefined
 #define AT_FDCWD -100

In file included from tty.c:25:
/boot/system/develop/headers/posix/fcntl.h:62: note: this is the location of the previous definition
 #define AT_FDCWD  (-1)  /* CWD FD for the *at() functions */

tty.c: In function 'tty_init_termios':
tty.c:278:48: error: 'IMAXBEL' undeclared (first use in this function); did you mean 'MAXLABEL'?
  tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|IMAXBEL|ISTRIP);
                                                ^~~~~~~
                                                MAXLABEL
tty.c:278:48: note: each undeclared identifier is reported only once for each function it appears in
Makefile:969: recipe for target 'tty.o' failed
make: *** [tty.o] Error 1

Сейчас, похоже, msgpack не виновен. Комментирую IMAXLABEL в tty.c так:


tio.c_iflag &= ~(IXON|IXOFF|ICRNL|INLCR|IGNCR|/*IMAXBEL|*/ISTRIP);

Результат:


osdep-unknown.c: In function 'osdep_get_cwd':
osdep-unknown.c:32:19: warning: unused parameter 'fd' [-Wunused-parameter]
 osdep_get_cwd(int fd)
               ~~~~^~
make: *** No rule to make target 'compat/forkpty-unknown.c', needed by 'compat/forkpty-unknown.o'.  Stop.

Ну вот, опять… Кстати:


/Haiku/home/tmate> ./configure | grep -i OPENAT
checking for openat... no

mr. waddlesplash подсказывает, куда копать:


/Haiku/home/tmate> ./configure LDFLAGS="-lbsd"
(...)/Haiku/home/tmate> make
(...)
In file included from tmux.h:40,
                 from window.c:31:
compat.h:266: warning: "AT_FDCWD" redefined
 #define AT_FDCWD -100

In file included from window.c:22:
/boot/system/develop/headers/posix/fcntl.h:62: note: this is the location of the previous definition
 #define AT_FDCWD  (-1)  /* CWD FD for the *at() functions */

make: *** No rule to make target 'compat/forkpty-unknown.c', needed by 'compat/forkpty-unknown.o'.  Stop.

Здесь я выложил config.log.


Мне пояснили, что к libresolv на Haiku есть что-то еще в libnetwork. По всей видимости надо дальше править код. Надо подумать...


find . -type f -exec sed -i -e 's|lresolv|lnetwork|g'  {} \;

Извечный вопрос: что же происходит.


/Haiku/home/tmate> ./configure LDFLAGS="-lbsd"
(...)/Haiku/home/tmate> make
(...)
# Success!# Let's run it:/Haiku/home/tmate> ./tmate
runtime_loader: /boot/system/lib/libssh.so.4.7.2: Could not resolve symbol '__stack_chk_guard'
resolve symbol "__stack_chk_guard" returned: -2147478780
runtime_loader: /boot/system/lib/libssh.so.4.7.2: Troubles relocating: Symbol not found

То же, только в профиль. Погуглил и нашел это. Если добавить -lssp "иногда" помогает, пробую:


/Haiku/home/tmate> ./configure LDFLAGS="-lbsd -lssp"
(...)/Haiku/home/tmate> make
(...)/Haiku/home/tmate> ./tmate

Ух ты! Оно запускается! Но...


[tmate] ssh.tmate.io lookup failure. Retrying in 2 seconds (non-recoverable failure in name resolution)

Попробую отладить, файл тут:


/Haiku/home/tmate> strace -f ./tmate >log 2>&1

"Bad port ID" — это уже как визитка хайку. Может, кто-то представляет, что не так, и как это поправить? Если что, я обновлю статью. Ссылка на GitHub.


Портирование GUI приложения на Qt.


Выбираю простое приложение QML.


/> cd /Haiku/home//Haiku/home> git clone https://github.com/probonopd/QtQuickApp
/Haiku/home/QtQuickApp> qmake .
/Haiku/home/QtQuickApp> make
/Haiku/home/QtQuickApp> ./QtQuickApp # Works!

Реально просто. Меньше минуты!


Упаковка приложений в hpkg используя haikuporter и haikuports.


С чего бы начать? Нет простейшей документации, иду на канал #haiku в irc.freenode.net и слышу:


  • Команда package — низкоуровневый способ создания пакетов. По большей части ей достаточно PackageInfo, как описано в разделе "Making it into a proper .hpkg package"
  • Мне надо сделать что-то такое
  • Можно использовать hpkg-creator (у меня вылетает, отчет об ошибках)

Непонятно, что делать. Полагаю, мне нужно пособие для новичков в стиле "Привет, Мир!", в идеале — видео. Было бы неплохо еще обзавестись удобным введением в HaikuPorter, как сделано в GNU hello.


Читаю следующее:


haikuporter это инструмент для создания общих пакетных проектов для Haiku. Он использует репозиторий HaikuPorts в качестве базы для всех пакетов. Для создания пакетов используются рецепты haikuporter.

Дополнительно узнаю, что:


Нет необходимости держать рецепты в хранилище HaikuPorts. Можно сделать еще один репозиторий, поместить в него рецепты, после чего указать haikuporter на него.

Как раз то, что мне нужно — если не искать способа для публичного размещения пакета. Но это тема для другого поста.


Установка haikuporter и haikuports


cd /boot/home/
git clone https://github.com/haikuports/haikuporter --depth=50
git clone https://github.com/haikuports/haikuports --depth=50
ln -s /boot/home/haikuporter/haikuporter /boot/home/config/non-packaged/bin/ # make it runnable from anywhere
cd haikuporter
cp haikuports-sample.conf /boot/home/config/settings/haikuports.conf
sed -i -e 's|/mydisk/haikuports|/boot/home/haikuports|g' /boot/home/config/settings/haikuports.conf

Написание рецепта


SUMMARY="Demo QtQuick application"
DESCRIPTION="QtQuickApp is a demo QtQuick application for testing Haiku porting and packaging"
HOMEPAGE="https://github.com/probonopd/QtQuickApp"
COPYRIGHT="None"
LICENSE="MIT"
REVISION="1"
SOURCE_URI="https://github.com/probonopd/QtQuickApp.git"
#PATCHES=""
ARCHITECTURES="x86_64"
PROVIDES="
    QtQuickApp = $portVersion
"
REQUIRES="
    haiku
"
BUILD_REQUIRES="
    haiku_devel
    cmd:qmake
"BUILD()
{
    qmake .
    make $jobArgs
}INSTALL()
{
    make install
}

Сборка рецепта


Сохраняю файл под именем QtQuickApp-1.0.recipe, после чего запускаю aikuporter -S ./QuickApp-1.0.recipe. Проверяются зависимости для всех пакетов в репозитории haikuports, что занимает некоторое время. Пойду-ка кофейку попью.


А с какой стати эта проверка должна делаться на моей локальной машине, а не централизованно на сервере 1 раз для всех?


Согласно mr. waddlesplash:


С такой, что можно переписать любой файл в репозитории ;) Можно чутка оптимизировать это, вычисляя нужную информацию тогда, когда нужно, потому что последние сделанные изменения достаточно редкие.

~/QtQuickApp> haikuporter  QtQuickApp-1.0.recipe
Checking if any dependency-infos need to be updated ...
Looking for stale dependency-infos ...
Error: QtQuickApp not found in repository

Оказывается, не бывает обычного файла рецепта, в котором есть исходный код вашего приложения. Нужно держать его в репозитории в формате HaikuPorts.


~/QtQuickApp> mv QtQuickApp-1.0.recipe ../haikuports/app-misc/QtQuickApp/
~/QtQuickApp> ../haikuport
~/QtQuickApp> haikuporter -S QtQuickApp-1.0.recipe

Этот факт делает сборку более громоздкой. Мне это не особо нравится, но думаю, оно нужно для того, чтобы, в конечном итоге, все ПО с открытым исходным кодом появилось в HaikuPorts.


Получаю следующее:


~/QtQuickApp> haikuporter -S QtQuickApp-1.0.recipe
Checking if any dependency-infos need to be updated ...
        updating dependency infos of QtQuickApp-1.0
Looking for stale dependency-infos ...
Error: QtQuickApp-1.0.recipe not found in tree.

Что не так? После чтения irc делаю:


~/QtQuickApp> haikuporter -S QtQuickApp
Checking if any dependency-infos need to be updated ...
        updating dependency infos of QtQuickApp-1.0
Looking for stale dependency-infos ...
----------------------------------------------------------------------
app-misc::QtQuickApp-1.0
        /boot/home/haikuports/app-misc/QtQuickApp/QtQuickApp-1.0.recipe
----------------------------------------------------------------------Downloading: https://github.com/probonopd/QtQuickApp.git ...
--2019-07-14 16:12:44--  https://github.com/probonopd/QtQuickApp.git
Resolving github.com... 140.82.118.3
Connecting to github.com|140.82.118.3|:443... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://github.com/probonopd/QtQuickApp [following]
--2019-07-14 16:12:45--  https://github.com/probonopd/QtQuickApp
Reusing existing connection to github.com:443.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: ‘/boot/home/haikuports/app-misc/QtQuickApp/download/QtQuickApp.git’
     0K .                                                     1.34M=0.06s
2019-07-14 16:12:45 (1.34 MB/s) - ‘/boot/home/haikuports/app-misc/QtQuickApp/download/QtQuickApp.git’ saved [90094]
Validating checksum of QtQuickApp.git
Warning: ----- CHECKSUM TEMPLATE -----
Warning: CHECKSUM_SHA256="cf906a65442748c95df16730c66307a46d02ab3a12137f89076ec7018d8ce18c"
Warning: -----------------------------
Error: No checksum found in recipe!

Возник интересный вопрос. Если я добавлю контрольную сумму в рецепт — будет ли она соответствовать последнему git commit для непрерывной интеграции? (Разработчик подтверждает: «Ничего не выйдет. Рецепты разработаны так, чтобы быть относительно стабильными").


Для прикола добавляют в рецепт:


CHECKSUM_SHA256="cf906a65442748c95df16730c66307a46d02ab3a12137f89076ec7018d8ce18c"

Все еще не устраивает:


~/QtQuickApp> haikuporter -S QtQuickApp
Checking if any dependency-infos need to be updated ...
        updating dependency infos of QtQuickApp-1.0
Looking for stale dependency-infos ...
----------------------------------------------------------------------
app-misc::QtQuickApp-1.0
        /boot/home/haikuports/app-misc/QtQuickApp/QtQuickApp-1.0.recipe
----------------------------------------------------------------------
Skipping download of source for QtQuickApp.git
Validating checksum of QtQuickApp.git
Unpacking source of QtQuickApp.git
Error: Unrecognized archive type in file /boot/home/haikuports/app-misc/QtQuickApp/download/QtQuickApp.git

Чего это он? Ведь это репозиторий git, код уже там напрямую, нечего распаковывать. С моей точки зрения, инструмент должен быть достаточно умным для того, чтобы не искать распаковщик, если ему над url с GitHub.


Возможно сработает uri git://


SOURCE_URI="git://github.com/probonopd/QtQuickApp.git"

Теперь оно жалуется так:


Downloading: git://github.com/probonopd/QtQuickApp.git ...
Error: Downloading from unsafe sources is disabled in haikuports.conf!

Хм, и почему все так сложно, почему нельзя "просто работать"? В конце концов не так уж и редко можно что-то собрать с GitHub. То ли дело инструменты, работающие сразу же, без необходимости настройки, или как я это называю "возни".


Может быть, сработает так:


SOURCE_URI="git+https://github.com/probonopd/QtQuickApp.git"

Не-а. Все еще получаю эту стремную ошибку и делаю, как описано здесь


sed -i -e 's|#ALLOW_UNSAFE_SOURCES|ALLOW_UNSAFE_SOURCES|g' /boot/home/config/settings/haikuports.conf

Продвигаюсь чутка дальше, но почему оно кричит на меня (GitHub-то не безопасный!) и все еще пытается распаковать что-то.


Согласно mr. waddlesplash:


Ну да, причиной послужило желание проверять целостность получаемых для сборки данных. Один из вариантов — сверка контрольной суммы архива, но можно, конечно, хешировать и отдельные файлы, что не будет реализовано, т.к. это занимает гораздо больше времени. Следствием этого и является "небезопасность" git и других VCS. Вероятнее всего так будет всегда, поскольку создать архив на GitHub достаточно легко и часто быстрее. Ну и в будущем, возможно, сообщение об ошибке не будет таким кричащим… (мы больше не проводим слияния таких рецептов в HaikuPorts).

~/QtQuickApp> haikuporter -S QtQuickApp
Checking if any dependency-infos need to be updated ...
Looking for stale dependency-infos ...
----------------------------------------------------------------------
app-misc::QtQuickApp-1.0
        /boot/home/haikuports/app-misc/QtQuickApp/QtQuickApp-1.0.recipe
----------------------------------------------------------------------Downloading: git+https://github.com/probonopd/QtQuickApp.git ...
Warning: UNSAFE SOURCES ARE BAD AND SHOULD NOT BE USED IN PRODUCTION
Warning: PLEASE MOVE TO A STATIC ARCHIVE DOWNLOAD WITH CHECKSUM ASAP!
Cloning into bare repository '/boot/home/haikuports/app-misc/QtQuickApp/download/QtQuickApp.git'...
Unpacking source of QtQuickApp.git
tar: /boot/home/haikuports/app-misc/QtQuickApp/work-1.0/sources/QtQuickApp-1.0: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now
Command 'git archive HEAD | tar -x -C "/boot/home/haikuports/app-misc/QtQuickApp/work-1.0/sources/QtQuickApp-1.0"' returned non-zero exit status 2

По старой привычке иду спрашивать добрых людей на канале #haiku в сети irc.freenode.net. И куда я без них? После подсказки понял, что надо использовать:


srcGitRev="d0769f53639eaffdcd070bddfb7113c04f2a0de8"
SOURCE_URI="https://github.com/probonopd/QtQuickApp/archive/$srcGitRev.tar.gz"
SOURCE_DIR="QtQuickApp-$srcGitRev"
CHECKSUM_SHA256="db8ab861cfec0ca201e9c7b6c0c9e5e828cb4e9e69d98e3714ce0369ba9d9522"

Хорошо, стало понятно что оно делает — качает архив с исходниками определенной ревизии. Глупо, с моей точки зрения, и не совсем то, что хотелось, а именно — скачать последнюю ревизию с мастер-ветки.


Один из разработчиков пояснил это так:


У нас есть свой CI, так что все, что помещается в репозиторий haikuports, будет опакечено для всех пользователей, а мы не хотим рисковать собирая и поставляя "все последней версии в upstream".

Понял! Во всяком случае получилось такое:


waiting for build package QtQuickApp-1.0-1 to be activated
waiting for build package QtQuickApp-1.0-1 to be activated
waiting for build package QtQuickApp-1.0-1 to be activated
waiting for build package QtQuickApp-1.0-1 to be activated
waiting for build package QtQuickApp-1.0-1 to be activated
(...)

Оно повторяет так до бесконечности. Видимо, это ошибка (есть заявка? я не нашел).


С haikuporter и репозиторием haikuports не чувствуется уровня "просто работает", но, как разработчику, некоторые вещи в работе с Haiku мне нравятся. По большей части это похоже на Open Build Service — набор инструментов для построения сборок Linux: чрезвычайно мощный, с системным подходом, но излишний для моего мелкого приложения уровня "hello world".


Опять же, согласно mr. waddlesplash:


Действительно, HaikuPorter весьма строгий по-умолчанию (плюс имеются режим lint, а также строгий режим, делающие его еще более строгим!), но только потому, что он создает пакеты, которые будут работать, а не просто создавать пакеты. Поэтому он и ругается на необъявленных зависимостях, не импортированных должным образом библиотеках, неверных версиях и т.п. Цель — отловить все без исключения проблемы, включая будущие, до того, как пользователь об этом узнает (поэтому не получилось установить avrdude, ведь в рецепте фактически была указана зависимость). Библиотеки не просто отдельные пакеты и даже не определенные версии SO. HaikuPorter следит за соблюдением всего этого в самих рецептах, чтобы избежать ошибок во время выполнения.

В принципе такой уровень строгости оправдан при создании операционной системы, но мне он кажется излишним для приложения "hello world". Я решил попробовать что-нибудь еще.


Сборка приложений в формате hpkg, используя команду "package create"


Может быть, эта простая инструкция подойдет мне лучше?


mkdir -p apps/
cp QtQuickApp apps/cat >  .PackageInfo <<\EOF
name QtQuickApp
version 1.0-1
architecture x86_64

summary "Demo QtQuick application"
description "QtQuickApp is a demo QtQuick application for testing Haiku porting and packaging"

packager "probono"
vendor "probono"

copyrights "probono"
licenses "MIT"

provides {
  QtQuickApp = 1.0-1
}requires {
  qt5
}
EOFpackage create -b QtQuickApp.hpkg
package add QtQuickApp.hpkg apps# See below if you also want the application
# to appear in the menu

Неожиданно быстро, неожиданно просто, неожиданно эффективно. Точно так, как мне нравится, потрясающе!


Установка — что и куда?


Переместил файл QtQuickApp.hpkg в ~/config/packages, используя файловый менеджер, после чего QtQuickApp магически появился в ~/config/apps.
Опять же неожиданно быстро, просто и эффективно. Потрясающе, невероятно!


Но… (куда без них!)


Приложение все еще отсутствует в списке меню приложений и в QuickLaunch. Думаю, уже знаю, как это починить. В файловом менеджере перемещаю QtQuickApp.hpkg с ~/config/packages в /system/packages.


Не-а, все еще отсутствует. По всей видимости, я (ну, и инструкция) что-то пропустил.


Осмотрев вкладку "Contents" в HaikuDepot для некоторых других приложений я увидел, что есть файлы вида /data/mimedb/application/x-vnd... что еще примечательней, /data/deskbar/menu/Applications/….


Ну, и что мне туда поместить? А ну-ка…


mkdir -p data/deskbar/menu/Applications/
( cd data/deskbar/menu/Applications ; ln -s ../../../../apps/QtQuickApp . )
package add QtQuickApp.hpkg apps data

Вполне уверен, что этот трюк прокатит, но остались вопросы: зачем это нужно, для чего это нужно? По-моему это разрушает общее впечатление, что система — такая утонченная.


Как пояснил mr. waddlesplash:


Иногда есть приложения, которые нужны другим приложениям, но не в меню. К примеру, LegacyPackageInstaller на Вашем снимке экрана, обрабатывающий архивы .pkg в формате BeOS. Хочется, чтобы пользователи их ставили, но их наличие в меню приведет к путанице.

Мне почему-то кажется, что есть более простое решение, к примеру Hidden=true в файлах .desktop на Linux. Почему бы не сделать "скрытую" информацию ресурсом и атрибутом файловой системы?


Что особенно не утонченно — название (некоего) приложения, показывающего меню, deskbar, жестко привязано в пути.


mr. waddlesplash по этому поводу поясняет:


"Deskbar" в данном случае следует понимать как некий общий термин (примерно так же, как "taskbar", относящийся как к приложению Windows, так и к общей концепции). Ну а поскольку это deskbar, а не "Deskbar", это тоже можно понимать схожим образом.


2 "почти идентичных" каталога с приложениями в них


Почему есть 2 каталога с приложениями, а также почему в одном мой QtQuickApplication есть, а в другом — нет? (Ведь это не один системный, а второй пользовательский, что лично мне было бы понятно).
Я реально запутался и думаю, что надо бы унифицировать это.


комментарий mr. waddlesplash


В каталоге Apps есть приложения, не нужные в меню. Но ситуацию с меню в самом деле надо улучшить, сделать его более настраиваемым.

Заявка, или этого не случится ;)


Я задумался: так ли необходимо размещать приложения в /system/apps, если пользователям их видеть там — нежелательно. Может, лучше разместить их в другом месте, где пользователь с ними не будет сталкиваться? Так же, как это сделано в Mac OS X, где содержимое пакетов .app, которое не должно быть видно пользователю в /Applications, прячется в недрах /System/Library/...```.


Что насчет зависимостей?


Думаю, стоит как-то указать зависимости, ведь так? Можно ли считать Qt обязательной частью установки Haiku по-умолчанию? Неа! Qt по умолчанию не установлен. Может ли программа сборки пакета автоматически определить зависимости проверив файлы ELF? Мне сказали, что HaikuPorter действительно так и делает, а вот package нет. Все потому, что он просто "сборщик пакета", который сам по себе просто создает файлы hpkg.


Стоит ли делать Haiku утонченнее, добавив политику, согласно которой у пакета не должно быть зависимостей от пакетов, не входящих в haikuports? (Мне бы так хотелось, поскольку подобная политика значительно облегчает задачу — система смогла бы автоматически разрешить зависимости каждого пакета, загружаемого откуда угодно, без возни с дополнительными источниками пакетов).


mr. waddlesplash поясняет:


Нам не хотелось бы ограничивать свободу разработчикам так сильно, ведь очевидно, что если КомпанияХ захочет поддержать свой собственный набор ПО с зависимостями (а следовательно и репозиторий) — она совершенно свободно сделает это.

В таком случае возможно стоило бы порекомендовать избегать сторонним пакетам зависимостей от чего-либо, не входящего в haikuports, путем полной упаковки всего необходимого с приложением. Но, я думаю, это тема для будущей статьи в этой серии. [Автор клонит к AppImage? — прим. переводчика]


Добавление иконки приложения


А что если я хочу добавить в ресурсы моего свежесозданного приложения одну из аккуратненьких встроенных иконок? Оказывается, это удивительная тема, так что она станет основной для следующей статьи.


Как организовать непрерывную сборку приложений?


Представьте себе проект, подобный Inkscape (да, я в курсе, что его пока нет в Haiku, но на нем удобно показывать). У них есть репозиторий исходного кода https://gitlab.com/inkscape/inkscape.
Каждый раз, когда кто-то фиксирует свои изменения в репозитории, запускаются конвейеры сборки, после чего правки автоматически тестируются, собираются, приложение упаковывается в различные пакеты, включая AppImage для Linux (автономный пакет приложения, который может быть загружен для локального тестирования независимо от того, что может, или не может быть установлено в системе [я так и знал! — прим. переводчика]). Аналогично все происходит при каждом запросе на слияние веток, так что можно скачать приложение, собранное из кода, предложенного в запросе на слияние, еще до слияния.



Запросы на слияние со статусами сборки и возможностью скачать собранные бинарники в случае успешной сборки (помечена зеленым)


Сборка запускается в контейнерах Docker. GitLab предлагает бесплатные runners на Linux, к тому же я думаю, что возможно подключить собственные runners (кстати, я не представляю, как это будет работать для систем вроде Haiku, которые, как я знаю, не имеют Docker или аналога, но для FreeBSD также нет Docker, так что эта проблема не уникальна для Haiku).


В идеальном случае сборка приложений для Haiku может быть выполнена внутри контейнера Docker для Linux. При таком раскладе сборка для Haiku может быть внедрена в существующие конвейеры. Есть кросскомпиляторы? Или надо эмулировать всю Haiku внутри контейнера Docker, используя что-то типа QEMU/KVM (при условии, что оно будет так работать внутри Docker)? Кстати, многие проекты используют схожие принципы. Например, Scribus делает так — он уже доступен для Haiku. Однажды наступит день, когда я смогу отправлять такие запросы на слияние в другие проекты, чтобы добавить в них поддержку Haiku.


Один из разработчиков поясняет:


Для других проектов, желающих создавать пакеты самостоятельно, поддерживается обычный метод CMake/CPack. Другие системы сборки могут быть поддержаны, если вызвать программу сборки пакета напрямую, что хорошо, если люди будут в этом заинтересованы. Опыт показывает: до сих пор особого интереса не было, так что haikuporter работал как удобно нам, но, в конечном итоге, оба способа должны работать совместно. Нам следует представить набор инструментов для перекрестной сборки ПО из Linux или любой другой серверной операционной системы (Haiku не предназначен для работы на серверах).

Аплодирую стоя. Обычные пользователи Linux тащат всю эту дополнительную нагрузку и дополнительный багаж (безопасность, строгий контроль и т.п.), нужный серверной операционке, но не персональной. Поэтому я полностью согласен, что возможность собирать приложения для Haiku на Linux — правильный путь.


Заключение


Портирование приложений POSIX на Haiku возможно, но может потребовать больше затрат, чем обычная пересборка. Я бы совершенно точно завяз с этим надолго, если бы не помощь людей с канала #haiku в сети irc.freenode.net. Но даже они не всегда сразу видели, что не так.


Приложения, написанные на Qt, — легкое исключение. Я собрал простейшее демонстрационное приложение без особых проблем.


Сборка пакета для простых приложений также достаточно легкая, но только для "выпускаемых традиционным способом", т.е. имеющих версионированные архивы исходного кода, предназначенного для поддержки в haikuports. Для непрерывной сборки (сборка на каждую фиксацию изменений) с GitHub все вроде не так просто. Тут Haiku больше чувствуется аналогично дистрибутиву Linux, чем результату на Mаc, где при нажатии кнопки "Собрать" в XCode получается пакет .app, готовый к вставке в образ диска .dmg, подготовленный к загрузке на моем сайте.
Непрерывная сборка приложений на основе "серверной" операционки, к примеру, Linux, скорее всего станет возможной, если будет спрос со стороны разработчиков, но на данный момент у проекта Haiku есть другие, более насущные задачи.


Попробуйте сами! Ведь проект Haiku предоставляет образы для загрузки с DVD или USB, формируемые ежедневно. Для установки достаточно скачать образ и записать его на флешку с помощью Etcher


Появились вопросы? Приглашаем вас в русскоязычный telegram-канал.


Обзор ошибок: Как выстрелить себе в ногу в C и C++. Сборник рецептов Haiku OS


От автора перевода: это пятая статья из цикла про Haiku.


Список статей: Первая Вторая Третья Четвертая

Комментарии (1)


  1. pal666
    16.08.2019 01:16

    на первый взгляд, эффективнее было бы один раз спортировать хайку на линух, чем портировать туда все приложения