File Coverage

blib/lib/Devel/CheckCompiler.pm
Criterion Covered Total %
statement 52 54 96.3
branch 17 26 65.3
condition 1 3 33.3
subroutine 11 11 100.0
pod 3 3 100.0
total 84 97 86.6


line stmt bran cond sub pod time code
1             package Devel::CheckCompiler;
2 5     5   160867 use strict;
  5         10  
  5         171  
3 5     5   22 use warnings;
  5         9  
  5         131  
4 5     5   97 use 5.008001;
  5         15  
  5         261  
5             our $VERSION = '0.06';
6 5     5   1103 use parent qw/Exporter/;
  5         717  
  5         25  
7              
8             our @EXPORT = qw/check_c99 check_c99_or_exit check_compile/;
9 5     5   346 use Config;
  5         6  
  5         170  
10 5     5   2453 use ExtUtils::CBuilder;
  5         320499  
  5         1863  
11              
12             my $C99_SOURCE = <<'C99';
13             // include a C99 header
14             #include
15             inline // a C99 keyword with C99 style comments
16             int test_c99() {
17             int i = 0;
18             i++;
19             int j = i - 1; // another C99 feature: declaration after statement
20             // another C99 feature: for loop variable declarations
21             for (int k = 0; k < 3; i++) {
22             }
23             return j;
24             }
25             C99
26              
27             sub check_c99 {
28 4     4 1 4177 check_compile($C99_SOURCE);
29             }
30              
31             sub check_c99_or_exit {
32 4 100   4 1 2243 check_compile($C99_SOURCE) or do {
33 2         164 warn "Your system is not support C99(OS unsupported)\n";
34 2         13 exit 0;
35             };
36             }
37              
38             sub _is_gcc {
39 7 50   7   2722 return 0 if $Config{gccversion} eq '';
40             # For clang on MacOSX and *BSD distributions
41 7 50       10887 return 0 if $Config{gccversion} =~ m/clang/i;
42             # For Intel C and C++ compiler
43 7 50       45 return 0 if $Config{gccversion} =~ m/intel/i;
44              
45 7         25 return 1;
46             }
47              
48             sub _gcc_version {
49 7 50   7   64 if ($Config{gccversion} =~ m/^(\d+)\.(\d+)\.(\d+)/) {
50             return {
51 7         49 major => $1,
52             minor => $2,
53             patch => $3,
54             };
55             }
56              
57 0         0 return;
58             }
59              
60             sub check_compile {
61 11     11 1 5589 my ($src, %opt) = @_;
62              
63 11         52 my $cbuilder = ExtUtils::CBuilder->new(quiet => 1);
64 11 100       69 return 0 unless $cbuilder->have_compiler;
65              
66 7         73 require File::Temp;
67              
68 7         43 my $tmpfile = File::Temp->new(SUFFIX => '.c');
69 7         2439 $tmpfile->print($src);
70 7         119 $tmpfile->close();
71              
72 7         49135 my $compile_flags;
73 7 50       29 if (_is_gcc()) {
74 7         23 my $gcc_version = _gcc_version();
75             # '-std=gnu11' is default from GCC 5
76 7 50 33     63 if (defined $gcc_version && $gcc_version->{major} < 5) {
77 7         31 $compile_flags = ['-std=c99'];
78             }
79             }
80              
81 7         12 my $objname = eval {
82 7         59 $cbuilder->compile(source => $tmpfile->filename, extra_compiler_flags => $compile_flags);
83             };
84 7 100       96 if ($objname) {
85 6         8 my $ret = 1;
86 6 100       20 if ($opt{executable}) {
87 2         3 my $execfile = eval {
88 2         5 $cbuilder->link_executable(objects => $objname,
89             extra_linker_flags => $opt{extra_linker_flags});
90             };
91              
92 2 50       17 if ($execfile) {
93 2 50       71 unlink $execfile or warn "Cannot unlink $execfile (ignored): $!";
94             } else {
95 0         0 $ret = 0;
96             }
97             }
98 6 50       329 unlink $objname or warn "Cannot unlink $objname (ignored): $!";
99 6         40 return $ret;
100             } else {
101 1         7 return 0;
102             }
103             }
104              
105             1;
106             __END__