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