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