📄 makemaker.pm
字号:
}
}
$self->init_dirscan();
$self->init_others();
push @{$self->{RESULT}}, <<END;
# This Makefile is for the $self->{NAME} extension to perl.
#
# It was generated automatically by MakeMaker version
# $VERSION (Revision: $Revision) from the contents of
# Makefile.PL. Don't edit this file, edit Makefile.PL instead.
#
# ANY CHANGES MADE HERE WILL BE LOST!
#
# MakeMaker Parameters:
END
foreach $key (sort keys %initial_att){
my($v) = neatvalue($initial_att{$key});
$v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/;
$v =~ tr/\n/ /s;
push @{$self->{RESULT}}, "# $key => $v";
}
# turn the SKIP array into a SKIPHASH hash
my (%skip,$skip);
for $skip (@{$self->{SKIP} || []}) {
$self->{SKIPHASH}{$skip} = 1;
}
delete $self->{SKIP}; # free memory
if ($self->{PARENT}) {
for (qw/install dist dist_basics dist_core dist_dir dist_test dist_ci/) {
$self->{SKIPHASH}{$_} = 1;
}
}
# We run all the subdirectories now. They don't have much to query
# from the parent, but the parent has to query them: if they need linking!
unless ($self->{NORECURS}) {
$self->eval_in_subdirs if @{$self->{DIR}};
}
my $section;
foreach $section ( @MM_Sections ){
print "Processing Makefile '$section' section\n" if ($Verbose >= 2);
my($skipit) = $self->skipcheck($section);
if ($skipit){
push @{$self->{RESULT}}, "\n# --- MakeMaker $section section $skipit.";
} else {
my(%a) = %{$self->{$section} || {}};
push @{$self->{RESULT}}, "\n# --- MakeMaker $section section:";
push @{$self->{RESULT}}, "# " . join ", ", %a if $Verbose && %a;
push @{$self->{RESULT}}, $self->nicetext($self->$section( %a ));
}
}
push @{$self->{RESULT}}, "\n# End.";
pop @Parent;
$self;
}
sub WriteEmptyMakefile {
if (-f 'Makefile.old') {
chmod 0666, 'Makefile.old';
unlink 'Makefile.old' or warn "unlink Makefile.old: $!";
}
rename 'Makefile', 'Makefile.old' or warn "rename Makefile Makefile.old: $!"
if -f 'Makefile';
open MF, '> Makefile' or die "open Makefile for write: $!";
print MF <<'EOP';
all:
clean:
install:
makemakerdflt:
test:
EOP
close MF or die "close Makefile for write: $!";
}
sub check_manifest {
print STDOUT "Checking if your kit is complete...\n";
require ExtUtils::Manifest;
$ExtUtils::Manifest::Quiet=$ExtUtils::Manifest::Quiet=1; #avoid warning
my(@missed)=ExtUtils::Manifest::manicheck();
if (@missed){
print STDOUT "Warning: the following files are missing in your kit:\n";
print "\t", join "\n\t", @missed;
print STDOUT "\n";
print STDOUT "Please inform the author.\n";
} else {
print STDOUT "Looks good\n";
}
}
sub parse_args{
my($self, @args) = @_;
foreach (@args){
unless (m/(.*?)=(.*)/){
help(),exit 1 if m/^help$/;
++$Verbose if m/^verb/;
next;
}
my($name, $value) = ($1, $2);
if ($value =~ m/^~(\w+)?/){ # tilde with optional username
$value =~ s [^~(\w*)]
[$1 ?
((getpwnam($1))[7] || "~$1") :
(getpwuid($>))[7]
]ex;
}
$self->{uc($name)} = $value;
}
# catch old-style 'potential_libs' and inform user how to 'upgrade'
if (defined $self->{potential_libs}){
my($msg)="'potential_libs' => '$self->{potential_libs}' should be";
if ($self->{potential_libs}){
print STDOUT "$msg changed to:\n\t'LIBS' => ['$self->{potential_libs}']\n";
} else {
print STDOUT "$msg deleted.\n";
}
$self->{LIBS} = [$self->{potential_libs}];
delete $self->{potential_libs};
}
# catch old-style 'ARMAYBE' and inform user how to 'upgrade'
if (defined $self->{ARMAYBE}){
my($armaybe) = $self->{ARMAYBE};
print STDOUT "ARMAYBE => '$armaybe' should be changed to:\n",
"\t'dynamic_lib' => {ARMAYBE => '$armaybe'}\n";
my(%dl) = %{$self->{dynamic_lib} || {}};
$self->{dynamic_lib} = { %dl, ARMAYBE => $armaybe};
delete $self->{ARMAYBE};
}
if (defined $self->{LDTARGET}){
print STDOUT "LDTARGET should be changed to LDFROM\n";
$self->{LDFROM} = $self->{LDTARGET};
delete $self->{LDTARGET};
}
# Turn a DIR argument on the command line into an array
if (defined $self->{DIR} && ref \$self->{DIR} eq 'SCALAR') {
# So they can choose from the command line, which extensions they want
# the grep enables them to have some colons too much in case they
# have to build a list with the shell
$self->{DIR} = [grep $_, split ":", $self->{DIR}];
}
# Turn a INCLUDE_EXT argument on the command line into an array
if (defined $self->{INCLUDE_EXT} && ref \$self->{INCLUDE_EXT} eq 'SCALAR') {
$self->{INCLUDE_EXT} = [grep $_, split '\s+', $self->{INCLUDE_EXT}];
}
# Turn a EXCLUDE_EXT argument on the command line into an array
if (defined $self->{EXCLUDE_EXT} && ref \$self->{EXCLUDE_EXT} eq 'SCALAR') {
$self->{EXCLUDE_EXT} = [grep $_, split '\s+', $self->{EXCLUDE_EXT}];
}
my $mmkey;
foreach $mmkey (sort keys %$self){
print STDOUT " $mmkey => ", neatvalue($self->{$mmkey}), "\n" if $Verbose;
print STDOUT "'$mmkey' is not a known MakeMaker parameter name.\n"
unless exists $Recognized_Att_Keys{$mmkey};
}
$| = 1 if $Verbose;
}
sub check_hints {
my($self) = @_;
# We allow extension-specific hints files.
return unless -d "hints";
# First we look for the best hintsfile we have
my(@goodhints);
my($hint)="${^O}_$Config{osvers}";
$hint =~ s/\./_/g;
$hint =~ s/_$//;
return unless $hint;
# Also try without trailing minor version numbers.
while (1) {
last if -f "hints/$hint.pl"; # found
} continue {
last unless $hint =~ s/_[^_]*$//; # nothing to cut off
}
return unless -f "hints/$hint.pl"; # really there
# execute the hintsfile:
# use FileHandle ();
# my $fh = new FileHandle;
# $fh->open("hints/$hint.pl");
local *FH;
open(FH,"hints/$hint.pl");
# @goodhints = <$fh>;
@goodhints = <FH>;
# $fh->close;
close FH;
print STDOUT "Processing hints file hints/$hint.pl\n";
eval join('',@goodhints);
print STDOUT $@ if $@;
}
sub mv_all_methods {
my($from,$to) = @_;
my($method);
my($symtab) = \%{"${from}::"};
# no strict;
# Here you see the *current* list of methods that are overridable
# from Makefile.PL via MY:: subroutines. As of VERSION 5.07 I'm
# still trying to reduce the list to some reasonable minimum --
# because I want to make it easier for the user. A.K.
foreach $method (@Overridable) {
# We cannot say "next" here. Nick might call MY->makeaperl
# which isn't defined right now
# Above statement was written at 4.23 time when Tk-b8 was
# around. As Tk-b9 only builds with 5.002something and MM 5 is
# standard, we try to enable the next line again. It was
# commented out until MM 5.23
next unless defined &{"${from}::$method"};
*{"${to}::$method"} = \&{"${from}::$method"};
# delete would do, if we were sure, nobody ever called
# MY->makeaperl directly
# delete $symtab->{$method};
# If we delete a method, then it will be undefined and cannot
# be called. But as long as we have Makefile.PLs that rely on
# %MY:: being intact, we have to fill the hole with an
# inheriting method:
eval "package MY; sub $method { shift->SUPER::$method(\@_); }";
}
# We have to clean out %INC also, because the current directory is
# changed frequently and Graham Barr prefers to get his version
# out of a History.pl file which is "required" so woudn't get
# loaded again in another extension requiring a History.pl
# With perl5.002_01 the deletion of entries in %INC caused Tk-b11
# to core dump in the middle of a require statement. The required
# file was Tk/MMutil.pm. The consequence is, we have to be
# extremely careful when we try to give perl a reason to reload a
# library with same name. The workaround prefers to drop nothing
# from %INC and teach the writers not to use such libraries.
# my $inc;
# foreach $inc (keys %INC) {
# #warn "***$inc*** deleted";
# delete $INC{$inc};
# }
}
sub skipcheck {
my($self) = shift;
my($section) = @_;
if ($section eq 'dynamic') {
print STDOUT "Warning (non-fatal): Target 'dynamic' depends on targets ",
"in skipped section 'dynamic_bs'\n"
if $self->{SKIPHASH}{dynamic_bs} && $Verbose;
print STDOUT "Warning (non-fatal): Target 'dynamic' depends on targets ",
"in skipped section 'dynamic_lib'\n"
if $self->{SKIPHASH}{dynamic_lib} && $Verbose;
}
if ($section eq 'dynamic_lib') {
print STDOUT "Warning (non-fatal): Target '\$(INST_DYNAMIC)' depends on ",
"targets in skipped section 'dynamic_bs'\n"
if $self->{SKIPHASH}{dynamic_bs} && $Verbose;
}
if ($section eq 'static') {
print STDOUT "Warning (non-fatal): Target 'static' depends on targets ",
"in skipped section 'static_lib'\n"
if $self->{SKIPHASH}{static_lib} && $Verbose;
}
return 'skipped' if $self->{SKIPHASH}{$section};
return '';
}
sub flush {
my $self = shift;
my($chunk);
# use FileHandle ();
# my $fh = new FileHandle;
local *FH;
print STDOUT "Writing $self->{MAKEFILE} for $self->{NAME}\n";
unlink($self->{MAKEFILE}, "MakeMaker.tmp", $Is_VMS ? 'Descrip.MMS' : '');
# $fh->open(">MakeMaker.tmp") or die "Unable to open MakeMaker.tmp: $!";
open(FH,">MakeMaker.tmp") or die "Unable to open MakeMaker.tmp: $!";
for $chunk (@{$self->{RESULT}}) {
# print $fh "$chunk\n";
print FH "$chunk\n";
}
# $fh->close;
close FH;
my($finalname) = $self->{MAKEFILE};
rename("MakeMaker.tmp", $finalname);
chmod 0644, $finalname unless $Is_VMS;
if ($self->{PARENT}) {
foreach (keys %$self) { # safe memory
delete $self->{$_} unless $Keep_after_flush{$_};
}
}
system("$Config::Config{eunicefix} $finalname") unless $Config::Config{eunicefix} eq ":";
}
# The following mkbootstrap() is only for installations that are calling
# the pre-4.1 mkbootstrap() from their old Makefiles. This MakeMaker
# writes Makefiles, that use ExtUtils::Mkbootstrap directly.
sub mkbootstrap {
die <<END;
!!! Your Makefile has been built such a long time ago, !!!
!!! that is unlikely to work with current MakeMaker. !!!
!!! Please rebuild your Makefile !!!
END
}
# Ditto for mksymlists() as of MakeMaker 5.17
sub mksymlists {
die <<END;
!!! Your Makefile has been built such a long time ago, !!!
!!! that is unlikely to work with current MakeMaker. !!!
!!! Please rebuild your Makefile !!!
END
}
sub neatvalue {
my($v) = @_;
return "undef" unless defined $v;
my($t) = ref $v;
return "q[$v]" unless $t;
if ($t eq 'ARRAY') {
my(@m, $elem, @neat);
push @m, "[";
foreach $elem (@$v) {
push @neat, "q[$elem]";
}
push @m, join ", ", @neat;
push @m, "]";
return join "", @m;
}
return "$v" unless $t eq 'HASH';
my(@m, $key, $val);
while (($key,$val) = each %$v){
last unless defined $key; # cautious programming in case (undef,undef) is true
push(@m,"$key=>".neatvalue($val)) ;
}
return "{ ".join(', ',@m)." }";
}
sub selfdocument {
my($self) = @_;
my(@m);
if ($Verbose){
push @m, "\n# Full list of MakeMaker attribute values:";
foreach $key (sort keys %$self){
next if $key eq 'RESULT' || $key =~ /^[A-Z][a-z]/;
my($v) = neatvalue($self->{$key});
$v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/;
$v =~ tr/\n/ /s;
push @m, "# $key => $v";
}
}
join "\n", @m;
}
package ExtUtils::MakeMaker;
1;
__END__
=head1 NAME
ExtUtils::MakeMaker - create an extension Makefile
=head1 SYNOPSIS
C<use ExtUtils::MakeMaker;>
C<WriteMakefile( ATTRIBUTE =E<gt> VALUE [, ...] );>
which is really
C<MM-E<gt>new(\%att)-E<gt>flush;>
=head1 DESCRIPTION
This utility is designed to write a Makefile for an extension module
from a Makefile.PL. It is based on the Makefile.SH model provided by
Andy Dougherty and the perl5-porters.
It splits the task of generating the Makefile into several subroutines
that can be individually overridden. Each subroutine returns the text
it wishes to have written to the Makefile.
MakeMaker is object oriented. Each directory below the current
directory that contains a Makefile.PL. Is treated as a separate
object. This makes it possible to write an unlimited number of
Makefiles with a single invocation of WriteMakefile().
=head2 How To Write A Makefile.PL
The short answer is: Don't.
Always begin with h2xs.
Always begin with h2xs!
ALWAYS BEGIN WITH H2XS!
even if you're not building around a header file, and even if you
don't have an XS component.
Run h2xs(1) before you start thinking about writing a module. For so
called pm-only modules that consist of C<*.pm> files only, h2xs has
the C<-X> switch. This will generate dummy files of all kinds that are
useful for the module developer.
The medium answer is:
use ExtUtils::MakeMaker;
WriteMakefile( NAME => "Foo::Bar" );
The long answer is the rest of the manpage :-)
=head2 Default Makefile Behaviour
The generated Makefile enables the user of the extension to invoke
perl Makefile.PL # optionally "perl Makefile.PL verbose"
make
make test # optionally set TEST_VERBOSE=1
make install # See below
The Makefile to be produced may be altered by adding arguments of the
form C<KEY=VALUE>. E.g.
perl Makefile.PL PREFIX=/tmp/myperl5
Other interesting targets in the generated Makefile are
make config # to check if the Makefile is up-to-date
make clean # delete local temp files (Makefile gets renamed)
make realclean # delete derived files (including ./blib)
make ci # check in all the files in the MANIFEST file
make dist # see below the Distribution Support section
=head2 make test
MakeMaker checks for the existence of a file named F<test.pl> in the
current directory and if it exists it adds commands to the test target
of the generated Makefile that will execute the script with the proper
set of perl C<-I> options.
MakeMaker also checks for any files matching glob("t/*.t"). It will
add commands to the test target of the generated Makefile that execute
all matching files via the L<Test::Harness> module with the C<-I>
switches set correctly.
=head2 make testdb
A useful variation of the above is the target C<testdb>. It runs the
test under the Perl debugger (see L<perldebug>). If the file
F<test.pl> exists in the current directory, it is used for the test.
If you want to debug some other testfile, set C<TEST_FILE> variable
thusly:
make testdb TEST_FILE=t/mytest.t
By default the debugger is called using C<-d> option to perl. If you
want to specify some other option, set C<TESTDB_SW> variable:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -