当写好一个或多个模块后,能够将它构建、打包成"tar.gz",以便让别人安装或者上传到CPAN(若是愿意的话)。对于模块的使用者来讲,也不用再使用use lib 'LIB_PATH'
来找pm文件,安装后通常都会安装到@INC
路径下,而后直接使用use MODULE
便可。git
在很早之前,使用h2xz工具,但它实在太古老了。如今不少人使用Dist::Zilla
模块来建立并安装模块。不过本文只是基础,只介绍Module::Starter
构建和打包的方法。json
先安装:windows
$ cpan -i Module::Starter
Module::Starter
模块提供了一个命令行程序module-starter
,它能够用来构建模块。svn
例如,构建一个名为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
其中:ui
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文件的前几行:
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文件的前几行:
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=.
便可。