ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

使用 FPM 将 CPAN Perl 模块打包为 deb、rpm:完整指南与源码级解析

使用 FPM 将 CPAN Perl 模块打包为 deb、rpm:完整指南与源码级解析 使用 FPM 将 CPAN Perl 模块打包为 deb、rpm完整指南与源码级解析【免费下载链接】fpmEffing package management! Build packages for multiple platforms (deb, rpm, etc) with great ease and sanity.项目地址: https://gitcode.com/gh_mirrors/fp/fpm导读本文聚焦 FPMEffing Package Management项目中的cpan输入类型讲解如何把 CPAN 上的 Perl 模块或本地 Perl 模块目录一键转换成 deb、rpm 等系统原生包。读完本文你将掌握fpm -s cpan -t deb的完整实战用法、cpan 专属命令行参数的默认值与行为以及 FPM 从 MetaCPAN 搜索、下载、构建到生成包的底层调用链可直接用于 Perl 依赖的自动化打包与分发。一、cpan 输入类型的定位只进不出在 FPM 中每种包类型既可以作为输入-ssource也可以作为输出-ttarget。但根据 docs/packages/cpan.rst 的明确说明cpan类型只支持作为输入类型使用你不能用-t cpan把其他格式转换为 CPAN 发行包你只能用fpm -s cpan -t 输出格式把 Perl 模块转换为 deb、rpm、solaris、freebsd、osxpkg、puppet、sh、tar、zip 等输出格式完整输出类型见 docs/getting-started.rst。这一设计从代码结构上也可以印证在 lib/fpm/package/cpan.rb 中类FPM::Package::CPAN只实现并公开了input(package)方法见文件末尾public(:input)而没有实现output相关的转换逻辑其他包类型的输出转换由各自对应的 lib/fpm/package/ 文件完成。二、输入参数模块名或本地目录作为输入类型时fpm命令位置参数即模块名支持两种写法MetaCPAN 上的模块名例如Regexp::Common、File::Temp、Digest::MD5。FPM 会先在 MetaCPAN 上搜索该模块找到后自动下载对应发行包用于构建本地目录路径包含某个 Perl 模块源码的本地目录。FPM 会直接使用该目录进行构建跳过 MetaCPAN 搜索与下载环节。这一分支逻辑位于 lib/fpm/package/cpan.rbif File.exist?(package) moduledir package # 本地目录直接使用 result {} else result search_module(package, version) # 远程模块先搜索 tarball download(result, version) # 再下载 moduledir unpack(tarball) # 解压到构建目录 end位置参数数量不限任意多个都可以每个参数按上述规则独立处理。三、快速上手把 Regexp::Common 打包成 deb原文档给出了一个完整可复现的示例——将 CPAN 上的Regexp::Common模块打包为 Debian 包fpm -s cpan -t deb Regexp::CommonFPM 帮你完成了大量工作先在 MetaCPAN 上搜索Regexp::Common然后下载最新版本最后构建出 deb 包。实际运行时你会看到如下输出Downcasing provides perl-Regexp-Common because deb packages dont work so good with uppercase names {:level:warn} Downcasing provides perl-Regexp-Common-Entry because deb packages dont work so good with uppercase names {:level:warn} Debian tools (dpkg/apt) dont do well with packages that use capital letters in the name. In some cases it will automatically downcase them, in others it will not. It is confusing. Best to not use any capital letters at all. I have downcased the package name for you just to be safe. {:oldnameperl-Regexp-Common, :fixednameperl-regexp-common, :level:warn} Debian packaging tools generally labels all files in /etc as config files, as mandated by policy, so fpm defaults to this behavior for deb packages. You can disable this default behavior with --deb-no-default-config-files flag {:level:warn} Created package {:pathperl-regexp-common_2017060201_all.deb}3.1 关于那些警告信息示例中出现的几行警告并非错误而是 FPM 为让生成包被 Debian 工具链接纳所做的主动适配包名小写化Debian 包名约定全部使用小写。FPM 在检测到perl-Regexp-Common这类含大写字母的名字时会提示已经帮你转为小写fixednameperl-regexp-common::替换为-Debian 包名不允许包含::FPM 自动将其替换为短横线。Regexp::Common最终得到包名perl-Regexp-Common再经小写化变为perl-regexp-common/etc 配置文件策略Debian 策略要求 /etc 下的文件一律标记为配置文件FPM 默认遵循该行为可通过--deb-no-default-config-files关闭该 flag 属于 deb 输出类型详见 docs/packages/deb.rst。3.2 底层命名逻辑上述转换由 lib/fpm/package/cpan.rb 中的两个私有方法实现def cap_name(name) return perl( name.gsub(-, ::) ) end def fix_name(name) case name when perl; return perl else; return [attributes[:cpan_package_name_prefix], name].join(-).gsub(::, -) end endfix_name负责包名把前缀默认perl与发行包名用-连接并把::替换成-cap_name负责依赖与 provides 的命名把模块名包装成perl(模块名)形式如perl(Regexp::Common)这是 Debian/CPAN 生态通用的虚拟包命名习惯小写化则由 deb 输出端在构建阶段统一完成。四、指定版本使用 -v 参数FPM 默认下载 MetaCPAN 上的最新版本。如果你需要固定某个版本使用全局的-v参数即可例如fpm -s cpan -t deb -v 2016060201 Regexp::Common在源码层面版本号会同时作用于两处MetaCPAN 搜索search_module(module_name, version)构建查询时若指定版本则匹配module.version否则匹配status: latest见 lib/fpm/package/cpan.rb下载地址定位download(metadata, version)会用发行包名-版本号精确查询 MetaCPAN 的 release 搜索接口得到该版本的 download_url见 lib/fpm/package/cpan.rb。五、安装与验证生成的包原文档示范了完整的安装与使用闭环。先安装刚才生成的 deb 包sudo dpkg -i perl-regexp-common_2017060201_all.deb输出示例Selecting previously unselected package perl-regexp-common. (Reading database ... 81209 files and directories currently installed.) Preparing to unpack perl-regexp-common_2017060201_all.deb ... Unpacking perl-regexp-common (2017060201) ... Setting up perl-regexp-common (2017060201) ... Processing triggers for man-db (2.9.1-1) ...然后验证模块可用——让Regexp::Common输出一个匹配实数的正则表达式perl -MRegexp::Common -e print $RE{num}{real}输出(?:(?i)(?:[-]?)(?:(?[.]?[0123456789])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[-]?)(?:[0123456789]))|))这说明模块已成功安装到 Perl 的库路径中可以被use正常加载打包验证通过。六、cpan 专属命令行参数详解除全局参数如-s、-t、-v、-p、-n外cpan 输入类型还提供一组专属参数定义在 lib/fpm/package/cpan.rb并被 docs/packages/cli/cpan.rst 收录。下面结合源码中的默认值逐一说明命令行参数参数值作用默认值--cpan-perl-bin PERL_EXECUTABLE字符串指定要调用的 perl 可执行文件路径perl--cpan-cpanm-bin CPANM_EXECUTABLE字符串指定要运行的 cpanm 可执行文件路径cpanm--cpan-mirror CPAN_MIRROR字符串使用指定的 CPAN 镜像替代默认源源码默认回退http://www.cpan.org/无--[no-]cpan-mirror-only布尔仅用指定镜像获取元数据依赖--cpan-mirrorfalse--cpan-package-name-prefix NAME_PREFIX字符串包名前缀perl--cpan-perl-lib-path PERL_LIB_PATH字符串目标 Perl 库安装路径无跟随本机路径--[no-]cpan-sandbox-non-core布尔对非核心模块做沙箱隔离即使已安装也重新安装到临时目录true--[no-]cpan-test布尔打包前是否运行模块测试true--[no-]cpan-verbose布尔是否让 cpanm 输出详细日志false--cpan-cpanm-force布尔向 cpanm 传递--force参数跳过失败继续安装false--cpan-disable-dependency MODULE多值从自动生成的依赖中过滤指定模块按 Perl 模块名如URI::Escape[vars,warnings,strict,Config]--cpan-metacpan-api-url URL字符串MetaCPAN API 地址https://fastapi.metacpan.org6.1 关于--[no-]布尔参数布尔型参数支持--flag与--no-flag两种写法。这一机制来自 lib/fpm/package.rb 的option定义当参数为:flag类型时FPM 会自动为它生成--[no-]类型-名称形式。例如fpm -s cpan -t deb --no-cpan-test Regexp::Common会跳过测试速度更快适合 CI 流水线fpm -s cpan -t deb --no-cpan-sandbox-non-core Regexp::Common会取消依赖沙箱。6.2 与全局参数的关系-v指定模块版本而--cpan-package-name-prefix指定生成包的前缀若某模块名本身就是perl如对 Perl 核心打补丁的场景fix_name会直接返回perl而不再拼接前缀见上文fix_name代码。七、与 Perl 模块打包相关的常见调优示例结合 docs/getting-started.rst 中Packaging a CPAN module一节FPM 对 CPAN 打包默认持有三条假设均可通过参数调整本机 Perl 库路径即目标 Perl 库路径包名默认以perl为前缀CPAN 依赖关系有效且依赖的命名均以perl为前缀。若本机 Perl 安装在/opt/usr/share/perl5.10但希望生成的包将模块安装到/usr/share/perl5目标机器路径可执行fpm -t deb -s cpan --cpan-perl-lib-path /usr/share/perl5 Fennec若希望包名前缀从perl-Fennec变为fubar-Fennecfpm -t deb -s cpan --cpan-package-name-prefix fubar Fennec最朴素的用法则是直接用模块名打包fpm -s cpan -t deb FennecFPM 会自动从 CPAN 下载 Fennec 并生成本地 Debian 包。八、源码级解析一次fpm -s cpan的完整调用链理解内部流程有助于排查构建失败。FPM::Package::CPAN#inputlib/fpm/package/cpan.rb的完整流程如下获取源码本地目录直接使用否则search_module查询 MetaCPAN module 接口要求maturity: released未指定版本时取status: latestdownload再通过 MetaCPAN release 接口拿到精确下载地址默认回退到http://www.cpan.org/下的路径最终unpack解压到构建目录解压时会用--transform去掉顶层目录。读取元数据按META.json→META.yml→MYMETA.json→MYMETA.yml的优先级读取模块元数据lib/fpm/package/cpan.rb并与 MetaCPAN 查询结果合并本地 META 文件优先。若全部缺失抛出FPM::InvalidPackageConfiguration。填充包元信息从元数据中提取版本、描述abstract、许可证license数组取第一个缺失为 unknown、作者vendor缺失为 No Vendor Or Author Provided、主页 URLarchitecture默认all。安装构建/配置依赖调用cpanm默认参数-L沙箱目录或-l局部目录 --installdeps仅安装依赖不重复构建目标模块。--no-cpan-test追加-n--cpan-mirror追加--mirror--cpan-mirror-only追加--mirror-only--cpan-cpanm-force追加--forcelib/fpm/package/cpan.rb。自动解析依赖合并 META 中的requires与prereqs.runtime.requires生成perl(模块名)形式的依赖可用--cpan-disable-dependency过滤。其中对perl核心依赖会做版本号格式转换如5.010形式的转换版本为0视为任意版本复杂的版本字符串如 0, ! 1.0, ! 1.2会被拆分处理lib/fpm/package/cpan.rb。构建与安装在模块目录内若存在Build.PL则走 Module::Build 流程Build.PL→./Build→./Build test→./Build install否则若存在Makefile.PL则走 ExtUtils::MakeMaker 流程Makefile.PL PREFIX... INSTALL_BASE→make→make test→make DESTDIR... install两者都没有则报错lib/fpm/package/cpan.rb。--cpan-perl-lib-path会作为LIB/--install_path lib参与安装路径控制。清理无用文件删除perllocal.pod与.packlist后者连同空父目录一并移除避免多包冲突与冗余lib/fpm/package/cpan.rb。架构修正在暂存目录中查找.so共享库文件若发现则把架构从all改为native——这解决了含 XS 编译扩展的模块必须按本机架构打包的问题lib/fpm/package/cpan.rb。九、测试与质量保障仓库在 spec/fpm/package/cpan_spec.rb 中对 cpan 输入类型有完整覆盖可帮助你理解各行为的预期包名前缀拼接fix_name(Foo::Bar) prefix-Foo-Bar模块名包装cap_name(Foo::Bar) perl(Foo::Bar)真实网络请求对 MetaCPAN 的httpfetch/httppost返回Net::HTTPOK元数据搜索search_module(File::Temp)返回 distributionFile-Temp精确版本下载download(metadata, 0.01)得到Set-Tiny-0.01.tar.gzprovides 生成search_provided_modules(Test-DB, 0.10)得到perl(Test::DB) 0.10等条目含无版本模块端到端打包Digest::MD5验证依赖解析与Regexp::Common均可生成名为perl-*的包。这些测试需要系统 PATH 中存在cpanm否则会被跳过见测试文件顶部的检测逻辑这提醒我们在使用 cpan 输入类型前须先确保本机安装好 perl 与 cpanm。十、使用前提与注意事项环境依赖cpan 输入类型依赖本机的perl与cpanm可执行文件默认路径为 PATH 中的perl/cpanm可通过--cpan-perl-bin/--cpan-cpanm-bin指定网络依赖搜索与下载模块需要能访问 MetaCPAN API默认https://fastapi.metacpan.org可配置下载源默认回退http://www.cpan.org/可通过--cpan-mirror换成镜像。源码中的 HTTP 请求支持http_proxy环境变量代理见 lib/fpm/package/cpan.rb命名适配输出为 deb 时包名会被小写化并将::替换为-这是为了兼容 Debian 工具链的强制约束属于预期行为关闭自动依赖若不想自动生成依赖可使用全局参数--no-auto-depends见 lib/fpm/command.rbCI 提速在自动化构建中可配合--no-cpan-test跳过上游模块测试以缩短构建时间但需评估风险。综上FPM 的 cpan 输入类型打通了CPAN Perl 模块 → 系统原生包的自动化通道一条fpm -s cpan -t deb命令即可完成搜索、下载、依赖解析、构建、命名适配与打包源码实现lib/fpm/package/cpan.rb与测试spec/fpm/package/cpan_spec.rb为每项行为提供了可验证的依据适合在需要批量交付 Perl 依赖的运维与发布场景中直接落地。【免费下载链接】fpmEffing package management! Build packages for multiple platforms (deb, rpm, etc) with great ease and sanity.项目地址: https://gitcode.com/gh_mirrors/fp/fpm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表