File Coverage

blib/lib/SPVM/Builder/CC.pm
Criterion Covered Total %
statement 311 371 83.8
branch 78 124 62.9
condition 14 28 50.0
subroutine 32 32 100.0
pod 0 15 0.0
total 435 570 76.3


line stmt bran cond sub pod time code
1             package SPVM::Builder::CC;
2              
3 279     279   71616 use strict;
  279         512  
  279         7733  
4 279     279   1261 use warnings;
  279         520  
  279         8657  
5 279     279   1447 use Carp 'confess';
  279         587  
  279         11714  
6 279     279   1708 use Config;
  279         603  
  279         12674  
7              
8 279     279   132435 use ExtUtils::CBuilder;
  279         22112871  
  279         11840  
9 279     279   137106 use File::Copy 'copy', 'move';
  279         608301  
  279         18308  
10 279     279   2121 use File::Path 'mkpath';
  279         708  
  279         12284  
11 279     279   1954 use File::Find 'find';
  279         678  
  279         11427  
12 279     279   1743 use File::Basename 'dirname', 'basename';
  279         678  
  279         12467  
13              
14 279     279   159119 use SPVM::Builder::Util;
  279         1242  
  279         14808  
15 279     279   128988 use SPVM::Builder::Util::API;
  279         755  
  279         8464  
16 279     279   1723 use SPVM::Builder::Config;
  279         560  
  279         5265  
17 279     279   119560 use SPVM::Builder::CompileInfo;
  279         1985  
  279         10884  
18 279     279   115662 use SPVM::Builder::ObjectFileInfo;
  279         830  
  279         8017  
19 279     279   119912 use SPVM::Builder::LinkInfo;
  279         732  
  279         8395  
20 279     279   1694 use SPVM::Builder::Resource;
  279         565  
  279         924542  
21              
22             # Fields
23             sub build_dir {
24 717     717 0 2593 my $self = shift;
25 717 50       2745 if (@_) {
26 0         0 $self->{build_dir} = $_[0];
27 0         0 return $self;
28             }
29             else {
30 717         3016 return $self->{build_dir};
31             }
32             }
33              
34             sub force {
35 1027     1027 0 2990 my $self = shift;
36 1027 100       3915 if (@_) {
37 3         7 $self->{force} = $_[0];
38 3         6 return $self;
39             }
40             else {
41 1024         15760 return $self->{force};
42             }
43             }
44              
45             sub quiet {
46 615     615 0 2277 my $self = shift;
47 615 100       1995 if (@_) {
48 4         8 $self->{quiet} = $_[0];
49 4         8 return $self;
50             }
51             else {
52 611         9827 return $self->{quiet};
53             }
54             }
55              
56             sub at_runtime {
57 606     606 0 1727 my $self = shift;
58 606 100       2033 if (@_) {
59 4         6 $self->{at_runtime} = $_[0];
60 4         8 return $self;
61             }
62             else {
63 602         3332 return $self->{at_runtime};
64             }
65             }
66              
67             sub debug {
68 873     873 0 4725 my $self = shift;
69 873 100       3555 if (@_) {
70 2         5 $self->{debug} = $_[0];
71 2         4 return $self;
72             }
73             else {
74 871         33503 return $self->{debug};
75             }
76             }
77              
78             # Class Methods
79             sub new {
80 845     845 0 2722 my $class = shift;
81            
82 845         3494 my $self = {@_};
83            
84 845         2018 bless $self, $class;
85            
86 845         3777 my $env_spvm_cc_debug = SPVM::Builder::Util::get_normalized_env('SPVM_CC_DEBUG');
87 845 50       2568 if (defined $env_spvm_cc_debug) {
88 0         0 $self->debug(1);
89             }
90            
91 845         2106 my $env_spvm_cc_quiet = SPVM::Builder::Util::get_normalized_env('SPVM_CC_QUIET');
92 845 50       2550 if (defined $env_spvm_cc_quiet) {
93 0         0 $self->quiet(!!$env_spvm_cc_quiet);
94             }
95            
96 845         2134 my $env_spvm_cc_force = SPVM::Builder::Util::get_normalized_env('SPVM_CC_FORCE');
97 845 50       2403 if (defined $env_spvm_cc_force) {
98 0         0 $self->force(1);
99             }
100            
101 845         2508 return $self;
102             }
103              
104             # Instance Methods
105             sub resource_src_dir_from_basic_type_name {
106 10     10 0 51 my ($self, $basic_type_name) = @_;
107              
108 10         143 my $config_file = SPVM::Builder::Util::get_config_file_from_basic_type_name($basic_type_name);
109 10         61 my $config_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($basic_type_name, 'config');
110            
111 10         65 my $resource_src_dir = $config_file;
112 10         451 $resource_src_dir =~ s|/\Q$config_rel_file\E$||;
113            
114 10         64 return $resource_src_dir;
115             }
116              
117             sub get_resource_object_dir_from_basic_type_name {
118 10     10 0 55 my ($self, $basic_type_name) = @_;
119              
120 10         46 my $module_rel_dir = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($basic_type_name);
121            
122 10         57 my $resource_object_dir = SPVM::Builder::Util::create_build_object_path($self->build_dir, "$module_rel_dir.resource");
123            
124 10         74 return $resource_object_dir;
125             }
126              
127             sub detect_force {
128 1021     1021 0 4121 my ($self, $config) = @_;
129            
130 1021         1995 my $force;
131            
132 1021 100 100     4705 if (defined $self->force) {
    100          
133 3         6 $force = $self->force;
134             }
135             elsif (defined $config && defined $config->force) {
136 3         8 $force = $config->force;
137             }
138             else {
139 1015         2036 $force = 0;
140             }
141            
142 1021         3223 return $force;
143             }
144              
145             sub detect_quiet {
146 610     610 0 2302 my ($self, $config) = @_;
147            
148 610         1197 my $quiet;
149            
150 610 100 66     3244 if (defined $self->debug) {
    100          
    100          
    100          
151 2         3 $quiet = 0;
152             }
153             elsif (defined $self->quiet) {
154 3         6 $quiet = $self->quiet;
155             }
156             elsif (defined $config && defined $config->quiet) {
157 3         6 $quiet = $config->quiet;
158             }
159             elsif ($self->at_runtime) {
160 521         1261 $quiet = 1;
161             }
162             else {
163 81         216 $quiet = 0;
164             }
165            
166 610         1811 return $quiet;
167             }
168              
169             sub build_precompile_module_source_file {
170 317     317 0 1239 my ($self, $basic_type_name, $options) = @_;
171              
172 317         865 my $precompile_source = $options->{precompile_source};
173 317         831 my $class_file = $options->{class_file};
174            
175             # Force
176 317         1892 my $force = $self->detect_force;
177              
178             # Output - Precompile C source file
179 317         813 my $output_dir = $options->{output_dir};
180 317         2706 my $source_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($basic_type_name, 'precompile.c');
181 317         1502 my $source_file = "$output_dir/$source_rel_file";
182            
183             # Check if generating is needed
184 317         1418 my $spvm_include_dir = $INC{'SPVM/Builder.pm'};
185 317         3107 $spvm_include_dir =~ s/\.pm$//;
186 317         1206 $spvm_include_dir .= '/src';
187 317         1448 my $spvm_precompile_soruce_file = "$spvm_include_dir/spvm_precompile.c";
188 317 50       8571 unless (-f $spvm_precompile_soruce_file) {
189 0         0 confess "Can't find $spvm_precompile_soruce_file";
190             }
191 317         5585 my $need_generate = SPVM::Builder::Util::need_generate({
192             force => $force,
193             output_file => $source_file,
194             input_files => [$class_file, $spvm_precompile_soruce_file],
195             });
196            
197             # Generate precompile C source file
198 317 100       2483 if ($need_generate) {
199 247         56324 mkpath dirname $source_file;
200 247 50       34074 open my $fh, '>', $source_file
201             or die "Can't create $source_file";
202 247         58518 print $fh $precompile_source;
203 247         14479 close $fh;
204             }
205             }
206              
207             sub compile_source_file {
208 339     339 0 1278 my ($self, $compile_info) = @_;
209            
210 339         2093 my $config = $compile_info->config;
211            
212             # Quiet output
213 339         1998 my $quiet = $self->detect_quiet($config);
214            
215 339         2375 my $source_file = $compile_info->source_file;
216              
217             # Execute compile command
218 339         6533 my $cbuilder = ExtUtils::CBuilder->new(quiet => 1);
219 339         15195054 my $cc_cmd = $compile_info->create_compile_command;
220            
221 339 100       1407 unless ($quiet) {
222 78         11887 warn "@$cc_cmd\n";
223             }
224            
225 339 50       4189 $cbuilder->do_system(@$cc_cmd)
226             or confess "$source_file file cannnot be compiled by the following command:\n@$cc_cmd\n";
227             }
228              
229             sub compile_source_files {
230 354     354 0 1471 my ($self, $basic_type_name, $options) = @_;
231            
232 354   50     1295 $options ||= {};
233            
234             # Category
235 354         941 my $category = $options->{category};
236              
237             # Build directory
238 354         1716 my $build_dir = $self->build_dir;
239 354 50       1198 if (defined $build_dir) {
240 354         11226 mkpath $build_dir;
241             }
242             else {
243 0         0 confess "Build directory is not specified. Maybe forget to set \"SPVM_BUILD_DIR\" environment variable?";
244             }
245            
246             # Input directory
247 354         1786 my $input_dir = $options->{input_dir};
248            
249             # Object directory
250 354         907 my $output_dir = $options->{output_dir};
251 354 50 33     7566 unless (defined $output_dir && -d $output_dir) {
252 0         0 confess "Output directory must exists for " . $options->{category} . " build";
253             }
254            
255             # Config
256 354         1642 my $config = $options->{config};
257            
258             # Force compile
259 354         1593 my $force = $self->detect_force($config);
260              
261 354         854 my $ignore_native_module = $options->{ignore_native_module};
262            
263             # Native class file
264 354         714 my $native_class_file;
265 354 100       1380 unless ($ignore_native_module) {
266             # Native class file
267 344         1182 my $native_module_ext = $config->ext;
268 344 50       1418 unless (defined $native_module_ext) {
269 0         0 confess "Source extension is not specified";
270             }
271 344         2062 my $native_class_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_category_rel_file($basic_type_name, $category, $native_module_ext);
272 344         2058 $native_class_file = "$input_dir/$native_class_rel_file";
273            
274 344 50       6530 unless (-f $native_class_file) {
275 0         0 confess "Can't find source file $native_class_file";
276             }
277             }
278            
279             # Own resource source files
280 354         2116 my $own_source_files = $config->source_files;
281 354         1254 my $native_src_dir = $config->native_src_dir;
282 354         808 my $resource_src_files;
283 354 100       1363 if (defined $native_src_dir) {
284 37         190 $resource_src_files = [map { "$native_src_dir/$_" } @$own_source_files ];
  28         190  
285             }
286            
287             # Compile source files
288 354         1311 my $object_files = [];
289 354         938 my $is_native_module = 1;
290 354         1690 for my $source_file ($native_class_file, @$resource_src_files) {
291 382         916 my $current_is_native_module = $is_native_module;
292 382         737 $is_native_module = 0;
293            
294 382 100       1260 next unless defined $source_file;
295            
296 372         722 my $object_file_name;
297            
298             # Object file of native class
299 372 100       1098 if ($current_is_native_module) {
300 344         1271 my $object_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_category_rel_file($basic_type_name, $category, 'o');
301 344         2079 $object_file_name = "$output_dir/$object_rel_file";
302             }
303             # Object file of resource source file
304             else {
305 28         399 my $object_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_category_rel_file($basic_type_name, $category, 'native');
306            
307 28         127 my $object_file_base = $source_file;
308 28         792 $object_file_base =~ s/^\Q$native_src_dir//;
309 28         306 $object_file_base =~ s/^[\\\/]//;
310            
311 28         325 $object_file_base =~ s/\.[^\.]+$/.o/;
312 28         223 $object_file_name = "$output_dir/$object_rel_file/$object_file_base";
313            
314 28         2968 my $output_dir = dirname $object_file_name;
315 28         6252 mkpath $output_dir;
316             }
317            
318             # Check if object file need to be generated
319 372         990 my $need_generate;
320             {
321             # Own resource header files
322 372         1182 my @own_header_files;
  372         744  
323 372         1541 my $native_include_dir = $config->native_include_dir;
324 372 100 100     3732 if (defined $native_include_dir && -d $native_include_dir) {
325             find(
326             {
327             wanted => sub {
328 128     128   387 my $include_file_name = $File::Find::name;
329 128 100       9360 if (-f $include_file_name) {
330 83         1540 push @own_header_files, $include_file_name;
331             }
332             },
333 33         6401 no_chdir => 1,
334             },
335             $native_include_dir,
336             );
337             }
338 372         1573 my $input_files = [$source_file, @own_header_files];
339 372 100       1469 if (defined $config->file) {
340 55         215 push @$input_files, $config->file;
341             };
342 372 100       1284 if ($current_is_native_module) {
343 344         727 my $class_file = $source_file;
344 344         3009 $class_file =~ s/\.[^\/\\]+$//;
345 344         926 $class_file .= '.spvm';
346            
347 344         1099 push @$input_files, $class_file;
348             }
349 372         3012 $need_generate = SPVM::Builder::Util::need_generate({
350             force => $force,
351             output_file => $object_file_name,
352             input_files => $input_files,
353             });
354             }
355            
356             # Compile-information
357 372         7173 my $compile_info = SPVM::Builder::CompileInfo->new(
358             output_file => $object_file_name,
359             source_file => $source_file,
360             config => $config,
361             );
362            
363 372         1642 my $before_compile_cbs = $config->before_compile_cbs;
364 372         1268 for my $before_compile_cb (@$before_compile_cbs) {
365 10         146 $before_compile_cb->($config, $compile_info);
366             }
367            
368             # Compile a source file
369 372 100       1418 if ($need_generate) {
370 284         1402 my $module_rel_dir = SPVM::Builder::Util::convert_basic_type_name_to_rel_dir($basic_type_name);
371 284         1625 my $work_output_dir = "$output_dir/$module_rel_dir";
372 284         32470 mkpath dirname $object_file_name;
373            
374 284         2477 $self->compile_source_file($compile_info);
375             }
376            
377             # Object file information
378 372         148871697 my $compile_info_cc = $compile_info->{cc};
379 372         2422 my $compile_info_ccflags = $compile_info->{ccflags};
380 372         15132 my $object_file = SPVM::Builder::ObjectFileInfo->new(
381             file => $object_file_name,
382             compile_info => $compile_info,
383             );
384            
385             # Add object file information
386 372         4678 push @$object_files, $object_file;
387             }
388            
389 354         8253 return $object_files;
390             }
391              
392             sub create_link_info {
393 343     343 0 2510 my ($self, $basic_type_name, $object_files, $config, $options) = @_;
394            
395 343         1687 my $category = $options->{category};
396              
397 343         1903 my $all_object_files = [@$object_files];
398            
399 343   50     2487 $options ||= {};
400            
401             # Linker
402 343         4859 my $ld = $config->ld;
403            
404             # Output type
405 343         4641 my $output_type = $config->output_type;
406            
407             # Libraries
408 343         1692 my $lib_infos = [];
409 343         3498 my $libs = $config->libs;
410 343         3203 my $lib_dirs = $config->lib_dirs;
411 343         2642 for my $lib (@$libs) {
412 3         40 my $lib_info;
413            
414             # Library is linked by file path
415             my $static;
416 3         0 my $lib_name;
417 3         0 my $is_abs;
418 3 50       31 if (ref $lib) {
419 0         0 $static = $lib->is_static;
420 0         0 $lib_name = $lib->name;
421 0         0 $is_abs = $lib->is_abs;
422 0         0 $lib_info = $lib;
423             }
424             else {
425 3         25 $lib_name = $lib;
426 3         103 $lib_info = SPVM::Builder::LibInfo->new;
427 3         35 $lib_info->name($lib_name);
428             }
429            
430 3 50       25 if ($is_abs) {
431 0         0 my $found_lib_file;
432 0         0 for my $lib_dir (@$lib_dirs) {
433 0         0 $lib_dir =~ s|[\\/]$||;
434            
435             # Search dynamic library
436 0 0       0 unless ($static) {
437 0         0 my $dynamic_lib_file_base = "lib$lib_name.$Config{dlext}";
438 0         0 my $dynamic_lib_file = "$lib_dir/$dynamic_lib_file_base";
439              
440 0 0       0 if (-f $dynamic_lib_file) {
441 0         0 $found_lib_file = $dynamic_lib_file;
442 0         0 last;
443             }
444             }
445            
446             # Search static library
447 0         0 my $static_lib_file_base = "lib$lib_name.a";
448 0         0 my $static_lib_file = "$lib_dir/$static_lib_file_base";
449 0 0       0 if (-f $static_lib_file) {
450 0         0 $found_lib_file = $static_lib_file;
451 0         0 last;
452             }
453             }
454            
455 0 0       0 if (defined $found_lib_file) {
456 0         0 $lib_info->file = $found_lib_file;
457             }
458             }
459            
460 3         29 push @$lib_infos, $lib_info;
461             }
462 343         2652 $config->libs($lib_infos);
463            
464             # Use resources
465 343         4926 my $resource_names = $config->get_resource_names;
466 343         2352 my $resource_include_dirs = [];
467 343         1796 for my $resource_name (@$resource_names) {
468 10         124 my $resource = $config->get_resource($resource_name);
469 10         111 my $resource_config = $resource->config;
470 10         83 my $resource_include_dir = $resource_config->native_include_dir;
471 10 50       206 if (defined $resource_include_dir) {
472 10         67 push @$resource_include_dirs, $resource_include_dir;
473             }
474             }
475            
476 343         1725 for my $resource_name (@$resource_names) {
477 10         150 my $resource = $config->get_resource($resource_name);
478            
479             # Build native classes
480 10         92 my $builder_cc_resource = SPVM::Builder::CC->new(
481             build_dir => $self->build_dir,
482             );
483            
484 10         91 my $resource_src_dir = $self->resource_src_dir_from_basic_type_name($resource);
485 10         64 my $resource_object_dir = $self->get_resource_object_dir_from_basic_type_name($basic_type_name);
486 10         2475 mkpath $resource_object_dir;
487            
488 10         54 my $resource_basic_type_name;
489             my $resource_config;
490 10 50       131 if (ref $resource) {
491 10         86 $resource_basic_type_name = $resource->class_name;
492 10         75 $resource_config = $resource->config;
493             }
494             else {
495 0         0 $resource_basic_type_name = $resource;
496             }
497            
498 10         215 $resource_config->add_include_dir(@$resource_include_dirs);
499            
500 10         83 $resource_config->disable_resource(1);
501 10         110 my $compile_options = {
502             input_dir => $resource_src_dir,
503             output_dir => $resource_object_dir,
504             ignore_native_module => 1,
505             config => $resource_config,
506             category => $category,
507             };
508            
509 10         81 my $object_files = $builder_cc_resource->compile_source_files($resource_basic_type_name, $compile_options);
510            
511 10         504 push @$all_object_files, @$object_files;
512             }
513              
514             # Output file
515 343         1676 my $output_file = $options->{output_file};
516 343 100       2193 unless (defined $output_file) {
517             # Dynamic library directory
518 341         1386 my $output_dir = $options->{output_dir};
519 341 50 33     10455 unless (defined $output_dir && -d $output_dir) {
520 0         0 confess "Shared lib directory must be specified for link";
521             }
522            
523             # Dynamic library file
524 341         5649 my $output_rel_file = SPVM::Builder::Util::convert_basic_type_name_to_category_rel_file($basic_type_name, $options->{category});
525 341         3813 $output_file = "$output_dir/$output_rel_file";
526             }
527            
528             # Add output file extension
529 343         48325 my $output_file_base = basename $output_file;
530 343 50 66     6547 if ($output_file_base =~ /\.precompile$/ || $output_file_base !~ /\./) {
531 343         1327 my $exe_ext;
532            
533             # Dynamic library
534 343 100       2219 if ($output_type eq 'dynamic_lib') {
    50          
    50          
535 341         12775 $exe_ext = ".$Config{dlext}"
536             }
537             # Static library
538             elsif ($output_type eq 'static_lib') {
539 0         0 $exe_ext = '.a';
540             }
541             # Executable file
542             elsif ($output_type eq 'exe') {
543 2         85 $exe_ext = $Config{exe_ext};
544             }
545            
546 343         3619 $output_file .= $exe_ext;
547             }
548              
549             # Optimize
550 343         3164 my $ld_optimize = $config->ld_optimize;
551            
552 343         6975 my $link_info = SPVM::Builder::LinkInfo->new(
553             class_name => $basic_type_name,
554             config => $config,
555             object_files => $all_object_files,
556             output_file => $output_file,
557             );
558            
559 343         2032 return $link_info;
560             }
561              
562             sub link {
563 343     343 0 2753 my ($self, $basic_type_name, $object_files, $options) = @_;
564            
565 343         1839 my $dl_func_list = $options->{dl_func_list};
566            
567 343         1692 my $category = $options->{category};
568            
569             # Build directory
570 343         4567 my $build_dir = $self->build_dir;
571 343 50       2788 if (defined $build_dir) {
572 343         28859 mkpath $build_dir;
573             }
574             else {
575 0         0 confess "The \"build_dir\" field must be defined to build the native class for $category methods. Perhaps the setting of the SPVM_BUILD_DIR environment variable is forgotten";
576             }
577            
578             # Config
579 343         2294 my $config = $options->{config};
580 343 50       2968 unless ($config) {
581 0         0 confess "Need config option";
582             }
583              
584             # Force link
585 343         4074 my $force = $self->detect_force($config);
586            
587             # Link information
588 343         3026 my $link_info = $self->create_link_info($basic_type_name, $object_files, $config, $options);
589            
590             # Output file
591 343         2967 my $output_file = $link_info->output_file;
592            
593             # Execute the callback before this link
594 343         3196 my $before_link_cbs = $config->before_link_cbs;
595 343         1847 for my $before_link_cb (@$before_link_cbs) {
596 3         58 $before_link_cb->($config, $link_info);
597             }
598            
599 343         1230 my @object_files = map { "$_" } @{$link_info->object_files};
  480         8015  
  343         1881  
600 343         1799 my $input_files = [@object_files];
601 343 100       3321 if (defined $config->file) {
602 27         179 push @$input_files, $config->file;
603             }
604 343         7324 my $need_generate = SPVM::Builder::Util::need_generate({
605             force => $force,
606             output_file => $output_file,
607             input_files => $input_files,
608             });
609            
610 343 100       2357 if ($need_generate) {
611             # Move temporary dynamic library file to blib directory
612 261         45023 mkpath dirname $output_file;
613            
614 261         2402 my $ld = $config->ld;
615            
616 261         6058 my $cbuilder_config = {
617             ld => $ld,
618             lddlflags => '',
619             shrpenv => '',
620             libpth => '',
621             libperl => '',
622            
623             # "perllibs" should be empty string, but ExtUtils::CBuiler outputs "INPUT()" into
624             # Linker Script File(.lds) when "perllibs" is empty string.
625             # This is syntax error in Linker Script File(.lds)
626             # For the reason, libm is linked which seems to have no effect.
627             perllibs => '-lm',
628             };
629              
630             # Quiet output
631 261         2851 my $quiet = $self->detect_quiet($config);
632              
633             # ExtUtils::CBuilder object
634 261         5455 my $cbuilder = ExtUtils::CBuilder->new(quiet => 1, config => $cbuilder_config);
635            
636 261         2614127 my $link_info_output_file = $link_info->output_file;
637 261         1710 my $link_info_object_files = $link_info->object_files;
638            
639 261         2259 my $link_command_args = $link_info->create_link_command_args;
640            
641 261         1210 my $link_info_object_file_names = [map { $_->to_string; } @$link_info_object_files];
  392         1951  
642              
643 261         1052 my @tmp_files;
644            
645 261         1524 my $output_type = $config->output_type;
646            
647             # Create a dynamic library
648 261 100       1728 if ($output_type eq 'dynamic_lib') {
    50          
    50          
649 259         5102 (undef, @tmp_files) = $cbuilder->link(
650             objects => $link_info_object_file_names,
651             module_name => $basic_type_name,
652             lib_file => $link_info_output_file,
653             extra_linker_flags => "@$link_command_args",
654             dl_func_list => $dl_func_list,
655             );
656 259 50       9834616 unless ($quiet) {
657 0         0 my $link_command = $link_info->to_cmd;
658 0         0 warn "$link_command\n";
659             }
660             }
661             # Create a static library
662             elsif ($output_type eq 'static_lib') {
663 0         0 my @object_files = map { "$_" } @$link_info_object_file_names;
  0         0  
664 0         0 my @ar_cmd = ('ar', 'rc', $link_info_output_file, @object_files);
665 0 0       0 $cbuilder->do_system(@ar_cmd)
666             or confess "Can't execute command @ar_cmd";
667 0 0       0 unless ($quiet) {
668 0         0 warn "@ar_cmd\n";
669             }
670             }
671             # Create an executable file
672             elsif ($output_type eq 'exe') {
673 2         64 (undef, @tmp_files) = $cbuilder->link_executable(
674             objects => $link_info_object_file_names,
675             module_name => $basic_type_name,
676             exe_file => $link_info_output_file,
677             extra_linker_flags => "@$link_command_args",
678             );
679 2 50       163603 unless ($quiet) {
680 2         88 my $link_command = $link_info->to_cmd;
681 2         388 warn "$link_command\n";
682             }
683             }
684             else {
685 0         0 confess "Unknown output_type \"$output_type\"";
686             }
687              
688 261 50       8477 if ($self->debug) {
689 0 0       0 if ($^O eq 'MSWin32') {
690 0         0 my $def_file;
691             my $lds_file;
692 0         0 for my $tmp_file (@tmp_files) {
693             # Remove double quote
694 0         0 $tmp_file =~ s/^"//;
695 0         0 $tmp_file =~ s/"$//;
696              
697 0 0       0 if ($tmp_file =~ /\.def$/) {
698 0         0 $def_file = $tmp_file;
699 0         0 $lds_file = $def_file;
700 0         0 $lds_file =~ s/\.def$/.lds/;
701 0         0 last;
702             }
703             }
704 0 0 0     0 if (defined $def_file && -f $def_file) {
705 0         0 my $def_content = SPVM::Builder::Util::slurp_binary($def_file);
706 0         0 warn "[$def_file]\n$def_content\n";
707             }
708 0 0 0     0 if (defined $lds_file && -f $lds_file) {
709 0         0 my $lds_content = SPVM::Builder::Util::slurp_binary($lds_file);
710 0         0 warn "[$lds_file]\n$lds_content\n";
711             }
712             }
713             }
714             }
715            
716 343         1213596 return $output_file;
717             }
718              
719             1;
720              
721             =head1 Name
722              
723             SPVM::Builder::CC - Compilation and Link of Native Class
724              
725             =head1 Description
726              
727             The SPVM::Builder::CC class has methods to compile and link a SPVM native class.
728              
729             =head1 Copyright & License
730              
731             Copyright (c) 2023 Yuki Kimoto
732              
733             MIT License