This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
U/WIN: final (for now) touches from John P. Linderman;
[perl5.git] / lib / ExtUtils / MM_Any.pm
CommitLineData
f6d6199c
MS
1package ExtUtils::MM_Any;
2
3use strict;
4use vars qw($VERSION @ISA);
dedf98bc 5$VERSION = 0.05;
479d2113 6@ISA = qw(File::Spec);
f6d6199c
MS
7
8use Config;
9use File::Spec;
10
11
12=head1 NAME
13
14ExtUtils::MM_Any - Platform agnostic MM methods
15
16=head1 SYNOPSIS
17
18 FOR INTERNAL USE ONLY!
19
20 package ExtUtils::MM_SomeOS;
21
22 # Temporarily, you have to subclass both. Put MM_Any first.
23 require ExtUtils::MM_Any;
24 require ExtUtils::MM_Unix;
25 @ISA = qw(ExtUtils::MM_Any ExtUtils::Unix);
26
27=head1 DESCRIPTION
28
29B<FOR INTERNAL USE ONLY!>
30
31ExtUtils::MM_Any is a superclass for the ExtUtils::MM_* set of
32modules. It contains methods which are either inherently
33cross-platform or are written in a cross-platform manner.
34
35Subclass off of ExtUtils::MM_Any I<and> ExtUtils::MM_Unix. This is a
36temporary solution.
37
38B<THIS MAY BE TEMPORARY!>
39
40=head1 Inherently Cross-Platform Methods
41
42These are methods which are by their nature cross-platform and should
43always be cross-platform.
44
dedf98bc
MS
45=over 4
46
47=item os_flavor_is
48
49 $mm->os_flavor_is($this_flavor);
50 $mm->os_flavor_is(@one_of_these_flavors);
51
52Checks to see if the current operating system is one of the given flavors.
53
54This is useful for code like:
55
56 if( $mm->os_flavor_is('Unix') ) {
57 $out = `foo 2>&1`;
58 }
59 else {
60 $out = `foo`;
61 }
62
63=cut
64
65sub os_flavor_is {
66 my $self = shift;
67 my %flavors = map { ($_ => 1) } $self->os_flavor;
68 return (grep { $flavors{$_} } @_) ? 1 : 0;
69}
70
71=back
72
479d2113 73=head2 File::Spec wrappers
f6d6199c 74
479d2113
MS
75ExtUtils::MM_Any is a subclass of File::Spec. The methods noted here
76override File::Spec.
f6d6199c 77
479d2113
MS
78=over 4
79
80=item catfile
81
82File::Spec <= 0.83 has a bug where the file part of catfile is not
83canonicalized. This override fixes that bug.
84
85=cut
86
87sub catfile {
88 my $self = shift;
89 return $self->canonpath($self->SUPER::catfile(@_));
90}
91
92=back
93
94=head1 Thought To Be Cross-Platform Methods
95
96These are methods which are thought to be cross-platform by virtue of
97having been written in a way to avoid incompatibilities. They may
98require partial overrides.
f6d6199c
MS
99
100=over 4
101
479d2113
MS
102=item B<split_command>
103
104 my @cmds = $MM->split_command($cmd, @args);
105
106Most OS have a maximum command length they can execute at once. Large
107modules can easily generate commands well past that limit. Its
108necessary to split long commands up into a series of shorter commands.
109
110split_command() will return a series of @cmds each processing part of
111the args. Collectively they will process all the arguments. Each
112individual line in @cmds will not be longer than the
113$self->max_exec_len being careful to take into account macro expansion.
114
115$cmd should include any switches and repeated initial arguments.
116
117If no @args are given, no @cmds will be returned.
118
119Pairs of arguments will always be preserved in a single command, this
120is a heuristic for things like pm_to_blib and pod2man which work on
121pairs of arguments. This makes things like this safe:
122
123 $self->split_command($cmd, %pod2man);
124
f6d6199c
MS
125
126=cut
127
479d2113
MS
128sub split_command {
129 my($self, $cmd, @args) = @_;
130
131 my @cmds = ();
132 return(@cmds) unless @args;
133
134 # If the command was given as a here-doc, there's probably a trailing
135 # newline.
136 chomp $cmd;
137
138 # set aside 20% for macro expansion.
139 my $len_left = int($self->max_exec_len * 0.80);
140 $len_left -= length $self->_expand_macros($cmd);
141
142 do {
143 my $arg_str = '';
144 my @next_args;
145 while( @next_args = splice(@args, 0, 2) ) {
146 # Two at a time to preserve pairs.
147 my $next_arg_str = "\t ". join ' ', @next_args, "\n";
148
149 if( !length $arg_str ) {
150 $arg_str .= $next_arg_str
151 }
152 elsif( length($arg_str) + length($next_arg_str) > $len_left ) {
153 unshift @args, @next_args;
154 last;
155 }
156 else {
157 $arg_str .= $next_arg_str;
158 }
159 }
160 chop $arg_str;
161
162 push @cmds, $self->escape_newlines("$cmd\n$arg_str");
163 } while @args;
164
165 return @cmds;
f6d6199c
MS
166}
167
479d2113
MS
168
169sub _expand_macros {
170 my($self, $cmd) = @_;
171
172 $cmd =~ s{\$\((\w+)\)}{
173 defined $self->{$1} ? $self->{$1} : "\$($1)"
174 }e;
175 return $cmd;
176}
177
178
179=item B<echo>
180
181 my @commands = $MM->echo($text);
182 my @commands = $MM->echo($text, $file);
183 my @commands = $MM->echo($text, $file, $appending);
184
185Generates a set of @commands which print the $text to a $file.
186
187If $file is not given, output goes to STDOUT.
188
189If $appending is true the $file will be appended to rather than
190overwritten.
f6d6199c
MS
191
192=cut
193
479d2113
MS
194sub echo {
195 my($self, $text, $file, $appending) = @_;
196 $appending ||= 0;
197
198 my @cmds = map { '$(NOECHO) $(ECHO) '.$self->quote_literal($_) }
199 split /\n/, $text;
200 if( $file ) {
201 my $redirect = $appending ? '>>' : '>';
202 $cmds[0] .= " $redirect $file";
203 $_ .= " >> $file" foreach @cmds[1..$#cmds];
204 }
205
206 return @cmds;
f6d6199c
MS
207}
208
479d2113
MS
209
210=item init_VERSION
211
212 $mm->init_VERSION
213
214Initialize macros representing versions of MakeMaker and other tools
215
216MAKEMAKER: path to the MakeMaker module.
217
218MM_VERSION: ExtUtils::MakeMaker Version
219
220MM_REVISION: ExtUtils::MakeMaker version control revision (for backwards
221 compat)
222
223VERSION: version of your module
224
225VERSION_MACRO: which macro represents the version (usually 'VERSION')
226
227VERSION_SYM: like version but safe for use as an RCS revision number
228
229DEFINE_VERSION: -D line to set the module version when compiling
230
231XS_VERSION: version in your .xs file. Defaults to $(VERSION)
232
233XS_VERSION_MACRO: which macro represents the XS version.
234
235XS_DEFINE_VERSION: -D line to set the xs version when compiling.
236
237Called by init_main.
f6d6199c
MS
238
239=cut
240
479d2113
MS
241sub init_VERSION {
242 my($self) = shift;
243
dedf98bc 244 $self->{MAKEMAKER} = $ExtUtils::MakeMaker::Filename;
479d2113
MS
245 $self->{MM_VERSION} = $ExtUtils::MakeMaker::VERSION;
246 $self->{MM_REVISION}= $ExtUtils::MakeMaker::Revision;
247 $self->{VERSION_FROM} ||= '';
248
249 if ($self->{VERSION_FROM}){
250 $self->{VERSION} = $self->parse_version($self->{VERSION_FROM});
251 if( $self->{VERSION} eq 'undef' ) {
252 require Carp;
253 Carp::carp("WARNING: Setting VERSION via file ".
254 "'$self->{VERSION_FROM}' failed\n");
255 }
256 }
257
258 # strip blanks
259 if (defined $self->{VERSION}) {
260 $self->{VERSION} =~ s/^\s+//;
261 $self->{VERSION} =~ s/\s+$//;
262 }
263 else {
264 $self->{VERSION} = '';
265 }
266
267
268 $self->{VERSION_MACRO} = 'VERSION';
269 ($self->{VERSION_SYM} = $self->{VERSION}) =~ s/\W/_/g;
270 $self->{DEFINE_VERSION} = '-D$(VERSION_MACRO)=\"$(VERSION)\"';
271
272
273 # Graham Barr and Paul Marquess had some ideas how to ensure
274 # version compatibility between the *.pm file and the
275 # corresponding *.xs file. The bottomline was, that we need an
276 # XS_VERSION macro that defaults to VERSION:
277 $self->{XS_VERSION} ||= $self->{VERSION};
278
279 $self->{XS_VERSION_MACRO} = 'XS_VERSION';
280 $self->{XS_DEFINE_VERSION} = '-D$(XS_VERSION_MACRO)=\"$(XS_VERSION)\"';
281
f6d6199c
MS
282}
283
479d2113
MS
284=item wraplist
285
286Takes an array of items and turns them into a well-formatted list of
287arguments. In most cases this is simply something like:
288
289 FOO \
290 BAR \
291 BAZ
f6d6199c
MS
292
293=cut
294
479d2113
MS
295sub wraplist {
296 my $self = shift;
297 return join " \\\n\t", @_;
f6d6199c
MS
298}
299
479d2113
MS
300=item manifypods
301
302Defines targets and routines to translate the pods into manpages and
303put them into the INST_* directories.
f6d6199c
MS
304
305=cut
306
479d2113
MS
307sub manifypods {
308 my $self = shift;
309
310 my $POD2MAN_EXE_macro = $self->POD2MAN_EXE_macro();
311 my $manifypods_target = $self->manifypods_target();
312
313 return <<END_OF_TARGET;
314
315# --- Begin manifypods section:
316$POD2MAN_EXE_macro
317
318$manifypods_target
319
320# --- End manifypods section --- #
321
322END_OF_TARGET
323
f6d6199c
MS
324}
325
479d2113
MS
326
327=item manifypods_target
328
329 my $manifypods_target = $self->manifypods_target;
330
331Generates the manifypods target. This target generates man pages from
332all POD files in MAN1PODS and MAN3PODS.
f6d6199c
MS
333
334=cut
335
479d2113
MS
336sub manifypods_target {
337 my($self) = shift;
338
339 my $man1pods = '';
340 my $man3pods = '';
341 my $dependencies = '';
342
343 # populate manXpods & dependencies:
344 foreach my $name (keys %{$self->{MAN1PODS}}, keys %{$self->{MAN3PODS}}) {
345 $dependencies .= " \\\n\t$name";
346 }
347
348 foreach my $name (keys %{$self->{MAN3PODS}}) {
349 $dependencies .= " \\\n\t$name"
350 }
351
352 my $manify = <<END;
353manifypods : pure_all $dependencies
354END
355
356 my @man_cmds;
357 foreach my $section (qw(1 3)) {
358 my $pods = $self->{"MAN${section}PODS"};
359 push @man_cmds, $self->split_command(<<CMD, %$pods);
360 \$(NOECHO) \$(POD2MAN_EXE) --section=$section --perm_rw=\$(PERM_RW)
361CMD
362 }
363
dedf98bc 364 $manify .= "\t\$(NOECHO) \$(NOOP)\n" unless @man_cmds;
479d2113
MS
365 $manify .= join '', map { "$_\n" } @man_cmds;
366
367 return $manify;
f6d6199c
MS
368}
369
479d2113
MS
370
371=item makemakerdflt_target
372
373 my $make_frag = $mm->makemakerdflt_target
374
375Returns a make fragment with the makemakerdeflt_target specified.
376This target is the first target in the Makefile, is the default target
377and simply points off to 'all' just in case any make variant gets
378confused or something gets snuck in before the real 'all' target.
f6d6199c
MS
379
380=cut
381
479d2113
MS
382sub makemakerdflt_target {
383 return <<'MAKE_FRAG';
384makemakerdflt: all
385 $(NOECHO) $(NOOP)
386MAKE_FRAG
387
f6d6199c
MS
388}
389
479d2113
MS
390
391=item special_targets
392
393 my $make_frag = $mm->special_targets
394
395Returns a make fragment containing any targets which have special
396meaning to make. For example, .SUFFIXES and .PHONY.
f6d6199c
MS
397
398=cut
399
479d2113
MS
400sub special_targets {
401 my $make_frag = <<'MAKE_FRAG';
402.SUFFIXES: .xs .c .C .cpp .i .s .cxx .cc $(OBJ_EXT)
403
404.PHONY: all config static dynamic test linkext manifest
405
406MAKE_FRAG
407
408 $make_frag .= <<'MAKE_FRAG' if $ENV{CLEARCASE_ROOT};
409.NO_CONFIG_REC: Makefile
410
411MAKE_FRAG
412
413 return $make_frag;
f6d6199c
MS
414}
415
479d2113 416=item POD2MAN_EXE_macro
f6d6199c 417
479d2113 418 my $pod2man_exe_macro = $self->POD2MAN_EXE_macro
f6d6199c 419
479d2113
MS
420Returns a definition for the POD2MAN_EXE macro. This is a program
421which emulates the pod2man utility. You can add more switches to the
422command by simply appending them on the macro.
423
424Typical usage:
425
426 $(POD2MAN_EXE) --section=3 --perm_rw=$(PERM_RW) podfile man_page
427
428=cut
429
430sub POD2MAN_EXE_macro {
431 my $self = shift;
432
433# Need the trailing '--' so perl stops gobbling arguments and - happens
434# to be an alternative end of line seperator on VMS so we quote it
435 return <<'END_OF_DEF';
436POD2MAN_EXE = $(PERLRUN) "-MExtUtils::Command::MM" -e pod2man "--"
437END_OF_DEF
438}
f6d6199c 439
f6d6199c
MS
440
441=item test_via_harness
442
443 my $command = $mm->test_via_harness($perl, $tests);
444
445Returns a $command line which runs the given set of $tests with
446Test::Harness and the given $perl.
447
448Used on the t/*.t files.
449
450=cut
451
452sub test_via_harness {
453 my($self, $perl, $tests) = @_;
454
e0678a30
MS
455 return qq{\t$perl "-MExtUtils::Command::MM" }.
456 qq{"-e" "test_harness(\$(TEST_VERBOSE), '\$(INST_LIB)', '\$(INST_ARCHLIB)')" $tests\n};
f6d6199c
MS
457}
458
459=item test_via_script
460
461 my $command = $mm->test_via_script($perl, $script);
462
463Returns a $command line which just runs a single test without
464Test::Harness. No checks are done on the results, they're just
465printed.
466
467Used for test.pl, since they don't always follow Test::Harness
468formatting.
469
470=cut
471
472sub test_via_script {
473 my($self, $perl, $script) = @_;
e0678a30 474 return qq{\t$perl "-I\$(INST_LIB)" "-I\$(INST_ARCHLIB)" $script\n};
f6d6199c
MS
475}
476
479d2113
MS
477=item libscan
478
479 my $wanted = $self->libscan($path);
480
481Takes a path to a file or dir and returns an empty string if we don't
482want to include this file in the library. Otherwise it returns the
483the $path unchanged.
484
485Mainly used to exclude RCS, CVS, and SCCS directories from
486installation.
487
488=cut
489
490sub libscan {
491 my($self,$path) = @_;
492 my($dirs,$file) = ($self->splitpath($path))[1,2];
493 return '' if grep /^RCS|CVS|SCCS|\.svn$/,
494 $self->splitdir($dirs), $file;
495
496 return $path;
497}
498
499=item tool_autosplit
500
501Defines a simple perl call that runs autosplit. May be deprecated by
502pm_to_blib soon.
503
504=cut
505
506sub tool_autosplit {
507 my($self, %attribs) = @_;
508
509 my $maxlen = $attribs{MAXLEN} ? '$$AutoSplit::Maxlen=$attribs{MAXLEN};'
510 : '';
511
512 my $asplit = $self->oneliner(sprintf <<'PERL_CODE', $maxlen);
513use AutoSplit; %s autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1)
514PERL_CODE
515
516 return sprintf <<'MAKE_FRAG', $asplit;
517# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
518AUTOSPLITFILE = %s
519
520MAKE_FRAG
521
522}
523
524
525=item all_target
526
527Generate the default target 'all'.
528
529=cut
530
531sub all_target {
532 my $self = shift;
533
534 return <<'MAKE_EXT';
535all :: pure_all
536 $(NOECHO) $(NOOP)
537MAKE_EXT
538
539}
540
541
542=item metafile_target
543
544 my $target = $mm->metafile_target;
545
546Generate the metafile target.
547
548Writes the file META.yml, YAML encoded meta-data about the module. The
549format follows Module::Build's as closely as possible. Additionally, we
550include:
551
552 version_from
553 installdirs
554
555=cut
556
557sub metafile_target {
558 my $self = shift;
559
431b0fc4
MS
560 return <<'MAKE_FRAG' if $self->{NO_META};
561metafile:
562 $(NOECHO) $(NOOP)
563MAKE_FRAG
564
479d2113
MS
565 my $prereq_pm = '';
566 while( my($mod, $ver) = each %{$self->{PREREQ_PM}} ) {
567 $prereq_pm .= sprintf " %-30s %s\n", "$mod:", $ver;
568 }
569
570 my $meta = <<YAML;
571#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
572name: $self->{DISTNAME}
573version: $self->{VERSION}
574version_from: $self->{VERSION_FROM}
575installdirs: $self->{INSTALLDIRS}
576requires:
577$prereq_pm
578distribution_type: module
579generated_by: ExtUtils::MakeMaker version $ExtUtils::MakeMaker::VERSION
580YAML
581
582 my @write_meta = $self->echo($meta, 'META.yml');
583 return sprintf <<'MAKE_FRAG', join "\n\t", @write_meta;
584metafile :
585 %s
586MAKE_FRAG
587
588}
589
590
591=item metafile_addtomanifest_target
592
593 my $target = $mm->metafile_addtomanifest_target
594
595Adds the META.yml file to the MANIFEST.
596
597=cut
598
599sub metafile_addtomanifest_target {
600 my $self = shift;
601
431b0fc4
MS
602 return <<'MAKE_FRAG' if $self->{NO_META};
603metafile_addtomanifest:
604 $(NOECHO) $(NOOP)
605MAKE_FRAG
606
479d2113 607 my $add_meta = $self->oneliner(<<'CODE', ['-MExtUtils::Manifest=maniadd']);
2530b651 608maniadd({q{META.yml} => q{Module meta-data (added by MakeMaker)}});
479d2113
MS
609CODE
610
611 return sprintf <<'MAKE_FRAG', $add_meta;
612metafile_addtomanifest:
613 $(NOECHO) %s
614MAKE_FRAG
615
616}
617
618
619=back
620
621=head2 Abstract methods
622
623Methods which cannot be made cross-platform and each subclass will
624have to do their own implementation.
625
626=over 4
627
628=item oneliner
629
630 my $oneliner = $MM->oneliner($perl_code);
631 my $oneliner = $MM->oneliner($perl_code, \@switches);
632
633This will generate a perl one-liner safe for the particular platform
634you're on based on the given $perl_code and @switches (a -e is
635assumed) suitable for using in a make target. It will use the proper
636shell quoting and escapes.
637
638$(PERLRUN) will be used as perl.
639
640Any newlines in $perl_code will be escaped. Leading and trailing
641newlines will be stripped. Makes this idiom much easier:
642
643 my $code = $MM->oneliner(<<'CODE', [...switches...]);
644some code here
645another line here
646CODE
647
648Usage might be something like:
649
650 # an echo emulation
651 $oneliner = $MM->oneliner('print "Foo\n"');
652 $make = '$oneliner > somefile';
653
654All dollar signs must be doubled in the $perl_code if you expect them
655to be interpreted normally, otherwise it will be considered a make
656macro. Also remember to quote make macros else it might be used as a
657bareword. For example:
658
659 # Assign the value of the $(VERSION_FROM) make macro to $vf.
660 $oneliner = $MM->oneliner('$$vf = "$(VERSION_FROM)"');
661
662Its currently very simple and may be expanded sometime in the figure
663to include more flexible code and switches.
664
665
666=item B<quote_literal>
667
668 my $safe_text = $MM->quote_literal($text);
669
670This will quote $text so it is interpreted literally in the shell.
671
672For example, on Unix this would escape any single-quotes in $text and
673put single-quotes around the whole thing.
674
675
676=item B<escape_newlines>
677
678 my $escaped_text = $MM->escape_newlines($text);
679
680Shell escapes newlines in $text.
681
682
683=item max_exec_len
684
685 my $max_exec_len = $MM->max_exec_len;
686
687Calculates the maximum command size the OS can exec. Effectively,
688this is the max size of a shell command line.
689
690=for _private
691$self->{_MAX_EXEC_LEN} is set by this method, but only for testing purposes.
692
693=item B<init_others>
694
695 $MM->init_others();
696
697Initializes the macro definitions used by tools_other() and places them
698in the $MM object.
699
700If there is no description, its the same as the parameter to
701WriteMakefile() documented in ExtUtils::MakeMaker.
702
703Defines at least these macros.
704
705 Macro Description
706
dedf98bc
MS
707 NOOP Do nothing
708 NOECHO Tell make not to display the command itself
479d2113
MS
709
710 MAKEFILE
711 FIRST_MAKEFILE
712 MAKEFILE_OLD
713 MAKE_APERL_FILE File used by MAKE_APERL
714
715 SHELL Program used to run
716 shell commands
717
dedf98bc 718 ECHO Print text adding a newline on the end
479d2113
MS
719 RM_F Remove a file
720 RM_RF Remove a directory
721 TOUCH Update a file's timestamp
722 TEST_F Test for a file's existence
723 CP Copy a file
724 MV Move a file
725 CHMOD Change permissions on a
726 file
727
728 UMASK_NULL Nullify umask
729 DEV_NULL Supress all command output
730
731=item init_DIRFILESEP
732
733 $MM->init_DIRFILESEP;
734 my $dirfilesep = $MM->{DIRFILESEP};
735
736Initializes the DIRFILESEP macro which is the seperator between the
737directory and filename in a filepath. ie. / on Unix, \ on Win32 and
738nothing on VMS.
739
740For example:
741
742 # instead of $(INST_ARCHAUTODIR)/extralibs.ld
743 $(INST_ARCHAUTODIR)$(DIRFILESEP)extralibs.ld
744
745Something of a hack but it prevents a lot of code duplication between
746MM_* variants.
747
748Do not use this as a seperator between directories. Some operating
749systems use different seperators between subdirectories as between
750directories and filenames (for example: VOLUME:[dir1.dir2]file on VMS).
751
752=item init_linker
753
754 $mm->init_linker;
755
756Initialize macros which have to do with linking.
757
758PERL_ARCHIVE: path to libperl.a equivalent to be linked to dynamic
759extensions.
760
761PERL_ARCHIVE_AFTER: path to a library which should be put on the
762linker command line I<after> the external libraries to be linked to
763dynamic extensions. This may be needed if the linker is one-pass, and
764Perl includes some overrides for C RTL functions, such as malloc().
765
766EXPORT_LIST: name of a file that is passed to linker to define symbols
767to be exported.
768
769Some OSes do not need these in which case leave it blank.
770
771
772=item init_platform
773
774 $mm->init_platform
775
776Initialize any macros which are for platform specific use only.
777
778A typical one is the version number of your OS specific mocule.
779(ie. MM_Unix_VERSION or MM_VMS_VERSION).
780
781=item platform_constants
782
783 my $make_frag = $mm->platform_constants
784
785Returns a make fragment defining all the macros initialized in
786init_platform() rather than put them in constants().
787
788=cut
789
790sub init_platform {
791 return '';
792}
793
794sub platform_constants {
795 return '';
796}
797
dedf98bc
MS
798=item os_flavor
799
800 my @os_flavor = $mm->os_flavor;
801
802@os_flavor is the style of operating system this is, usually
803corresponding to the MM_*.pm file we're using.
804
805The first element of @os_flavor is the major family (ie. Unix,
806Windows, VMS, OS/2, MacOS, etc...) and the rest are sub families.
807
808Some examples:
809
810 Cygwin98 ('Unix', 'Cygwin', 'Cygwin9x')
811 Windows NT ('Win32', 'WinNT')
812 Win98 ('Win32', 'Win9x')
813 Linux ('Unix', 'Linux')
814 MacOS Classic ('MacOS', 'MacOS Classic')
815 MacOS X ('Unix', 'Darwin', 'MacOS', 'MacOS X')
816 OS/2 ('OS/2')
817
818This is used to write code for styles of operating system.
819See os_flavor_is() for use.
820
479d2113 821
f6d6199c
MS
822=back
823
824=head1 AUTHOR
825
479d2113
MS
826Michael G Schwern <schwern@pobox.com> and the denizens of
827makemaker@perl.org with code from ExtUtils::MM_Unix and
828ExtUtils::MM_Win32.
f6d6199c
MS
829
830
831=cut
832
8331;