File Coverage

blib/lib/Clownfish/CFC/Perl/Build/Charmonic.pm
Criterion Covered Total %
statement 21 81 25.9
branch 0 34 0.0
condition 0 11 0.0
subroutine 7 12 58.3
pod 0 4 0.0
total 28 142 19.7


line stmt bran cond sub pod time code
1             # Licensed to the Apache Software Foundation (ASF) under one or more
2             # contributor license agreements. See the NOTICE file distributed with
3             # this work for additional information regarding copyright ownership.
4             # The ASF licenses this file to You under the Apache License, Version 2.0
5             # (the "License"); you may not use this file except in compliance with
6             # the License. You may obtain a copy of the License at
7             #
8             # http://www.apache.org/licenses/LICENSE-2.0
9             #
10             # Unless required by applicable law or agreed to in writing, software
11             # distributed under the License is distributed on an "AS IS" BASIS,
12             # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13             # See the License for the specific language governing permissions and
14             # limitations under the License.
15              
16 1     1   1619 use strict;
  1         3  
  1         33  
17 1     1   4 use warnings;
  1         2  
  1         81  
18              
19             package Clownfish::CFC::Perl::Build::Charmonic;
20              
21 1     1   8 use base qw( Module::Build );
  1         1  
  1         182  
22              
23             our $VERSION = '0.006001';
24             $VERSION = eval $VERSION;
25              
26 1     1   7 use Carp;
  1         2  
  1         95  
27 1     1   6 use Config;
  1         3  
  1         60  
28 1     1   6 use Cwd qw( getcwd );
  1         3  
  1         69  
29 1     1   5 use File::Spec::Functions qw( catfile curdir );
  1         2  
  1         1267  
30              
31             # Add a custom Module::Build hashref property to pass the following build
32             # parameters.
33             # charmonizer_c: Charmonizer C file, required
34             # create_makefile: Whether to create a Makefile.
35             # make_options: Options passed to make.
36             if ( $Module::Build::VERSION <= 0.30 ) {
37             __PACKAGE__->add_property( charmonizer_params => {} );
38             }
39             else {
40             __PACKAGE__->add_property(
41             'charmonizer_params',
42             default => {},
43             );
44             }
45              
46             my $CHARMONIZER_EXE_PATH = catfile( curdir(), "charmonizer$Config{_exe}" );
47             my $CHARMONY_H_PATH = 'charmony.h';
48             my $CHARMONY_PM_PATH = 'Charmony.pm';
49              
50             # Compile and run the charmonizer executable, creating the charmony.h and
51             # Charmony.pm files.
52             sub ACTION_charmony {
53 0     0 0   my $self = shift;
54              
55 0           my $cc = $self->config('cc');
56 0           my $is_msvc = lc($cc) =~ /^cl\b/;
57 0           my $charmonizer_c = $self->charmonizer_params('charmonizer_c');
58 0           my $create_makefile = $self->charmonizer_params('create_makefile');
59              
60 0           $self->add_to_cleanup($CHARMONIZER_EXE_PATH);
61 0 0         if ( !$self->up_to_date( $charmonizer_c, $CHARMONIZER_EXE_PATH ) ) {
62 0           print "\nCompiling $CHARMONIZER_EXE_PATH...\n\n";
63 0           my @command = ( $self->split_like_shell($cc), $charmonizer_c );
64 0 0         if ($is_msvc) {
65 0           push @command, "/Fe$CHARMONIZER_EXE_PATH";
66             }
67             else {
68 0           push @command, '-o', $CHARMONIZER_EXE_PATH;
69             }
70 0 0         system @command
71             and die "Failed to compile $CHARMONIZER_EXE_PATH";
72             }
73              
74 0           my @derived_files = ( $CHARMONY_H_PATH, $CHARMONY_PM_PATH );
75 0 0         push @derived_files, 'Makefile' if $create_makefile;
76 0 0         return if $self->up_to_date( $CHARMONIZER_EXE_PATH, \@derived_files );
77 0           print "\nRunning $CHARMONIZER_EXE_PATH...\n\n";
78              
79 0           $self->add_to_cleanup($CHARMONY_H_PATH);
80 0           $self->add_to_cleanup($CHARMONY_PM_PATH);
81             # Clean up after charmonizer if it doesn't succeed on its own.
82 0           $self->add_to_cleanup("_charm*");
83              
84 0 0         if ($is_msvc) {
85 0           $self->add_to_cleanup('charmonizer.obj');
86             }
87              
88             # Prepare arguments to charmonizer.
89 0           my @command = (
90             $CHARMONIZER_EXE_PATH,
91             "--cc=$cc", # May contain spaces and args.
92             '--host=perl',
93             '--enable-c',
94             '--enable-perl',
95             );
96 0 0         if ($create_makefile) {
97 0           push @command,
98             '--make=' . $self->config('make'),
99             '--enable-makefile';
100 0           $self->add_to_cleanup('Makefile');
101             }
102             # Perl 5.8.7 added support for CLONE_SKIP.
103             # Thread support in 5.10.0 seems completely broken (CLOWNFISH-107).
104 0 0 0       if ( !$self->config('usethreads') || $^V lt v5.8.7 || $^V eq v5.10.0 ) {
      0        
105 0           push @command, '--disable-threads';
106             }
107 0           push @command, (
108             '--', $self->config('ccflags'),
109             '-I' . File::Spec->catdir($self->config('archlibexp'), 'CORE'),
110             );
111 0 0         if ( $ENV{CHARM_VALGRIND} ) {
112 0           unshift @command, "valgrind", "--leak-check=yes";
113             }
114 0           print join( " ", @command ), $/;
115              
116 0 0         if ( system(@command) != 0 ) {
117 0           warn "Failed to run $CHARMONIZER_EXE_PATH: $!\n";
118              
119 0 0 0       if ( ( $ENV{CHARM_VERBOSITY} || 0 ) < 2 ) {
120 0           print "Rerunning $CHARMONIZER_EXE_PATH with CHARM_VERBOSITY=2\n\n";
121 0           $ENV{CHARM_VERBOSITY} = 2;
122 0           system(@command);
123             }
124              
125 0           die "Aborted";
126             }
127             }
128              
129             my $config;
130              
131             sub charmony {
132 0     0 0   my ( undef, $key ) = @_;
133 0 0         if (!$config) {
134 0           eval { require 'Charmony.pm'; };
  0            
135 0 0         if ( !$@ ) {
136 0           $config = Charmony->config;
137             }
138             }
139 0 0         if ($config) {
140 0           return $config->{$key};
141             }
142 0           return;
143             }
144              
145             sub cf_make_objects {
146 0     0 0   my ( $self, $target ) = @_;
147              
148 0 0         return [] unless $self->charmonizer_params('create_makefile');
149              
150 0           $self->_cf_charm_run_make(lc($target));
151              
152 0           return [ split( /\s+/, $self->charmony(uc($target)) ) ];
153             }
154              
155             sub cf_make_clean {
156 0     0 0   my $self = shift;
157              
158 0 0 0       return unless $self->charmonizer_params('create_makefile')
159             && -e 'Makefile';
160              
161 0           $self->_cf_charm_run_make('clean');
162             }
163              
164             sub _cf_charm_run_make {
165 0     0     my ( $self, $target ) = @_;
166              
167 0           my $make_options = $self->charmonizer_params('make_options');
168 0           my @command = (
169             $self->config('make'),
170             $self->split_like_shell($make_options),
171             $target,
172             );
173 0           print join(' ', @command), "\n";
174 0 0         system @command and die($self->config('make') . " failed");
175             }
176              
177             1;
178              
179             __END__