Perl构建和打包自己的模块
当写好一个或多个模块后,可以将它构建、打包成"tar.gz",以便让别人安装或者上传到CPAN(如果愿意的话)。对于模块的使用者来说,也不用再使用use lib 'LIB_PATH'
来找pm文件,安装后一般都会安装到@INC
路径下,然后直接使用use MODULE
即可。
Module::Starter
在很早以前,使用h2xz工具,但它实在太古老了。现在很多人使用Dist::Zilla
模块来创建并安装模块。不过本文只是基础,只介绍Module::Starter
构建和打包的方法。
先安装:
$ cpan -i Module::Starter
Module::Starter
模块提供了一个命令行程序module-starter
,它可以用来构建模块。
例如,构建一个名为My::Number::Utilities
的模块(模块可以不用存在,它会自动创建一些文件结构)
$ module-starter --module "My::Number::Utilities" --author="ma long shuai" --email="79123@qq.com"
上面第一条命令将会创建如下的目录树:
$ tree My-Number-Utilities
My-Number-Utilities
├── Changes
├── ignore.txt
├── lib
│ └── My
│ └── Number
│ └── Utilities.pm
├── Makefile.PL
├── MANIFEST
├── README
├── t
│ ├── 00-load.t
│ ├── manifest.t
│ ├── pod-coverage.t
│ └── pod.t
└── xt
└── boilerplate.t
其中:
Changes
:包含程序版本的变化信息MANIFEST
:列出发布的模块版本中必须包含的每个文件Makefile.PL
:是Perl程序创建的Makefile,Makefile文件中包含了如何编译和构建程序的说明。如果不是非常熟悉Makefile格式,千万不能修改,一个tab和空格的不同可能都会导致编译出错。README
:包含了如何构建和安装程序的文档,一般来说,程序的说明文档会嵌入在此文件中。ignore.txt
:是类似于git/svn版本控制系统的文件忽略模板,你可能会经常拷贝该文件到你的版本控制系统中。lib/
:该目录包含了实际要安装的模块。t/
:该目录包含了模块测试相关的文件。
上面的文件可能已经包含了一些内容,例如lib/My/Number/Utilities.pm
文件中已经自动包含了一些编译指示,还包含了默认的pod文档。
$ head -n 10 My-Number-Utilities/lib/My/Number/Utilities.pm
package My::Number::Utilities;
use 5.006;
use strict;
use warnings;
=head1 NAME
My::Number::Utilities - The great new My::Number::Utilities!
默认情况下,Module::Starter
构建的模式是Makefile.PL,如果想要构建Build.PL,可以加上--builder=Module::Build
或者无需选项参数的选项--mb
:
$ module-starter --builder=Module::Build --module "My::Number::Utilities" --author="ma long shuai" --email="79123@qq.com"
$ module-starter --mb --module "My::Number::Utilities" --author="ma long shuai" --email="79123@qq.com"
因为每次在module-starter
命令行上都写author和email选项很麻烦,可以在家目录下创建一个文件$HOME/.module-starter/config
(该目录可由环境变量MODULE_STARTER_DIR
设置,只需在该环境变量指定的目录下包含config文件即可。例如windows下.module-starter目录可能会有些问题),包含每次想要在命令行中省略的选项即可,例如:
author: ma long shuai
email: 79123@qq.com
builder: Module::Build
verbose: 1
以后再执行module-stater时,只需一个--module
选项即可:
module-starter --module=My::Module
现在,只需将自己写的pm模块文件拷贝覆盖到My-Number-Utilities/lib/My/Number/Utilities.pm
,将独立的pod文档放到pm同目录下即可。然后就可以编译、安装模块了。
perl Makefile.PL
make
make test
make install
# 或者
perl Build.PL
./Build
./Build test
./Build install
上面的过程中,只要不是error,出现了warning可以忽略。
最后,执行下面两种命令,可将模块打包成".tar.gz"格式的文件。
make dist
./Build dist
例如,生成Build格式的包:
$ ./Build dist
Created META.yml and META.json
Creating Cat-New-0.01
Creating Cat-New-0.01.tar.gz
Makefile.PL和Build.PL
虽然Makefile.PL和Build.PL不建议修改,但小心翼翼点也可以修改。
Makefile.PL
先看Makefile.PL文件的前几行:
use 5.006;
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'My::Number::Utilities',
AUTHOR => q{ma long shuai <79123@qq.com>},
VERSION_FROM => 'lib/My/Number/Utilities.pm',
ABSTRACT_FROM => 'lib/My/Number/Utilities.pm',
LICENSE => 'artistic_2',
PL_FILES => {},
MIN_PERL_VERSION => '5.006',
CONFIGURE_REQUIRES => {
'ExtUtils::MakeMaker' => '0',
},
BUILD_REQUIRES => {
'Test::More' => '0',
},
PREREQ_PM => {
#'ABC' => '1.6',
#'Foo::Bar::Module' => '5.0401',
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'My-Number-Utilities-*' },
);
主要是其中的PREREQ_PM
项,它表示安装此模块时所依赖的模块,也就是要安装此模块,必须先安装该项指定的模块。它是一个hash结构,每个模块名是键,其值是模块的版本号,表示最低要安装该版本的模块。
此外,如果想要安装一些perl程序文件,而非模块文件,可以如下书写:
WriteMakefile(
...
EXE_FILES => [ qw( scripts/barnyard.pl ) ],
...
);
上面的要求是将barnyard.pl程序文件放在scripts目录下。通过这种方式,即使是没有包含任何模块,也能构建perl程序包。在安装模块的时候,这个文件会放进/usr/local/bin目录下。
Build.PL
再看Build.PL文件的前几行:
use 5.006;
use strict;
use warnings;
use Module::Build;
my $builder = Module::Build->new(
module_name => 'Cat',
license => 'artistic_2',
dist_author => q{ma long shuai <79123@qq.com>},
dist_version_from => 'lib/Cat.pm',
release_status => 'stable',
configure_requires => {
'Module::Build' => '0',
},
build_requires => {
'Test::More' => '0',
},
requires => {
#'ABC' => '1.6',
#'Foo::Bar::Module' => '5.0401',
},
add_to_cleanup => [ 'Cat-*' ],
);
$builder->create_build_script();
主要是其中的requires
项,它表示安装此模块时所依赖的模块。
此外,如果想要安装一些perl程序文件,而非模块文件,可以如下书写:
my $builder = Module::Build->new(
...
script_files => [ qw(scripts/barnyard.pl) ],
...
);
上面的要求是将barnyard.pl程序文件放在scripts目录下。
当执行Module::Starter
的module-starter时,会调用ExtUtil::Makefile
构建多个模块
如果想一次性构建多个模块,且知道各模块名称,则可以:
$ module-starter --module=Animal,Cow,Horse,Mouse
它会以第一个模块名称作为顶级目录,然后在lib中创建各模块文件。
参考如下目录结构:
$ tree Animal/
Animal/
├── Changes
├── lib
│ ├── Animal.pm
│ ├── Cow.pm
│ ├── Horse.pm
│ └── Mouse.pm
├── Makefile.PL
├── MANIFEST
├── README
├── t
│ ├── 00-load.t
│ ├── manifest.t
│ ├── pod-coverage.t
│ └── pod.t
└── xt
└── boilerplate.t
如果模块是多层次的(包含双冒号的),则构建的目录结构如下:
$ module-starter --module=Animal::Rule,Cow::Rule,Horse,Mouse
$ tree Animal-Rule
Animal-Rule/
├── Changes
├── lib
│ ├── Animal
│ │ └── Rule.pm
│ ├── Cow
│ │ └── Rule.pm
│ ├── Horse.pm
│ └── Mouse.pm
├── Makefile
├── Makefile.PL
├── MANIFEST
├── MYMETA.json
├── MYMETA.yml
├── README
├── t
│ ├── 00-load.t
│ ├── manifest.t
│ ├── pod-coverage.t
│ └── pod.t
└── xt
└── boilerplate.t
添加新模块
如果想要向已有模块目录添加一个新模块,需要使用Module::Starter::AddModule
插件,不过得先安装:
$ cpan -i Module::Starter::AddModule
然后在Module::Starter
的配置文件$HOME/.module-starter/config
中加入一行:
author: ma long shuai
email: 79123@qq.com
verbose: 1
plugins: Module::Starter::AddModule # 新加此行
然后就可以添加新模块:
$ module-starter --module=Sheep --dist=Animal-Rule
其中--dist
指定要添加到的模块目录,如果已经在Animal-Rule目录下,则使用相对路径--dist=.
即可。
Perl构建和打包自己的模块的更多相关文章
- 打包发布Python模块或程序,安装包
Python模块.扩展和应用程序可以按以下几种形式进行打包和发布: python setup.py获取帮助的方式 python setup.py --help python setup.py --he ...
- Angular企业级开发(6)-使用Gulp构建和打包前端项目
1.gulp介绍 基于流的前端自动化构建工具,利用gulp可以提高前端开发效率,特别是在前后端分离的项目中.使用gulp能完成以下任务: 压缩html.css和js 编译less或sass等 压缩图片 ...
- 基于dubbo构建分布式项目与服务模块
关于分布式服务架构的背景和需求可查阅http://dubbo.io/.不同于传统的单工程项目,本文主要学习如何通过maven和dubbo将构建分布项目以及服务模块,下面直接开始. 创建项目以及模块 ...
- 敏捷开发之产品日日新,一步通之---自动化代码构建->自动化打包->自动化安装部署
本文将介绍如何自动化实现代码构建,自动化代码打包成exe安装包,自动化安装到测试环境.通过计划任务的方式,每天自动化发布最新的产品供老板展示,供测试人员使用,真正实现敏捷的快速迭代. 自动代码构建 自 ...
- Android使用Jenkins自动化构建测试打包apk
Jenkins这东西搭建起来真是一点也不省心啊,看着别人的教程摸着石头过河,配置的东西有点多啊,稍有不慎,就构建不成功啦!即使步骤跟别人一样也会报各种乱七八糟的错误啊哈哈~~这东西只能佛系搭建~~在经 ...
- Maven创建Web工程并执行构建/测试/打包/部署
创建工程基本参考上一篇Java Application工程,不同的是命令参数变了,创建Web工程的命令如下: mvn archetype:generate -DgroupId=com.jsoft.te ...
- Maven的构建/测试/打包
继上一篇http://www.cnblogs.com/EasonJim/p/6809882.html使用Maven创建工程后,接下来是使用Maven进行构建/测试/打包. 在打包之前,先熟悉一下Mav ...
- rpmbuild - 构建 RPM 打包
SYNOPSIS 构建打包: rpmbuild {-ba|-bb|-bp|-bc|-bi|-bl|-bs} [rpmbuild-options] SPECFILE ... rpmbuild {-ta| ...
- 实用程序包utils - 基于Rollup打包输出各模块文件(二)
上一次,我们讲到了如何去搭建一个前端工具库的工程,那么今天我们来聊一聊如何去将其打包输出. 需求 事情是这个样子的.我有一个这样的需求,或者是我发现有这么一个需求.就是有时候吧,我也不想搞的那么复杂, ...
随机推荐
- vue solt 属性浅析
solt 也就是插槽,通俗的讲也是和div,span,p等类似的html标签,只是solt是子组件中的html标签.它显示不显示完全是由父组件决定的, 但是显示的位置是由子组件自己决定的.插槽主要分为 ...
- 解读IEEE 7417的软件体系架构描述的概念模型
本文将解读标准IEEE Std 1471-2000(密集型软件的体系结构描述推荐实施规程)的概念模型图部分,从中一窥作为软件架构师的进行架构设计的思考角度与策略.如果我们把世界当做一场游戏,现在要玩的 ...
- optimizer
在很多机器学习和深度学习的应用中,我们发现用的最多的优化器是 Adam,为什么呢? 下面是 TensorFlow 中的优化器, https://www.tensorflow.org/api_guide ...
- 【高速接口-RapidIO】1、RapidIO协议概述
一.RapidIO背景介绍 RapidIO是由Motorola和Mercury等公司率先倡导的一种高性能. 低引脚数. 基于数据包交换的互连体系结构,是为满足和未来高性能嵌入式系统需求而设计的一种开放 ...
- Android开发 - 掌握ConstraintLayout(九)分组(Group)
使用ConstraintLayout后我们的布局是没有层级关系的,各个View之间都是平级关系,但是如果根据某个业务条件来控制多个View的显示与否,我们需要分别对每个View进行控制,需要调用多次s ...
- 迈向高阶:优秀Android程序员必知必会的网络基础
1.前言 网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用 ...
- 给你的WordPress站点添加下雪特效
今天看到这个教程,感觉挺应景的,就自己尝试了下,效果还行,没截GIF图 方法: 该js文件已支持https,同时已将其及相关雪花图片进行CDN加速处理,可直接调用. 找到WordPress主题的foo ...
- Web前端JQuery面试题(三)
Web前端JQuery面试题(三) 1.怎么阻止冒泡过程? stopPropagation(); // 阻止冒泡过程 2.ready()方法和onload()方法的区别? onload()方法要等页面 ...
- 免费翻译API破解(简易翻译工具)
思路:选取有道翻译,用fiddler抓取接口请求信息,提取相关请求参数,破解加密部分. 主要请求数据: i :翻译文本 ts:时间戳 salt:ts +随机数 sign:加密信息,经过抓取信息,发现 ...
- Python的GUI用法1
代码: #python GUI的例子1 import tkinter as tk class Window: def __init__(self,master): frame = tk.Frame(m ...