# MM_MacOS.pm # MakeMaker default methods for MacOS # This package is inserted into @ISA of MakeMaker's MM before the # built-in ExtUtils::MM_Unix methods if MakeMaker.pm is run under MacOS. # # Author: Matthias Neeracher # Maintainer: Chris Nandor package ExtUtils::MM_MacOS; require ExtUtils::MM_Any; require ExtUtils::MM_Unix; @ISA = qw( ExtUtils::MM_Any ExtUtils::MM_Unix ); use vars qw($VERSION); $VERSION = '1.07'; use Config; use Cwd 'cwd'; require Exporter; use File::Basename; use vars qw(%make_data); my $Mac_FS = eval { require Mac::FileSpec::Unixish }; use ExtUtils::MakeMaker qw($Verbose &neatvalue); =head1 NAME ExtUtils::MM_MacOS - methods to override UN*X behaviour in ExtUtils::MakeMaker =head1 SYNOPSIS use ExtUtils::MM_MacOS; # Done internally by ExtUtils::MakeMaker if needed =head1 DESCRIPTION MM_MacOS currently only produces an approximation to the correct Makefile. =over 4 =cut sub new { my($class,$self) = @_; my($key); my($cwd) = cwd(); print STDOUT "Mac MakeMaker (v$ExtUtils::MakeMaker::VERSION)\n" if $Verbose; if (-f "MANIFEST" && ! -f "Makefile.mk"){ ExtUtils::MakeMaker::check_manifest(); } mkdir("Obj", 0777) unless -d "Obj"; $self = {} unless defined $self; check_hints($self); my(%initial_att) = %$self; # record initial attributes if (defined $self->{CONFIGURE}) { if (ref $self->{CONFIGURE} eq 'CODE') { $self = { %$self, %{&{$self->{CONFIGURE}}}}; } else { require Carp; Carp::croak("Attribute 'CONFIGURE' to WriteMakefile() not a code reference\n"); } } my $newclass = ++$ExtUtils::MakeMaker::PACKNAME; local @ExtUtils::MakeMaker::Parent = @ExtUtils::MakeMaker::Parent; # Protect against non-local exits { no strict 'refs'; print "Blessing Object into class [$newclass]\n" if $Verbose>=2; ExtUtils::MakeMaker::mv_all_methods("MY",$newclass); bless $self, $newclass; push @Parent, $self; require ExtUtils::MY; @{"$newclass\:\:ISA"} = 'MM'; } $ExtUtils::MakeMaker::Recognized_Att_Keys{$_} = 1 for map { $_ . 'Optimize' } qw(MWC MWCPPC MWC68K MPW MRC MRC SC); if (defined $ExtUtils::MakeMaker::Parent[-2]){ $self->{PARENT} = $ExtUtils::MakeMaker::Parent[-2]; my $key; for $key (@ExtUtils::MakeMaker::Prepend_parent) { next unless defined $self->{PARENT}{$key}; $self->{$key} = $self->{PARENT}{$key}; if ($key !~ /PERL$/) { $self->{$key} = $self->catdir("..",$self->{$key}) unless $self->file_name_is_absolute($self->{$key}); } else { # PERL or FULLPERL will be a command verb or even a # command with an argument instead of a full file # specification under VMS. So, don't turn the command # into a filespec, but do add a level to the path of # the argument if not already absolute. my @cmd = split /\s+/, $self->{$key}; $cmd[1] = $self->catfile('[-]',$cmd[1]) unless (@cmd < 2) || $self->file_name_is_absolute($cmd[1]); $self->{$key} = join(' ', @cmd); } } if ($self->{PARENT}) { $self->{PARENT}->{CHILDREN}->{$newclass} = $self; foreach my $opt (qw(POLLUTE PERL_CORE)) { if (exists $self->{PARENT}->{$opt} and not exists $self->{$opt}) { # inherit, but only if already unspecified $self->{$opt} = $self->{PARENT}->{$opt}; } } } my @fm = grep /^FIRST_MAKEFILE=/, @ARGV; $self->parse_args(@fm) if @fm; } else { $self->parse_args(split(' ', $ENV{PERL_MM_OPT} || ''),@ARGV); } $self->{NAME} ||= $self->guess_name; ($self->{NAME_SYM} = $self->{NAME}) =~ s/\W+/_/g; $self->init_main(); $self->init_dirscan(); $self->init_others(); push @{$self->{RESULT}}, <{NAME} extension to perl. # # It was generated automatically by MakeMaker version # $ExtUtils::MakeMaker::VERSION (Revision: $ExtUtils::MakeMaker::Revision) from the contents of # Makefile.PL. Don't edit this file, edit Makefile.PL instead. # # ANY CHANGES MADE HERE WILL BE LOST! # # MakeMaker Parameters: END foreach $key (sort keys %initial_att){ my($v) = neatvalue($initial_att{$key}); $v =~ s/(CODE|HASH|ARRAY|SCALAR)\([\dxa-f]+\)/$1\(...\)/; $v =~ tr/\n/ /s; push @{$self->{RESULT}}, "# $key => $v"; } # turn the SKIP array into a SKIPHASH hash my (%skip,$skip); for $skip (@{$self->{SKIP} || []}) { $self->{SKIPHASH}{$skip} = 1; } delete $self->{SKIP}; # free memory # We skip many sections for MacOS, but we don't say anything about it in the Makefile for (qw/ const_config tool_autosplit tool_xsubpp tools_other dist macro depend post_constants pasthru c_o xs_c xs_o top_targets linkext dynamic_bs dynamic_lib static_lib manifypods installbin subdirs dist_basics dist_core distdir dist_test dist_ci install force perldepend makefile staticmake test pm_to_blib selfdocument const_loadlibs const_cccmd /) { $self->{SKIPHASH}{$_} = 2; } push @ExtUtils::MakeMaker::MM_Sections, "rulez" unless grep /rulez/, @ExtUtils::MakeMaker::MM_Sections; if ($self->{PARENT}) { for (qw/install dist dist_basics dist_core distdir dist_test dist_ci/) { $self->{SKIPHASH}{$_} = 1; } } # We run all the subdirectories now. They don't have much to query # from the parent, but the parent has to query them: if they need linking! unless ($self->{NORECURS}) { $self->eval_in_subdirs if @{$self->{DIR}}; } my $section; foreach $section ( @ExtUtils::MakeMaker::MM_Sections ){ next if defined $self->{SKIPHASH}{$section} && $self->{SKIPHASH}{$section} == 2; print "Processing Makefile '$section' section\n" if ($Verbose >= 2); $self->{ABSTRACT_FROM} = macify($self->{ABSTRACT_FROM}) if $self->{ABSTRACT_FROM}; my($skipit) = $self->skipcheck($section); if ($skipit){ push @{$self->{RESULT}}, "\n# --- MakeMaker $section section $skipit."; } else { my(%a) = %{$self->{$section} || {}}; push @{$self->{RESULT}}, "\n# --- MakeMaker $section section:"; push @{$self->{RESULT}}, "# " . join ", ", %a if $Verbose && %a; push @{$self->{RESULT}}, $self->nicetext($self->$section( %a )); } } push @{$self->{RESULT}}, "\n# End."; pop @Parent; $ExtUtils::MM_MacOS::make_data{$cwd} = $self; $self; } sub skipcheck { my($self) = shift; my($section) = @_; return 'skipped' if $self->{SKIPHASH}{$section}; return ''; } =item maybe_command Returns true, if the argument is likely to be a command. =cut sub maybe_command { my($self,$file) = @_; return $file if ! -d $file; return; } =item guess_name Guess the name of this package by examining the working directory's name. MakeMaker calls this only if the developer has not supplied a NAME attribute. =cut sub guess_name { my($self) = @_; my $name = cwd(); $name =~ s/.*:// unless ($name =~ s/^.*:ext://); $name =~ s#:#::#g; $name =~ s#[\-_][\d.\-]+$##; # this is new with MM 5.00 $name; } =item macify Translate relative Unix filepaths into Mac names. =cut sub macify { my($unix) = @_; my(@mac); foreach (split(/[ \t\n]+/, $unix)) { if (m|/|) { if ($Mac_FS) { # should always be true $_ = Mac::FileSpec::Unixish::nativize($_); } else { s|^\./||; s|/|:|g; $_ = ":$_"; } } push(@mac, $_); } return "@mac"; } =item patternify Translate Unix filepaths and shell globs to Mac style. =cut sub patternify { my($unix) = @_; my(@mac); use ExtUtils::MakeMaker::bytes; # Non-UTF-8 high bytes below. foreach (split(/[ \t\n]+/, $unix)) { if (m|/|) { $_ = ":$_"; s|/|:|g; s|\*|Å|g; $_ = "'$_'" if /[?Å]/; push(@mac, $_); } } return "@mac"; } =item init_main Initializes some of NAME, FULLEXT, BASEEXT, DLBASE, PERL_SRC, PERL_LIB, PERL_ARCHLIB, PERL_INC, INSTALLDIRS, INST_*, INSTALL*, PREFIX, CONFIG, AR, AR_STATIC_ARGS, LD, OBJ_EXT, LIB_EXT, MAP_TARGET, LIBPERL_A, VERSION_FROM, VERSION, DISTNAME, VERSION_SYM. =cut sub init_main { my($self) = @_; # --- Initialize Module Name and Paths # NAME = The perl module name for this extension (eg DBD::Oracle). # FULLEXT = Pathname for extension directory (eg DBD/Oracle). # BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. ($self->{FULLEXT} = $self->{NAME}) =~ s!::!:!g ; #eg. BSD:Foo:Socket ($self->{BASEEXT} = $self->{NAME}) =~ s!.*::!! ; #eg. Socket # --- Initialize PERL_LIB, INST_LIB, PERL_SRC # *Real* information: where did we get these two from? ... my $inc_config_dir = dirname($INC{'Config.pm'}); my $inc_carp_dir = dirname($INC{'Carp.pm'}); unless ($self->{PERL_SRC}){ my($dir); foreach $dir (qw(:: ::: :::: ::::: ::::::)){ if (-f "${dir}perl.h") { $self->{PERL_SRC}=$dir ; last; } } if (!$self->{PERL_SRC} && -f "$ENV{MACPERL}CORE:perl:perl.h") { # Mac pathnames may be very nasty, so we'll install symlinks unlink(":PerlCore", ":PerlLib"); symlink("$ENV{MACPERL}CORE:", "PerlCore"); symlink("$ENV{MACPERL}lib:", "PerlLib"); $self->{PERL_SRC} = ":PerlCore:perl:" ; $self->{PERL_LIB} = ":PerlLib:"; } } if ($self->{PERL_SRC}){ $self->{PERL_LIB} ||= $self->catdir("$self->{PERL_SRC}","lib"); $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; $self->{PERL_INC} = $self->{PERL_SRC}; } else { # hmmmmmmm ... ? $self->{PERL_LIB} ||= "$ENV{MACPERL}site_perl"; $self->{PERL_ARCHLIB} = $self->{PERL_LIB}; $self->{PERL_INC} = $ENV{MACPERL}; $self->{PERL_SRC} = ''; } $self->{INSTALLDIRS} = "perl"; $self->{INST_LIB} = $self->{INST_ARCHLIB} = $self->{PERL_LIB}; $self->{INST_MAN1DIR} = $self->{INSTALLMAN1DIR} = "none"; $self->{MAN1EXT} ||= $Config::Config{man1ext}; $self->{INST_MAN3DIR} = $self->{INSTALLMAN3DIR} = "none"; $self->{MAN3EXT} ||= $Config::Config{man3ext}; $self->{MAP_TARGET} ||= "perl"; # make a simple check if we find Exporter # hm ... do we really care? at all? # warn "Warning: PERL_LIB ($self->{PERL_LIB}) seems not to be a perl library directory # (Exporter.pm not found)" # unless -f $self->catfile("$self->{PERL_LIB}","Exporter.pm") || # $self->{NAME} eq "ExtUtils::MakeMaker"; # Determine VERSION and VERSION_FROM ($self->{DISTNAME}=$self->{NAME}) =~ s#(::)#-#g unless $self->{DISTNAME}; if ($self->{VERSION_FROM}){ # XXX replace with parse_version() override local *FH; open(FH,macify($self->{VERSION_FROM})) or die "Could not open '$self->{VERSION_FROM}' (attribute VERSION_FROM): $!"; while () { chop; next unless /\$([\w:]*\bVERSION)\b.*=/; local $ExtUtils::MakeMaker::module_version_variable = $1; my($eval) = "$_;"; eval $eval; die "Could not eval '$eval': $@" if $@; if ($self->{VERSION} = $ {$ExtUtils::MakeMaker::module_version_variable}){ print "$self->{NAME} VERSION is $self->{VERSION} (from $self->{VERSION_FROM})\n" if $Verbose; } else { # XXX this should probably croak print "WARNING: Setting VERSION via file '$self->{VERSION_FROM}' failed\n"; } last; } close FH; } if ($self->{VERSION}) { $self->{VERSION} =~ s/^\s+//; $self->{VERSION} =~ s/\s+$//; } $self->{VERSION} = "0.10" unless $self->{VERSION}; ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g; # Graham Barr and Paul Marquess had some ideas how to ensure # version compatibility between the *.pm file and the # corresponding *.xs file. The bottomline was, that we need an # XS_VERSION macro that defaults to VERSION: $self->{XS_VERSION} ||= $self->{VERSION}; $self->{DEFINE} .= " \$(XS_DEFINE_VERSION) \$(DEFINE_VERSION)"; # Preprocessor definitions may be useful $self->{DEFINE} =~ s/-D/-d /g; # UN*X includes probably are not useful $self->{DEFINE} =~ s/-I\S+/_include($1)/eg; if ($self->{INC}) { # UN*X includes probably are not useful $self->{INC} =~ s/-I(\S+)/_include($1)/eg; } # --- Initialize Perl Binary Locations # Find Perl 5. The only contract here is that both 'PERL' and 'FULLPERL' # will be working versions of perl 5. miniperl has priority over perl # for PERL to ensure that $(PERL) is usable while building ./ext/* my ($component,@defpath); foreach $component ($self->{PERL_SRC}, $self->path(), $Config::Config{binexp}) { push @defpath, $component if defined $component; } $self->{PERL} = "$self->{PERL_SRC}miniperl"; } =item init_others Initializes LDLOADLIBS, LIBS =cut sub init_others { # --- Initialize Other Attributes my($self) = shift; if ( !$self->{OBJECT} ) { # init_dirscan should have found out, if we have C files $self->{OBJECT} = ""; $self->{OBJECT} = "$self->{BASEEXT}.c" if @{$self->{C}||[]}; } else { $self->{OBJECT} =~ s/\$\(O_FILES\)/@{$self->{C}||[]}/; } my($src); foreach (split(/[ \t\n]+/, $self->{OBJECT})) { if (/^$self->{BASEEXT}\.o(bj)?$/) { $src .= " $self->{BASEEXT}.c"; } elsif (/^(.*\..*)\.o$/) { $src .= " $1"; } elsif (/^(.*)(\.o(bj)?|\$\(OBJ_EXT\))$/) { if (-f "$1.cp") { $src .= " $1.cp"; } else { $src .= " $1.c"; } } else { $src .= " $_"; } } $self->{SOURCE} = $src; $self->{FULLPERL} = "$self->{PERL_SRC}perl"; $self->{MAKEFILE} = "Makefile.mk"; $self->{FIRST_MAKEFILE} = $self->{MAKEFILE}; $self->{MAKEFILE_OLD} = $self->{MAKEFILE}.'.old'; $self->{'DEV_NULL'} ||= ' \xB3 Dev:Null'; return 1; } =item init_platform Add MACPERL_SRC MACPERL_LIB =item platform_constants Add MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED XXX Few are initialized. How many of these are ever used? =cut sub init_platform { my $self = shift; $self->{MACPERL_SRC} = $self->catdir("$self->{PERL_SRC}","macos:"); $self->{MACPERL_LIB} ||= $self->catdir("$self->{MACPERL_SRC}","lib"); $self->{MACPERL_INC} = $self->{MACPERL_SRC}; } sub platform_constants { my $self = shift; foreach my $macro (qw(MACPERL_SRC MACPERL_LIB MACLIBS_68K MACLIBS_PPC MACLIBS_SC MACLIBS_MRC MACLIBS_ALL_68K MACLIBS_ALL_PPC MACLIBS_SHARED)) { next unless defined $self->{$macro}; $make_frag .= "$macro = $self->{$macro}\n"; } return $make_frag; } =item init_dirscan Initializes DIR, XS, PM, C, O_FILES, H, PL_FILES, MAN*PODS, EXE_FILES. =cut sub init_dirscan { # --- File and Directory Lists (.xs .pm .pod etc) my($self) = @_; my($name, %dir, %xs, %c, %h, %ignore, %pl_files, %manifypods); local(%pm); #the sub in find() has to see this hash # in case we don't find it below! if ($self->{VERSION_FROM}) { my $version_from = macify($self->{VERSION_FROM}); $pm{$version_from} = $self->catfile('$(INST_LIBDIR)', $version_from); } $ignore{'test.pl'} = 1; foreach $name ($self->lsdir(":")){ next if ($name =~ /^\./ or $ignore{$name}); next unless $self->libscan($name); if (-d $name){ next if $self->{NORECURS}; $dir{$name} = $name if (-f ":$name:Makefile.PL"); } elsif ($name =~ /\.xs$/){ my($c); ($c = $name) =~ s/\.xs$/.c/; $xs{$name} = $c; $c{$c} = 1; } elsif ($name =~ /\.c(p|pp|xx|c)?$/i){ # .c .C .cpp .cxx .cc .cp $c{$name} = 1 unless $name =~ m/perlmain\.c/; # See MAP_TARGET } elsif ($name =~ /\.h$/i){ $h{$name} = 1; } elsif ($name =~ /\.(p[ml]|pod)$/){ $pm{$name} = $self->catfile('$(INST_LIBDIR)',$name); } elsif ($name =~ /\.PL$/ && $name ne "Makefile.PL") { ($pl_files{$name} = $name) =~ s/\.PL$// ; } } # Some larger extensions often wish to install a number of *.pm/pl # files into the library in various locations. # The attribute PMLIBDIRS holds an array reference which lists # subdirectories which we should search for library files to # install. PMLIBDIRS defaults to [ 'lib', $self->{BASEEXT} ]. We # recursively search through the named directories (skipping any # which don't exist or contain Makefile.PL files). # For each *.pm or *.pl file found $self->libscan() is called with # the default installation path in $_[1]. The return value of # libscan defines the actual installation location. The default # libscan function simply returns the path. The file is skipped # if libscan returns false. # The default installation location passed to libscan in $_[1] is: # # ./*.pm => $(INST_LIBDIR)/*.pm # ./xyz/... => $(INST_LIBDIR)/xyz/... # ./lib/... => $(INST_LIB)/... # # In this way the 'lib' directory is seen as the root of the actual # perl library whereas the others are relative to INST_LIBDIR # This is a subtle distinction but one that's important for nested # modules. $self->{PMLIBDIRS} = ['lib', $self->{BASEEXT}] unless $self->{PMLIBDIRS}; #only existing directories that aren't in $dir are allowed my (@pmlibdirs) = map { macify ($_) } @{$self->{PMLIBDIRS}}; my ($pmlibdir); @{$self->{PMLIBDIRS}} = (); foreach $pmlibdir (@pmlibdirs) { -d $pmlibdir && !$dir{$pmlibdir} && push @{$self->{PMLIBDIRS}}, $pmlibdir; } if (@{$self->{PMLIBDIRS}}){ print "Searching PMLIBDIRS: @{$self->{PMLIBDIRS}}\n" if ($Verbose >= 2); require File::Find; File::Find::find(sub { if (-d $_){ unless ($self->libscan($_)){ $File::Find::prune = 1; } return; } my($path, $prefix) = ($File::Find::name, '$(INST_LIBDIR)'); my($striplibpath,$striplibname); $prefix = '$(INST_LIB)' if (($striplibpath = $path) =~ s:^(\W*)lib\W:$1:); ($striplibname,$striplibpath) = fileparse($striplibpath); my($inst) = $self->catfile($prefix,$striplibpath,$striplibname); local($_) = $inst; # for backwards compatibility $inst = $self->libscan($inst); print "libscan($path) => '$inst'\n" if ($Verbose >= 2); return unless $inst; $pm{$path} = $inst; }, @{$self->{PMLIBDIRS}}); } $self->{DIR} = [sort keys %dir] unless $self->{DIR}; $self->{XS} = \%xs unless $self->{XS}; $self->{PM} = \%pm unless $self->{PM}; $self->{C} = [sort keys %c] unless $self->{C}; $self->{H} = [sort keys %h] unless $self->{H}; $self->{PL_FILES} = \%pl_files unless $self->{PL_FILES}; # Set up names of manual pages to generate from pods unless ($self->{MAN1PODS}) { $self->{MAN1PODS} = {}; } unless ($self->{MAN3PODS}) { $self->{MAN3PODS} = {}; } } =item init_VERSION (o) Change DEFINE_VERSION and XS_DEFINE_VERSION =cut sub init_VERSION { my $self = shift; $self->SUPER::init_VERSION; $self->{DEFINE_VERSION} = '-d $(VERSION_MACRO)="¶"$(VERSION)¶""'; $self->{XS_DEFINE_VERSION} = '-d $(XS_VERSION_MACRO)="¶"$(XS_VERSION)¶""'; } =item special_targets (o) Add .INCLUDE =cut sub special_targets { my $self = shift; my $make_frag = $self->SUPER::special_targets; return $make_frag . <<'MAKE_FRAG'; .INCLUDE : $(MACPERL_SRC)BuildRules.mk $(MACPERL_SRC)ExtBuildRules.mk MAKE_FRAG } =item static (o) Defines the static target. =cut sub static { # --- Static Loading Sections --- my($self) = shift; my($extlib) = $self->{MYEXTLIB} ? "\nstatic :: myextlib\n" : ""; ' all :: static install :: do_install_static install_static :: do_install_static ' . $extlib; } =item dlsyms (o) Used by MacOS to define DL_FUNCS and DL_VARS and write the *.exp files. =cut sub dlsyms { my($self,%attribs) = @_; return '' unless !$self->{SKIPHASH}{'dynamic'}; my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {}; my($vars) = $attribs{DL_VARS} || $self->{DL_VARS} || []; my(@m); push(@m," dynamic :: $self->{BASEEXT}.exp ") unless $self->{SKIPHASH}{'dynamic'}; my($extlib) = $self->{MYEXTLIB} ? " myextlib" : ""; push(@m," $self->{BASEEXT}.exp: Makefile.PL$extlib ", qq[\t\$(PERL) "-I\$(PERL_LIB)" -e 'use ExtUtils::Mksymlists; ], 'Mksymlists("NAME" => "',$self->{NAME},'", "DL_FUNCS" => ', neatvalue($funcs),', "DL_VARS" => ', neatvalue($vars), ');\' '); join('',@m); } =item dynamic (o) Defines the dynamic target. =cut sub dynamic { # --- dynamic Loading Sections --- my($self) = shift; ' all :: dynamic install :: do_install_dynamic install_dynamic :: do_install_dynamic '; } =item clean (o) Defines the clean target. =cut sub clean { # --- Cleanup and Distribution Sections --- my($self, %attribs) = @_; my(@m,$dir); push(@m, ' # Delete temporary files but do not touch installed files. We don\'t delete # the Makefile here so a later make realclean still has a makefile to use. clean :: clean_subdirs '); my(@otherfiles) = values %{$self->{XS}}; # .c files from *.xs files push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; push @m, "\t\$(RM_RF) @otherfiles\n"; # See realclean and ext/utils/make_ext for usage of Makefile.old push(@m, "\t\$(MV) \$(FIRST_MAKEFILE) \$(MAKEFILE_OLD)\n"); push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; join("", @m); } =item clean_subdirs_target MacOS semantics for changing directories and checking for existence very different than everyone else. =cut sub clean_subdirs_target { my($self) = shift; # No subdirectories, no cleaning. return <<'NOOP_FRAG' unless @{$self->{DIR}}; clean_subdirs : $(NOECHO)$(NOOP) NOOP_FRAG my $clean = "clean_subdirs :\n"; for my $dir (@{$self->{DIR}}) { $clean .= sprintf <<'MAKE_FRAG', $dir; Set OldEcho {Echo} Set Echo 0 Directory %s If "`Exists -f $(FIRST_MAKEFILE)`" != "" $(MAKE) clean End Set Echo {OldEcho} MAKE_FRAG } return $clean; } =item realclean (o) Defines the realclean target. =cut sub realclean { my($self, %attribs) = @_; my(@m); push(@m,' # Delete temporary files (via clean) and also delete installed files realclean purge :: clean '); my(@otherfiles) = ('$(FIRST_MAKEFILE)', '$(MAKEFILE_OLD)'); # Makefiles last push(@otherfiles, patternify($attribs{FILES})) if $attribs{FILES}; push(@m, "\t\$(RM_RF) @otherfiles\n") if @otherfiles; push(@m, "\t$attribs{POSTOP}\n") if $attribs{POSTOP}; join("", @m); } =item realclean_subdirs_target MacOS semantics for changing directories and checking for existence very different than everyone else. =cut sub realclean_subdirs_target { my $self = shift; return <<'NOOP_FRAG' unless @{$self->{DIR}}; realclean_subdirs : $(NOECHO)$(NOOP) NOOP_FRAG my $rclean = "realclean_subdirs :\n"; foreach my $dir (@{$self->{DIR}}){ $rclean .= sprintf <<'RCLEAN', $dir, Set OldEcho \{Echo\} Set Echo 0 Directory %s If \"\`Exists -f $(FIRST_MAKEFILE)\`\" != \"\" \$(MAKE) realclean End Set Echo \{OldEcho\} RCLEAN } return $rclean; } =item rulez (o) =cut sub rulez { my($self) = shift; qq' install install_static install_dynamic :: \t\$(MACPERL_SRC)PerlInstall -l \$(PERL_LIB) .INCLUDE : \$(MACPERL_SRC)BulkBuildRules.mk '; } =item processPL (o) Defines targets to run *.PL files. =cut sub processPL { my($self) = shift; return "" unless $self->{PL_FILES}; my(@m, $plfile); foreach $plfile (sort keys %{$self->{PL_FILES}}) { my $list = ref($self->{PL_FILES}->{$plfile}) ? $self->{PL_FILES}->{$plfile} : [$self->{PL_FILES}->{$plfile}]; foreach $target (@$list) { push @m, " ProcessPL :: $target \t$(NOECHO)\$(NOOP) $target :: $plfile \t\$(PERL) -I\$(MACPERL_LIB) -I\$(PERL_LIB) $plfile $target "; } } join "", @m; } sub cflags { my($self,$libperl) = @_; my $optimize = ''; for (map { $_ . "Optimize" } qw(MWC MWCPPC MWC68K MPW MRC MRC SC)) { $optimize .= "$_ = $self->{$_}" if exists $self->{$_}; } return $self->{CFLAGS} = $optimize; } sub _include { # for Unix-style includes, with -I instead of -i my($inc) = @_; require File::Spec::Unix; # allow only relative paths if (File::Spec::Unix->file_name_is_absolute($inc)) { return ''; } else { return '-i ' . macify($inc); } } =item os_flavor MacOS Classic is MacOS and MacOS Classic. =cut sub os_flavor { return('MacOS', 'MacOS Classic'); } =back =cut 1;