tagged release 0.6.4
[parrot.git] / config / auto / warnings.pm
blob8e3d2fd8850a7c3b922ab7526772804a14d2c0fb
1 # Copyright (C) 2007-2008, The Perl Foundation.
2 # $Id$
4 =head1 NAME
6 config/auto/warnings.pm - Warning flags detection
8 =head1 DESCRIPTION
10 Automagically detect what warning flags, like -Wall, -Wextra,
11 -Wchar-subscripts, etc., that the compiler can support. Directly hacked
12 from F<config/auto/attributes.pm>.
14 =head1 SUBROUTINES
16 =over 4
18 =cut
20 package auto::warnings;
22 use strict;
23 use warnings;
26 use base qw(Parrot::Configure::Step);
28 use Parrot::Configure::Utils ();
29 use Parrot::BuildUtil;
31 sub _init {
32 my $self = shift;
33 my %data;
34 $data{description} = q{Detecting supported compiler warnings (-Wxxx)};
35 $data{result} = q{};
37 # potential addition? -fvisibility=hidden
38 # Please keep these sorted by flag name, such that "-Wno-foo" is
39 # sorted as "-Wfoo", so we can turn off/on as needed.
40 my @potential_warnings = qw(
41 -falign-functions=16
42 -fvisibility=hidden
43 -maccumulate-outgoing-args
45 -Wall
46 -Waggregate-return
47 -Wcast-align
48 -Wcast-qual
49 -Wchar-subscripts
50 -Wcomment
51 -Wdisabled-optimization
52 -Wendif-labels
53 -Wextra
54 -Wformat
55 -Wformat-extra-args
56 -Wformat-nonliteral
57 -Wformat-security
58 -Wformat-y2k
59 -Wimplicit
60 -Wimport
61 -Winit-self
62 -Winline
63 -Winvalid-pch
64 -Wlogical-op
65 -Wmissing-braces
66 -Wmissing-field-initializers
67 -Wno-missing-format-attribute
68 -Wmissing-include-dirs
69 -Wpacked
70 -Wparentheses
71 -Wpointer-arith
72 -Wreturn-type
73 -Wsequence-point
74 -Wno-shadow
75 -Wsign-compare
76 -Wstrict-aliasing
77 -Wstrict-aliasing=2
78 -Wswitch
79 -Wswitch-default
80 -Wtrigraphs
81 -Wundef
82 -Wunknown-pragmas
83 -Wno-unused
84 -Wvariadic-macros
85 -Wwrite-strings
86 -Wnot-a-real-warning
88 my @potential_warnings_no_cpp = qw(
89 -Wbad-function-cast
90 -Wc++-compat
91 -Wdeclaration-after-statement
92 -Wimplicit-function-declaration
93 -Wimplicit-int
94 -Wmain
95 -Wmissing-declarations
96 -Wmissing-prototypes
97 -Wnested-externs
98 -Wnonnull
99 -Wold-style-definition
100 -Wstrict-prototypes
103 my @cage_warnings = qw(
104 -std=c89
105 -Wconversion
106 -Werror-implicit-function-declaration
107 -Wformat=2
108 -Wlarger-than-4096
109 -Wlong-long
110 -Wmissing-format-attribute
111 -Wmissing-noreturn
112 -Wno-deprecated-declarations
113 -Wno-div-by-zero
114 -Wno-format-extra-args
115 -Wno-import
116 -Wno-multichar
117 -Wno-pointer-sign
118 -Wold-style-definition
119 -Wpadded
120 -Wredundant-decls
121 -Wswitch-enum
122 -Wsystem-headers
123 -Wunreachable-code
124 -Wunused-function
125 -Wunused-label
126 -Wunused-parameter
127 -Wunused-value
128 -Wunused-variable
131 my @nice_to_have_but_too_noisy_for_now = qw(
132 -pedantic
133 -Wint-to-pointer-cast
134 -Wshadow
135 -Wunused-macros
138 $data{potential_warnings} = \@potential_warnings;
139 $data{potential_warnings_no_cpp} = \@potential_warnings_no_cpp;
140 $data{cage_warnings} = \@cage_warnings;
142 return \%data;
145 sub runstep {
146 my ( $self, $conf ) = @_;
148 my $verbose = $conf->options->get('verbose');
149 print "\n" if $verbose;
150 if ( defined $conf->data->get('gccversion') ) {
152 # Dirty way of checking if compiling with c++
153 my $nocpp = index($conf->data->get('cc'), '++') < 0;
155 # add on some extra warnings if requested
156 $self->_add_cage_warnings($conf);
157 $self->_add_maintainer_warnings($conf);
159 # now try out our warnings
160 for my $maybe_warning (@{ $self->{potential_warnings} }) {
161 $self->try_warning( $conf, $maybe_warning, $verbose );
163 if ($nocpp) {
164 for my $maybe_warning (@{ $self->{potential_warnings_no_cpp} }) {
165 $self->try_warning( $conf, $maybe_warning, $verbose );
169 if ($nocpp) {
170 $self->set_result("set for gcc");
172 else {
173 $self->set_result("set for g++");
176 else {
177 print "Currently we only set warnings if using gcc as C compiler\n"
178 if $verbose;
179 $self->set_result("skipped");
181 return 1;
184 sub _add_cage_warnings {
185 my ($self, $conf) = @_;
186 push @{ $self->{potential_warnings} }, @{ $self->{cage_warnings} }
187 if $conf->options->get('cage');
190 sub _add_maintainer_warnings {
191 my ($self, $conf) = @_;
192 push @{ $self->{potential_warnings} }, '-Wlarger-than-4096'
193 if $conf->options->get('maintainer');
196 =item C<try_warning>
198 Try a given warning to see if it is supported by the compiler. The compiler
199 is determined by the C<cc> value of the C<Parrot::Configure> object passed
200 in as the first argument to the method (not counting C<$self>. The warning
201 to be checked is passed in as the second argument to the method.
203 Returns true if the warning flag is recognised by the compiler and undef
204 otherwise.
206 =cut
208 sub try_warning {
209 my ( $self, $conf, $warning, $verbose ) = @_;
211 my $output_file = 'test.cco';
213 $verbose and print "trying attribute '$warning'\n";
215 my $cc = $conf->option_or_data('cc');
216 $conf->cc_gen('config/auto/warnings/test_c.in');
218 my $ccflags = $conf->data->get('ccflags');
219 my $tryflags = "$ccflags $warning";
221 my $command_line = Parrot::Configure::Utils::_build_compile_command( $cc, $tryflags );
222 $verbose and print " ", $command_line, "\n";
224 # Don't use cc_build, because failure is expected.
225 my $exit_code = Parrot::Configure::Utils::_run_command(
226 $command_line, $output_file, $output_file
228 _set_warning($conf, $warning, $exit_code, $verbose);
230 return if $exit_code;
232 my $output = Parrot::BuildUtil::slurp_file($output_file);
233 return _set_ccflags($conf, $output, $tryflags, $verbose);
236 sub _set_warning {
237 my ($conf, $warning, $exit_code, $verbose) = @_;
238 $verbose and print " exit code: $exit_code\n";
239 $conf->data->set( $warning => !$exit_code || 0 );
242 sub _set_ccflags {
243 my ($conf, $output, $tryflags, $verbose) = @_;
244 $verbose and print " output: $output\n";
246 if ( $output !~ /error|warning|not supported/i ) {
247 $conf->data->set( ccflags => $tryflags );
248 $verbose and print " ccflags: ", $conf->data->get("ccflags"), "\n";
249 return 1;
251 else {
252 return 0;
256 =back
258 =head1 AUTHOR
260 Paul Cochrane <paultcochrane at gmail dot com>
262 =cut
266 # Local Variables:
267 # mode: cperl
268 # cperl-indent-level: 4
269 # fill-column: 100
270 # End:
271 # vim: expandtab shiftwidth=4: