File Coverage

blib/lib/ExtUtils/LibBuilder.pm
Criterion Covered Total %
statement 45 65 69.2
branch 12 34 35.2
condition 2 9 22.2
subroutine 8 10 80.0
pod 1 1 100.0
total 68 119 57.1


line stmt bran cond sub pod time code
1             package ExtUtils::LibBuilder;
2              
3 2     2   46094 use warnings;
  2         5  
  2         60  
4 2     2   10 use strict;
  2         4  
  2         86  
5              
6             our $VERSION = '0.07';
7             our $DEBUG = 0;
8              
9 2     2   8 use base 'ExtUtils::CBuilder';
  2         7  
  2         1759  
10              
11 2     2   237328 use File::Spec;
  2         5  
  2         43  
12 2     2   8 use File::Temp qw/tempdir/;
  2         4  
  2         1606  
13              
14             =head1 NAME
15              
16             ExtUtils::LibBuilder - A tool to build C libraries.
17              
18             =head1 SYNOPSIS
19              
20             use ExtUtils::LibBuilder;
21             my $libbuilder = ExtUtils::LibBuilder->new( %options );
22              
23             =head1 METHODS
24              
25             Supports all the method from ExtUtils::CBuilder. The following three
26             methods were adapted to be used in standalone C libraries.
27              
28             =head2 new
29              
30             This method creates a new ExtUtils::LibBuilder object. While it
31             supports all C methods some might work slightly
32             differently (namely the two bellow).
33              
34             You can supply to the constructor any option recognized by
35             C constructor. None of them will be used by
36             C.
37              
38             =head2 link
39              
40             $libbuilder -> link( objects => [ "foo.o", "bar.o" ],
41             module_name => "foobar",
42             lib_file => "libfoobar$libbuilder->{libext}");
43              
44             Options to the link method are the same as the C
45             counterpart. Note that the result is a standalone C Library and not a
46             bundle to be loaded by Perl.
47              
48             Also, note that you can use the C key to retrieve from the
49             object the common library extension on the running system (including
50             the dot).
51              
52             =head2 link_executable
53              
54             $libbuilder->link_executable( objects => ["main.o"],
55             extra_linker_flags => "-L. -lfoobar",
56             exe_file => "foobarcmd$libbuilder->{exeext}");
57              
58             The C needs, as C options, the
59             name of the library and the search path. Future versions might include
60             better handling on the library files.
61              
62             Also, note that you can use the C key to retrieve from the
63             object the common executable extension on the running system
64             (including the dot).
65              
66             =cut
67              
68             sub new {
69 1     1 1 15 my $class = shift;
70 1         3 my %options = @_;
71              
72 1         20 my $self = bless ExtUtils::CBuilder->new(%options) => $class;
73             # $self->{quiet} = 1;
74              
75 1 50       38827 $self->{libext} = $^O eq "darwin" ? ".dylib" : ( $^O =~ /win/i ? ".dll" : ".so");
    50          
76 1 50       7 $self->{exeext} = $^O =~ /win32/i ? ".exe" : "";
77              
78 1 50       5 $DEBUG && print STDERR "\nTesting Linux\n\n";
79 1 50 33     16 return $self if $^O !~ /darwin|win32/i && $self->_try;
80              
81 0 0       0 $DEBUG && print STDERR "\nTesting Darwin\n\n";
82 0         0 $self->{config}{lddlflags} =~ s/-bundle/-dynamiclib/;
83 0 0 0     0 return $self if $^O !~ /win32/i && $self->_try;
84              
85 0 0       0 $DEBUG && print STDERR "\nTesting Win32\n\n";
86             *link = sub {
87 0     0   0 my ($self, %options) = @_;
88 0         0 my $LD = $self->{config}{ld};
89 0 0       0 $options{objects} = [$options{objects}] unless ref $options{objects};
90             system($LD, "-shared", "-o",
91             $options{lib_file},
92 0         0 @{$options{objects}});
  0         0  
93 0         0 };
94             *link_executable = sub {
95 0     0   0 my ($self, %options) = @_;
96 0         0 my $LD = $self->{config}{ld};
97 0         0 my @CFLAGS = split /\s+/, $options{extra_linker_flags};
98 0 0       0 $options{objects} = [$options{objects}] unless ref $options{objects};
99             system($LD, "-o",
100             $options{exe_file},
101             @CFLAGS,
102 0         0 @{$options{objects}});
  0         0  
103 0         0 };
104 0 0       0 return $self if $self->_try;
105              
106 0 0       0 $DEBUG && print STDERR "\nNothing...\n\n";
107 0         0 return undef;
108             }
109              
110             sub _try {
111 1     1   2 my ($self) = @_;
112 1         11 my $tmp = tempdir CLEANUP => 1;
113 1         6421 _write_files($tmp);
114              
115 1         2 my @csources = map { File::Spec->catfile($tmp, $_) } qw'library.c test.c';
  2         19  
116 1         4 my @cobjects = map { $self->compile( source => $_) } @csources;
  2         51065  
117              
118 1         58151 my $libfile = File::Spec->catfile($tmp => "libfoo$self->{libext}");
119 1         21 my $exefile = File::Spec->catfile($tmp => "foo$self->{exeext}");
120              
121 1         32 $self->link( objects => [$cobjects[0]],
122             module_name => "foo",
123             lib_file => $libfile );
124              
125 1 50       45441 return 0 unless -f $libfile;
126              
127 1         57 $self->link_executable( exe_file => $exefile,
128             extra_linker_flags => "-L$tmp -lfoo",
129             objects => [$cobjects[1]]);
130              
131 1 50 33     46879 return 0 unless -f $exefile && -x _;
132 1         39 return 1;
133             }
134              
135             =head1 AUTHOR
136              
137             Alberto Simoes, C<< >>
138              
139             =head1 BUGS
140              
141             Please report any bugs or feature requests to
142             C, or through the web
143             interface at
144             L.
145             I will be notified, and then you'll automatically be notified of
146             progress on your bug as I make changes.
147              
148              
149              
150              
151             =head1 SUPPORT
152              
153             You can find documentation for this module with the perldoc command.
154              
155             perldoc ExtUtils::LibBuilder
156              
157              
158             You can also look for information at:
159              
160             =over 4
161              
162             =item * RT: CPAN's request tracker
163              
164             L
165              
166             =item * AnnoCPAN: Annotated CPAN documentation
167              
168             L
169              
170             =item * CPAN Ratings
171              
172             L
173              
174             =item * Search CPAN
175              
176             L
177              
178             =back
179              
180             =head1 LICENSE AND COPYRIGHT
181              
182             Copyright 2010 Alberto Simoes.
183              
184             This program is free software; you can redistribute it and/or modify it
185             under the terms of either: the GNU General Public License as published
186             by the Free Software Foundation; or the Artistic License.
187              
188             See http://dev.perl.org/licenses/ for more information.
189              
190              
191             =cut
192              
193              
194             sub _write_files {
195 1     1   3 my $outpath = shift;
196 1         3 my $fh;
197 1         9 seek DATA, 0, 0;
198 1         38 while() {
199 226 100       819 if (m!^==\[(.*?)\]==!) {
    100          
200 2         7 my $fname = $1;
201 2         23 $fname = File::Spec->catfile($outpath, $fname);
202 2 50       189 open $fh, ">$fname" or die "Can't create temporary file $fname\n";
203             } elsif ($fh) {
204 12         70 print $fh $_;
205             }
206             }
207             }
208              
209             1; # End of ExtUtils::LibBuilder
210              
211              
212             __DATA__