f32b5dcfb074c04704aca0bed56f7706527f1849
[p5sagit/p5-mst-13.2.git] / lib / ExtUtils / MM_MacOS.pm
1 #   MM_MacOS.pm
2 #   MakeMaker default methods for MacOS
3 #   This package is inserted into @ISA of MakeMaker's MM before the
4 #   built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under MacOS.
5 #
6 #   Author:  Matthias Neeracher <neeracher@mac.com>
7
8 package ExtUtils::MM_MacOS;
9 require ExtUtils::MM_Any;
10 require ExtUtils::MM_Unix;
11 @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
12
13 use vars qw($VERSION);
14 $VERSION = '1.00';
15
16 use Config;
17 use Cwd 'cwd';
18 require Exporter;
19 use File::Basename;
20 use File::Spec;
21 use vars qw(%make_data);
22
23 use ExtUtils::MakeMaker qw($Verbose &neatvalue);
24
25 =head1 NAME
26
27 ExtUtils::MM_MacOS - methods to override UN*X behaviour in ExtUtils::MakeMaker
28
29 =head1 SYNOPSIS
30
31  use ExtUtils::MM_MacOS; # Done internally by ExtUtils::MakeMaker if needed
32
33 =head1 DESCRIPTION
34
35 MM_MacOS currently only produces an approximation to the correct Makefile.
36
37 =cut
38
39 sub new {
40     my($class,$self) = @_;
41     my($key);
42     my($cwd) = cwd();
43
44     print STDOUT "Mac MakeMaker (v$ExtUtils::MakeMaker::VERSION)\n" if $Verbose;
45     if (-f "MANIFEST" && ! -f "Makefile.mk"){
46         ExtUtils::MakeMaker::check_manifest();
47     }
48
49     mkdir("Obj", 0777) unless -d "Obj";
50     
51     $self = {} unless (defined $self);
52
53     my(%initial_att) = %$self; # record initial attributes
54
55     if (defined $self->{CONFIGURE}) {
56         if (ref $self->{CONFIGURE} eq 'CODE') {
57             $self = { %$self, %{&{$self->{CONFIGURE}}}};
58         } else {
59             Carp::croak "Attribute 'CONFIGURE' to WriteMakefile() not a code reference\n";
60         }
61     }
62
63     $class = ++$ExtUtils::MakeMaker::PACKNAME;
64     {
65         print "Blessing Object into class [$class]\n" if $Verbose>=2;
66         ExtUtils::MakeMaker::mv_all_methods("MY",$class);
67         bless $self, $class;
68         push @Parent, $self;
69         @{"$class\:\:ISA"} = 'MM';
70     }
71
72     if (defined $Parent[-2]){
73         $self->{PARENT} = $Parent[-2];
74         my $key;
75         for $key (keys %Prepend_dot_dot) {
76             next unless defined $self->{PARENT}{$key};
77             $self->{$key} = $self->{PARENT}{$key};
78             $self->{$key} = File::Spec->catdir("::",$self->{$key})
79                 unless File::Spec->file_name_is_absolute($self->{$key});
80         }
81         $self->{PARENT}->{CHILDREN}->{$class} = $self if $self->{PARENT};
82     } else {
83         $self->parse_args(@ARGV);
84     }
85
86     $self->{NAME} ||= $self->guess_name;
87
88     ($self->{NAME_SYM} = $self->{NAME}) =~ s/\W+/_/g;
89
90     $self->init_main();
91     $self->init_dirscan();
92     $self->init_others();
93
94     push @{$self->{RESULT}}, <<END;
95 # This Makefile is for the $self->{NAME} extension to perl.
96 #
97 # It was generated automatically by MakeMaker version
98 # $VERSION (Revision: $Revision) from the contents of
99 # Makefile.PL. Don't edit this file, edit Makefile.PL instead.
100 #
101 #       ANY CHANGES MADE HERE WILL BE LOST!
102 #
103 #   MakeMaker Parameters:
104 END
105
106     foreach $key (sort keys %initial_att){
107         my($v) = neatvalue($initial_att{$key});
108         $v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/;
109         $v =~ tr/\n/ /s;
110         push @{$self->{RESULT}}, "#     $key => $v";
111     }
112
113     # turn the SKIP array into a SKIPHASH hash
114     my (%skip,$skip);
115     for $skip (@{$self->{SKIP} || []}) {
116         $self->{SKIPHASH}{$skip} = 1;
117     }
118     delete $self->{SKIP}; # free memory
119
120     # We skip many sections for MacOS, but we don't say anything about it in the Makefile
121     for (qw/post_initialize const_config tool_autosplit
122             tool_xsubpp tools_other dist macro depend post_constants
123             pasthru c_o xs_c xs_o top_targets linkext 
124             dynamic_bs dynamic_lib static_lib manifypods
125             installbin subdirs dist_basics dist_core
126             dist_dir dist_test dist_ci install force perldepend makefile
127             staticmake test pm_to_blib selfdocument cflags 
128             const_loadlibs const_cccmd
129     /) 
130     {
131         $self->{SKIPHASH}{$_} = 2;
132     }
133     push @ExtUtils::MakeMaker::MM_Sections, "rulez" 
134         unless grep /rulez/, @ExtUtils::MakeMaker::MM_Sections;
135     
136     if ($self->{PARENT}) {
137         for (qw/install dist dist_basics dist_core dist_dir dist_test dist_ci/) {
138             $self->{SKIPHASH}{$_} = 1;
139         }
140     }
141
142     # We run all the subdirectories now. They don't have much to query
143     # from the parent, but the parent has to query them: if they need linking!
144     unless ($self->{NORECURS}) {
145         $self->eval_in_subdirs if @{$self->{DIR}};
146     }
147
148     my $section;
149     foreach $section ( @ExtUtils::MakeMaker::MM_Sections ){
150         next if ($self->{SKIPHASH}{$section} == 2);
151         print "Processing Makefile '$section' section\n" if ($Verbose >= 2);
152         $self->{ABSTRACT_FROM} = macify($self->{ABSTRACT_FROM})
153                 if $self->{ABSTRACT_FROM};
154         my($skipit) = $self->skipcheck($section);
155         if ($skipit){
156             push @{$self->{RESULT}}, "\n# --- MakeMaker $section section $skipit.";
157         } else {
158             my(%a) = %{$self->{$section} || {}};
159             push @{$self->{RESULT}}, "\n# --- MakeMaker $section section:";
160             push @{$self->{RESULT}}, "# " . join ", ", %a if $Verbose && %a;
161             push @{$self->{RESULT}}, $self->nicetext($self->$section( %a ));
162         }
163     }
164
165     push @{$self->{RESULT}}, "\n# End.";
166     pop @Parent;
167
168     $ExtUtils::MM_MacOS::make_data{$cwd} = $self;
169     $self;
170 }
171
172 sub skipcheck {
173     my($self) = shift;
174     my($section) = @_;
175     return 'skipped' if $self->{SKIPHASH}{$section};
176     return '';
177 }
178
179 =item maybe_command
180
181 Returns true, if the argument is likely to be a command.
182
183 =cut
184
185 sub maybe_command {
186     my($self,$file) = @_;
187     return $file if ! -d $file;
188     return;
189 }
190
191 =item guess_name
192
193 Guess the name of this package by examining the working directory's
194 name. MakeMaker calls this only if the developer has not supplied a
195 NAME attribute.
196
197 =cut
198
199 sub guess_name {
200     my($self) = @_;
201     my $name = cwd();
202     $name =~ s/.*:// unless ($name =~ s/^.*:ext://);
203     $name =~ s#:#::#g;
204     $name =~  s#[\-_][\d.\-]+$##;  # this is new with MM 5.00
205     $name;
206 }
207
208 =item macify
209
210 Translate relative path names into Mac names.
211
212 =cut
213
214 sub macify {
215     # mmm, better ... and this condition should always be satisified,
216     # as the module is now distributed with MacPerl, but leave in anyway
217     if (do 'Mac/FileSpec/Unixish.pm') {
218         return Mac::FileSpec::Unixish::nativize($_[0]);
219     }
220
221     my($unix) = @_;
222     my(@mac);
223
224     $unix =~ s|^\./||;
225
226     foreach (split(/[ \t\n]+/, $unix)) {
227         if (m|/|) {
228             $_ = ":$_";
229             s|/|:|g;
230         } 
231         push(@mac, $_);
232     }
233     
234     return "@mac";
235 }
236
237 =item patternify
238
239 Translate to Mac names & patterns
240
241 =cut
242
243 sub patternify {
244     my($unix) = @_;
245     my(@mac);
246     
247     foreach (split(/[ \t\n]+/, $unix)) {
248         if (m|/|) {
249             $_ = ":$_";
250             s|/|:|g;
251             s|\*|Å|g;
252             $_ = "'$_'" if /[?Å]/;
253             push(@mac, $_);
254         }
255     }
256     
257     return "@mac";
258 }
259
260 =item init_main
261
262 Initializes some of NAME, FULLEXT, BASEEXT, ROOTEXT, DLBASE, PERL_SRC,
263 PERL_LIB, PERL_ARCHLIB, PERL_INC, INSTALLDIRS, INST_*, INSTALL*,
264 PREFIX, CONFIG, AR, AR_STATIC_ARGS, LD, OBJ_EXT, LIB_EXT, MAP_TARGET,
265 LIBPERL_A, VERSION_FROM, VERSION, DISTNAME, VERSION_SYM.
266
267 =cut
268
269 sub init_main {
270     my($self) = @_;
271     unless (ref $self){
272         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
273         $self = $ExtUtils::MakeMaker::Parent[-1];
274     }
275
276     # --- Initialize Module Name and Paths
277
278     # NAME    = The perl module name for this extension (eg DBD::Oracle).
279     # FULLEXT = Pathname for extension directory (eg DBD/Oracle).
280     # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
281     # ROOTEXT = Directory part of FULLEXT with trailing :.
282     ($self->{FULLEXT} =
283      $self->{NAME}) =~ s!::!:!g ;                    #eg. BSD:Foo:Socket
284     ($self->{BASEEXT} =
285      $self->{NAME}) =~ s!.*::!! ;                            #eg. Socket
286     ($self->{ROOTEXT} =
287      $self->{FULLEXT}) =~ s#:?\Q$self->{BASEEXT}\E$## ;      #eg. BSD:Foo
288     $self->{ROOTEXT} .= ":" if ($self->{ROOTEXT});
289
290     # --- Initialize PERL_LIB, INST_LIB, PERL_SRC
291
292     # *Real* information: where did we get these two from? ...
293     my $inc_config_dir = dirname($INC{'Config.pm'});
294     my $inc_carp_dir   = dirname($INC{'Carp.pm'});
295
296     unless ($self->{PERL_SRC}){
297         my($dir);
298         foreach $dir (qw(:: ::: :::: ::::: ::::::)){
299             if (-f "${dir}perl.h") {
300                 $self->{PERL_SRC}=$dir ;
301                 last;
302             }
303         }
304         if (!$self->{PERL_SRC} && -f "$ENV{MACPERL}CORE:perl:perl.h") {
305             # Mac pathnames may be very nasty, so we'll install symlinks
306             unlink(":PerlCore", ":PerlLib");
307             symlink("$ENV{MACPERL}CORE:", "PerlCore");
308             symlink("$ENV{MACPERL}lib:", "PerlLib");
309             $self->{PERL_SRC} = ":PerlCore:perl:" ;
310             $self->{PERL_LIB} = ":PerlLib:";
311         }
312     }
313     if ($self->{PERL_SRC}){
314         $self->{MACPERL_SRC}  = File::Spec->catdir("$self->{PERL_SRC}","macos:");
315         $self->{MACPERL_LIB}  ||= File::Spec->catdir("$self->{MACPERL_SRC}","lib");
316         $self->{PERL_LIB}     ||= File::Spec->catdir("$self->{PERL_SRC}","lib");
317         $self->{PERL_ARCHLIB} = $self->{PERL_LIB};
318         $self->{PERL_INC}     = $self->{PERL_SRC};
319         $self->{MACPERL_INC}  = $self->{MACPERL_SRC};
320     } else {
321 # hmmmmmmm ... ?
322     $self->{PERL_LIB} ||= "$ENV{MACPERL}site_perl";
323         $self->{PERL_ARCHLIB} = $self->{PERL_LIB};
324         $self->{PERL_INC}     = $ENV{MACPERL};
325 #       die <<END;
326 #On MacOS, we need to build under the Perl source directory or have the MacPerl SDK
327 #installed in the MacPerl folder.
328 #END
329     }
330
331     $self->{INSTALLDIRS} = "perl";
332     $self->{INST_LIB} = $self->{INST_ARCHLIB} = $self->{PERL_LIB};
333     $self->{INST_MAN1DIR} = $self->{INSTALLMAN1DIR} = "none";
334     $self->{MAN1EXT} ||= $Config::Config{man1ext};
335     $self->{INST_MAN3DIR} = $self->{INSTALLMAN3DIR} = "none";
336     $self->{MAN3EXT} ||= $Config::Config{man3ext};
337     $self->{MAP_TARGET} ||= "perl";
338
339     # make a simple check if we find Exporter
340     # hm ... do we really care?  at all?
341 #    warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory
342 #        (Exporter.pm not found)"
343 #       unless -f File::Spec->catfile("$self->{PERL_LIB}","Exporter.pm") ||
344 #        $self->{NAME} eq "ExtUtils::MakeMaker";
345
346     # Determine VERSION and VERSION_FROM
347     ($self->{DISTNAME}=$self->{NAME}) =~ s#(::)#-#g unless $self->{DISTNAME};
348     if ($self->{VERSION_FROM}){
349         local *FH;
350         open(FH,macify($self->{VERSION_FROM})) or
351             die "Could not open '$self->{VERSION_FROM}' (attribute VERSION_FROM): $!";
352         while (<FH>) {
353             chop;
354             next unless /\$([\w:]*\bVERSION)\b.*=/;
355             local $ExtUtils::MakeMaker::module_version_variable = $1;
356             my($eval) = "$_;";
357             eval $eval;
358             die "Could not eval '$eval': $@" if $@;
359             if ($self->{VERSION} = $ {$ExtUtils::MakeMaker::module_version_variable}){
360                 print "$self->{NAME} VERSION is $self->{VERSION} (from $self->{VERSION_FROM})\n" if $Verbose;
361             } else {
362                 # XXX this should probably croak
363                 print "WARNING: Setting VERSION via file '$self->{VERSION_FROM}' failed\n";
364             }
365             last;
366         }
367         close FH;
368     }
369
370     if ($self->{VERSION}) {
371         $self->{VERSION} =~ s/^\s+//;
372         $self->{VERSION} =~ s/\s+$//;
373     }
374
375     $self->{VERSION} = "0.10" unless $self->{VERSION};
376     ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g;
377
378
379     # Graham Barr and Paul Marquess had some ideas how to ensure
380     # version compatibility between the *.pm file and the
381     # corresponding *.xs file. The bottomline was, that we need an
382     # XS_VERSION macro that defaults to VERSION:
383     $self->{XS_VERSION} ||= $self->{VERSION};
384
385     # --- Initialize Perl Binary Locations
386
387     # Find Perl 5. The only contract here is that both 'PERL' and 'FULLPERL'
388     # will be working versions of perl 5. miniperl has priority over perl
389     # for PERL to ensure that $(PERL) is usable while building ./ext/*
390     my ($component,@defpath);
391     foreach $component ($self->{PERL_SRC}, File::Spec->path(), $Config::Config{binexp}) {
392         push @defpath, $component if defined $component;
393     }
394     $self->{PERL} = "$self->{PERL_SRC}miniperl";
395     $self->{FULLPERL} = "$self->{PERL_SRC}perl";
396     $self->{MAKEFILE} = "Makefile.mk";
397 }
398
399 =item init_others
400
401 Initializes LDLOADLIBS, LIBS
402
403 =cut
404
405 sub init_others {       # --- Initialize Other Attributes
406     my($self) = shift;
407     unless (ref $self){
408         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
409         $self = $ExtUtils::MakeMaker::Parent[-1];
410     }
411
412     if ( !$self->{OBJECT} ) {
413         # init_dirscan should have found out, if we have C files
414         $self->{OBJECT} = "";
415         $self->{OBJECT} = "$self->{BASEEXT}.c" if @{$self->{C}||[]};
416     } else {
417         $self->{OBJECT} =~ s/\$\(O_FILES\)/@{$self->{C}||[]}/;
418     }
419     my($src);
420     foreach (split(/[ \t\n]+/, $self->{OBJECT})) {
421         if (/^$self->{BASEEXT}\.o(bj)?$/) {
422             $src .= " $self->{BASEEXT}.c";
423         } elsif (/^(.*\..*)\.o$/) {
424             $src .= " $1";
425         } elsif (/^(.*)(\.o(bj)?|\$\(OBJ_EXT\))$/) {
426             if (-f "$1.cp") {
427                 $src .= " $1.cp";
428             } else {
429                 $src .= " $1.c";
430             }
431         } else {
432             $src .= " $_";
433         }
434     }
435     $self->{SOURCE} = $src;
436 }
437
438
439 =item init_dirscan
440
441 Initializes DIR, XS, PM, C, O_FILES, H, PL_FILES, MAN*PODS, EXE_FILES.
442
443 =cut
444
445 sub init_dirscan {      # --- File and Directory Lists (.xs .pm .pod etc)
446     my($self) = @_;
447     unless (ref $self){
448         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
449         $self = $ExtUtils::MakeMaker::Parent[-1];
450     }
451     my($name, %dir, %xs, %c, %h, %ignore, %pl_files, %manifypods);
452     local(%pm); #the sub in find() has to see this hash
453
454     # in case we don't find it below!
455     if ($self->{VERSION_FROM}) {
456         my $version_from = macify($self->{VERSION_FROM});
457         $pm{$version_from} = File::Spec->catfile('$(INST_LIBDIR)',
458             $version_from);
459     }
460
461     $ignore{'test.pl'} = 1;
462     foreach $name ($self->lsdir(":")){
463         next if ($name =~ /^\./ or $ignore{$name});
464         next unless $self->libscan($name);
465         if (-d $name){
466             $dir{$name} = $name if (-f ":$name:Makefile.PL");
467         } elsif ($name =~ /\.xs$/){
468             my($c); ($c = $name) =~ s/\.xs$/.c/;
469             $xs{$name} = $c;
470             $c{$c} = 1;
471         } elsif ($name =~ /\.c(p|pp|xx|c)?$/i){  # .c .C .cpp .cxx .cc .cp
472             $c{$name} = 1
473                 unless $name =~ m/perlmain\.c/; # See MAP_TARGET
474         } elsif ($name =~ /\.h$/i){
475             $h{$name} = 1;
476         } elsif ($name =~ /\.(p[ml]|pod)$/){
477             $pm{$name} = File::Spec->catfile('$(INST_LIBDIR)',$name);
478         } elsif ($name =~ /\.PL$/ && $name ne "Makefile.PL") {
479             ($pl_files{$name} = $name) =~ s/\.PL$// ;
480         }
481     }
482
483     # Some larger extensions often wish to install a number of *.pm/pl
484     # files into the library in various locations.
485
486     # The attribute PMLIBDIRS holds an array reference which lists
487     # subdirectories which we should search for library files to
488     # install. PMLIBDIRS defaults to [ 'lib', $self->{BASEEXT} ].  We
489     # recursively search through the named directories (skipping any
490     # which don't exist or contain Makefile.PL files).
491
492     # For each *.pm or *.pl file found $self->libscan() is called with
493     # the default installation path in $_[1]. The return value of
494     # libscan defines the actual installation location.  The default
495     # libscan function simply returns the path.  The file is skipped
496     # if libscan returns false.
497
498     # The default installation location passed to libscan in $_[1] is:
499     #
500     #  ./*.pm           => $(INST_LIBDIR)/*.pm
501     #  ./xyz/...        => $(INST_LIBDIR)/xyz/...
502     #  ./lib/...        => $(INST_LIB)/...
503     #
504     # In this way the 'lib' directory is seen as the root of the actual
505     # perl library whereas the others are relative to INST_LIBDIR
506     # (which includes ROOTEXT). This is a subtle distinction but one
507     # that's important for nested modules.
508
509     $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}]
510         unless $self->{PMLIBDIRS};
511
512     #only existing directories that aren't in $dir are allowed
513
514     my (@pmlibdirs) = map { macify ($_) } @{$self->{PMLIBDIRS}};
515     my ($pmlibdir);
516     @{$self->{PMLIBDIRS}} = ();
517     foreach $pmlibdir (@pmlibdirs) {
518         -d $pmlibdir && !$dir{$pmlibdir} && push @{$self->{PMLIBDIRS}}, $pmlibdir;
519     }
520
521     if (@{$self->{PMLIBDIRS}}){
522         print "Searching PMLIBDIRS: @{$self->{PMLIBDIRS}}\n"
523             if ($Verbose >= 2);
524         require File::Find;
525         File::Find::find(sub {
526             if (-d $_){
527                 if ($_ eq "CVS" || $_ eq "RCS"){
528                     $File::Find::prune = 1;
529                 }
530                 return;
531             }
532             my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)');
533             my($striplibpath,$striplibname);
534             $prefix =  '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:);
535             ($striplibname,$striplibpath) = fileparse($striplibpath);
536             my($inst) = File::Spec->catfile($prefix,$striplibpath,$striplibname);
537             local($_) = $inst; # for backwards compatibility
538             $inst = $self->libscan($inst);
539             print "libscan($path) => '$inst'\n" if ($Verbose >= 2);
540             return unless $inst;
541             $pm{$path} = $inst;
542         }, @{$self->{PMLIBDIRS}});
543     }
544
545     $self->{DIR} = [sort keys %dir] unless $self->{DIR};
546     $self->{XS}  = \%xs             unless $self->{XS};
547     $self->{PM}  = \%pm             unless $self->{PM};
548     $self->{C}   = [sort keys %c]   unless $self->{C};
549     $self->{H}   = [sort keys %h]   unless $self->{H};
550     $self->{PL_FILES} = \%pl_files unless $self->{PL_FILES};
551
552     # Set up names of manual pages to generate from pods
553     unless ($self->{MAN1PODS}) {
554         $self->{MAN1PODS} = {};
555     }
556     unless ($self->{MAN3PODS}) {
557         $self->{MAN3PODS} = {};
558     }
559 }
560
561 =item libscan (o)
562
563 Takes a path to a file that is found by init_dirscan and returns false
564 if we don't want to include this file in the library. Mainly used to
565 exclude RCS, CVS, and SCCS directories from installation.
566
567 =cut
568
569 # ';
570
571 sub libscan {
572     my($self,$path) = @_;
573     return '' if $path =~ m/:(RCS|CVS|SCCS):/ ;
574     $path;
575 }
576
577 =item constants (o)
578
579 Initializes lots of constants and .SUFFIXES and .PHONY
580
581 =cut
582
583 sub constants {
584     my($self) = @_;
585     unless (ref $self){
586         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
587         $self = $ExtUtils::MakeMaker::Parent[-1];
588     }
589     my(@m,$tmp);
590
591     for $tmp (qw/
592               NAME DISTNAME NAME_SYM VERSION VERSION_SYM XS_VERSION
593               INST_LIB INST_ARCHLIB PERL_LIB PERL_SRC MACPERL_SRC MACPERL_LIB PERL FULLPERL
594               XSPROTOARG MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED SOURCE TYPEMAPS
595               / ) {
596         next unless defined $self->{$tmp};
597         push @m, "$tmp = $self->{$tmp}\n";
598     }
599
600     push @m, q{
601 MODULES = }.join(" \\\n\t", sort keys %{$self->{PM}})."\n";
602     push @m, "PMLIBDIRS = @{$self->{PMLIBDIRS}}\n" if @{$self->{PMLIBDIRS}};
603
604     push @m, '
605
606 .INCLUDE : $(MACPERL_SRC)BuildRules.mk
607
608 ';
609
610     push @m, qq{
611 VERSION_MACRO = VERSION
612 DEFINE_VERSION = -d \$(VERSION_MACRO)="¶"\$(VERSION)¶""
613 XS_VERSION_MACRO = XS_VERSION
614 XS_DEFINE_VERSION = -d \$(XS_VERSION_MACRO)="¶"\$(XS_VERSION)¶""
615 };
616
617     $self->{DEFINE} .= " \$(XS_DEFINE_VERSION) \$(DEFINE_VERSION)";
618
619     push @m, qq{
620 MAKEMAKER = $INC{'ExtUtils/MakeMaker.pm'}
621 MM_VERSION = $ExtUtils::MakeMaker::VERSION
622 };
623
624     push @m, q{
625 # FULLEXT = Pathname for extension directory (eg DBD:Oracle).
626 # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT.
627 # ROOTEXT = Directory part of FULLEXT (eg DBD)
628 # DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
629 };
630
631     if ($self->{DEFINE}) {
632         $self->{DEFINE} =~ s/-D/-d /g; # Preprocessor definitions may be useful
633         $self->{DEFINE} =~ s/-I\S+//g; # UN*X includes probably are not useful
634     }
635     if ($self->{INC}) {
636         $self->{INC} =~ s/-I\S+//g; # UN*X includes probably are not useful
637     }
638     for $tmp (qw/
639               FULLEXT BASEEXT ROOTEXT DEFINE INC
640               / ) {
641         next unless defined $self->{$tmp};
642         push @m, "$tmp = $self->{$tmp}\n";
643     }
644
645     push @m, "
646 # Handy lists of source code files:
647 XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})."
648 C_FILES = ".join(" \\\n\t", @{$self->{C}})."
649 H_FILES = ".join(" \\\n\t", @{$self->{H}})."
650 ";
651
652     push @m, '
653
654 .INCLUDE : $(MACPERL_SRC)ExtBuildRules.mk
655 ';
656
657     join('',@m);
658 }
659
660 =item static (o)
661
662 Defines the static target.
663
664 =cut
665
666 sub static {
667 # --- Static Loading Sections ---
668
669     my($self) = shift;
670     unless (ref $self){
671         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
672         $self = $ExtUtils::MakeMaker::Parent[-1];
673     }
674     my($extlib) = $self->{MYEXTLIB} ? "\nstatic :: myextlib\n" : "";
675     '
676 all :: static
677
678 install :: do_install_static
679
680 install_static :: do_install_static
681 ' . $extlib;
682 }
683
684 =item dlsyms (o)
685
686 Used by MacOS to define DL_FUNCS and DL_VARS and write the *.exp
687 files.
688
689 =cut
690
691 sub dlsyms {
692     my($self,%attribs) = @_;
693     unless (ref $self){
694         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
695         $self = $ExtUtils::MakeMaker::Parent[-1];
696     }
697
698     return '' unless !$self->{SKIPHASH}{'dynamic'};
699
700     my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
701     my($vars)  = $attribs{DL_VARS} || $self->{DL_VARS} || [];
702     my(@m);
703
704     push(@m,"
705 dynamic :: $self->{BASEEXT}.exp
706
707 ") unless $self->{SKIPHASH}{'dynamic'};
708
709     my($extlib) = $self->{MYEXTLIB} ? " myextlib" : "";
710
711     push(@m,"
712 $self->{BASEEXT}.exp: Makefile.PL$extlib
713 ", qq[\t\$(PERL) "-I\$(PERL_LIB)" -e 'use ExtUtils::Mksymlists; ],
714         'Mksymlists("NAME" => "',$self->{NAME},'", "DL_FUNCS" => ',
715         neatvalue($funcs),', "DL_VARS" => ', neatvalue($vars), ');\'
716 ');
717
718     join('',@m);
719 }
720
721 =item dynamic (o)
722
723 Defines the dynamic target.
724
725 =cut
726
727 sub dynamic {
728 # --- dynamic Loading Sections ---
729
730     my($self) = shift;
731     unless (ref $self){
732         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
733         $self = $ExtUtils::MakeMaker::Parent[-1];
734     }
735     '
736 all :: dynamic
737
738 install :: do_install_dynamic
739
740 install_dynamic :: do_install_dynamic
741 ';
742 }
743
744
745 =item clean (o)
746
747 Defines the clean target.
748
749 =cut
750
751 sub clean {
752 # --- Cleanup and Distribution Sections ---
753
754     my($self, %attribs) = @_;
755     unless (ref $self){
756         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
757         $self = $ExtUtils::MakeMaker::Parent[-1];
758     }
759     my(@m,$dir);
760     push(@m, '
761 # Delete temporary files but do not touch installed files. We don\'t delete
762 # the Makefile here so a later make realclean still has a makefile to use.
763
764 clean ::
765 ');
766     # clean subdirectories first
767     for $dir (@{$self->{DIR}}) {
768         push @m, 
769 "       Set OldEcho \{Echo\}
770         Set Echo 0
771         Directory $dir
772         If \"\`Exists -f $self->{MAKEFILE}\`\" != \"\"
773             \$(MAKE) clean
774         End
775         Set Echo \{OldEcho\}
776         ";
777     }
778
779     my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
780     push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES};
781     push @m, "\t\$(RM_RF) @otherfiles\n";
782     # See realclean and ext/utils/make_ext for usage of Makefile.old
783     push(@m,
784          "\t\$(MV) $self->{MAKEFILE} $self->{MAKEFILE}.old\n");
785     push(@m,
786          "\t$attribs{POSTOP}\n")   if $attribs{POSTOP};
787     join("", @m);
788 }
789
790 =item realclean (o)
791
792 Defines the realclean target.
793
794 =cut
795
796 sub realclean {
797     my($self, %attribs) = @_;
798     unless (ref $self){
799         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
800         $self = $ExtUtils::MakeMaker::Parent[-1];
801     }
802     my(@m);
803     push(@m,'
804 # Delete temporary files (via clean) and also delete installed files
805 realclean purge ::  clean
806 ');
807     # realclean subdirectories first (already cleaned)
808     my $sub = 
809 "       Set OldEcho \{Echo\}
810         Set Echo 0
811         Directory %s
812         If \"\`Exists -f %s\`\" != \"\"
813             \$(MAKE) realclean
814         End
815         Set Echo \{OldEcho\}
816         ";
817     foreach(@{$self->{DIR}}){
818         push(@m, sprintf($sub,$_,"$self->{MAKEFILE}.old","-f $self->{MAKEFILE}.old"));
819         push(@m, sprintf($sub,$_,"$self->{MAKEFILE}",''));
820     }
821     my(@otherfiles) = ($self->{MAKEFILE},
822                        "$self->{MAKEFILE}.old"); # Makefiles last
823     push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES};
824     push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles;
825     push(@m, "\t$attribs{POSTOP}\n")       if $attribs{POSTOP};
826     join("", @m);
827 }
828
829 =item rulez (o)
830
831 =cut
832
833 sub rulez {
834     my($self) = shift;
835     unless (ref $self){
836         ExtUtils::MakeMaker::TieAtt::warndirectuse((caller(0))[3]);
837         $self = $ExtUtils::MakeMaker::Parent[-1];
838     }
839     qq'
840 install install_static install_dynamic :: 
841 \t\$(MACPERL_SRC)PerlInstall -l \$(PERL_LIB)
842
843 .INCLUDE : \$(MACPERL_SRC)BulkBuildRules.mk
844 ';
845 }
846
847 sub xsubpp_version
848 {
849     return $ExtUtils::MakeMaker::Version;
850 }
851
852
853 =item processPL (o)
854
855 Defines targets to run *.PL files.
856
857 =cut
858
859 sub processPL {
860     my($self) = shift;
861     return "" unless $self->{PL_FILES};
862     my(@m, $plfile);
863     foreach $plfile (sort keys %{$self->{PL_FILES}}) {
864         my $list = ref($self->{PL_FILES}->{$plfile})
865                 ? $self->{PL_FILES}->{$plfile}
866                 : [$self->{PL_FILES}->{$plfile}];
867         foreach $target (@$list) {
868         push @m, "
869 ProcessPL :: $target
870 \t$self->{NOECHO}\$(NOOP)
871
872 $target :: $plfile
873 \t\$(PERL) -I\$(MACPERL_LIB) -I\$(PERL_LIB) $plfile $target
874 ";
875         }
876     }
877     join "", @m;
878 }
879
880 1;
881
882 __END__