ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

V 语言(Vlang)发行版打包指南:构建可在只读系统中稳定运行的 v 软件包

V 语言(Vlang)发行版打包指南:构建可在只读系统中稳定运行的 v 软件包 V 语言Vlang发行版打包指南构建可在只读系统中稳定运行的 v 软件包【免费下载链接】vSimple, fast, safe, compiled language for developing maintainable software. Compiles itself in 1s with zero library dependencies. Supports automatic C V translation. https://vlang.io项目地址: https://gitcode.com/GitHub_Trending/v/v引言本文根据 packaging_v_for_distributions.md 整理而成面向那些希望把 V 语言编译器打包进各发行版仓库并长期维护软件包的打包维护者。V 的编译命令设计上会按需自举自身工具并默认假设安装目录可写、可自我更新这与发行版软件包安装后只读、更新走系统包管理器的惯例存在冲突。读完本文你将掌握让打包版 V 适配只读环境的完整方法包括预构建cmd/tools/下全部工具、用.disable_autorecompilation禁用自动重编译、改造v up与v self、瘦身包内容、约束vlib/布局以及利用VEXE/VFLAGS/VCACHE/VTMP/VMODULES等环境变量编写动态启动脚本。文中所有关键结论都能在当前仓库的源码中找到实现依据。打包 V 前的认知准备V 仍在快速迭代中因此上游官方仍然建议对大多数用户而言从源码安装依旧是分发 V 的推荐方式。本指南则面向勇敢的打包维护者——他们需要把上游源码适配到某个发行版/平台并借助标准包管理器完成安装与更新使其与发行版中其他程序的行为一致。打包不是一次性动作难点在于长期维护V 的某个实现细节可能在后续版本中变化打包脚本需要与上游保持同步并持续跟进问题。核心冲突V 的按需自举模型与只读打包理解下面几个打包注意事项之前首先要理解 V 运行时的一个关键机制——工具按需编译。V 会把v up、v self、vfmt、v test、v run等大量子命令的实现放在 cmd/tools/ 文件夹中注意vbuild-tools.v、vup.v、vself.v等工具源码都在其中。当用户第一次运行某个工具时V 会比较工具源码.v文件与对应可执行文件的时间戳如果 V 自身或其工具源码比可执行文件新就会自动触发一次重编译。这段逻辑的源码注释在 util.v 中写得很清楚// launch_tool uses a timestamp based detection mechanism, so that after v self, each tool // will be recompiled too, before it is used, which guarantees that it would be up to date with // V itself. That mechanism can be disabled by package managers by creating/touching a small // cmd/tools/.disable_autorecompilation file, OR by changing the timestamps of all executables // in cmd/tools to be 1024 seconds (in unix time).这种设计为开发者和从源码安装的用户节省了磁盘与编译时间但对只读打包却是个问题一旦安装后文件系统变为只读V 尝试向cmd/tools/写入可执行文件就会失败。下面逐条给出打包时必须处理的 10 个要点。要点 1预构建 cmd/tools/ 下的全部工具如果打包的是预编译的 V 包并且希望安装后的包处于只读状态就必须提前构建好 cmd/tools/ 中所有工具的二进制文件。对应的命令是./v build-tools该命令会逐个编译cmd/tools/下的全部工具保证用户之后不再需要写入该目录。在 other.txt 的帮助文本中build-tools的描述是 Test if all tools can be built.它是打包流程最前置的一步。要点 2用哨兵文件禁用自动重编译仅预构建一次还不够还需要告诉 V以后别再尝试重编译工具了。V 通过检查是否存在名为cmd/tools/.disable_autorecompilation的文件来实现克隆版 V 中该文件默认不存在因此源码安装的 V 仍具备按需自动重编译能力打包时创建touch它即可禁用该机制该文件的内容无关紧要只有是否存在起作用。其底层实现见 recompilation.vdisabling_file()拼出{vroot}/cmd/tools/.disable_autorecompilation路径must_be_enabled()则检查该文件是否存在若存在就打印错误并exit(1)。顺带一提文档还提供了另一个等价手段把cmd/tools/下所有可执行文件的时间戳改得足够旧unix 时间小于v self/编译发生的时刻源码注释中给出的参考是 1024 秒量级也能达到同样效果——不过用哨兵文件显然更清晰、更可维护。要点 3处理v up自更新工具V 内置了v up工具用于从主仓库master分支快速拉取并自举更新。但绝大多数发行版不允许软件包自我修改要求用户一律走发行版自带的包管理器。因此文档建议维护者删除或替换cmd/tools/vup.v用一个简短的 V 程序替代它提示最终用户改用包管理器或改用从源码安装的 V。替换文件的源码保留在cmd/tools/vup.v中先于后续构建步骤生成println(use your package manager to update V, println(or if you want more recent V versions, just clone V from source, println(see https://github.com/vlang/v#installing-v-from-source)从源码也能印证这一机制真正的vup.v在入口处调用recompilation.must_be_enabled(app.vroot, Please install V from source, to usev up.)见 cmd/tools/vup.v即一旦检测到.disable_autorecompilation存在就直接中止。打包时替换源码只是让提示更贴合发行版语境双保险之下v up在打包版中绝不会真正执行更新。要点 4处理v self自举重编译v self同样是会改写安装目录的命令它会在vroot下用当前源码重新编译 V 本体。文档建议将其一并禁用把cmd/tools/vself.v替换成一个小程序告知用户打包版不推荐使用v self并建议需要v self的用户从源码安装 V。替换文件的内容示例println(v self is disabled for packaged versions of V. println(Use your package manager, to update your V package instead. println(Alternatively, if you do want a more recent V version, just clone V from source, println(then follow the instructions here: https://github.com/vlang/v#installing-v-from-source)真实实现同样会在入口处调用recompilation.must_be_enabled(vroot, Please install V from source, to use ... self .)见 cmd/tools/vself.v因此打包版环境中该命令会被哨兵文件机制直接拦下。要点 5可安全剔除的源码仓库内容源码克隆中有些大型文件夹与最终用户无关打包时可以一并移除以缩小体积.git/若按建议禁用了v up克隆历史对用户毫无用处thirdparty/tcc/.git/同样是嵌入式 TCC 子仓库的历史不需要随包分发Makefile、makev.bat、GNUmakefile仅用于从源码构建/自举打包预编译分发后不再需要。是否进一步剔除examples/取决于你对包体积的要求。文档建议保留示例通常更好但可以把它们拆到单独的包里。这里有一个很实际的考量如果用户在只读打包中直接编译examples/下的源码默认情况下可执行文件会被输出到.v源文件同目录而该目录是只读的编译会失败——除非显式传入-o path_to_executable_name指定输出路径。要点 6vlib/ 必须紧邻可执行文件附符号链接方案V 期望其vlib/标准库目录与v可执行文件位于同一目录层级当前 V 源码中大量路径基于VEXEROOT推导例如 cbuilder/parallel_cc.v 依据VEXEROOT/thirdparty/tcc定位 TCC且这一点目前难以定制。如果打包维护者呼声足够高上游可能在未来版本中开放配置可在 V 的 issue 跟踪器中表达诉求。但当前阶段有一个很实用的变通方案把可执行文件与vlib/放好之后再通过符号链接把可执行文件暴露到用户的PATH中即可。例如把可执行文件放在/opt/vlang/v把标准库放在/opt/vlang/vlib/然后sudo ln -s /opt/vlang/v /usr/bin/v # 或 sudo ln -s /opt/vlang/v /bin/v这样既满足了vlib/ 紧邻 v的硬约束又让用户能直接在命令行调用v。要点 7用 VEXE 指定可执行文件位置环境变量VEXE用于指定v可执行文件的绝对路径其默认值就是 V 可执行文件自身的绝对路径。在源码中它被多处读取例如 pref/default.v 中vexe : os.getenv(VEXE)而v up/v self在启动时也会通过os.real_path(os.getenv_opt(VEXE) or { VEXE })计算vroot见 cmd/tools/vup.v。当包内可执行文件被改名如去掉版本后缀或被脚本包装时显式设置VEXE可避免路径推导出错。要点 8用 VMODULES 指定模块安装目录v install安装第三方模块的目标目录由环境变量VMODULES控制。默认值类 Unix 系统~/.vmodulesWindowsC:\Users\用户ID\.vmodules。源码侧同样存在对应支持见 pref.v 中vmodules_paths的注释can be overridden by setting VMODULES。打包时建议保持默认行为让模块落在每个用户自己的家目录下避免写入系统目录。要点 9用 VTMP 指定临时目录V 编译过程中产生的临时文件目录由环境变量VTMP控制默认使用系统的 TEMP 目录。构建错误诊断链路中也大量使用了该变量见 c_error_report.v 的注释 it inherits the environment, and VTMP plus every V_MACOS_V3_REPORT_*。在系统临时目录空间受限或需要集中清理缓存的环境如 CI、容器中把VTMP指到专用路径会更可控。要点 10用 VFLAGS 注入默认编译参数VFLAGS环境变量可以为每次编译追加额外的 V 命令行参数。例如希望打包版 V 默认使用某个特定的 C 编译器而不是探测到的系统默认值可以统一设置-cc /usr/bin/custom_cc。用启动脚本launcher实现动态环境配置要点 710 的价值在于它们允许维护者编写一个名为v的小包装 shell 脚本在脚本内根据当前用户动态设置上述变量然后把脚本放进包的 bin 目录如/usr/bin/v、/bin/v替代直接放 V 主可执行文件或指向它的符号链接。脚本内可统一设置VEXE—— 指向真实 V 可执行文件如/opt/vlang/v保证子命令能正确定位vroot与vlib/VFLAGS—— 注入默认编译参数VCACHE—— 缓存目录注意文档示例中注释指出其默认值其实是~/.vmodules/cache可按需改为系统级缓存目录如/var/cache/...VTMP—— 指向系统级临时目录VMODULES—— 指向当前用户家目录下的模块目录如$HOME/.vmodules。这样一个脚本能同时兼顾系统级只读安装与每个用户可写的模块/缓存目录是打包版 V 良好体验的关键一环。完整打包脚本从源码到可分发产物把以上要点汇总文档给出了一段可以直接作为打包脚本基座的完整流程在源码克隆目录内执行echo println(use your package manager to update V, cmd/tools/vup.v echo or if you want more recent V versions, just clone V from source, cmd/tools/vup.v echo see https://github.com/vlang/v#installing-v-from-source) cmd/tools/vup.v echo println(v self is disabled for packaged versions of V. cmd/tools/vself.v echo Use your package manager, to update your V package instead. cmd/tools/vself.v echo Alternatively, if you do want a more recent V version, just clone V from source, cmd/tools/vself.v echo then follow the instructions here: https://github.com/vlang/v#installing-v-from-source) cmd/tools/vself.v v -prod -o v cmd/v ## 以 -prod 模式构建 V 本体 ./v build-tools ## 构建所有工具 ## 注意此处不要传 -prod ## 像 c_builder.v 这样的大工具在 -prod 的 LTO C 编译阶段可能耗尽内存 touch ./cmd/tools/.disable_autorecompilation ## 告诉 V 以后不要再重编译任何工具 ### 清理打包版不需要的文件夹 ### 这些内容与 V 源码仓库的版本管理强相关 rm -rf .git/ rm -rf thirdparty/tcc/.git/需要特别留意脚本中的两个注释性警告-prod只用于构建 V 本体./v build-tools这一步不要加-prod——像c_builder.v这样的大型工具在做-prod的 LTO C 编译时可能耗尽内存脚本中echo生成的是上文要点 3、4 的占位源码文件需在build-tools之前完成这样v build-tools编译出的vup/vself恰好是提示用户走包管理器的新版本。仓库根目录下确实存在 Makefile、makev.bat、GNUmakefile这些自举构建入口在预编译打包后同样不再需要可按要点 5 一并移除移除时机通常在构建与自检之后。bin 目录中的 v 启动脚本示例打包好真实可执行文件之后还需要一个面向用户的入口脚本。文档提供了可直接放入 bin 目录的示例按需调整其中的路径与-cc参数#!/usr/bin/env bash export VEXE/opt/vlang/v export VFLAGS-cc /usr/bin/custom_cc export VCACHE/var/cache/custom_vcache_folder ## ~/.vmodules/cache by default export VTMP/var/cache/custom_tmp export VMODULES$HOME/.vmodules /opt/vlang/v $不要忘记在包的 post-install 脚本中给入口脚本加执行权限chmod x /usr/bin/v否则用户即使装好了包也无法直接运行v。使用前自检清单与故障排查提示按下面的顺序核对可以显著降低打包版 V 的线上故障率工具是否全部预构建确认cmd/tools/下所有工具的二进制都在且安装后的目录确实为只读哨兵文件是否就位确认cmd/tools/.disable_autorecompilation存在于最终包中源码参考recompilation.v 中must_be_enabled依赖它拦截v up/v selfv up/v self是否已替换从源码克隆构建前先确认cmd/tools/vup.v、cmd/tools/vself.v的内容已被替换为提示走包管理器的占位程序相关源码入口cmd/tools/vup.v、cmd/tools/vself.v目录布局是否符合约束vlib/必须与v可执行文件处于同一层级可用符号链接把入口暴露到PATH启动脚本环境变量是否完整VEXE、VFLAGS、VCACHE、VTMP、VMODULES是否按目标系统的权限策略设置妥当尤其VMODULES要指向用户可写目录执行权限post-install 中是否执行了chmod x。如果用户报告某个工具编译失败/写入被拒绝优先排查第 1、2 条是否在构建产物中遗漏如果报告模块装不上或找不到 vlib则优先排查第 4、5 条。借助上述哨兵文件机制与目录约束大部分问题都能在打包阶段被提前暴露而不是留给最终用户在只读环境中才碰到。总结V 的按需自举设计对发行版打包提出了独特要求但通过 10 项明确的操作要点预构建工具、哨兵文件禁用自动重编译、替换v up/v self、安全瘦身、符号链接布局、环境变量与启动脚本维护者完全可以交付一个在只读系统上稳定运行、更新走系统包管理器的 V 软件包。本文提供的两段脚本——源码侧的准备脚本与 bin 侧的启动脚本——可以直接作为打包工程的起点相关机制均可在 vlib/v/util/recompilation/recompilation.v、vlib/v/util/util.v 以及 cmd/tools/ 下各工具源码中反复验证。【免费下载链接】vSimple, fast, safe, compiled language for developing maintainable software. Compiles itself in 1s with zero library dependencies. Supports automatic C V translation. https://vlang.io项目地址: https://gitcode.com/GitHub_Trending/v/v创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表