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