资讯动态

RHEL源码编译huge版Vim9:依赖、configure与特性验证

发布时间:2026/10/27 3:47:56 来源:尧图企业网站定制
1. 为什么要自己编译一个 huge 版 vim系统自带的 vim 有个很典型的现象你敲vim --version看到一串-号-python3、-lua、-clipboard、-terminal甚至-syntax。这些减号代表当前这个二进制在编译阶段就没有把对应特性链接进去。平时改改配置文件感觉不出来一旦你想用插件、想剪贴板互通、想用:terminal开个窗口跑命令就会立刻撞墙。所以这篇内容讲的是在 RHEL 系系统上从源码编译一个huge特性的 vim9把那些减号全部变成加号整个流程熟练之后三分钟能走完一遍。我把话说在前面这篇不介绍任何花哨的东西全部围绕一条主线——拿到源码、配好依赖、开对编译选项、装到独立前缀不污染系统、最后验证特性列表。适合两类人看一类是刚接触 RHEL 系、发现系统 vim 残缺但不知道差在哪的另一类是已经会编译、但每次都在--with-features和依赖包上反复试错、想沉淀一套稳定命令的。先解释一下huge到底是什么。vim 的特性等级从tiny、small、normal、big到huge这是一组预设宏集合本质是feature.h里按等级批量开关的#define。huge是最大的那一档打开绝大多数可用特性多级撤销、语法高亮、折叠、diff、命令行补全、鼠标支持、多字节字符、eval表达式引擎等等。但注意一个关键点huge不等于“所有特性都有”它只覆盖 vim 自身代码里的特性宏像python3、lua、clipboard这类依赖外部库的必须在configure阶段显式指定路径否则即便--with-featureshuge也照样是减号。这是最多人误解的地方也是后面要重点处理的部分。至于为什么选 vim9 而不是老版本简单说就是脚本引擎换了代。vim9 script 把执行方式从逐行解释改成编译成指令再跑函数调用、循环、类定义这些场景下性能差距很明显尤其是那些用 vimscript 写了不少自动化逻辑的人升级收益直接能感知到。加上 9.x 系列对 LSP 客户端、弹出窗口、文本属性的支持更完整很多现代插件的硬性门槛就在这。所以对 RHEL 用户来说系统源里的版本普遍偏旧自己编一个是性价比很高的选择。另外要强调的是不要把编译结果覆盖系统 vim。RHEL 上很多东西包括一些系统脚本、vi的软链接关系依赖系统自带的那份你make install到/usr/local或者独立目录用PATH或者alternatives去切换是最稳的做法。我踩过的坑是早期图省事直接make install覆盖/usr/bin/vim结果某次升级后包管理器又把它盖回去两份二进制混着用排查了半天。这个教训后面还会展开。2. 编译前的准备工作依赖清单与常见缺包2.1 先把开发工具链补齐RHEL 系的包管理用dnf老版本是yum编译源码第一件事是装开发工具组。Development Tools这个组包含 gcc、make、autoconf、automake 等一整套一条命令搞定sudo dnf groupinstall -y Development Tools如果你在最小化安装的系统上操作可能连tar、wget都没有顺手补上sudo dnf install -y tar wget curl这里有个经验不要在没装工具链的情况下直接跑./configure它会在检测编译器阶段报一堆C compiler cannot create executables看起来像源码有问题实际就是没装 gcc。我在帮别人看问题时遇到过好几次对方以为是下载的源码包损坏反复重新下载其实是环境问题。2.2 决定你最终特性列表的那几个库这一节是重点。很多教程只写dnf install ncurses-devel然后编译完发现python3、clipboard全是减号又回头找原因。我建议你先把想要的特性想清楚再一次性把对应的-devel包装全。下表是我常用的对照关系想要开启的特性需要安装的包configure 选项终端界面基础必需ncurses-devel无需显式指定Python3 插件支持python3-devel--enable-python3interpyesLua 插件支持lua-devel--enable-luainterpyes系统剪贴板互通libXt-devel、libX11-devel或终端剪贴板方案--with-x或依赖终端终端窗口:terminal无额外依赖--enable-terminal字符编码转换libicu-devel--enable-xim等多语言消息gettext默认开启一条命令把常用的装上sudo dnf install -y ncurses-devel python3-devel lua-devel libXt-devel libX11-devel git注意python3-devel装完后configure才能找到python3-config这个脚本。如果你系统上有多个 Python 版本共存要确保python3-config指向的是你想链接的那个版本可以用which python3-config确认一下路径。这里有个细节vim 编译时链接的是 Python 的动态库运行时如果 Python 版本被替换或者路径变了vim启动会直接报undefined symbol所以尽量用系统自带的python3-devel别去手动编译一个私有的 Python 再拿来链接后期维护成本高。关于剪贴板这里要单独说明一下因为这是 RHEL 用户最容易困惑的点。clipboard特性在传统 X11 环境下依赖libXt但如果你日常是在终端里工作比如通过 SSH 连服务器根本没有 X 显示那么clipboard即使编进去了也用不了因为 vim 找不到可用的剪贴板提供者。这时候正确的思路是让终端模拟器去接管复制粘贴vim 侧只需要clipboard存在、能识别y寄存器就行——很多时候不装libXt-devel也会显示clipboard靠的是终端自身的 OSC 52 等机制配合。但为了保险还是建议装上libXt-devel让编译期完整。2.3 确认源码来源和版本源码从官方仓库拉最稳妥用 git 可以随时切 taggit clone --depth 1 https://github.com/vim/vim.git ~/src/vim--depth 1只拉最新一次提交省时间。如果你要某个具体版本先git ls-remote --tags看有哪些 tag再git fetch --depth 1 origin tag v9.x.xxxx切过去。这里我给个建议生产环境上手之前先在测试机上把某个固定 tag 编一遍并记录特性列表之后再升级时对比列表差异能快速发现某个依赖是不是没装上。这种“快照式”的验证方法在编译第三方软件时特别有用比事后猜要高效得多。如果你的机器不能直连外网那就下载 release 的 tar 包解压后进目录效果一样。注意解压后目录结构是vim-9.x/里面套src/configure脚本在src/目录下别在顶层目录找。3. configure 选项逐个拆解每个开关背后的取舍3.1 安装前缀的选择为什么不装到 /usr--prefix决定最终make install装到哪里。默认是/usr/local这个位置本身合理因为它在系统包管理器的管辖范围之外不会被dnf覆盖。但我更推荐装到一个带版本号的独立目录比如--prefix/opt/vim9理由是升级和回滚都方便。你想换版本直接编译新的装到/opt/vim9-new验证没问题再改软链接想回滚切回旧目录即可不用重新编译。而/usr/local虽然也能用多个版本混在同一目录里make install会直接覆盖同名文件出问题不好回溯。还有一点值得说如果你装到独立目录还要处理运行时文件路径。vim 找语法文件、插件目录靠的是编译期写死的$VIMRUNTIME具体来说configure会把 prefix 拼进去。所以编译前的 prefix 决定了安装后的路径中途改 prefix 必须重新跑configure不能只改 Makefile。3.2 特性等级与解释器huge 加满的完整命令行下面这段是我现在固定使用的一套参数你可以直接抄cd ~/src/vim/src ./configure \ --prefix/opt/vim9 \ --with-featureshuge \ --enable-multibyte \ --enable-python3interpyes \ --enable-luainterpyes \ --enable-terminal \ --enable-cscope \ --enable-guino \ --enable-fontset \ --with-tlibncursesw \ --disable-netbeans \ --with-compiledbylocal-build逐条说理由。--with-featureshuge是主线前面讲过了。--enable-multibyte是让 vim 内部用多字节方式处理文本中文环境必须开虽然huge默认会带但显式写出来更保险。--enable-python3interpyes和--enable-luainterpyes是对应解释器支持注意yes和dynamic的区别yes静态链接vim 二进制直接依赖对应动态库找不到库就启动失败。dynamic运行时用dlopen动态加载找不到库时 vim 照常启动只是该特性不可用。我个人的选择是 Python3 用dynamic、Lua 用dynamic理由是如果哪天环境里的 Python 升级了静态链接的 vim 可能直接起不来而动态加载模式下 vim 至少还能用只是:python3报错你能进去改配置排查。所以更稳的写法是--enable-python3interpdynamic \ --enable-luainterpdynamic \这里补充一个容易忽略的点用dynamic时configure仍然需要python3-devel来获取头文件路径只是链接方式变了。所以依赖包还是得装别以为 dynamic 就什么都不用装。--enable-terminal是开启:terminal内置终端需要 vim 版本足够新9.x 全都支持。这个特性是我最常用的之一可以在编辑文件的同时开一个 shell 跑测试不用切窗口。--enable-cscope是给 C 代码跳转用的如果你写 C/C 可以留着不写也没坏处。--enable-guino明确不要图形界面版本只编终端版。编 GUI 版需要 GTK 或者 Motif 的整套开发库体积大、编译慢而且我日常就在终端里编辑GUI 版用不上。如果你确实需要 gvim把这里换成--enable-guigtk3并补装gtk3-devel。--with-tlibncursesw指定链接带宽字符支持的 ncurses这是中文、日文等宽字符正常显示的前提。RHEL 上默认可能探测成ncurses非宽字符版导致中文在终端里占位错乱。--disable-netbeans是关掉 NetBeans 集成这个功能现在基本没人用关掉省依赖。--with-compiledby是打在:version输出里的一行标识写上自己方便和其他机器区分纯属个人习惯。3.3 configure 之后的检查看它到底认了什么configure跑完会打印一长串摘要很容易被刷过去。我的做法是紧跟着做两件事。第一件确认退出码是 0echo $?如果非 0往上翻输出找checking ... no里关键的那几项通常是缺包或者路径不对。第二件直接看生成的配置文件里关键特性是否开启grep -E FEAT_(HUGE|PYTHON3|LUA|TERMINAL|MULTIBYTE) src/auto/config.h能看到#define FEAT_HUGE 1这类行就说明配进去了。这一步很重要我见过有人 configure 时写错选项名比如把--enable-luainterp写成--enable-luaconfigure 不报错只是忽略最后编译出来是减号还以为源码有问题。选项拼写错误是 configure 阶段最隐蔽的坑因为它不会让你失败只会默默不生效。提示configure日志建议重定向保存一份比如./configure ... 21 | tee ~/vim-configure.log。出问题时这份日志比事后回忆有用得多尤其是依赖检测那一大段。4. 编译与安装时间、并发与路径细节4.1 make 参数与耗时预期源码目录src/下面直接跑make -j$(nproc)-j$(nproc)用满所有 CPU 核心编译快很多。在普通 4 核测试机上全量编译大约一到三分钟配置高的机器更快所以标题里说三分钟不算夸张但前提是依赖提前装好、configure 一次过。这里有个经验值得讲如果编译中途报错中途停掉第二次跑make之前先make clean。因为第一次编译可能留下半成品.o文件直接重跑有时候会用到旧对象出现莫名其妙的链接错误。虽然 vim 的 Makefile 依赖关系写得不错但清理一下再编是最省心的做法尤其在改动过 configure 选项之后——如果你改了--enable-python3interp这类影响 CFLAGS 和链接的选项之前的.o全是按旧配置编的不 clean 就会得到行为诡异的二进制。4.2 安装与 PATH 配置sudo make install装到/opt/vim9之后/opt/vim9/bin/vim就是你的新二进制。让它生效有几种做法我按推荐程度排第一种改用户自己的PATH在~/.bashrc里加export PATH/opt/vim9/bin:$PATH放在前面让它优先命中。这种方式只影响当前用户不影响其他人也不动系统文件是最轻量的。第二种用alternatives系统统一管理适合多用户机器sudo alternatives --install /usr/bin/vim vim /opt/vim9/bin/vim 100数字是优先级越大越优先。之后可以用alternatives --config vim交互切换。第三种是软链接sudo ln -sf /opt/vim9/bin/vim /usr/local/bin/vim。简单直接但注意/usr/local/bin得在PATH里且在/usr/bin前面否则系统 vim 还是抢先。这里提醒一点PATH 顺序决定了你到底在用哪个 vim。排查“我明明装了新版怎么特性还是老的”这类问题时第一个命令永远是which -a vim把所有命中的路径列出来再看vim --version输出第一行的路径两者一对就清楚了。另外别忘了很多系统里vi是个软链接vim -v和vi可能指向不同二进制测试时要用完整命令确认。4.3 安装后验证把特性列表逐项对一遍vim --version | head -20重点看第一行的版本号和下面那一大段/-。我会特别检查这几项特性期望不满足时的典型原因python3有没装python3-devel或选项拼错lua有没装lua-devel或选项拼错terminal有忘了--enable-terminalclipboard有缺libXt-devel或编译时报过警告syntax有一般 huge 都带若缺说明 prefix 有问题multi_byte有没开 multibyte再用:echo has(python3)在 vim 里确认一次返回1才算真通。有些情况下--version显示python3但运行时报E370: Could not load library那就是动态链接在运行时找不到.so用ldd $(which vim) | grep python看链接情况或者检查 Python 库路径。最后确认$VIMRUNTIME指向新装的运行时目录:echo $VIMRUNTIME应该是/opt/vim9/share/vim/vim90这类路径。如果它指到系统旧目录说明你跑的还是旧二进制回到which -a vim那一步重查。5. 踩坑实录几个让人绕远路的细节5.1 中文乱码与 tlib 探测失败我在一台最小化安装的机器上编译完打开带中文的文件发现中文显示成方框或者每行错位。查下来是configure探测时把终端库定成了ncurses而不是ncursesw导致宽字符处理没启用。表现是multi_byte明明是加号但实际渲染还是按字节宽度算。解决办法就是前面提到的--with-tlibncursesw前提是ncurses-devel装的是宽字符版本。RHEL 上ncurses-devel通常同时提供两者但configure的自动探测顺序不一定命中宽字符那个。如果你已经编完才想起来必须重新configure再make clean make只重新make是没用的因为 tlib 是写进 config.h 的。还有一个相关的小细节终端本身的 locale 也要设置正确echo $LANG要是en_US.UTF-8或zh_CN.UTF-8这类纯POSIX环境下中文一样显示异常这跟 vim 编译无关别把两件事混在一起排查。5.2 剪贴板寄存器显示为加号但粘贴没反应这个坑我遇到不止一次。vim --version显示clipboard但在里面用y复制去别的窗口CtrlV粘贴什么都没有。原因分两种情况。第一种是在纯终端环境无 X11里工作。这时候 vim 的clipboard依赖外部提供者如果检测不到可用的剪贴板管理程序寄存器操作会静默失败。可以在 vim 里执行:echo has(clipboard)看是否返回 1再看:echo $DISPLAY是否为空。空的情况下就要靠终端模拟器自身的复制粘贴能力vim 这边不需要纠结y。第二种是装了 X11 库但configure时libXt-devel缺失导致clipboard是加号但实现不完整。这种就得补装libXt-devel后重新编译。这里给一个实操判断技巧在 vim 里执行:reg 看寄存器内容是否为空再试:let test然后用系统工具去粘贴。如果:reg 显示有内容但系统剪贴板没有那就是跨进程通道断了属于环境问题而非编译问题。把这条链路分开验证比一上来就怀疑编译错误高效。5.3 重装后插件目录和配置的错位从系统 vim 切到/opt/vim9之后一个很典型的问题是插件不生效。原因是老版本 vim 的插件加载路径和新版的默认路径不完全一致尤其是如果你之前手动往/usr/share/vim/vimXX/plugin里放过东西新装的 vim 根本不会去读那个目录。我的做法是把个人配置和插件全部放在~/.vim和~/.vimrc下让新 vim 通过$HOME去读取这样二进制换不换都不影响。如果你的 vim9 使用了新的默认配置目录比如~/.vim与新式的~/.config/vim并存先执行:echo $MYVIMRC确认它到底加载了哪个文件再看:scriptnames列出所有被加载的脚本插件没生效时这两个命令能直接定位断点。一个额外的注意点不要在新 vim 里沿用旧的~/.vimrc却不检查其中的版本判断。有些老配置里写了if v:version 800之类的分支逻辑在 vim9 下可能走偏尤其是对set nocompatible、filetype plugin indent on这些顺序敏感的配置建议先清空配置验证基本功能再一段段把个人配置合并回去。5.4 编译过程中最容易误判的报错有几个报错信息看着吓人实际不用管或者处理方式很简单列出来省得你慌。第一checking for ... no出现一大堆是正常的configure会探测几百个可选特性大部分在huge下也用不到。你要关注的是摘要里明确列出、而你又想要的特性别被满屏的no吓到。第二Warning: Compiling with ...这类警告一般不影响结果但如果最后python3是减号就去翻src/auto/config.log里跟 python 相关的段落那里会写清楚是缺头文件还是版本不匹配。第三make阶段的undefined reference to ...基本都是链接库没找到。最常见的是编 GUI 版缺 GTK 库或者 Python 版本与头文件不一致。这时候看报错里涉及的库名用dnf provides */libXXX.so定位包名装上去再make clean重来。第四configure: error: cannot run C compiled programs一般出现在/tmp被挂成noexec的机器上或者 SELinux 策略限制换个可执行目录重试即可TMPDIR~/tmp ./configure ...。6. 装好之后的几件收尾事编译装完之后我一般还会做几件小事让这套环境真正可用。第一是给新 vim 配一个独立的runtimepath规划把插件目录、语法文件、字典放在同一棵树下避免和系统 vim 交叉污染。我的习惯是set runtimepath^~/.vim再加set packpath^~/.vim用 vim 自带的packages机制管理插件这样不依赖外部插件管理器也能用。第二是检查:help能不能正常打开。如果报E149: Sorry, no help for ...说明$VIMRUNTIME/doc路径不对回到前面确认 prefix 和 runtime 路径。这个功能平时不常用但排查问题时查帮助很关键装完就验证一下省得日后抓瞎。第三是给这个二进制加个别名我用的是alias v9/opt/vim9/bin/vim这样系统 vim 和新版同时留着各自有明确入口不会因为改 PATH 影响其他工具链。什么时候觉得新版完全稳了再把 PATH 里的优先级调上去。第四把编译时用的完整 configure 命令行记到某个文本文件里比如~/.vim-build-notes连同当时的依赖包列表一起。下次换机器、或者一年后重编直接照着跑就行不用再从头推理一遍。这个习惯我坚持了很久回报率极高尤其是编译那些选项多、容易忘的软件时。注意每次升级 vim 后如果之前用dynamic方式链接了 Python3务必先在一个子 shell 里跑一遍vim --version确认不报库加载错误再切换全局 PATH。否则可能出现在终端里完全打不开 vim、只能靠其他编辑器改 PATH 的尴尬局面。我在实际使用中的体会是编译 vim 这件事真正花时间的从来不是make那几分钟而是前面确认特性需求和后面验证特性列表这两头。把依赖清单和 configure 选项固化下来之后一台新机器从零到可用基本就是复制粘贴几条命令的事。而最值得记住的一条经验是每次改动 configure 参数之后一定make clean再编——这个动作能挡掉我遇到过的绝大多数“为什么编出来的特性跟预期不一样”的疑问。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑