File Coverage

blib/lib/Test/CChecker.pm
Criterion Covered Total %
statement 67 91 73.6
branch 13 32 40.6
condition 7 19 36.8
subroutine 16 20 80.0
pod 7 7 100.0
total 110 169 65.0


line stmt bran cond sub pod time code
1             package Test::CChecker;
2              
3 3     3   44180 use strict;
  3         9  
  3         87  
4 3     3   18 use warnings;
  3         7  
  3         107  
5 3     3   17 use base qw( Test::Builder::Module );
  3         6  
  3         338  
6 3     3   2519 use ExtUtils::CChecker;
  3         298030  
  3         110  
7 3     3   2590 use Capture::Tiny qw( capture_merged );
  3         13001  
  3         187  
8 3     3   19 use Text::ParseWords qw( shellwords );
  3         8  
  3         151  
9 3     3   3535 use Env qw( @LD_LIBRARY_PATH );
  3         8864  
  3         20  
10 3     3   441 use File::Spec;
  3         6  
  3         68  
11 3     3   2193 use FindBin ();
  3         3134  
  3         57  
12 3     3   35 use File::Temp ();
  3         6  
  3         58  
13 3     3   15 use Scalar::Util qw( blessed );
  3         7  
  3         2794  
14              
15             our @EXPORT = qw(
16             cc
17             compile_ok
18             compile_run_ok
19             compile_with_alien
20             compile_output_to_nowhere
21             compile_output_to_diag
22             compile_output_to_note
23             );
24              
25             # ABSTRACT: Test-time utilities for checking C headers, libraries, or OS features
26             our $VERSION = '0.07'; # VERSION
27              
28              
29             do {
30             my $cc;
31             sub cc ()
32             {
33 4   66 4 1 44 $cc ||= ExtUtils::CChecker->new( quiet => 0 );
34             }
35             };
36              
37              
38             my $output = '';
39              
40             sub compile_run_ok ($;$)
41             {
42 2     2 1 755 my($args, $message) = @_;
43 2   50     9 $message ||= "compile ok";
44 2         12 my $cc = cc();
45 2         46094 my $tb = __PACKAGE__->builder;
46            
47 2         29 my $ok;
48 2 100   2   148 my $out = capture_merged { $ok = $cc->try_compile_run(ref($args) eq 'HASH' ? %$args : $args) };
  2         3344  
49            
50 2         1167135 $tb->ok($ok, $message);
51 2 50 33     2374 if(!$ok || $output eq 'diag')
    50          
52             {
53 0         0 $tb->diag($out);
54             }
55             elsif($output eq 'note')
56             {
57 0         0 $tb->note($out);
58             }
59            
60 2         35 $ok;
61             }
62              
63              
64             sub compile_ok ($;$)
65             {
66 2     2 1 519 my($args, $message) = @_;
67 2   50     9 $message ||= "compile ok";
68 2 100       13 $args = ref $args ? $args : { source => $args };
69 2         10 my $cc = cc();
70 2         44537 my $tb = __PACKAGE__->builder;
71              
72 2         41 my($fh, $filename) = File::Temp::tempfile("ccheckerXXXXX", SUFFIX => '.c');
73 2         1254 print $fh $args->{source};
74 2         244 close $fh;
75 2         6 my $obj;
76 2         11 my %compile = ( source => $filename );
77 2 100       17 $compile{extra_compiler_flags} = $args->{extra_compiler_flags} if defined $args->{extra_compiler_flags};
78 2         6 my $err;
79 2     2   184 my $out = capture_merged { $obj = eval { $cc->compile(%compile) }; $err = $@ };
  2         2977  
  2         17  
  2         76314  
80            
81 2         3579 my $ok = !!$obj;
82 2 50       267 unlink $filename if $ok;
83 2 50 33     330 unlink $obj if defined $obj && -f $obj;
84 2         50 $tb->ok($ok, $message);
85 2 50 33     1589 if(!$ok || $output eq 'diag')
    50          
86             {
87 0         0 $tb->diag($out);
88             }
89             elsif($output eq 'note')
90             {
91 0         0 $tb->note($out);
92             }
93            
94 2 50       16 $tb->diag($err) if $err;
95            
96 2         45 $ok;
97             }
98              
99              
100             sub compile_with_alien ($)
101             {
102 0     0 1   my $alien = shift;
103 0 0         $alien = $alien->new unless ref $alien;
104              
105 0 0         if($alien->can('dist_dir'))
106             {
107 0           my $dir = eval { File::Spec->catdir($alien->dist_dir, 'lib') };
  0            
108 0 0 0       unshift @LD_LIBRARY_PATH, $dir if defined $dir && -d $dir;
109             }
110            
111 0           my $tdir = File::Spec->catdir($FindBin::Bin, File::Spec->updir, '_test');
112 0 0         if(-d $tdir)
113             {
114             cc->push_extra_compiler_flags(map {
115 0 0         /^-I(.*)$/ ? ("-I".File::Spec->catdir($tdir, $1), $_) : ($_)
  0            
116             } shellwords $alien->cflags);
117             cc->push_extra_linker_flags(map {
118 0 0         /^-L(.*)$/ ? ( map { push @LD_LIBRARY_PATH, $_; "-L$_" } File::Spec->catdir($tdir, $1), $_) : ($_)
  0            
  0            
  0            
119             } shellwords $alien->libs);
120             }
121             else
122             {
123 0           cc->push_extra_compiler_flags(shellwords $alien->cflags);
124 0           cc->push_extra_linker_flags(shellwords $alien->libs);
125             }
126              
127 0           return;
128             }
129              
130              
131             sub compile_output_to_nowhere ()
132             {
133 0     0 1   $output = '';
134             }
135              
136              
137             sub compile_output_to_diag ()
138             {
139 0     0 1   $output = 'diag';
140             }
141              
142              
143             sub compile_output_to_note ()
144             {
145 0     0 1   $output = 'note';
146             }
147              
148             1;
149              
150             __END__