xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/ExtUtils/MM_MacOS.pm (revision 0:68f95e015346)
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
9package ExtUtils::MM_MacOS;
10require ExtUtils::MM_Any;
11require ExtUtils::MM_Unix;
12@ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix );
13
14use vars qw($VERSION);
15$VERSION = '1.07';
16
17use Config;
18use Cwd 'cwd';
19require Exporter;
20use File::Basename;
21use vars qw(%make_data);
22
23my $Mac_FS = eval { require Mac::FileSpec::Unixish };
24
25use ExtUtils::MakeMaker qw($Verbose &neatvalue);
26
27=head1 NAME
28
29ExtUtils::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
37MM_MacOS currently only produces an approximation to the correct Makefile.
38
39=over 4
40
41=cut
42
43sub 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:
141END
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
210sub skipcheck {
211    my($self) = shift;
212    my($section) = @_;
213    return 'skipped' if $self->{SKIPHASH}{$section};
214    return '';
215}
216
217=item maybe_command
218
219Returns true, if the argument is likely to be a command.
220
221=cut
222
223sub maybe_command {
224    my($self,$file) = @_;
225    return $file if ! -d $file;
226    return;
227}
228
229=item guess_name
230
231Guess the name of this package by examining the working directory's
232name. MakeMaker calls this only if the developer has not supplied a
233NAME attribute.
234
235=cut
236
237sub 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
248Translate relative Unix filepaths into Mac names.
249
250=cut
251
252sub 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
274Translate Unix filepaths and shell globs to Mac style.
275
276=cut
277
278sub patternify {
279    my($unix) = @_;
280    my(@mac);
281    use ExtUtils::MakeMaker::bytes; # Non-UTF-8 high bytes 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
298Initializes some of NAME, FULLEXT, BASEEXT, DLBASE, PERL_SRC,
299PERL_LIB, PERL_ARCHLIB, PERL_INC, INSTALLDIRS, INST_*, INSTALL*,
300PREFIX, CONFIG, AR, AR_STATIC_ARGS, LD, OBJ_EXT, LIB_EXT, MAP_TARGET,
301LIBPERL_A, VERSION_FROM, VERSION, DISTNAME, VERSION_SYM.
302
303=cut
304
305sub 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
438Initializes LDLOADLIBS, LIBS
439
440=cut
441
442sub 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
481Add MACPERL_SRC MACPERL_LIB
482
483=item platform_constants
484
485Add MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC
486MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED
487
488XXX Few are initialized.  How many of these are ever used?
489
490=cut
491
492sub 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
502sub 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
519Initializes DIR, XS, PM, C, O_FILES, H, PL_FILES, MAN*PODS, EXE_FILES.
520
521=cut
522
523sub 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            next if $self->{NORECURS};
541	    $dir{$name} = $name if (-f ":$name:Makefile.PL");
542	} elsif ($name =~ /\.xs$/){
543	    my($c); ($c = $name) =~ s/\.xs$/.c/;
544	    $xs{$name} = $c;
545	    $c{$c} = 1;
546	} elsif ($name =~ /\.c(p|pp|xx|c)?$/i){  # .c .C .cpp .cxx .cc .cp
547	    $c{$name} = 1
548		unless $name =~ m/perlmain\.c/; # See MAP_TARGET
549	} elsif ($name =~ /\.h$/i){
550	    $h{$name} = 1;
551	} elsif ($name =~ /\.(p[ml]|pod)$/){
552	    $pm{$name} = $self->catfile('$(INST_LIBDIR)',$name);
553	} elsif ($name =~ /\.PL$/ && $name ne "Makefile.PL") {
554	    ($pl_files{$name} = $name) =~ s/\.PL$// ;
555	}
556    }
557
558    # Some larger extensions often wish to install a number of *.pm/pl
559    # files into the library in various locations.
560
561    # The attribute PMLIBDIRS holds an array reference which lists
562    # subdirectories which we should search for library files to
563    # install. PMLIBDIRS defaults to [ 'lib', $self->{BASEEXT} ].  We
564    # recursively search through the named directories (skipping any
565    # which don't exist or contain Makefile.PL files).
566
567    # For each *.pm or *.pl file found $self->libscan() is called with
568    # the default installation path in $_[1]. The return value of
569    # libscan defines the actual installation location.  The default
570    # libscan function simply returns the path.  The file is skipped
571    # if libscan returns false.
572
573    # The default installation location passed to libscan in $_[1] is:
574    #
575    #  ./*.pm		=> $(INST_LIBDIR)/*.pm
576    #  ./xyz/...	=> $(INST_LIBDIR)/xyz/...
577    #  ./lib/...	=> $(INST_LIB)/...
578    #
579    # In this way the 'lib' directory is seen as the root of the actual
580    # perl library whereas the others are relative to INST_LIBDIR
581    # This is a subtle distinction but one that's important for nested
582    # modules.
583
584    $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}]
585	unless $self->{PMLIBDIRS};
586
587    #only existing directories that aren't in $dir are allowed
588
589    my (@pmlibdirs) = map { macify ($_) } @{$self->{PMLIBDIRS}};
590    my ($pmlibdir);
591    @{$self->{PMLIBDIRS}} = ();
592    foreach $pmlibdir (@pmlibdirs) {
593	-d $pmlibdir && !$dir{$pmlibdir} && push @{$self->{PMLIBDIRS}}, $pmlibdir;
594    }
595
596    if (@{$self->{PMLIBDIRS}}){
597	print "Searching PMLIBDIRS: @{$self->{PMLIBDIRS}}\n"
598	    if ($Verbose >= 2);
599	require File::Find;
600	File::Find::find(sub {
601	    if (-d $_){
602	        unless ($self->libscan($_)){
603		    $File::Find::prune = 1;
604		}
605		return;
606	    }
607	    my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)');
608	    my($striplibpath,$striplibname);
609	    $prefix =  '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:);
610	    ($striplibname,$striplibpath) = fileparse($striplibpath);
611	    my($inst) = $self->catfile($prefix,$striplibpath,$striplibname);
612	    local($_) = $inst; # for backwards compatibility
613	    $inst = $self->libscan($inst);
614	    print "libscan($path) => '$inst'\n" if ($Verbose >= 2);
615	    return unless $inst;
616	    $pm{$path} = $inst;
617	}, @{$self->{PMLIBDIRS}});
618    }
619
620    $self->{DIR} = [sort keys %dir] unless $self->{DIR};
621    $self->{XS}  = \%xs             unless $self->{XS};
622    $self->{PM}  = \%pm             unless $self->{PM};
623    $self->{C}   = [sort keys %c]   unless $self->{C};
624    $self->{H}   = [sort keys %h]   unless $self->{H};
625    $self->{PL_FILES} = \%pl_files unless $self->{PL_FILES};
626
627    # Set up names of manual pages to generate from pods
628    unless ($self->{MAN1PODS}) {
629    	$self->{MAN1PODS} = {};
630    }
631    unless ($self->{MAN3PODS}) {
632    	$self->{MAN3PODS} = {};
633    }
634}
635
636
637=item init_VERSION (o)
638
639Change DEFINE_VERSION and XS_DEFINE_VERSION
640
641=cut
642
643sub init_VERSION {
644    my $self = shift;
645
646    $self->SUPER::init_VERSION;
647
648    $self->{DEFINE_VERSION}    = '-d $(VERSION_MACRO)="�"$(VERSION)�""';
649    $self->{XS_DEFINE_VERSION} = '-d $(XS_VERSION_MACRO)="�"$(XS_VERSION)�""';
650}
651
652
653=item special_targets (o)
654
655Add .INCLUDE
656
657=cut
658
659sub special_targets {
660    my $self = shift;
661
662    my $make_frag = $self->SUPER::special_targets;
663
664    return $make_frag . <<'MAKE_FRAG';
665.INCLUDE : $(MACPERL_SRC)BuildRules.mk $(MACPERL_SRC)ExtBuildRules.mk
666
667MAKE_FRAG
668
669}
670
671=item static (o)
672
673Defines the static target.
674
675=cut
676
677sub static {
678# --- Static Loading Sections ---
679
680    my($self) = shift;
681    my($extlib) = $self->{MYEXTLIB} ? "\nstatic :: myextlib\n" : "";
682    '
683all :: static
684
685install :: do_install_static
686
687install_static :: do_install_static
688' . $extlib;
689}
690
691=item dlsyms (o)
692
693Used by MacOS to define DL_FUNCS and DL_VARS and write the *.exp
694files.
695
696=cut
697
698sub dlsyms {
699    my($self,%attribs) = @_;
700
701    return '' unless !$self->{SKIPHASH}{'dynamic'};
702
703    my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
704    my($vars)  = $attribs{DL_VARS} || $self->{DL_VARS} || [];
705    my(@m);
706
707    push(@m,"
708dynamic :: $self->{BASEEXT}.exp
709
710") unless $self->{SKIPHASH}{'dynamic'};
711
712    my($extlib) = $self->{MYEXTLIB} ? " myextlib" : "";
713
714    push(@m,"
715$self->{BASEEXT}.exp: Makefile.PL$extlib
716", qq[\t\$(PERL) "-I\$(PERL_LIB)" -e 'use ExtUtils::Mksymlists; ],
717        'Mksymlists("NAME" => "',$self->{NAME},'", "DL_FUNCS" => ',
718	neatvalue($funcs),', "DL_VARS" => ', neatvalue($vars), ');\'
719');
720
721    join('',@m);
722}
723
724=item dynamic (o)
725
726Defines the dynamic target.
727
728=cut
729
730sub dynamic {
731# --- dynamic Loading Sections ---
732
733    my($self) = shift;
734    '
735all :: dynamic
736
737install :: do_install_dynamic
738
739install_dynamic :: do_install_dynamic
740';
741}
742
743
744=item clean (o)
745
746Defines the clean target.
747
748=cut
749
750sub clean {
751# --- Cleanup and Distribution Sections ---
752
753    my($self, %attribs) = @_;
754    my(@m,$dir);
755    push(@m, '
756# Delete temporary files but do not touch installed files. We don\'t delete
757# the Makefile here so a later make realclean still has a makefile to use.
758
759clean :: clean_subdirs
760');
761
762    my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files
763    push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES};
764    push @m, "\t\$(RM_RF) @otherfiles\n";
765    # See realclean and ext/utils/make_ext for usage of Makefile.old
766    push(@m,
767	 "\t\$(MV) \$(FIRST_MAKEFILE) \$(MAKEFILE_OLD)\n");
768    push(@m,
769	 "\t$attribs{POSTOP}\n")   if $attribs{POSTOP};
770    join("", @m);
771}
772
773=item clean_subdirs_target
774
775MacOS semantics for changing directories and checking for existence
776very different than everyone else.
777
778=cut
779
780sub clean_subdirs_target {
781    my($self) = shift;
782
783    # No subdirectories, no cleaning.
784    return <<'NOOP_FRAG' unless @{$self->{DIR}};
785clean_subdirs :
786	$(NOECHO)$(NOOP)
787NOOP_FRAG
788
789
790    my $clean = "clean_subdirs :\n";
791
792    for my $dir (@{$self->{DIR}}) {
793        $clean .= sprintf <<'MAKE_FRAG', $dir;
794	Set OldEcho {Echo}
795	Set Echo 0
796	Directory %s
797	If "`Exists -f $(FIRST_MAKEFILE)`" != ""
798	    $(MAKE) clean
799	End
800	Set Echo {OldEcho}
801
802MAKE_FRAG
803    }
804
805    return $clean;
806}
807
808
809=item realclean (o)
810
811Defines the realclean target.
812
813=cut
814
815sub realclean {
816    my($self, %attribs) = @_;
817    my(@m);
818    push(@m,'
819# Delete temporary files (via clean) and also delete installed files
820realclean purge ::  clean
821');
822
823    my(@otherfiles) = ('$(FIRST_MAKEFILE)', '$(MAKEFILE_OLD)'); # Makefiles last
824    push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES};
825    push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles;
826    push(@m, "\t$attribs{POSTOP}\n")       if $attribs{POSTOP};
827    join("", @m);
828}
829
830
831=item realclean_subdirs_target
832
833MacOS semantics for changing directories and checking for existence
834very different than everyone else.
835
836=cut
837
838sub realclean_subdirs_target {
839    my $self = shift;
840
841    return <<'NOOP_FRAG' unless @{$self->{DIR}};
842realclean_subdirs :
843	$(NOECHO)$(NOOP)
844NOOP_FRAG
845
846    my $rclean = "realclean_subdirs :\n";
847
848    foreach my $dir (@{$self->{DIR}}){
849        $rclean .= sprintf <<'RCLEAN', $dir,
850	Set OldEcho \{Echo\}
851	Set Echo 0
852	Directory %s
853	If \"\`Exists -f $(FIRST_MAKEFILE)\`\" != \"\"
854	    \$(MAKE) realclean
855	End
856	Set Echo \{OldEcho\}
857
858RCLEAN
859
860    }
861
862    return $rclean;
863}
864
865
866=item rulez (o)
867
868=cut
869
870sub rulez {
871    my($self) = shift;
872    qq'
873install install_static install_dynamic ::
874\t\$(MACPERL_SRC)PerlInstall -l \$(PERL_LIB)
875
876.INCLUDE : \$(MACPERL_SRC)BulkBuildRules.mk
877';
878}
879
880
881=item processPL (o)
882
883Defines targets to run *.PL files.
884
885=cut
886
887sub processPL {
888    my($self) = shift;
889    return "" unless $self->{PL_FILES};
890    my(@m, $plfile);
891    foreach $plfile (sort keys %{$self->{PL_FILES}}) {
892        my $list = ref($self->{PL_FILES}->{$plfile})
893		? $self->{PL_FILES}->{$plfile}
894		: [$self->{PL_FILES}->{$plfile}];
895	foreach $target (@$list) {
896	push @m, "
897ProcessPL :: $target
898\t$(NOECHO)\$(NOOP)
899
900$target :: $plfile
901\t\$(PERL) -I\$(MACPERL_LIB) -I\$(PERL_LIB) $plfile $target
902";
903	}
904    }
905    join "", @m;
906}
907
908sub cflags {
909    my($self,$libperl) = @_;
910    my $optimize = '';
911
912    for (map { $_ . "Optimize" } qw(MWC MWCPPC MWC68K MPW MRC MRC SC)) {
913        $optimize .= "$_ = $self->{$_}" if exists $self->{$_};
914    }
915
916    return $self->{CFLAGS} = $optimize;
917}
918
919
920sub _include {  # for Unix-style includes, with -I instead of -i
921	my($inc) = @_;
922	require File::Spec::Unix;
923
924	# allow only relative paths
925	if (File::Spec::Unix->file_name_is_absolute($inc)) {
926		return '';
927	} else {
928		return '-i ' . macify($inc);
929	}
930}
931
932=item os_flavor
933
934MacOS Classic is MacOS and MacOS Classic.
935
936=cut
937
938sub os_flavor {
939    return('MacOS', 'MacOS Classic');
940}
941
942=back
943
944=cut
945
9461;
947