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