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