nixpkgs 中 WeeChat 的 override 定制机制:按插件裁剪闭包、注入 Python 库与启动脚本
2026/9/18 11:26:56 网站建设 项目流程

nixpkgs 中 WeeChat 的 override 定制机制:按插件裁剪闭包、注入 Python 库与启动脚本

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

在 nixpkgs 中,WeeChat 默认会编译并打包所有可用插件,这会让它的 closure(依赖闭包)变得偏大。本文以 doc/packages/weechat.section.md 为主体,完整讲解 WeeChat 的override { configure }定制机制:如何通过availablePlugins精确选择插件以缩减闭包、如何用withPackages为 Python/Perl 插件额外注入第三方库、如何用init传递--run-command启动命令、如何用scripts声明 WeeChat 脚本,以及如何编写符合 nixpkgs 规范的 WeeChat 脚本 derivation(passthru.scripts$out/share约定)。读完后你可以复制即用这些表达式,并在需要时深入脚本打包的底层约定。

一、为什么需要 override 定制:默认全量插件的代价

WeeChat 是一个终端 IRC/聊天客户端,功能依赖插件提供。在 nixpkgs 里,若不额外配置,它会把pythonperlrubyguiletcllua等所有可用插件都构建进去,导致安装时把整套解释器及相关依赖都拉进闭包,体积和构建耗时都上升。

官方文档给出的解法是通过包对象的override方法注入一个configure函数,覆盖其默认配置。这是 WeeChat 定制的核心入口——后续所有“选插件、加库、加命令、加脚本”的操作,都是在configure返回的 attrset 里完成的。

当前仓库中 WeeChat 是一个真实存在的包:例如 pkgs/by-name/we/weechat-matrix-rs/package.nix 将weechat作为buildInputs之一,并把矩阵插件库移动到$out/lib/weechat/plugins/matrix<sharedLibrary>,这正说明了 WeeChat 插件被放置在lib/weechat/plugins下的运行时布局,也从侧面印证了“按需裁剪插件”对控制闭包体积的实际意义。

二、按 availablePlugins 选择插件,缩减闭包体积

configure函数接收一个包含availablePlugins的参数集,availablePlugins是一个以插件名为键、以对应插件 derivation 为值的 attrset。通过plugins属性给出你实际需要的插件列表,即可只构建这些插件:

weechat.override { configure = ( { availablePlugins, ... }: { plugins = with availablePlugins; [ python perl ]; } ); }

要点:

  • with availablePlugins; [ python perl ]等价于[ availablePlugins.python availablePlugins.perl ],用with让表达式更简洁。
  • plugins是一个 derivation 列表,最终决定 WeeChat 构建时链接哪些插件。

文档明确说明:configure返回的 attrset 中没有plugins属性,则会自动使用availablePlugins(即全部插件)。这意味着你只要提供一个不触及pluginsconfigure,WeeChat 就会退回“全量插件”的默认行为,行为与不定制一致。

当前可用的插件为:pythonperlrubyguiletcllua。从源码结构看,这些名字正是availablePluginsattrset 的键,按需取用即可。

三、用 withPackages 为 Python / Perl 插件注入额外库

pythonperl插件支持“追加额外库”的能力。典型场景来自 doc/packages/weechat.section.md 描述的weechat-scripts生态:

  • inotify.py脚本需要 D-Bus 或 libnotify;
  • fish.py脚本需要pycrypto

要满足这些脚本的运行期依赖,使用插件的withPackages属性,把第三方 Python 包“包裹”进该插件 derivation:

weechat.override { configure = { availablePlugins, ... }: { plugins = with availablePlugins; [ (python.withPackages ( ps: with ps; [ pycrypto python-dbus ] )) ]; }; }

其中python.withPackages (ps: ...)返回一个“带额外 Python 包”的新插件 derivation,参数ps就是可用的 Python 包集合,with ps; [ pycrypto python-dbus ]在其中挑选pycryptopython-dbus。Perl 插件同理可用perl.withPackages(对应 Perl 模块集合)。

这一机制的本质是:插件自身就是一个可再 override 的对象,withPackages在插件层面追加解释器的运行依赖,而不影响主包的其它部分,从而把“插件需要哪些库”与“客户端主体”解耦。

四、保留全部默认插件的同时为部分插件追加库

上面的写法会“替换”整个plugins列表。如果你的需求是“保留全部默认插件,同时给python插件额外加上库”,文档给出了一种 attrset 覆盖技巧——先用//覆盖对应键,再用builtins.attrValues摊平回列表:

weechat.override { configure = { availablePlugins, ... }: { plugins = builtins.attrValues ( availablePlugins // { python = availablePlugins.python.withPackages ( ps: with ps; [ pycrypto python-dbus ] ); } ); }; }

逐行理解:

  • availablePlugins // { python = ... }:以//(attrset 更新)的方式,仅把python键替换为“带额外库”的版本,其余键(perlruby等)保持原值。
  • builtins.attrValues (...):把 attrset 的所有值摊平为列表,还原成plugins要求的 derivation 列表形态。

这样就实现了“全量插件 + 单插件增强”的折中方案,既控制住了python的依赖,又保留了其它插件的完整能力。

五、用 init 传递 --run-command 启动命令

WeeChat 支持通过--run-command在启动时执行默认命令。configure中的init属性就是用来承载这些命令的,init的值是一段字符串(''...''),里面写 WeeChat 的斜杠命令,例如设置变量、添加服务器:

weechat.override { configure = { availablePlugins, ... }: { init = '' /set foo bar /server add libera irc.libera.chat ''; }; }

文档补充说明:这些命令等价于运行时执行weechat --run-command "your-commands"时传入的命令列表;在打包阶段写入init,则每次启动 WeeChat 都会自动带上这些配置,无需手动在终端敲命令。

六、用 scripts 声明启动时加载的 WeeChat 脚本

除了命令,你还可以指定一组在 WeeChat 启动时加载的脚本。文档强调这些脚本会在init中的命令之前加载,因此脚本负责安装/注册,而init里再针对这些脚本做配置项(/set plugins.var...)的设置:

weechat.override { configure = { availablePlugins, ... }: { scripts = with pkgs.weechatScripts; [ weechat-xmpp weechat-matrix-bridge wee-slack ]; init = '' /set plugins.var.python.jabber.key "val" ''; }; }

要点:

  • scripts是一个 derivation 列表,这里从pkgs.weechatScripts这个“脚本子包”中挑选weechat-xmppweechat-matrix-bridgewee-slack
  • 加载顺序为:先加载scripts中列出的脚本,再执行init中的命令。上例中init里设置 jabber 的 key,正是依赖 xmpp 脚本已经加载完成后的配置项路径。
  • 从仓库结构看,weechatScripts是 nixpkgs 中专门存放 WeeChat 脚本 derivation 的子包,weechat-matrix-rs(见 pkgs/by-name/we/weechat-matrix-rs/package.nix)这类依赖weechat的插件/脚本正是这一生态的组成部分。

七、编写 WeeChat 脚本 derivation 的约定:passthru.scripts 与 $out/share

当你需要打包一个不在weechatScripts子包中的 WeeChat 脚本时,需要遵循 nixpkgs 的脚本 derivation 约定。文档给出的要求是:

  1. derivation 必须提供一个passthru.scripts属性,内容是“store 路径内所有脚本”的文件名列表;
  2. 所有脚本必须最终落在$out/share目录下。

一个示例 derivation 如下:

{ stdenv, fetchurl }: stdenv.mkDerivation { name = "exemplary-weechat-script"; src = fetchurl { url = "https://scripts.tld/your-scripts.tar.gz"; hash = "..."; }; passthru.scripts = [ "foo.py" "bar.lua" ]; installPhase = '' runHook preInstall mkdir $out/share cp foo.py $out/share cp bar.lua $out/share runHook postInstall ''; }

要点解析:

  • passthru.scripts = [ "foo.py" "bar.lua" ]:声明本次 derivation 携带了哪些脚本文件,nixpkgs 的 WeeChat 脚本聚合逻辑会依据这个列表去识别与注册脚本。
  • installPhasemkdir $out/share后把脚本复制到$out/share,满足“所有脚本都必须在$out/share”的约定;runHook preInstall/runHook postInstall是 stdenv 的标准 hook 调用,保证安装阶段前后的通用逻辑不被绕过。
  • 由于脚本最终位于$out/share且文件名与passthru.scripts对应,WeeChat 运行时才能正确发现并加载它们。

这条约定解释了为何文档中scripts属性可以直接接受一个 derivation:nixpkgs 依赖passthru.scripts+$out/share这两个信号,把任意符合约定的 derivation 识别成一组可被 WeeChat 加载的脚本。

八、定制机制小结与适用前提

把 doc/packages/weechat.section.md 的内容串起来,WeeChat 的定制完全围绕override { configure }展开,configure返回的 attrset 里三类关键属性各司其职:

  • plugins:决定构建/链接哪些插件(缺省时自动使用全部availablePlugins);python/perl插件可再用withPackages追加解释器依赖。
  • init:一段 WeeChat 斜杠命令字符串,等价于启动时的--run-command
  • scripts:启动时先于init加载的 WeeChat 脚本 derivation 列表,脚本需满足passthru.scripts$out/share约定。

适用前提与限制:

  • 上述表达式都依赖 nixpkgs 中 WeeChat 包暴露override { configure }接口,且availablePlugins的键为pythonperlrubyguiletcllua。若上游接口或可用插件集合发生变化,应以当前仓库实际包定义为准。
  • withPackages仅对pythonperl插件有意义(对应解释器的包集合),其余插件按文档描述不涉及该机制。
  • 脚本加载顺序(先scriptsinit)决定了“脚本负责安装、init负责设置配置项”的分工,编写脚本相关init命令时应以此顺序为前提。

通过本文的四个可复制表达式(选插件、加库、保留全量插件、传启动命令)与一个脚本 derivation 模板,你可以在 nixpkgs 里把 WeeChat 配置成既精简又满足脚本依赖的定制版本,并在需要时按仓库约定自行打包新的 WeeChat 脚本。

【免费下载链接】nixpkgsNix Packages collection & NixOS项目地址: https://gitcode.com/GitHub_Trending/ni/nixpkgs

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询