File Coverage

blib/lib/ExtUtils/CChecker.pm
Criterion Covered Total %
statement 105 131 80.1
branch 29 52 55.7
condition 1 3 33.3
subroutine 20 23 86.9
pod 13 17 76.4
total 168 226 74.3


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2010-2015 -- leonerd@leonerd.org.uk
5              
6             package ExtUtils::CChecker;
7              
8 6     6   121433 use strict;
  6         15  
  6         275  
9 6     6   34 use warnings;
  6         9  
  6         328  
10              
11             our $VERSION = '0.10';
12              
13 6     6   45 use Carp;
  6         8  
  6         579  
14              
15 6     6   4570 use ExtUtils::CBuilder;
  6         577823  
  6         7828  
16              
17             =head1 NAME
18              
19             C - configure-time utilities for using C headers,
20             libraries, or OS features
21              
22             =head1 SYNOPSIS
23              
24             use Module::Build;
25             use ExtUtils::CChecker;
26              
27             my $cc = ExtUtils::CChecker->new;
28            
29             $cc->assert_compile_run(
30             diag => "no PF_MOONLASER",
31             source => <<'EOF' );
32             #include
33             #include
34             int main(int argc, char *argv[]) {
35             printf("PF_MOONLASER is %d\n", PF_MOONLASER);
36             return 0;
37             }
38             EOF
39              
40             Module::Build->new(
41             ...
42             )->create_build_script;
43              
44             =head1 DESCRIPTION
45              
46             Often Perl modules are written to wrap functionality found in existing C
47             headers, libraries, or to use OS-specific features. It is useful in the
48             F or F file to check for the existance of these
49             requirements before attempting to actually build the module.
50              
51             Objects in this class provide an extension around L to
52             simplify the creation of a F<.c> file, compiling, linking and running it, to
53             test if a certain feature is present.
54              
55             It may also be necessary to search for the correct library to link against,
56             or for the right include directories to find header files in. This class also
57             provides assistance here.
58              
59             =cut
60              
61             =head1 CONSTRUCTOR
62              
63             =cut
64              
65             =head2 $cc = ExtUtils::CChecker->new( %args )
66              
67             Returns a new instance of a C object. Takes the following
68             named parameters:
69              
70             =over 8
71              
72             =item defines_to => PATH
73              
74             If given, defined symbols will be written to a C preprocessor F<.h> file of
75             the given name, instead of by adding extra C<-DI> arguments to the
76             compiler flags.
77              
78             =item quiet => BOOL
79              
80             If given, sets the C option to the underlying C
81             instance. If absent, defaults to enabled. To disable quietness, i.e. to print
82             more verbosely, pass a defined-but-false value, such as C<0>.
83              
84             =item config => HASH
85              
86             If given, passed through as the configuration of the underlying
87             C instance.
88              
89             =back
90              
91             =cut
92              
93             sub new
94             {
95 5     5 1 69 my $class = shift;
96 5         17 my %args = @_;
97              
98 5         13 my $quiet = 1;
99 5 50 33     30 $quiet = 0 if defined $args{quiet} and !$args{quiet};
100              
101 5         93 my $cb = ExtUtils::CBuilder->new(
102             quiet => $quiet,
103             config => $args{config},
104             );
105              
106 5         261316 return bless {
107             cb => $cb,
108             seq => 0,
109              
110             defines_to => $args{defines_to},
111              
112             include_dirs => [],
113             extra_compiler_flags => [],
114             extra_linker_flags => [],
115             }, $class;
116             }
117              
118             =head1 METHODS
119              
120             =cut
121              
122             =head2 $dirs = $cc->include_dirs
123              
124             Returns the currently-configured include directories in an ARRAY reference.
125              
126             =cut
127              
128             sub include_dirs
129             {
130 5     5 1 13 my $self = shift;
131             # clone it just so caller can't modify ours
132 5         6 return [ @{ $self->{include_dirs} } ];
  5         32  
133             }
134              
135             =head2 $flags = $cc->extra_compiler_flags
136              
137             Returns the currently-configured extra compiler flags in an ARRAY reference.
138              
139             =cut
140              
141             sub extra_compiler_flags
142             {
143 7     7 1 28 my $self = shift;
144             # clone it just so caller can't modify ours
145 7         15 return [ @{ $self->{extra_compiler_flags} } ];
  7         52  
146             }
147              
148             =head2 $flags = $cc->extra_linker_flags
149              
150             Returns the currently-configured extra linker flags in an ARRAY reference.
151              
152             =cut
153              
154             sub extra_linker_flags
155             {
156 5     5 1 10 my $self = shift;
157             # clone it just so caller can't modify ours
158 5         6 return [ @{ $self->{extra_linker_flags} } ];
  5         19  
159             }
160              
161             =head2 $cc->push_include_dirs( @dirs )
162              
163             Adds more include directories
164              
165             =cut
166              
167             sub push_include_dirs
168             {
169 2     2 1 1602 my $self = shift;
170 2         5 push @{ $self->{include_dirs} }, @_;
  2         12  
171             }
172              
173             =head2 $cc->push_extra_compiler_flags( @flags )
174              
175             Adds more compiler flags
176              
177             =cut
178              
179             sub push_extra_compiler_flags
180             {
181 3     3 1 9 my $self = shift;
182 3         7 push @{ $self->{extra_compiler_flags} }, @_;
  3         15  
183             }
184              
185             =head2 $cc->push_extra_linker_flags( @flags )
186              
187             Adds more linker flags
188              
189             =cut
190              
191             sub push_extra_linker_flags
192             {
193 2     2 1 6 my $self = shift;
194 2         3 push @{ $self->{extra_linker_flags} }, @_;
  2         8  
195             }
196              
197             sub cbuilder
198             {
199 12     12 0 22 my $self = shift;
200 12         226 return $self->{cb};
201             }
202              
203             sub compile
204             {
205 7     7 0 11 my $self = shift;
206 7         19 my %args = @_;
207              
208 7 100       37 $args{include_dirs} = [ map { defined $_ ? @$_ : () } $self->{include_dirs}, $args{include_dirs} ];
  14         53  
209 7 100       25 $args{extra_compiler_flags} = [ map { defined $_ ? @$_ : () } $self->{extra_compiler_flags}, $args{extra_compiler_flags} ];
  14         34  
210              
211 7         28 $self->cbuilder->compile( %args );
212             }
213              
214             sub link_executable
215             {
216 5     5 0 13 my $self = shift;
217 5         17 my %args = @_;
218              
219 5 100       41 $args{extra_linker_flags} = [ map { defined $_ ? @$_ : () } $self->{extra_linker_flags}, $args{extra_linker_flags} ];
  10         126  
220              
221 5         49 $self->cbuilder->link_executable( %args );
222             }
223              
224             sub fail
225             {
226 1     1 0 5 my $self = shift;
227 1         5 my ( $diag ) = @_;
228              
229 1 50       14 my $message = defined $diag ? "OS unsupported - $diag\n" : "OS unsupported\n";
230 1         19 die $message;
231             }
232              
233             sub define
234             {
235 2     2 1 14 my $self = shift;
236 2         19 my ( $symbol ) = @_;
237              
238 2 100       25 if( $self->{defines_to} ) {
239 1 50       9 unless( $self->{defines_fh} ) {
240 1 50       132 open $self->{defines_fh}, ">", $self->{defines_to} or croak "Cannot open $self->{defines_to} for writing - $!";
241 1         36 $self->{defines_fh}->autoflush(1);
242             }
243              
244 1         136 $self->{defines_fh}->print( "#define $symbol /**/\n" );
245             }
246             else {
247 1         16 $self->push_extra_compiler_flags( "-D$symbol" );
248             }
249             }
250              
251             =head2 $success = $cc->try_compile_run( %args )
252              
253             =head2 $success = $cc->try_compile_run( $source )
254              
255             Try to compile, link, and execute a C program whose source is given. Returns
256             true if the program compiled and linked, and exited successfully. Returns
257             false if any of these steps fail.
258              
259             Takes the following named arguments. If a single argument is given, that is
260             taken as the source string.
261              
262             =over 8
263              
264             =item * source => STRING
265              
266             The source code of the C program to try compiling, building, and running.
267              
268             =item * extra_compiler_flags => ARRAY
269              
270             Optional. If specified, pass extra flags to the compiler.
271              
272             =item * extra_linker_flags => ARRAY
273              
274             Optional. If specified, pass extra flags to the linker.
275              
276             =item * define => STRING
277              
278             Optional. If specified, then the named symbol will be defined if the program
279             ran successfully. This will either on the C compiler commandline (by passing
280             an option C<-DI>), or in the C file.
281              
282             =back
283              
284             =cut
285              
286             sub try_compile_run
287             {
288 7     7 1 1914 my $self = shift;
289 7 100       63 my %args = ( @_ == 1 ) ? ( source => $_[0] ) : @_;
290              
291 7 50       44 defined $args{source} or croak "Expected 'source'";
292              
293 7         40 my $seq = $self->{seq}++;
294              
295 7         51 my $test_source = "test-$$-$seq.c";
296              
297 7 50       877 open( my $test_source_fh, "> $test_source" ) or die "Cannot write $test_source - $!";
298              
299 7         100 print $test_source_fh $args{source};
300              
301 7         377 close $test_source_fh;
302              
303 7         37 my %compile_args = (
304             source => $test_source,
305             );
306              
307 7 50       29 $compile_args{include_dirs} = $args{include_dirs} if exists $args{include_dirs};
308 7 50       24 $compile_args{extra_compiler_flags} = $args{extra_compiler_flags} if exists $args{extra_compiler_flags};
309              
310 7         18 my $test_obj = eval { $self->compile( %compile_args ) };
  7         46  
311              
312 7         221093 unlink $test_source;
313              
314 7 100       82 if( not defined $test_obj ) {
315 2         91 return 0;
316             }
317              
318 5         42 my %link_args = (
319             objects => $test_obj,
320             );
321              
322 5 50       34 $link_args{extra_linker_flags} = $args{extra_linker_flags} if exists $args{extra_linker_flags};
323              
324 5         20 my $test_exe = eval { $self->link_executable( %link_args ) };
  5         92  
325              
326 5         166947 unlink $test_obj;
327              
328 5 50       67 if( not defined $test_exe ) {
329 0         0 return 0;
330             }
331              
332 5 50       17406 if( system( "./$test_exe" ) != 0 ) {
333 0         0 unlink $test_exe;
334 0         0 return 0;
335             }
336              
337 5         675 unlink $test_exe;
338              
339 5 100       384 $self->define( $args{define} ) if defined $args{define};
340              
341 5         499 return 1;
342             }
343              
344             =head2 $cc->assert_compile_run( %args )
345              
346             Calls C. If it fails, die with an C message.
347             Useful to call from F or F.
348              
349             Takes one extra optional argument:
350              
351             =over 8
352              
353             =item * diag => STRING
354              
355             If present, this string will be appended to the failure message if one is
356             generated. It may provide more useful information to the user on why the OS is
357             unsupported.
358              
359             =back
360              
361             =cut
362              
363             sub assert_compile_run
364             {
365 2     2 1 1164 my $self = shift;
366 2         13 my %args = @_;
367              
368 2         7 my $diag = delete $args{diag};
369 2 100       13 $self->try_compile_run( %args ) or $self->fail( $diag );
370             }
371              
372             =head2 $success = $cc->try_find_include_dirs_for( %args )
373              
374             Try to compile, link and execute the given source, using extra include
375             directories.
376              
377             When a usable combination is found, the directories required are stored in the
378             object for use in further compile operations, or returned by C.
379             The method then returns true.
380              
381             If no a usable combination is found, it returns false.
382              
383             Takes the following arguments:
384              
385             =over 8
386              
387             =item * source => STRING
388              
389             Source code to compile
390              
391             =item * dirs => ARRAY of ARRAYs
392              
393             Gives a list of sets of dirs. Each set of dirs should be strings in its own
394             array reference.
395              
396             =item * define => STRING
397              
398             Optional. If specified, then the named symbol will be defined if the program
399             ran successfully. This will either on the C compiler commandline (by passing
400             an option C<-DI>), or in the C file.
401              
402             =back
403              
404             =cut
405              
406             sub try_find_include_dirs_for
407             {
408 0     0 1 0 my $self = shift;
409 0         0 my %args = @_;
410              
411 0 0       0 ref( my $dirs = $args{dirs} ) eq "ARRAY" or croak "Expected 'dirs' as ARRAY ref";
412              
413 0         0 foreach my $d ( @$dirs ) {
414 0 0       0 ref $d eq "ARRAY" or croak "Expected 'dirs' element as ARRAY ref";
415              
416 0 0       0 $self->try_compile_run( %args, include_dirs => $d ) or next;
417              
418 0         0 $self->push_include_dirs( @$d );
419              
420 0         0 return 1;
421             }
422              
423 0         0 return 0;
424             }
425              
426             =head2 $success = $cc->try_find_libs_for( %args )
427              
428             Try to compile, link and execute the given source, when linked against a
429             given set of extra libraries.
430              
431             When a usable combination is found, the libraries required are stored in the
432             object for use in further link operations, or returned by
433             C. The method then returns true.
434              
435             If no usable combination is found, it returns false.
436              
437             Takes the following arguments:
438              
439             =over 8
440              
441             =item * source => STRING
442              
443             Source code to compile
444              
445             =item * libs => ARRAY of STRINGs
446              
447             Gives a list of sets of libraries. Each set of libraries should be
448             space-separated.
449              
450             =item * define => STRING
451              
452             Optional. If specified, then the named symbol will be defined if the program
453             ran successfully. This will either on the C compiler commandline (by passing
454             an option C<-DI>), or in the C file.
455              
456             =back
457              
458             =cut
459              
460             sub try_find_libs_for
461             {
462 0     0 1 0 my $self = shift;
463 0         0 my %args = @_;
464              
465 0 0       0 ref( my $libs = $args{libs} ) eq "ARRAY" or croak "Expected 'libs' as ARRAY ref";
466              
467 0         0 foreach my $l ( @$libs ) {
468 0         0 my @extra_linker_flags = map { "-l$_" } split m/\s+/, $l;
  0         0  
469              
470 0 0       0 $self->try_compile_run( %args, extra_linker_flags => \@extra_linker_flags ) or next;
471              
472 0         0 $self->push_extra_linker_flags( @extra_linker_flags );
473              
474 0         0 return 1;
475             }
476              
477 0         0 return 0;
478             }
479              
480             =head2 $cc->find_include_dirs_for( %args )
481              
482             =head2 $cc->find_libs_for( %args )
483              
484             Calls C or C respectively. If it
485             fails, die with an C message.
486              
487             Each method takes one extra optional argument:
488              
489             =over 8
490              
491             =item * diag => STRING
492              
493             If present, this string will be appended to the failure message if one is
494             generated. It may provide more useful information to the user on why the OS is
495             unsupported.
496              
497             =back
498              
499             =cut
500              
501             foreach ( qw( find_libs_for find_include_dirs_for ) ) {
502             my $trymethod = "try_$_";
503              
504             my $code = sub {
505 0     0   0 my $self = shift;
506 0         0 my %args = @_;
507              
508 0         0 my $diag = delete $args{diag};
509 0 0       0 $self->$trymethod( %args ) or $self->fail( $diag );
510             };
511              
512 6     6   65 no strict 'refs';
  6         11  
  6         1298  
513             *$_ = $code;
514             }
515              
516             =head2 $mb = $cc->new_module_build( %args )
517              
518             Construct and return a new L object, preconfigured with the
519             C, C and C options
520             that have been configured on this object, by the above methods.
521              
522             This is provided as a simple shortcut for the common use case, that a
523             F file is using the C object to detect the
524             required arguments to pass.
525              
526             =cut
527              
528             sub new_module_build
529             {
530 3     3 1 833 my $self = shift;
531 3         9 my %args = @_;
532              
533 3         885 require Module::Build;
534              
535 3         67812 foreach my $key (qw( include_dirs extra_compiler_flags extra_linker_flags )) {
536 9 100       15 if( exists $args{$key} ) {
537 3         3 $args{$key} = [ @{ $self->$key }, @{ $args{$key} } ];
  3         6  
  3         8  
538             }
539             else {
540 6         16 $args{$key} = $self->$key;
541             }
542             }
543              
544 3         15 return Module::Build->new( %args );
545             }
546              
547             =head1 EXAMPLES
548              
549             =head2 Socket Libraries
550              
551             Some operating systems provide the BSD sockets API in their primary F.
552             Others keep it in a separate library which should be linked against. The
553             following example demonstrates how this would be handled.
554              
555             use ExtUtils::CChecker;
556              
557             my $cc = ExtUtils::CChecker->new;
558              
559             $cc->find_libs_for(
560             diag => "no socket()",
561             libs => [ "", "socket nsl" ],
562             source => q[
563             #include
564             int main(int argc, char *argv) {
565             int fd = socket(PF_INET, SOCK_STREAM, 0);
566             if(fd < 0)
567             return 1;
568             return 0;
569             }
570             ] );
571              
572             $cc->new_module_build(
573             module_name => "Your::Name::Here",
574             requires => {
575             'IO::Socket' => 0,
576             },
577             ...
578             )->create_build_script;
579              
580             By using the C method, the detected C
581             value has been automatically passed into the new C object.
582              
583             =head2 Testing For Optional Features
584              
585             Sometimes a function or ability may be optionally provided by the OS, or you
586             may wish your module to be useable when only partial support is provided,
587             without requiring it all to be present. In these cases it is traditional to
588             detect the presence of this optional feature in the F script, and
589             define a symbol to declare this fact if it is found. The XS code can then use
590             this symbol to select between differing implementations. For example, the
591             F:
592              
593             use ExtUtils::CChecker;
594              
595             my $cc = ExtUtils::CChecker->new;
596              
597             $cc->try_compile_run(
598             define => "HAVE_MANGO",
599             source => <<'EOF' );
600             #include
601             #include
602             int main(void) {
603             if(mango() != 0)
604             exit(1);
605             exit(0);
606             }
607             EOF
608              
609             $cc->new_module_build(
610             ...
611             )->create_build_script;
612              
613             If the C code compiles and runs successfully, and exits with a true status,
614             the symbol C will be defined on the compiler commandline. This
615             allows the XS code to detect it, for example
616              
617             int
618             mango()
619             CODE:
620             #ifdef HAVE_MANGO
621             RETVAL = mango();
622             #else
623             croak("mango() not implemented");
624             #endif
625             OUTPUT:
626             RETVAL
627              
628             This module will then still compile even if the operating system lacks this
629             particular function. Trying to invoke the function at runtime will simply
630             throw an exception.
631              
632             =head2 Linux Kernel Headers
633              
634             Operating systems built on top of the F kernel often share a looser
635             association with their kernel version than most other operating systems. It
636             may be the case that the running kernel is newer, containing more features,
637             than the distribution's F headers would believe. In such circumstances
638             it can be difficult to make use of new socket options, Cs, etc..
639             without having the constants that define them and their parameter structures,
640             because the relevant header files are not visible to the compiler. In this
641             case, there may be little choice but to pull in some of the kernel header
642             files, which will provide the required constants and structures.
643              
644             The Linux kernel headers can be found using the F directory. A
645             fragment in F like the following, may be appropriate.
646              
647             chomp( my $uname_r = `uname -r` );
648              
649             my @dirs = (
650             [],
651             [ "/lib/modules/$uname_r/source/include" ],
652             );
653              
654             $cc->find_include_dirs_for(
655             diag => "no PF_MOONLASER",
656             dirs => \@dirs,
657             source => <<'EOF' );
658             #include
659             #include
660             int family = PF_MOONLASER;
661             struct laserwl lwl;
662             int main(int argc, char *argv[]) {
663             return 0;
664             }
665             EOF
666              
667             This fragment will first try to compile the program as it stands, hoping that
668             the F headers will be sufficient. If it fails, it will then try
669             including the kernel headers, which should make the constant and structure
670             visible, allowing the program to compile.
671              
672             =head2 Creating an C<#include> file
673              
674             Sometimes, rather than setting defined symbols on the compiler commandline, it
675             is preferrable to have them written to a C preprocessor include (F<.h>) file.
676             This may be beneficial for cross-platform portability concerns, as not all C
677             compilers may take extra C<-D> arguments on the command line, or platforms may
678             have small length restrictions on the length of a command line.
679              
680             use ExtUtils::CChecker;
681              
682             my $cc = ExtUtils::CChecker->new(
683             defines_to => "mymodule-config.h",
684             );
685              
686             $cc->try_compile_run(
687             define => "HAVE_MANGO",
688             source => <<'EOF' );
689             #include
690             #include
691             #include "mymodule-config.h"
692             int main(void) {
693             if(mango() != 0)
694             exit(1);
695             exit(0);
696             }
697             EOF
698              
699             Because the F file is written and flushed after every
700             define operation, it will still be useable in later C fragments to test for
701             features detected in earlier ones.
702              
703             It is suggested not to name the file simply F, as the core of Perl
704             itself has a file of that name containing its own compile-time detected
705             configuration. A confusion between the two could lead to surprising results.
706              
707             =head1 AUTHOR
708              
709             Paul Evans
710              
711             =cut
712              
713             0x55AA;