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