Gtk Rust交叉编译(二)
前情回顾
上次我们完成了对于gtk-rs项目的交叉编译,成功获得了一个exe文件, 并且可以正常在Windows环境下执行。不过虽说正常,但仍有几个问题尚未解决。
- 右上角图标显示不正常
- 双击exe运行时会出现命令行
- 尚未支持GTK的设置
- 尚未支持自定义主题
在这篇博文中,我们就要解决以上四个问题。其他的潜在的一些问题,我将来遇到了再解决。
图标显示不正常
可以看到在命令行中有很多的报错,其中有一条是这么说的:Failed to load icon /org/gtk/libgtk/icons/16x16/actions/window-maximize-symbolic.symbolic.png: Image type “png” is not supported
。
这个问题其实和gdk-pixbuf有关。这个库负责导入图片,比如PNG、JPEG等格式。如果没有的话,那么无法导入这些格式的图片。
当然,新的版本应该会自带一些常用格式的加载功能,不过我这里暂时还没有。
这个库依赖一些dll文件(各自对应一个文件格式的加载器),并且需要生成一个loaders.cache
来告诉它这些dll在哪里找。
这些文件在Msys2中处于/ming64/lib/gdk-pixbuf-2.0/2.10.0/loaders/
下,生成的loaders.cache
则位于/ming64/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
。
我们所要做的便是,根据这些dll,生成loaders.cache
文件,并把这些ddl和loaders.cache复制到我们将要分发的文件夹中。
交叉编译的小问题
我们这里会遇到一个问题,那就是我们所执行的gdk-pixbuf-query-loaders
,如果用Linux版本,则无法识别dll文件;如果用Windows版本,Linux下无法执行exe文件。
等下,Linux下无法执行exe文件吗?有请大名鼎鼎的Wine:Wine is not an emulator。有了它,我们就可以在Linux下执行exe文件。 而且我们要执行的也只是一个比较简单的命令行文件,无需担心兼容性问题。
但是对于Arch而言,wine不在常见的core、community、extra中,而在multilib中。因此我们需要添加这一条记录。
处理路径
如果我们执行wine /mingw64/bin/gdk-pixbuf-query-loaders /mingw64/lib/gdk-pixbuf-2.0/2.10.0/loaders/*.dll
,我们会发现
它包含了一些绝对路径,而这是我们不想要的,我们只想要相对路径。为此我们需要用sed之类的工具把lib
之前的路径,即/mingw64/
给截掉。
在执行之后,我们把ddl和loaders.cache根据原来的文件结构,放在./lib/gdk-pixbuf-2.0/2.10.0/loaders/
和./lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
下。
这也符合我们刚刚修改的相对路径。
这里假设我们的exe文件在./mygtk.exe
,而其他exe所需的ddl也都在./
下。
具体的文件可参考我的仓库。 如此一来,我们就可以看到我们的右上角图标了。
到此为止,我们不再需要mingw相关的包,可以暂时摆脱那个肥大的容器。注:那个容器可能需要30G空间来打包。
隐藏命令行
通过搜索引擎,我们可以发现在Rust 1.18版本中引入了一个属性叫windows_subsystem
。我们只需要设置它即可让Rust明白我们是个窗口程序,
无需命令行。
我们只要在main.rs
的第一行加上#![windows_subsystem = "windows"]
即可。
GTK的设置
这里说的设置指的是GSettings,用来保存对GTK应用的设置。我们只需要使用将xml文件放入./share/glib-2.0/schemas
下,并运行glib-compile-schemas即可。
自定义主题
GTK的一大优势就是可以自定义主题。我们可以换个更原生的主题,或者更漂亮的主题,比如Windows 10或者Nordic(这两个主题暂时不支持GTK4.0)。
我们所要做的便是下载一个主题,展开至share/themes
下。之后在etc/gtk4.0
下创建settings.ini
,并写入以下内容:
[Settings]
gtk-theme-name=主题的名字
主题的名字取决于展开后的文件夹叫什么。文件夹结构应当是share/themes/主题的名字
,其下应当包含gtk-4.0
这个文件夹,而这个文件夹包含gtk.css
和gtk-dark.css
。
如果在主题内无gtk-4.0
这个文件夹,说明它暂时不支持,可以考虑把gtk-3.0
的文件夹复制过去。不过不保证显示正常。
如果使用的是Gtk 3.0,则把以上4.0换成3.0。
总结
到此为止,可以算是认为成功地把gtk-rs程序交叉编译到Windows。
剩下尚未完成的可能还有:国际化(Get text)、生成安装文件(打包以上文件)。