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