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