
TL; DR :Haiku是专门为PC设计的操作系统,因此它有一些技巧可以使其工作环境比其他环境更好。 但是它是如何工作的呢?
我最近发现了Haiku,这是一个出乎意料的好系统。 它的运行如此平稳仍然令人惊讶,特别是与Linux桌面环境相比。 今天,我在引擎盖下看。 在需要深入了解的地方,我将与原始Macintosh,Mac OS X和Linux工作环境(freedesktop.org的XDG标准)进行比较。
ELF文件中的资源
昨天,我了解到IconOMatic可以将图标保存在ELF可执行文件的rdef资源中。 今天,我想看看它是如何工作的。
资源? 引用来自Macintosh Finder程序的原始作者和Macintosh Resource Manager的“父亲”的布鲁斯·霍恩 ( Bruce Horne) :
我担心传统代码编写的硬性。 对我来说,将应用程序冻结在代码中而无权动态更改任何东西的想法是最疯狂的。 在运行时阶段应尽可能进行更改。 当然,应用程序代码本身不能更改,但是可以在不重新编译代码的情况下更改某些内容?
在原始的Macintosh上,他们使这些文件具有“数据部分”和“资源部分”,这使得保存各种内容(例如图标,翻译等)变得极为容易。 在可执行文件中。
在Mac上, ResEdit用于此目的,这是一个图形程序-用于-突然-编辑资源。

原始Macintosh上的ResEdit
结果,就可以编辑图标,菜单项,翻译等。 足够容易,但是它们仍然可以“随身携带”应用程序。
无论如何,这种方法都有一个很大的缺点:它只能在Apple文件系统上工作,这是Apple切换到Mac OS X时放弃“资源部分”的原因之一。
在Mac OS X上,Apple需要独立于文件系统的解决方案,因此他们采用了软件包(来自NeXT)的概念,即文件管理器将其视为“不透明对象”的目录,例如文件,而不是目录。 任何带有.app
格式应用程序的软件包都具有一个Info.plist
文件(类似于Apple的JSON或YAML),其中包含应用程序元数据。

Mac OS X应用程序包中Info.plist文件的键。
资源(例如图标,UI文件等)作为文件存储在包中。 该概念实际上已恢复为NeXT的基础知识。

1989年在NeXTSTEP 1.0上使用Mathematica.app:在终端中显示为包含文件的目录,但在图形文件管理器中显示为单个对象。
回到Haiku所基于的BeOS。 从PEF(PowerPC)转换为ELF (x86)(Linux上使用的相同)时,其开发人员决定在ELF文件的末尾添加一个资源部分。 为此,没有使用我们自己的适当的ELF节,只是将其附加到ELF文件的末尾。 结果, strip
程序和其他不知道这一点的binutils都将其切断了。 因此,在BeOS的ELF文件中添加资源时,最好不要使用Linux工具。
Haiku现在发生了什么? 原则上,大致相同。
从理论上讲,您可以将资源放在ELF的右侧。 根据irc.freenode.net网络上#haiku频道上的开发人员的说法:
使用ELF,该部分会更有意义……我们不这样做的唯一原因是因为他们是在BeOS上完成的,
现在不值得更改。
资源管理
资源以结构化的“资源”格式编写:实际上,这是资源的列表,其中包含大小和内容。 我记得格式为ar 。
如何查看Haiku中的资源? 是否有类似ResEdit的内容?
根据文档 :
要查看应用程序包中提供的资源,您可以将可执行文件拖到诸如Resourcer的程序上。 您也可以转到终端并运行listres _
命令。
HaikuDepot中有一个Resourcer,但是对我来说它崩溃了。
如何管理ELF文件中的资源? 使用rsrc
和rdef
。 rdef
文件收集在rsrc
。 rdef
文件以纯文本格式存储,因此使用它要容易得多。 rsrc
文件rsrc
附加到ELF文件的末尾。 让我们尝试玩:
~> rc -h Haiku Resource Compiler 1.1To compile an rdef script into a resource file: rc [options] [-o <file>] <file>...To convert a resource file back into an rdef script: rc [options] [-o <file>] -d <file>...Options: -d --decompile create an rdef script from a resource file --auto-names construct resource names from ID symbols -h --help show this message -I --include <dir> add <dir> to the list of include paths -m --merge do not erase existing contents of output file -o --output specify output file name, default is out.xxx -q --quiet do not display any error messages -V --version show software version and license
您可以使用xres
程序来验证和管理:
/> xres Usage: xres ( -h | --help ) xres -l <file> ... xres <command> ...The first form prints this help text and exits.The second form lists the resources of all given files.The third form manipulates the resources of one or more files according to the given commands. (...)
好吧,我们尝试一下吗?
/> xres -l /Haiku/system/apps/WebPositive/Haiku/system/apps/WebPositive resources:type ID size name ------ ----------- ----------- -------------------- 'MIMS' 1 36 BEOS:APP_SIG 'APPF' 1 4 BEOS:APP_FLAGS 'MSGG' 1 421 BEOS:FILE_TYPES 'VICN' 101 7025 BEOS:ICON 'VICN' 201 91 kActionBack 'VICN' 202 91 kActionForward 'VICN' 203 300 kActionForward2 'VICN' 204 101 kActionStop 'VICN' 206 243 kActionGoStart 'MSGG' 205 1342 kActionGo 'APPV' 1 680 BEOS:APP_VERSION
您可以在此处阅读有关资源和rdef
格式的更多信息。
标准资源类型
尽管您可以在资源中放入任何内容,但是有一些定义的标准类型:
app_signature
:应用程序的MIME类型,用于匹配打开的文件,启动,IPC等。app_name_catalog_entry
:由于应用程序名称通常为英文,因此您可以在此处指定翻译名称的位置,因此如果需要,不同语言的用户将看到翻译后的应用程序名称。app_version
:正是您的想法app_flags
:告诉registrar
如何处理该申请。 我认为乍一看还有更多的东西。 例如,有B_SINGLE_LAUNCH
,它会根据用户的要求每次都强制系统启动一个新的应用程序进程(大多数Linux应用程序使用相同的原理)。 有B_MULTIPLE_LAUNCH
强制为每个文件启动一个进程。 最后,还有B_EXCLUSIVE_LAUNCH
,它强制系统一次仅启动一个进程,而不管用户启动它的频率如何(例如,Firefox也可以在Linux上启动;使用QtSingleApplication函数在Qt应用程序中也可以实现相同的结果)。 当用户再次尝试运行具有B_EXCLUSIVE_LAUNCH
应用程序时, B_EXCLUSIVE_LAUNCH
收到通知:例如,它们获得用户希望在其帮助下打开的文件路径。vector_icon
:矢量应用程序图标(BeOS中没有矢量图标,大多数应用程序在可执行文件中有两个栅格图标)。
当然,您可以添加具有任何所需ID和类型的资源,然后使用BResources
类在应用程序本身或其他应用程序中读取它们。 但是首先,让我们关注一下迷人的图标主题。
Haiku风格的矢量图标。
当然,不仅Haiku选择了最佳的图标格式,在这一部分中Linux工作环境的情况也远非理想:
me@host:~$ ls /usr/share/icons/hicolor/ 128x128 256x256 512x512 index.theme 160x160 28x28 64x64 scalable 16x16 32x32 72x72 symbolic 192x192 36x36 8x8 22x22 42x42 96x96 24x24 48x48 icon-theme.cache
看着这个,您已经可以感觉到它的一部分了。
当然,您可以理解,其中包含一个可扩展的矢量图标。 那为什么还有别的呢? 因为以小尺寸绘制矢量图形的结果可能不理想。 我想针对各种尺寸优化各种选项。 在Linux工作环境中,这是通过在文件系统上散布具有不同大小的图标来实现的。
me@host:~$ find /usr/share/icons/ -name 'firefox.*' /usr/share/icons/HighContrast/16x16/apps/firefox.png /usr/share/icons/HighContrast/22x22/apps/firefox.png /usr/share/icons/HighContrast/24x24/apps/firefox.png /usr/share/icons/HighContrast/256x256/apps/firefox.png /usr/share/icons/HighContrast/32x32/apps/firefox.png /usr/share/icons/HighContrast/48x48/apps/firefox.png /usr/share/icons/elementary-xfce/apps/128/firefox.png /usr/share/icons/elementary-xfce/apps/16/firefox.png /usr/share/icons/elementary-xfce/apps/22/firefox.png /usr/share/icons/elementary-xfce/apps/24/firefox.png /usr/share/icons/elementary-xfce/apps/32/firefox.png /usr/share/icons/elementary-xfce/apps/48/firefox.png /usr/share/icons/elementary-xfce/apps/64/firefox.png /usr/share/icons/elementary-xfce/apps/96/firefox.png /usr/share/icons/hicolor/128x128/apps/firefox.png
请注意:没有不同版本的Firefox的概念。 因此,在系统中存在多个版本的应用程序时,您无法巧妙地处理这种情况。

不同版本的不同Firefox图标。 没有各种拐杖,就不可能在Linux上进行处理。
Mac OS X处理起来更加复杂:
Mac:~ me$ find /Applications/Firefox.app | grep icns /Applications/Firefox.app/Contents/MacOS/crashreporter.app /Contents/Resources/crashreporter.icns /Applications/Firefox.app/Contents/MacOS/updater.app/Contents/Resources/updater.icns /Applications/Firefox.app/Contents/Resources/document.icns /Applications/Firefox.app/Contents/Resources/firefox.icns
可以看出, Firefox.app
软件包中有一个包含所有大小的firefox.icns
文件,因此同一应用程序的不同版本具有不同的图标。
好多了! 图标随应用程序一起移动,所有资源都在一个文件中。
回到Hai句。 一个令人鼓舞的决定,无一例外。 根据文档 :
开发了一种针对HVIF格式进行了高度优化的特殊功能,以实现小尺寸和快速渲染。 因此,我们的图标在很大程度上要比栅格或广泛使用的SVG格式的图标小得多。
并且它们进行了优化:

与其他格式相比,HVIF中的图标大小。
区别是一个数量级!
但是魔术并没有就此结束。 即使是矢量格式,相同的HVIF也会根据显示的大小显示不同级别的细节。

根据渲染大小的不同,细节水平(LOD)
现在,了解缺点:您无法使用SVG,将其放入ImageMagick并在此处结束,您需要经历几个周期才能创建HVIF格式的图标。 这里是解释。 但是,IconOMatic不能完美导入SVG。 大约有90%的SVG零件是有可能进口的,其余的10%则需要手动调整和更改。 您可以在Lea Ganson的博客上了解有关HVIF如何发挥作用的更多信息。
向应用程序添加图标
现在,考虑到收到的所有信息,我可以在上次创建的包中添加一个图标。
好吧,由于我并不是真的很想为我的“ Hello World” QtQuickApp绘制自己的图标-我将其从Qt Creator中拉出来。
/Haiku/home> xres /Haiku/system/apps/QtCreator/bin/Qt\ Creator -o /Haiku/home/QtQuickApp/QtQuickApp -a VICN:101:BEOS:ICON /Haiku/system/apps/QtCreator/bin/Qt\ Creator
让我们检查一下图标是否已复制:
/Haiku/home> xres -l /Haiku/home/QtQuickApp/QtQuickApp/Haiku/home/QtQuickApp/QtQuickApp resources:type ID size name ------ ----------- ----------- -------------------- 'VICN' 101 152238 BEOS:ICON
看起来不错,但是为什么在复制新图标时却没有出现?

复制的VICN:101:BEOS:图标尚未在文件管理器中用作应用程序的图标
我想念什么?
开发者评论:
必须使用所有资源创建一个rdef
文件,然后运行rc .rdef
,这将创建一个.rsrc
文件。 然后,您需要运行resattr -o _ .rsrc
。 至少,我使用类似的命令将图标添加到脚本中。
好吧,我想创建一个资源,而不是一个属性。 我直接感到困惑。
智能文件系统缓存
打开和读取ELF属性的速度很慢。 正如我在上面所写,图标是作为资源写入文件本身的。 此方法更可靠,可让您在复制到另一个文件系统中幸免。 但是,然后它也被复制到文件系统属性,例如BEOS:ICON
。 这仅适用于某些文件系统,例如BFS。 从此扩展属性中读取系统显示的图标(在Tracker和Deskbar中),因为这样的解决方案可以快速工作。 在某些地方(速度并不重要,例如,典型的“关于”窗口),系统直接从文件中的资源接收图标。 但这还不是终点。 记住,在Mac上,用户可以用自己的图标替换应用程序图标,目录和文档,因为在Mac上可以做这些“重要”的事情,例如, 用以前的图标替换新的Slack图标 。 在Haiku上,您应该将资源(文件中)作为应用程序随附的源图标,并将属性(BFS文件系统中)作为允许用户根据需要进行更改的内容(尽管有提示,用于将用户图标插入图标顶部的图形界面是默认值尚未实现)。
检查文件系统属性
使用resaddr
可以检查和设置文件系统的属性。
/> resattr Usage: resattr [ <options> ] -o <outFile> [ <inFile> ... ] Reads resources from zero or more input files and adds them as attributes to the specified output file, or (in reverse mode) reads attributes from zero or more input files and adds them as resources to the specified output file. If not existent the output file is created as an empty file. (...)
本质上,这是一种“胶水”,可以在(可靠)资源和(快速)文件系统属性之间进行来回转换。 并且由于系统假定接收到资源并自动执行复制,因此我将不再为此担心。
神奇的hpkg软件包
当前(通常) .hpkg
软件包用于获取Haiku .hpkg
。 不要被一个简单的名字所迷惑:.hpkg格式的工作方式与您遇到的具有相似名称的其他格式完全不同,它具有真正的超能力。
对于传统的数据包格式,由于这个事实,我很不高兴:您下载了一个(程序包),而另一个安装在系统上(程序包中的文件)。 以传统方式安装软件包时,很难管理文件(例如,删除文件)。 所有这些都是因为软件包内容分散在整个文件系统中 ,包括普通用户可能没有写访问权的地方。 相同的程序生成一类完整的程序,即程序包管理器 。 但是,将已经安装的软件(例如,转移到另一台计算机,可移动磁盘或文件服务器)变得更加困难,即使不是不可能。 在典型的基于Linux的系统中,很容易存在数十万到数百万个单独的文件。 不用说,它既脆弱又缓慢,例如,在系统的初始安装过程中,常规软件包的安装,更新和删除过程中以及将引导卷(根分区)复制到另一种介质时。
我正在研究AppImage项目,这是最终用户应用程序的部分拐杖。 这是一种软件分发格式,可将应用程序及其所有依赖项收集到在应用程序启动时安装的单个文件系统映像中。 由于同一ImageMagick突然变成单个文件,在文件管理器中由凡人管理,因此它大大简化了事情。 提议的方法仅适用于软件,这反映在项目的名称中,并且也有其自己的缺点,因为为Linux提供软件的人总是向我敞开大门。
回到Hai句。 您是否设法在传统包装系统和基于图像的软件的交付之间找到最佳平衡? 其.hpkg
软件包实际上是压缩的文件系统映像。 系统启动时,内核会使用大约以下内核消息挂载所有已安装的和活动的软件包:
KERN: package_daemon [16042853: 924] active package: "gawk-4.2.1-1-x86_64.hpkg" KERN: package_daemon [16043023: 924] active package: "ca_root_certificates_java-2019_01_23-1-any.hpkg" KERN: package_daemon [16043232: 924] active package: "python-2.7.16-3-x86_64.hpkg" KERN: package_daemon [16043405: 924] active package: "openjdk12_default-12.0.1.12-1-x86_64.hpkg" KERN: package_daemon [16043611: 924] active package: "llvm_libs-5.0.0-3-x86_64.hpkg"
酷吧? 等等,它会更凉!
有一个非常特殊的包:
KERN: package_daemon [16040020: 924] active package: "haiku-r1~beta1_hrev53242-1-x86_64.hpkg"
它包含一个非常小的操作系统,包括内核。 信不信由你,即使内核本身也不是从引导卷(根分区)中提取的,而是从.hpkg
软件包中精心加载到其位置的。 哇! 我已经提到,对我来说,Haiku的整体复杂性和连贯性的一部分是由于这样一个事实,即来自内核和基本用户空间的整个系统以及工作环境的软件包和基础结构的管理是由一个团队共同开发的。 想象一下,运行这样一个基于Linux的组需要多少不同的组和命令[我想象一个PuppyLinux项目-大约。 翻译者] 。 然后想象一下这种方法在发行版中实施需要多长时间。 他们说:承担一项简单的任务,将任务分配给不同的表演者,它将变得如此复杂,以至于无法解决。 在这种情况下,句睁开了我的眼睛。 我认为这正是Linux上正在发生的事情(在这种情况下,Linux是Linux / GNU / dpkg / apt / systemd / Xorg / dbus / Gtk / GNOME / XDG / Ubuntu堆栈的统称)。
使用hpkg进行系统回滚
以下情况多久发生一次:更新成功,然后事实证明某些事情没有按预期进行? 如果使用常规的软件包管理器,则很难将系统状态恢复到安装新软件包之前的时间点(例如,在出现问题的情况下)。 某些系统以文件系统快照的形式提供解决方法,但是它们非常繁琐,并且并非在所有系统上都使用。 在Haiku,可以使用.hpkg
软件包解决此问题。 只要系统中的软件包发生更改,旧软件包就不会被删除,而是永久存储在系统中,形式为/Haiku/system/packages/administrative/state-<...>/
。 不完整的操作/Haiku/system/packages/administrative/transaction-<...>/
其数据存储在/Haiku/system/packages/administrative/transaction-<...>/
子目录中。

内容/Haiku/system/packages/administrative
。 目录“ state ...”包含文本文件,其名称为活动软件包的名称,“ transaction ...”-软件包本身。
“旧的活动状态”,即 在每次操作之后,在文件管理器中的/Haiku/system/packages/administrative/state-<...>/activated-packages
文本文件中写入更改之前处于活动状态的.hpkg
软件包列表。 以类似的方式,新的“活动状态”被写入文本文件/Haiku/system/packages/administrative/activated-packages
。
/Haiku/system/packages/administrative/state-<...>/
目录仅包含带有此状态的活动软件包列表的文本文件(如果安装了软件包而未卸载),并且如果软件包被删除或更新,则状态目录包含旧版本的软件包。
当基于软件包列表加载系统时,将决定激活(安装)软件包。 好简单! 如果在下载过程中出现问题,可以告诉下载管理器使用其他旧列表。 问题解决了!

Haiku引导程序。 每个入口点都显示一个相应的“活动状态”
我喜欢将简单的文本文件作为“活动状态”列表的方法,在其中.hpkg
可理解的.hpkg
名称。 这与为文件系统中的机器而非人创建的OSTree或Flatpak 堆形成鲜明对比(与Microsoft GUID处于同一级别)。

每个时间点的活动软件包列表
配置数据
显然,目录/Haiku/system/packages/administrative/writable-files
包含软件包的配置文件,但可写。 毕竟,您还记得, .hpkg
仅安装用于读取。 因此,在写入之前必须从软件包中复制这些文件。 有道理。
.hpkg系统的GUI集成
现在,让我们看看这些出色的.hpkg
软件包如何.hpkg
与用户工作区(UX)的集成。 毕竟,Haiku毕竟是供个人使用的。 就个人而言,我通过将用户体验与Macintosh上的.app
软件包与.hpkg
上的相同体验进行比较来设定较高的.hpkg
。 我什至不会将这种情况与Linux上的工作环境进行比较,因为与其他任何环境相比,这绝对是可怕的。
想到以下情况:
- 我想查看软件包
.hpkg
的内容 - -,
- -,
- , Haiku ( , .)
- (, ) , ( ) ( , , ).
. , .
Mac Finder. ! ( , .pkg
, , ).
Haiku , "Contents" , . .
, () .hpkg
, . ( , .hpkg
Expander
, ).

HaikuDepot , , , README.md
Mac , HaikuDepot .
GUI
Mac , .dmg
.app
. , , , /Applications
Finder. , , . - Apple "" /Applications
( NeXT , ), $HOME/Applications
, .
Haiku , , "Install", . , , , HaikuPorts, . Linux , , — , . , Haiku.

'sanity' , , ( , ). Linux .
— , .hpkg
/Haiku/system/packages
( , -), /Haiku/home/config/packages
( ; — "config" , "settings"). Haiku (, — , , ).
Haiku, , .
GUI
Mac , , . !
Haiku , -, , , ( ). /Haiku/system/packages
( -), /Haiku/home/config/packages
( , "config" — ?). , .
! , . :

, /Haiku/system/packages
", " QtQuickApp. , — .hpkg
" " . , "", -.
mr. waddlesplash :
10 . , . .
, , , HaikuDepot? /Haiku/system/packages
, , "Uninstall". -, () «Install». «Uninstall», ?
, , "Install" . :

, .
:

"Apply changes" —
, , . [ , — . 译者]
: "Uninstall", /Haiku/system/packages
, /Haiku/home/config/packages
.
, HaikuDepot, .
Mac. , Haiku , Mac. ( : " HaikuDepot, ++", ?)
-
, .hpkg
, (, " " - ).
Mac , .dmg
, .app
. .dmg
, /Applications
. , , , Apple. ( , Mac. , , AppImage , . = . !)
Haiku , apps/
packages/
, , . , apps/
:

, .hpkg
( , ), .
: GUI .hpkg
, Alt+D. " ". , /system
( /system/packages
/system/settings
) packagefs (, df
?). , mount
( ), mountvolume
( loop .hpkg
""), .
, AppImage ( , , ). , , Haiku , Mac.
: , "" «». , "" «": , ( , , ). ?
Mac , .app
, — .
Haiku , , .
: ```.hpkg , , .
Mac. , . Haiku .hpkg
, ...
. , (, , Windows, Mac Linux) . , -, , , [ , Windows… — . ].
, , Windows Linux.
Mac , — .dmg
. , , MacOS -. , , java.
Haiku .hpkg
, , java, , java , . .hpkg
, , Haiku - , , Haiku?
Mac.
mr. waddlesplash:
, .hpkg
-, Haiku, 15 . , . .
.
, .hpkg
(, ) , ( ). ( ) — , () , . , .
Mac .app
Finder, . . !
Haiku , , .hpkg
, , . , , GUI.
Mac.
mr. waddlesplash:
. , , . .
.
: ( LAN ) , , (, Zeroconf), . , app_flags
.
hpkg c GUI
, - .hpkg
GUI . , , UX...
: Kernel Debug Land
kernel panic , syslog | grep usb
. , Haiku Kernel Debug Land. , kernel panic? , Alt+PrintScn+D ( Debug). Programmer's Key , Macintosh ( , ).
结论
, Haiku , .
Linux/GNU/dpkg/apt/systemd/Xorg/dbus/Gtk/GNOME/XDG/Ubuntu, , .
, .hpkg
, Snappy, Flatpak, AppImage, btrfs, " " Mac.
- "" , , .hpkg
, — . , . Mac.
, , , ( Gtk, Electron — , ), 3d , . . , , .
, Haiku .
, ?
- BeScreenCapture GIF, Peek. ffmpeg, Haiku. .
- ,
- WonderBrush, —
- Haiku, , . Krita, (. ). . .
自己尝试! 毕竟,Haiku项目每天都会从DVD或USB提供下载图像。 要安装,只需下载图像并使用Etcher将其写入USB闪存驱动器
有问题吗? 我们邀请您访问俄语电报频道 。
错误概述: 如何在C和C ++中扎根。 Haiku OS食谱集
: Haiku.
: