Make the pure-perl test generation compatible with bsd make implementations.
[gitmo/Class-MOP.git] / Makefile.PL
1 # The perl/C checking voodoo is mostly stolen from Graham Barr's
2 # Scalar-List-Utils distribution.
3 use strict;
4 use warnings;
5
6 use ExtUtils::MakeMaker;
7 use Config qw(%Config);
8 use File::Spec;
9
10 use 5.008;
11
12 # If undefined, try our best, if true, require XS, if false, never do
13 # XS
14 my $force_xs;
15
16 for (@ARGV) {
17     /^--pm/ and $force_xs = 0;
18     /^--xs/ and $force_xs = 1;
19 }
20
21 our $has_compiler = $force_xs;
22 unless ( defined $force_xs ) {
23     $has_compiler = check_for_compiler()
24         or no_cc();
25 }
26
27 my %prereqs = (
28     'Scalar::Util'             => '1.18',
29     'Sub::Name'                => '0.04',
30     'Sub::Identify'            => '0.03',
31     'MRO::Compat'              => '0.05',
32     'Test::More'               => '0',
33     'Test::Exception'          => '0',
34     'File::Spec'               => '0',
35     'Carp'                     => '0',
36     'Devel::GlobalDestruction' => '0',
37     'Task::Weaken'             => '0',
38     'B'                        => '0',
39 );
40
41 delete @prereqs{qw(Sub::Name Devel::GlobalDestruction)}
42     unless $has_compiler;
43
44 write_makefile();
45
46 sub write_makefile {
47     my $ccflags = -d '.svn' || $ENV{MAINTAINER_MODE} ? '-Wall' : '';
48
49     WriteMakefile(
50         VERSION_FROM  => 'lib/Class/MOP.pm',
51         NAME          => 'Class::MOP',
52         PREREQ_PM     => \%prereqs,
53         CONFIGURE     => \&init,
54         CCFLAGS       => $ccflags,
55         clean         => { FILES => 'test.c test.o t/pp*' },
56         ABSTRACT_FROM => 'lib/Class/MOP.pm',
57         AUTHOR        => 'Stevan Little <stevan@iinteractive.com>',
58         LICENSE       => 'perl',
59     );
60 }
61
62 sub no_cc {
63     print <<'EOF';
64
65  I cannot determine if you have a C compiler
66  so I will install a perl-only implementation
67
68  You can force installation of the XS version with
69
70     perl Makefile.PL --xs
71
72 EOF
73 }
74
75 sub check_for_compiler {
76     print "Testing if you have a C compiler\n";
77
78     eval { require ExtUtils::CBuilder };
79     if ($@) {
80         return _check_for_compiler_manually();
81     }
82     else {
83         return _check_for_compiler_with_cbuilder();
84     }
85 }
86
87 sub _check_for_compiler_with_cbuilder {
88     my $cb = ExtUtils::CBuilder->new( quiet => 1 );
89
90     return $cb->have_compiler();
91 }
92
93 sub _check_for_compiler_manually {
94     unless ( open F, '>', 'test.c' ) {
95         warn
96             "Cannot write test.c, skipping test compilation and installing pure Perl version.\n";
97         return 0;
98     }
99
100     print F <<'EOF';
101 int main() { return 0; }
102 EOF
103
104     close F or return 0;
105
106     my $cc = $Config{cc};
107     if ( $cc =~ /cl(\.exe)?$/ ) {
108
109         # stupid stupid MSVC compiler hack tacken from version.pm's
110         # Makefile.PL
111         $cc .= ' -c';    # prevent it from calling the linker
112     }
113
114     system("$cc -o test$Config{obj_ext} test.c") and return 0;
115
116     unlink $_ for grep {-f} 'test.c', "test$Config{obj_ext}";
117
118     return 1;
119 }
120
121 # This sucks, but it's the best guess we can make. Since we just use
122 # it to run two sets of tests, it's not big deal if it ends up true
123 # for a non-maintainer.
124 sub is_maintainer {
125     return 0 if $ENV{PERL5_CPAN_IS_RUNNING} || $ENV{PERL5_CPANPLUS_IS_RUNNING};
126
127     return 1;
128 }
129
130 sub get_pp_tests {
131     opendir my $dh, 't' or die "Cannot read t: $!";
132
133     return grep { $_ !~ /^99/ } grep {/^\d.+\.t$/} readdir $dh;
134 }
135
136 # This is EUMM voodoo
137 sub init {
138     my $hash = $_[1];
139
140     unless ($has_compiler) {
141         @{$hash}{ 'XS', 'C' } = ( {}, [] );
142     }
143
144     $hash;
145 }
146
147 package MY;
148
149 sub postamble {
150     my @test_files = ::get_pp_tests();
151     my $pp_tests = join q{ }, map { File::Spec->catfile('t', "pp_${_}") } @test_files;
152     my @pp_test_targets = join qq{\n}, map {
153         my $source = File::Spec->catfile('t', ${_});
154         File::Spec->catfile('t', "pp_${_}") . q{: }
155         . qq{$source t/header_pp.inc\n\t}
156         . q{$(NOECHO) $(ABSPERLRUN) "-MExtUtils::Command" -e cat t/header_pp.inc }
157         . $source . q{ > $@} . qq{\n}
158     } @test_files;
159     my $test_dep = $::has_compiler && (::is_maintainer() || $ENV{AUTOMATED_TESTING})
160         ? qq{pure_all :: pp_tests\n} . join qq{\n}, @pp_test_targets
161         : '';
162
163     return <<"EOM"
164 pp_tests: ${pp_tests}
165
166 ${test_dep}
167
168 EOM
169 }