當寫好一個或多個模塊後,能夠將它構建、打包成"tar.gz",以便讓別人安裝或者上傳到CPAN(若是願意的話)。對於模塊的使用者來講,也不用再使用use lib 'LIB_PATH'
來找pm文件,安裝後通常都會安裝到@INC
路徑下,而後直接使用use MODULE
便可。git
Module::Starter
在很早之前,使用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文檔。spa
$ 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=.
便可。