如何在Gentoo中Hook emerge安装进程

First Post:

Last Update:

Word Count:
880

Read Time:
4 min

TL;DR: 用/etc/portage/env实现,官方说明页面。

背景

最近发现在wps中无法使用输入法,具体来说是无法在hyprland上使用fcitx,现象是通过desktop entry启动时无法使用输入法,在命令行启动时可以使用,搜索了一下arch wiki说只要添加这些变量即可:

1
2
3
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx5
export XMODIFIERS=@im=fcitx

但是我已经在~/.zshenv下添加了,看来是从desktop entry启动没有读取shell的环境变量导致的,我也不想在整个系统中设置这个环境变量,进一步检查发现desktop entry调用的是/usr/bin下的启动脚本,但是这些文件每次更新都会被覆盖,我不想每次都手动修改。

于是 hook emerge 来修改脚本就理所应当了。当然,emerge允许用户的patch,但是我的需求是给几个脚本在指定行数添加几行代码,我觉得用hook的方式更方便。

如何hook emerge安装进程

Gentoo Handbook提供了这方面的介绍。
看起来我们要用的是Hooking into the emerge process这一节的内容,也就是/etc/portage/bashrc,其实不然,这个 界面提供了更详细的说明,第一句话就指出了 The /etc/portage/bashrc file is a global bashrc file referenced by Portage. bashrc中定义的hook是全局生效的,显然不适用于我们的情况,实际上我们应该使用的是第二节提到的env。

这个页面对env有更详细的说明:

To have a file called when emerging a specific package, it should be named following the pattern “/etc/portage/env/<category>/<package_name>” (versions can be included, see portage man page), the contents being as in /etc/portage/bashrc; the contents will be parsed as a bash script. These files can hook into specific phases of the emerge process.

虽然env这名字看起来只是用来设置环境变量,实际上用来hook也是完全没问题的,在我们的情况下,只需要创建文件/etc/portage/env/app-office/wps-office即可,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
post_src_install() {
local insert_block="export export GTK_IM_MODULE=fcitx\nexport QT_IM_MODULE=fcitx5\nexport XMODIFIERS=@im=fcitx"

einfo ">>> [Fcitx Hook] adding environment variables to wps-office scripts in /usr/bin ..."

local bin_dir="${D}/usr/bin"

if [[ -d "${bin_dir}" ]]; then
for script in "${bin_dir}"/*; do
if [[ -f "${script}" ]]; then
# safe check
if head -n 1 "${script}" | grep -q "^#!"; then
einfo "Patching: ${script##*/}"
sed -i "4i ${insert_block}" "${script}"
else
ewarn "Skipping: ${script##*/}"
fi
fi
done
else
ewarn "Warning: ${bin_dir} DONT exist! skip hook"
fi
}

轻松解决!
emerge log:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-> % sudo emerge -1 wps-office
Calculating dependencies... done!
Dependency resolution took 2.51 s (backtrack: 0/20).

[ebuild R ~] app-office/wps-office-12.1.2.22571

>>> Verifying ebuild manifests

>>> Emerging (1 of 1) app-office/wps-office-12.1.2.22571::gentoo-zh
* wps-office_12.1.2.22571_amd64.deb BLAKE2B SHA512 size ;-) ... [ ok ]
>>> Unpacking source...
>>> Unpacking wps-office_12.1.2.22571_amd64.deb to /var/tmp/portage/app-office/wps-office-12.1.2.22571/work
>>> Source unpacked in /var/tmp/portage/app-office/wps-office-12.1.2.22571/work
>>> Preparing source in /var/tmp/portage/app-office/wps-office-12.1.2.22571/work ...
>>> Source prepared.
>>> Configuring source in /var/tmp/portage/app-office/wps-office-12.1.2.22571/work ...
>>> Source configured.
>>> Compiling source in /var/tmp/portage/app-office/wps-office-12.1.2.22571/work ...
>>> Source compiled.
>>> Test phase [not enabled]: app-office/wps-office-12.1.2.22571

>>> Install app-office/wps-office-12.1.2.22571 into /var/tmp/portage/app-office/wps-office-12.1.2.22571/image
>>> Completed installing app-office/wps-office-12.1.2.22571 into /var/tmp/portage/app-office/wps-office-12.1.2.22571/image

* >>> [Fcitx Hook] adding environment variables to wps-office scripts in /usr/bin ...
* Patching: et
* Patching: misc
* Patching: wpp
* Patching: wps
* Patching: wpspdf
* Final size of build directory: 2385720 KiB (2.2 GiB)
* Final size of installed tree: 2361888 KiB (2.2 GiB)