���ѧۧݧ�ӧ�� �ާ֧ߧ֧էا֧� - ���֧էѧܧ�ڧ��ӧѧ�� - /home/ukubnwwtacc0unt/chapelbellstudios.com/uploads/cover/FAQ.pod.tar
���ѧ٧ѧ�
usr/share/perl5/IO/Compress/FAQ.pod 0000644 00000050400 15204035654 0012726 0 ustar 00 =head1 NAME IO::Compress::FAQ -- Frequently Asked Questions about IO::Compress =head1 DESCRIPTION Common questions answered. =head1 GENERAL =head2 Compatibility with Unix compress/uncompress. Although C<Compress::Zlib> has a pair of functions called C<compress> and C<uncompress>, they are I<not> related to the Unix programs of the same name. The C<Compress::Zlib> module is not compatible with Unix C<compress>. If you have the C<uncompress> program available, you can use this to read compressed files open F, "uncompress -c $filename |"; while (<F>) { ... Alternatively, if you have the C<gunzip> program available, you can use this to read compressed files open F, "gunzip -c $filename |"; while (<F>) { ... and this to write compress files, if you have the C<compress> program available open F, "| compress -c $filename "; print F "data"; ... close F ; =head2 Accessing .tar.Z files The C<Archive::Tar> module can optionally use C<Compress::Zlib> (via the C<IO::Zlib> module) to access tar files that have been compressed with C<gzip>. Unfortunately tar files compressed with the Unix C<compress> utility cannot be read by C<Compress::Zlib> and so cannot be directly accessed by C<Archive::Tar>. If the C<uncompress> or C<gunzip> programs are available, you can use one of these workarounds to read C<.tar.Z> files from C<Archive::Tar> Firstly with C<uncompress> use strict; use warnings; use Archive::Tar; open F, "uncompress -c $filename |"; my $tar = Archive::Tar->new(*F); ... and this with C<gunzip> use strict; use warnings; use Archive::Tar; open F, "gunzip -c $filename |"; my $tar = Archive::Tar->new(*F); ... Similarly, if the C<compress> program is available, you can use this to write a C<.tar.Z> file use strict; use warnings; use Archive::Tar; use IO::File; my $fh = new IO::File "| compress -c >$filename"; my $tar = Archive::Tar->new(); ... $tar->write($fh); $fh->close ; =head2 How do I recompress using a different compression? This is easier that you might expect if you realise that all the C<IO::Compress::*> objects are derived from C<IO::File> and that all the C<IO::Uncompress::*> modules can read from an C<IO::File> filehandle. So, for example, say you have a file compressed with gzip that you want to recompress with bzip2. Here is all that is needed to carry out the recompression. use IO::Uncompress::Gunzip ':all'; use IO::Compress::Bzip2 ':all'; my $gzipFile = "somefile.gz"; my $bzipFile = "somefile.bz2"; my $gunzip = new IO::Uncompress::Gunzip $gzipFile or die "Cannot gunzip $gzipFile: $GunzipError\n" ; bzip2 $gunzip => $bzipFile or die "Cannot bzip2 to $bzipFile: $Bzip2Error\n" ; Note, there is a limitation of this technique. Some compression file formats store extra information along with the compressed data payload. For example, gzip can optionally store the original filename and Zip stores a lot of information about the original file. If the original compressed file contains any of this extra information, it will not be transferred to the new compressed file using the technique above. =head1 ZIP =head2 What Compression Types do IO::Compress::Zip & IO::Uncompress::Unzip support? The following compression formats are supported by C<IO::Compress::Zip> and C<IO::Uncompress::Unzip> =over 5 =item * Store (method 0) No compression at all. =item * Deflate (method 8) This is the default compression used when creating a zip file with C<IO::Compress::Zip>. =item * Bzip2 (method 12) Only supported if the C<IO-Compress-Bzip2> module is installed. =item * Lzma (method 14) Only supported if the C<IO-Compress-Lzma> module is installed. =back =head2 Can I Read/Write Zip files larger the 4 Gig? Yes, both the C<IO-Compress-Zip> and C<IO-Uncompress-Unzip> modules support the zip feature called I<Zip64>. That allows them to read/write files/buffers larger than 4Gig. If you are creating a Zip file using the one-shot interface, and any of the input files is greater than 4Gig, a zip64 complaint zip file will be created. zip "really-large-file" => "my.zip"; Similarly with the one-shot interface, if the input is a buffer larger than 4 Gig, a zip64 complaint zip file will be created. zip \$really_large_buffer => "my.zip"; The one-shot interface allows you to force the creation of a zip64 zip file by including the C<Zip64> option. zip $filehandle => "my.zip", Zip64 => 1; If you want to create a zip64 zip file with the OO interface you must specify the C<Zip64> option. my $zip = new IO::Compress::Zip "whatever", Zip64 => 1; When uncompressing with C<IO-Uncompress-Unzip>, it will automatically detect if the zip file is zip64. If you intend to manipulate the Zip64 zip files created with C<IO-Compress-Zip> using an external zip/unzip, make sure that it supports Zip64. In particular, if you are using Info-Zip you need to have zip version 3.x or better to update a Zip64 archive and unzip version 6.x to read a zip64 archive. =head2 Can I write more that 64K entries is a Zip files? Yes. Zip64 allows this. See previous question. =head2 Zip Resources The primary reference for zip files is the "appnote" document available at L<http://www.pkware.com/documents/casestudies/APPNOTE.TXT> An alternatively is the Info-Zip appnote. This is available from L<ftp://ftp.info-zip.org/pub/infozip/doc/> =head1 GZIP =head2 Gzip Resources The primary reference for gzip files is RFC 1952 L<http://www.faqs.org/rfcs/rfc1952.html> The primary site for gzip is L<http://www.gzip.org>. =head2 Dealing with concatenated gzip files If the gunzip program encounters a file containing multiple gzip files concatenated together it will automatically uncompress them all. The example below illustrates this behaviour $ echo abc | gzip -c >x.gz $ echo def | gzip -c >>x.gz $ gunzip -c x.gz abc def By default C<IO::Uncompress::Gunzip> will I<not> behave like the gunzip program. It will only uncompress the first gzip data stream in the file, as shown below $ perl -MIO::Uncompress::Gunzip=:all -e 'gunzip "x.gz" => \*STDOUT' abc To force C<IO::Uncompress::Gunzip> to uncompress all the gzip data streams, include the C<MultiStream> option, as shown below $ perl -MIO::Uncompress::Gunzip=:all -e 'gunzip "x.gz" => \*STDOUT, MultiStream => 1' abc def =head2 Reading bgzip files with IO::Uncompress::Gunzip A C<bgzip> file consists of a series of valid gzip-compliant data streams concatenated together. To read a file created by C<bgzip> with C<IO::Uncompress::Gunzip> use the C<MultiStream> option as shown in the previous section. See the section titled "The BGZF compression format" in L<http://samtools.github.io/hts-specs/SAMv1.pdf> for a definition of C<bgzip>. =head1 ZLIB =head2 Zlib Resources The primary site for the I<zlib> compression library is L<http://www.zlib.org>. =head1 Bzip2 =head2 Bzip2 Resources The primary site for bzip2 is L<http://www.bzip.org>. =head2 Dealing with Concatenated bzip2 files If the bunzip2 program encounters a file containing multiple bzip2 files concatenated together it will automatically uncompress them all. The example below illustrates this behaviour $ echo abc | bzip2 -c >x.bz2 $ echo def | bzip2 -c >>x.bz2 $ bunzip2 -c x.bz2 abc def By default C<IO::Uncompress::Bunzip2> will I<not> behave like the bunzip2 program. It will only uncompress the first bunzip2 data stream in the file, as shown below $ perl -MIO::Uncompress::Bunzip2=:all -e 'bunzip2 "x.bz2" => \*STDOUT' abc To force C<IO::Uncompress::Bunzip2> to uncompress all the bzip2 data streams, include the C<MultiStream> option, as shown below $ perl -MIO::Uncompress::Bunzip2=:all -e 'bunzip2 "x.bz2" => \*STDOUT, MultiStream => 1' abc def =head2 Interoperating with Pbzip2 Pbzip2 (L<http://compression.ca/pbzip2/>) is a parallel implementation of bzip2. The output from pbzip2 consists of a series of concatenated bzip2 data streams. By default C<IO::Uncompress::Bzip2> will only uncompress the first bzip2 data stream in a pbzip2 file. To uncompress the complete pbzip2 file you must include the C<MultiStream> option, like this. bunzip2 $input => \$output, MultiStream => 1 or die "bunzip2 failed: $Bunzip2Error\n"; =head1 HTTP & NETWORK =head2 Apache::GZip Revisited Below is a mod_perl Apache compression module, called C<Apache::GZip>, taken from L<http://perl.apache.org/docs/tutorials/tips/mod_perl_tricks/mod_perl_tricks.html#On_the_Fly_Compression> package Apache::GZip; #File: Apache::GZip.pm use strict vars; use Apache::Constants ':common'; use Compress::Zlib; use IO::File; use constant GZIP_MAGIC => 0x1f8b; use constant OS_MAGIC => 0x03; sub handler { my $r = shift; my ($fh,$gz); my $file = $r->filename; return DECLINED unless $fh=IO::File->new($file); $r->header_out('Content-Encoding'=>'gzip'); $r->send_http_header; return OK if $r->header_only; tie *STDOUT,'Apache::GZip',$r; print($_) while <$fh>; untie *STDOUT; return OK; } sub TIEHANDLE { my($class,$r) = @_; # initialize a deflation stream my $d = deflateInit(-WindowBits=>-MAX_WBITS()) || return undef; # gzip header -- don't ask how I found out $r->print(pack("nccVcc",GZIP_MAGIC,Z_DEFLATED,0,time(),0,OS_MAGIC)); return bless { r => $r, crc => crc32(undef), d => $d, l => 0 },$class; } sub PRINT { my $self = shift; foreach (@_) { # deflate the data my $data = $self->{d}->deflate($_); $self->{r}->print($data); # keep track of its length and crc $self->{l} += length($_); $self->{crc} = crc32($_,$self->{crc}); } } sub DESTROY { my $self = shift; # flush the output buffers my $data = $self->{d}->flush; $self->{r}->print($data); # print the CRC and the total length (uncompressed) $self->{r}->print(pack("LL",@{$self}{qw/crc l/})); } 1; Here's the Apache configuration entry you'll need to make use of it. Once set it will result in everything in the /compressed directory will be compressed automagically. <Location /compressed> SetHandler perl-script PerlHandler Apache::GZip </Location> Although at first sight there seems to be quite a lot going on in C<Apache::GZip>, you could sum up what the code was doing as follows -- read the contents of the file in C<< $r->filename >>, compress it and write the compressed data to standard output. That's all. This code has to jump through a few hoops to achieve this because =over =item 1. The gzip support in C<Compress::Zlib> version 1.x can only work with a real filesystem filehandle. The filehandles used by Apache modules are not associated with the filesystem. =item 2. That means all the gzip support has to be done by hand - in this case by creating a tied filehandle to deal with creating the gzip header and trailer. =back C<IO::Compress::Gzip> doesn't have that filehandle limitation (this was one of the reasons for writing it in the first place). So if C<IO::Compress::Gzip> is used instead of C<Compress::Zlib> the whole tied filehandle code can be removed. Here is the rewritten code. package Apache::GZip; use strict vars; use Apache::Constants ':common'; use IO::Compress::Gzip; use IO::File; sub handler { my $r = shift; my ($fh,$gz); my $file = $r->filename; return DECLINED unless $fh=IO::File->new($file); $r->header_out('Content-Encoding'=>'gzip'); $r->send_http_header; return OK if $r->header_only; my $gz = new IO::Compress::Gzip '-', Minimal => 1 or return DECLINED ; print $gz $_ while <$fh>; return OK; } or even more succinctly, like this, using a one-shot gzip package Apache::GZip; use strict vars; use Apache::Constants ':common'; use IO::Compress::Gzip qw(gzip); sub handler { my $r = shift; $r->header_out('Content-Encoding'=>'gzip'); $r->send_http_header; return OK if $r->header_only; gzip $r->filename => '-', Minimal => 1 or return DECLINED ; return OK; } 1; The use of one-shot C<gzip> above just reads from C<< $r->filename >> and writes the compressed data to standard output. Note the use of the C<Minimal> option in the code above. When using gzip for Content-Encoding you should I<always> use this option. In the example above it will prevent the filename being included in the gzip header and make the size of the gzip data stream a slight bit smaller. =head2 Compressed files and Net::FTP The C<Net::FTP> module provides two low-level methods called C<stor> and C<retr> that both return filehandles. These filehandles can used with the C<IO::Compress/Uncompress> modules to compress or uncompress files read from or written to an FTP Server on the fly, without having to create a temporary file. Firstly, here is code that uses C<retr> to uncompressed a file as it is read from the FTP Server. use Net::FTP; use IO::Uncompress::Gunzip qw(:all); my $ftp = new Net::FTP ... my $retr_fh = $ftp->retr($compressed_filename); gunzip $retr_fh => $outFilename, AutoClose => 1 or die "Cannot uncompress '$compressed_file': $GunzipError\n"; and this to compress a file as it is written to the FTP Server use Net::FTP; use IO::Compress::Gzip qw(:all); my $stor_fh = $ftp->stor($filename); gzip "filename" => $stor_fh, AutoClose => 1 or die "Cannot compress '$filename': $GzipError\n"; =head1 MISC =head2 Using C<InputLength> to uncompress data embedded in a larger file/buffer. A fairly common use-case is where compressed data is embedded in a larger file/buffer and you want to read both. As an example consider the structure of a zip file. This is a well-defined file format that mixes both compressed and uncompressed sections of data in a single file. For the purposes of this discussion you can think of a zip file as sequence of compressed data streams, each of which is prefixed by an uncompressed local header. The local header contains information about the compressed data stream, including the name of the compressed file and, in particular, the length of the compressed data stream. To illustrate how to use C<InputLength> here is a script that walks a zip file and prints out how many lines are in each compressed file (if you intend write code to walking through a zip file for real see L<IO::Uncompress::Unzip/"Walking through a zip file"> ). Also, although this example uses the zlib-based compression, the technique can be used by the other C<IO::Uncompress::*> modules. use strict; use warnings; use IO::File; use IO::Uncompress::RawInflate qw(:all); use constant ZIP_LOCAL_HDR_SIG => 0x04034b50; use constant ZIP_LOCAL_HDR_LENGTH => 30; my $file = $ARGV[0] ; my $fh = new IO::File "<$file" or die "Cannot open '$file': $!\n"; while (1) { my $sig; my $buffer; my $x ; ($x = $fh->read($buffer, ZIP_LOCAL_HDR_LENGTH)) == ZIP_LOCAL_HDR_LENGTH or die "Truncated file: $!\n"; my $signature = unpack ("V", substr($buffer, 0, 4)); last unless $signature == ZIP_LOCAL_HDR_SIG; # Read Local Header my $gpFlag = unpack ("v", substr($buffer, 6, 2)); my $compressedMethod = unpack ("v", substr($buffer, 8, 2)); my $compressedLength = unpack ("V", substr($buffer, 18, 4)); my $uncompressedLength = unpack ("V", substr($buffer, 22, 4)); my $filename_length = unpack ("v", substr($buffer, 26, 2)); my $extra_length = unpack ("v", substr($buffer, 28, 2)); my $filename ; $fh->read($filename, $filename_length) == $filename_length or die "Truncated file\n"; $fh->read($buffer, $extra_length) == $extra_length or die "Truncated file\n"; if ($compressedMethod != 8 && $compressedMethod != 0) { warn "Skipping file '$filename' - not deflated $compressedMethod\n"; $fh->read($buffer, $compressedLength) == $compressedLength or die "Truncated file\n"; next; } if ($compressedMethod == 0 && $gpFlag & 8 == 8) { die "Streamed Stored not supported for '$filename'\n"; } next if $compressedLength == 0; # Done reading the Local Header my $inf = new IO::Uncompress::RawInflate $fh, Transparent => 1, InputLength => $compressedLength or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ; my $line_count = 0; while (<$inf>) { ++ $line_count; } print "$filename: $line_count\n"; } The majority of the code above is concerned with reading the zip local header data. The code that I want to focus on is at the bottom. while (1) { # read local zip header data # get $filename # get $compressedLength my $inf = new IO::Uncompress::RawInflate $fh, Transparent => 1, InputLength => $compressedLength or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ; my $line_count = 0; while (<$inf>) { ++ $line_count; } print "$filename: $line_count\n"; } The call to C<IO::Uncompress::RawInflate> creates a new filehandle C<$inf> that can be used to read from the parent filehandle C<$fh>, uncompressing it as it goes. The use of the C<InputLength> option will guarantee that I<at most> C<$compressedLength> bytes of compressed data will be read from the C<$fh> filehandle (The only exception is for an error case like a truncated file or a corrupt data stream). This means that once RawInflate is finished C<$fh> will be left at the byte directly after the compressed data stream. Now consider what the code looks like without C<InputLength> while (1) { # read local zip header data # get $filename # get $compressedLength # read all the compressed data into $data read($fh, $data, $compressedLength); my $inf = new IO::Uncompress::RawInflate \$data, Transparent => 1, or die "Cannot uncompress $file [$filename]: $RawInflateError\n" ; my $line_count = 0; while (<$inf>) { ++ $line_count; } print "$filename: $line_count\n"; } The difference here is the addition of the temporary variable C<$data>. This is used to store a copy of the compressed data while it is being uncompressed. If you know that C<$compressedLength> isn't that big then using temporary storage won't be a problem. But if C<$compressedLength> is very large or you are writing an application that other people will use, and so have no idea how big C<$compressedLength> will be, it could be an issue. Using C<InputLength> avoids the use of temporary storage and means the application can cope with large compressed data streams. One final point -- obviously C<InputLength> can only be used whenever you know the length of the compressed data beforehand, like here with a zip file. =head1 SEE ALSO L<Compress::Zlib>, L<IO::Compress::Gzip>, L<IO::Uncompress::Gunzip>, L<IO::Compress::Deflate>, L<IO::Uncompress::Inflate>, L<IO::Compress::RawDeflate>, L<IO::Uncompress::RawInflate>, L<IO::Compress::Bzip2>, L<IO::Uncompress::Bunzip2>, L<IO::Compress::Lzma>, L<IO::Uncompress::UnLzma>, L<IO::Compress::Xz>, L<IO::Uncompress::UnXz>, L<IO::Compress::Lzop>, L<IO::Uncompress::UnLzop>, L<IO::Compress::Lzf>, L<IO::Uncompress::UnLzf>, L<IO::Uncompress::AnyInflate>, L<IO::Uncompress::AnyUncompress> L<IO::Compress::FAQ|IO::Compress::FAQ> L<File::GlobMapper|File::GlobMapper>, L<Archive::Zip|Archive::Zip>, L<Archive::Tar|Archive::Tar>, L<IO::Zlib|IO::Zlib> =head1 AUTHOR This module was written by Paul Marquess, C<pmqs@cpan.org>. =head1 MODIFICATION HISTORY See the Changes file. =head1 COPYRIGHT AND LICENSE Copyright (c) 2005-2018 Paul Marquess. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. usr/share/perl5/vendor_perl/ExtUtils/MakeMaker/FAQ.pod 0000644 00000047173 15204050061 0016563 0 ustar 00 package ExtUtils::MakeMaker::FAQ; our $VERSION = '7.34'; $VERSION = eval $VERSION; 1; __END__ =head1 NAME ExtUtils::MakeMaker::FAQ - Frequently Asked Questions About MakeMaker =head1 DESCRIPTION FAQs, tricks and tips for C<ExtUtils::MakeMaker>. =head2 Module Installation =over 4 =item How do I install a module into my home directory? If you're not the Perl administrator you probably don't have permission to install a module to its default location. Ways of handling this with a B<lot> less manual effort on your part are L<perlbrew> and L<local::lib>. Otherwise, you can install it for your own use into your home directory like so: # Non-unix folks, replace ~ with /path/to/your/home/dir perl Makefile.PL INSTALL_BASE=~ This will put modules into F<~/lib/perl5>, man pages into F<~/man> and programs into F<~/bin>. To ensure your Perl programs can see these newly installed modules, set your C<PERL5LIB> environment variable to F<~/lib/perl5> or tell each of your programs to look in that directory with the following: use lib "$ENV{HOME}/lib/perl5"; or if $ENV{HOME} isn't set and you don't want to set it for some reason, do it the long way. use lib "/path/to/your/home/dir/lib/perl5"; =item How do I get MakeMaker and Module::Build to install to the same place? Module::Build, as of 0.28, supports two ways to install to the same location as MakeMaker. We highly recommend the install_base method, its the simplest and most closely approximates the expected behavior of an installation prefix. 1) Use INSTALL_BASE / C<--install_base> MakeMaker (as of 6.31) and Module::Build (as of 0.28) both can install to the same locations using the "install_base" concept. See L<ExtUtils::MakeMaker/INSTALL_BASE> for details. To get MM and MB to install to the same location simply set INSTALL_BASE in MM and C<--install_base> in MB to the same location. perl Makefile.PL INSTALL_BASE=/whatever perl Build.PL --install_base /whatever This works most like other language's behavior when you specify a prefix. We recommend this method. 2) Use PREFIX / C<--prefix> Module::Build 0.28 added support for C<--prefix> which works like MakeMaker's PREFIX. perl Makefile.PL PREFIX=/whatever perl Build.PL --prefix /whatever We highly discourage this method. It should only be used if you know what you're doing and specifically need the PREFIX behavior. The PREFIX algorithm is complicated and focused on matching the system installation. =item How do I keep from installing man pages? Recent versions of MakeMaker will only install man pages on Unix-like operating systems. For an individual module: perl Makefile.PL INSTALLMAN1DIR=none INSTALLMAN3DIR=none If you want to suppress man page installation for all modules you have to reconfigure Perl and tell it 'none' when it asks where to install man pages. =item How do I use a module without installing it? Two ways. One is to build the module normally... perl Makefile.PL make make test ...and then use L<blib> to point Perl at the built but uninstalled module: perl -Mblib script.pl perl -Mblib -e '...' The other is to install the module in a temporary location. perl Makefile.PL INSTALL_BASE=~/tmp make make test make install And then set PERL5LIB to F<~/tmp/lib/perl5>. This works well when you have multiple modules to work with. It also ensures that the module goes through its full installation process which may modify it. Again, L<local::lib> may assist you here. =item How can I organize tests into subdirectories and have them run? Let's take the following test directory structure: t/foo/sometest.t t/bar/othertest.t t/bar/baz/anothertest.t Now, inside of the C<WriteMakeFile()> function in your F<Makefile.PL>, specify where your tests are located with the C<test> directive: test => {TESTS => 't/*.t t/*/*.t t/*/*/*.t'} The first entry in the string will run all tests in the top-level F<t/> directory. The second will run all test files located in any subdirectory under F<t/>. The third, runs all test files within any subdirectory within any other subdirectory located under F<t/>. Note that you do not have to use wildcards. You can specify explicitly which subdirectories to run tests in: test => {TESTS => 't/*.t t/foo/*.t t/bar/baz/*.t'} =item PREFIX vs INSTALL_BASE from Module::Build::Cookbook The behavior of PREFIX is complicated and depends closely on how your Perl is configured. The resulting installation locations will vary from machine to machine and even different installations of Perl on the same machine. Because of this, its difficult to document where prefix will place your modules. In contrast, INSTALL_BASE has predictable, easy to explain installation locations. Now that Module::Build and MakeMaker both have INSTALL_BASE there is little reason to use PREFIX other than to preserve your existing installation locations. If you are starting a fresh Perl installation we encourage you to use INSTALL_BASE. If you have an existing installation installed via PREFIX, consider moving it to an installation structure matching INSTALL_BASE and using that instead. =item Generating *.pm files with substitutions eg of $VERSION If you want to configure your module files for local conditions, or to automatically insert a version number, you can use EUMM's C<PL_FILES> capability, where it will automatically run each F<*.PL> it finds to generate its basename. For instance: # Makefile.PL: require 'common.pl'; my $version = get_version(); my @pms = qw(Foo.pm); WriteMakefile( NAME => 'Foo', VERSION => $version, PM => { map { ($_ => "\$(INST_LIB)/$_") } @pms }, clean => { FILES => join ' ', @pms }, ); # common.pl: sub get_version { '0.04' } sub process { my $v = get_version(); s/__VERSION__/$v/g; } 1; # Foo.pm.PL: require 'common.pl'; $_ = join '', <DATA>; process(); my $file = shift; open my $fh, '>', $file or die "$file: $!"; print $fh $_; __DATA__ package Foo; our $VERSION = '__VERSION__'; 1; You may notice that C<PL_FILES> is not specified above, since the default of mapping each .PL file to its basename works well. If the generated module were architecture-specific, you could replace C<$(INST_LIB)> above with C<$(INST_ARCHLIB)>, although if you locate modules under F<lib>, that would involve ensuring any C<lib/> in front of the module location were removed. =back =head2 Common errors and problems =over 4 =item "No rule to make target `/usr/lib/perl5/CORE/config.h', needed by `Makefile'" Just what it says, you're missing that file. MakeMaker uses it to determine if perl has been rebuilt since the Makefile was made. It's a bit of a bug that it halts installation. Some operating systems don't ship the CORE directory with their base perl install. To solve the problem, you likely need to install a perl development package such as perl-devel (CentOS, Fedora and other Redhat systems) or perl (Ubuntu and other Debian systems). =back =head2 Philosophy and History =over 4 =item Why not just use <insert other build config tool here>? Why did MakeMaker reinvent the build configuration wheel? Why not just use autoconf or automake or ppm or Ant or ... There are many reasons, but the major one is cross-platform compatibility. Perl is one of the most ported pieces of software ever. It works on operating systems I've never even heard of (see perlport for details). It needs a build tool that can work on all those platforms and with any wacky C compilers and linkers they might have. No such build tool exists. Even make itself has wildly different dialects. So we have to build our own. =item What is Module::Build and how does it relate to MakeMaker? Module::Build is a project by Ken Williams to supplant MakeMaker. Its primary advantages are: =over 8 =item * pure perl. no make, no shell commands =item * easier to customize =item * cleaner internals =item * less cruft =back Module::Build was long the official heir apparent to MakeMaker. The rate of both its development and adoption has slowed in recent years, though, and it is unclear what the future holds for it. That said, Module::Build set the stage for I<something> to become the heir to MakeMaker. MakeMaker's maintainers have long said that it is a dead end and should be kept functioning, while being cautious about extending with new features. =back =head2 Module Writing =over 4 =item How do I keep my $VERSION up to date without resetting it manually? Often you want to manually set the $VERSION in the main module distribution because this is the version that everybody sees on CPAN and maybe you want to customize it a bit. But for all the other modules in your dist, $VERSION is really just bookkeeping and all that's important is it goes up every time the module is changed. Doing this by hand is a pain and you often forget. Probably the easiest way to do this is using F<perl-reversion> in L<Perl::Version>: perl-reversion -bump If your version control system supports revision numbers (git doesn't easily), the simplest way to do it automatically is to use its revision number (you are using version control, right?). In CVS, RCS and SVN you use $Revision$ (see the documentation of your version control system for details). Every time the file is checked in the $Revision$ will be updated, updating your $VERSION. SVN uses a simple integer for $Revision$ so you can adapt it for your $VERSION like so: ($VERSION) = q$Revision$ =~ /(\d+)/; In CVS and RCS version 1.9 is followed by 1.10. Since CPAN compares version numbers numerically we use a sprintf() to convert 1.9 to 1.009 and 1.10 to 1.010 which compare properly. $VERSION = sprintf "%d.%03d", q$Revision$ =~ /(\d+)\.(\d+)/g; If branches are involved (ie. $Revision: 1.5.3.4$) it's a little more complicated. # must be all on one line or MakeMaker will get confused. $VERSION = do { my @r = (q$Revision$ =~ /\d+/g); sprintf "%d."."%03d" x $#r, @r }; In SVN, $Revision$ should be the same for every file in the project so they would all have the same $VERSION. CVS and RCS have a different $Revision$ per file so each file will have a different $VERSION. Distributed version control systems, such as SVK, may have a different $Revision$ based on who checks out the file, leading to a different $VERSION on each machine! Finally, some distributed version control systems, such as darcs, have no concept of revision number at all. =item What's this F<META.yml> thing and how did it get in my F<MANIFEST>?! F<META.yml> is a module meta-data file pioneered by Module::Build and automatically generated as part of the 'distdir' target (and thus 'dist'). See L<ExtUtils::MakeMaker/"Module Meta-Data">. To shut off its generation, pass the C<NO_META> flag to C<WriteMakefile()>. =item How do I delete everything not in my F<MANIFEST>? Some folks are surprised that C<make distclean> does not delete everything not listed in their MANIFEST (thus making a clean distribution) but only tells them what they need to delete. This is done because it is considered too dangerous. While developing your module you might write a new file, not add it to the MANIFEST, then run a C<distclean> and be sad because your new work was deleted. If you really want to do this, you can use C<ExtUtils::Manifest::manifind()> to read the MANIFEST and File::Find to delete the files. But you have to be careful. Here's a script to do that. Use at your own risk. Have fun blowing holes in your foot. #!/usr/bin/perl -w use strict; use File::Spec; use File::Find; use ExtUtils::Manifest qw(maniread); my %manifest = map {( $_ => 1 )} grep { File::Spec->canonpath($_) } keys %{ maniread() }; if( !keys %manifest ) { print "No files found in MANIFEST. Stopping.\n"; exit; } find({ wanted => sub { my $path = File::Spec->canonpath($_); return unless -f $path; return if exists $manifest{ $path }; print "unlink $path\n"; unlink $path; }, no_chdir => 1 }, "." ); =item Which tar should I use on Windows? We recommend ptar from Archive::Tar not older than 1.66 with '-C' option. =item Which zip should I use on Windows for '[ndg]make zipdist'? We recommend InfoZIP: L<http://www.info-zip.org/Zip.html> =back =head2 XS =over 4 =item How do I prevent "object version X.XX does not match bootstrap parameter Y.YY" errors? XS code is very sensitive to the module version number and will complain if the version number in your Perl module doesn't match. If you change your module's version # without rerunning Makefile.PL the old version number will remain in the Makefile, causing the XS code to be built with the wrong number. To avoid this, you can force the Makefile to be rebuilt whenever you change the module containing the version number by adding this to your WriteMakefile() arguments. depend => { '$(FIRST_MAKEFILE)' => '$(VERSION_FROM)' } =item How do I make two or more XS files coexist in the same directory? Sometimes you need to have two and more XS files in the same package. There are three ways: C<XSMULTI>, separate directories, and bootstrapping one XS from another. =over 8 =item XSMULTI Structure your modules so they are all located under F<lib>, such that C<Foo::Bar> is in F<lib/Foo/Bar.pm> and F<lib/Foo/Bar.xs>, etc. Have your top-level C<WriteMakefile> set the variable C<XSMULTI> to a true value. Er, that's it. =item Separate directories Put each XS files into separate directories, each with their own F<Makefile.PL>. Make sure each of those F<Makefile.PL>s has the correct C<CFLAGS>, C<INC>, C<LIBS> etc. You will need to make sure the top-level F<Makefile.PL> refers to each of these using C<DIR>. =item Bootstrapping Let's assume that we have a package C<Cool::Foo>, which includes C<Cool::Foo> and C<Cool::Bar> modules each having a separate XS file. First we use the following I<Makefile.PL>: use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Cool::Foo', VERSION_FROM => 'Foo.pm', OBJECT => q/$(O_FILES)/, # ... other attrs ... ); Notice the C<OBJECT> attribute. MakeMaker generates the following variables in I<Makefile>: # Handy lists of source code files: XS_FILES= Bar.xs \ Foo.xs C_FILES = Bar.c \ Foo.c O_FILES = Bar.o \ Foo.o Therefore we can use the C<O_FILES> variable to tell MakeMaker to use these objects into the shared library. That's pretty much it. Now write I<Foo.pm> and I<Foo.xs>, I<Bar.pm> and I<Bar.xs>, where I<Foo.pm> bootstraps the shared library and I<Bar.pm> simply loading I<Foo.pm>. The only issue left is to how to bootstrap I<Bar.xs>. This is done from I<Foo.xs>: MODULE = Cool::Foo PACKAGE = Cool::Foo BOOT: # boot the second XS file boot_Cool__Bar(aTHX_ cv); If you have more than two files, this is the place where you should boot extra XS files from. The following four files sum up all the details discussed so far. Foo.pm: ------- package Cool::Foo; require DynaLoader; our @ISA = qw(DynaLoader); our $VERSION = '0.01'; bootstrap Cool::Foo $VERSION; 1; Bar.pm: ------- package Cool::Bar; use Cool::Foo; # bootstraps Bar.xs 1; Foo.xs: ------- #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = Cool::Foo PACKAGE = Cool::Foo BOOT: # boot the second XS file boot_Cool__Bar(aTHX_ cv); MODULE = Cool::Foo PACKAGE = Cool::Foo PREFIX = cool_foo_ void cool_foo_perl_rules() CODE: fprintf(stderr, "Cool::Foo says: Perl Rules\n"); Bar.xs: ------- #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = Cool::Bar PACKAGE = Cool::Bar PREFIX = cool_bar_ void cool_bar_perl_rules() CODE: fprintf(stderr, "Cool::Bar says: Perl Rules\n"); And of course a very basic test: t/cool.t: -------- use Test; BEGIN { plan tests => 1 }; use Cool::Foo; use Cool::Bar; Cool::Foo::perl_rules(); Cool::Bar::perl_rules(); ok 1; This tip has been brought to you by Nick Ing-Simmons and Stas Bekman. An alternative way to achieve this can be seen in L<Gtk2::CodeGen> and L<Glib::CodeGen>. =back =back =head1 DESIGN =head2 MakeMaker object hierarchy (simplified) What most people need to know (superclasses on top.) ExtUtils::MM_Any | ExtUtils::MM_Unix | ExtUtils::MM_{Current OS} | ExtUtils::MakeMaker | MY The object actually used is of the class MY which allows you to override bits of MakeMaker inside your Makefile.PL by declaring MY::foo() methods. =head2 MakeMaker object hierarchy (real) Here's how it really works: ExtUtils::MM_Any | ExtUtils::MM_Unix | ExtUtils::Liblist::Kid ExtUtils::MM_{Current OS} (if necessary) | | ExtUtils::Liblist ExtUtils::MakeMaker | | | | | | |----------------------- ExtUtils::MM | | ExtUtils::MY MM (created by ExtUtils::MM) | | MY (created by ExtUtils::MY) | . | (mixin) | . | PACK### (created each call to ExtUtils::MakeMaker->new) NOTE: Yes, this is a mess. See L<http://archive.develooper.com/makemaker@perl.org/msg00134.html> for some history. NOTE: When ExtUtils::MM is loaded it chooses a superclass for MM from amongst the ExtUtils::MM_* modules based on the current operating system. NOTE: ExtUtils::MM_{Current OS} represents one of the ExtUtils::MM_* modules except ExtUtils::MM_Any chosen based on your operating system. NOTE: The main object used by MakeMaker is a PACK### object, *not* ExtUtils::MakeMaker. It is, effectively, a subclass of MY, ExtUtils::Makemaker, ExtUtils::Liblist and ExtUtils::MM_{Current OS} NOTE: The methods in MY are simply copied into PACK### rather than MY being a superclass of PACK###. I don't remember the rationale. NOTE: ExtUtils::Liblist should be removed from the inheritance hiearchy and simply be called as functions. NOTE: Modules like File::Spec and Exporter have been omitted for clarity. =head2 The MM_* hierarchy MM_Win95 MM_NW5 \ / MM_BeOS MM_Cygwin MM_OS2 MM_VMS MM_Win32 MM_DOS MM_UWIN \ | | | / / / ------------------------------------------------ | | MM_Unix | | | MM_Any NOTE: Each direct MM_Unix subclass is also an MM_Any subclass. This is a temporary hack because MM_Unix overrides some MM_Any methods with Unix specific code. It allows the non-Unix modules to see the original MM_Any implementations. NOTE: Modules like File::Spec and Exporter have been omitted for clarity. =head1 PATCHING If you have a question you'd like to see added to the FAQ (whether or not you have the answer) please either: =over 2 =item * make a pull request on the MakeMaker github repository =item * raise a issue on the MakeMaker github repository =item * file an RT ticket =item * email makemaker@perl.org =back =head1 AUTHOR The denizens of makemaker@perl.org. =head1 SEE ALSO L<ExtUtils::MakeMaker> =cut
| ver. 1.4 |
Github
|
.
| PHP 8.1.34 | ���֧ߧ֧�ѧ�ڧ� ����ѧߧڧ��: 0.1 |
proxy
|
phpinfo
|
���ѧ����ۧܧ�