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