File Coverage

blib/lib/SPVM/Builder/Config.pm
Criterion Covered Total %
statement 349 387 90.1
branch 99 142 69.7
condition 4 9 44.4
subroutine 62 64 96.8
pod 53 55 96.3
total 567 657 86.3


line stmt bran cond sub pod time code
1             package SPVM::Builder::Config;
2              
3 283     283   70946 use strict;
  283         822  
  283         9445  
4 283     283   1878 use warnings;
  283         798  
  283         11741  
5 283     283   2174 use Config;
  283         667  
  283         11511  
6 283     283   1733 use Carp 'confess';
  283         751  
  283         14510  
7 283     283   1921 use File::Basename 'dirname', 'fileparse';
  283         857  
  283         13131  
8 283     283   2486 use SPVM::Builder::Util;
  283         810  
  283         8684  
9 283     283   135923 use SPVM::Builder::LibInfo;
  283         6071  
  283         22325  
10 283     283   264728 use SPVM::Builder::Resource;
  283         937  
  283         1157435  
11              
12             # Fields
13             sub class_name {
14 334     334 1 1083 my $self = shift;
15 334 100       1221 if (@_) {
16 331         1100 $self->{class_name} = $_[0];
17 331         860 return $self;
18             }
19             else {
20 3         70 return $self->{class_name};
21             }
22             }
23              
24             sub file {
25 1161     1161 1 3846 my $self = shift;
26 1161 100       4669 if (@_) {
27 12         30 $self->{file} = $_[0];
28 12         34 return $self;
29             }
30             else {
31 1149         6280 return $self->{file};
32             }
33             }
34              
35             sub file_optional {
36 382     382 1 1207 my $self = shift;
37 382 50       1508 if (@_) {
38 0         0 $self->{file_optional} = $_[0];
39 0         0 return $self;
40             }
41             else {
42 382         2223 return $self->{file_optional};
43             }
44             }
45              
46             sub ext {
47 707     707 1 1504 my $self = shift;
48 707 100       2034 if (@_) {
49 365         1148 $self->{ext} = $_[0];
50 365         867 return $self;
51             }
52             else {
53 342         1218 return $self->{ext};
54             }
55             }
56              
57             sub quiet {
58 613     613 1 2584 my $self = shift;
59 613 100       2491 if (@_) {
60 5         7 $self->{quiet} = $_[0];
61 5         12 return $self;
62             }
63             else {
64 608         5490 return $self->{quiet};
65             }
66             }
67              
68             sub force {
69 794     794 1 3538 my $self = shift;
70 794 100       3378 if (@_) {
71 4         8 $self->{force} = $_[0];
72 4         18 return $self;
73             }
74             else {
75 790         6846 return $self->{force};
76             }
77             }
78              
79             sub cc {
80 733     733 1 2078 my $self = shift;
81 733 100       2685 if (@_) {
82 389         3404 $self->{cc} = $_[0];
83 389         1255 return $self;
84             }
85             else {
86 344         1864 return $self->{cc};
87             }
88             }
89              
90             sub ccflags {
91 721     721 1 2004 my $self = shift;
92 721 100       2354 if (@_) {
93 382         1079 $self->{ccflags} = $_[0];
94 382         977 return $self;
95             }
96             else {
97 339         1450 return $self->{ccflags};
98             }
99             }
100              
101             sub dynamic_lib_ccflags {
102 721     721 1 1829 my $self = shift;
103 721 100       2658 if (@_) {
104 382         1060 $self->{dynamic_lib_ccflags} = $_[0];
105 382         1012 return $self;
106             }
107             else {
108 339         1841 return $self->{dynamic_lib_ccflags};
109             }
110             }
111              
112             sub thread_ccflags {
113 721     721 1 1812 my $self = shift;
114 721 100       2375 if (@_) {
115 382         1053 $self->{thread_ccflags} = $_[0];
116 382         876 return $self;
117             }
118             else {
119 339         1407 return $self->{thread_ccflags};
120             }
121             }
122              
123             sub std {
124 709     709 1 2409 my $self = shift;
125 709 100       2588 if (@_) {
126 363         1042 $self->{std} = $_[0];
127 363         766 return $self;
128             }
129             else {
130 346         1729 return $self->{std};
131             }
132             }
133              
134             sub optimize {
135 724     724 1 2166 my $self = shift;
136 724 100       2661 if (@_) {
137 385         1153 $self->{optimize} = $_[0];
138 385         947 return $self;
139             }
140             else {
141 339         1485 return $self->{optimize};
142             }
143             }
144              
145             sub include_dirs {
146 721     721 1 2057 my $self = shift;
147 721 100       2477 if (@_) {
148 382         991 $self->{include_dirs} = $_[0];
149 382         887 return $self;
150             }
151             else {
152 339         1883 return $self->{include_dirs};
153             }
154             }
155              
156             sub spvm_core_include_dir {
157 1103     1103 1 2325 my $self = shift;
158 1103 100       3484 if (@_) {
159 382         2175 $self->{spvm_core_include_dir} = $_[0];
160 382         1146 return $self;
161             }
162             else {
163 721         3107 return $self->{spvm_core_include_dir};
164             }
165             }
166              
167             sub native_include_dir {
168 1138     1138 1 2937 my $self = shift;
169 1138 100       3435 if (@_) {
170 37         127 $self->{native_include_dir} = $_[0];
171 37         115 return $self;
172             }
173             else {
174 1101         3942 return $self->{native_include_dir};
175             }
176             }
177              
178             sub native_src_dir {
179 761     761 1 1462 my $self = shift;
180 761 100       1913 if (@_) {
181 37         138 $self->{native_src_dir} = $_[0];
182 37         110 return $self;
183             }
184             else {
185 724         2391 return $self->{native_src_dir};
186             }
187             }
188              
189             sub source_files {
190 724     724 1 1616 my $self = shift;
191 724 100       2115 if (@_) {
192 382         1139 $self->{source_files} = $_[0];
193 382         937 return $self;
194             }
195             else {
196 342         1529 return $self->{source_files};
197             }
198             }
199              
200             sub before_compile_cbs {
201 742     742 1 1597 my $self = shift;
202 742 100       2150 if (@_) {
203 382         1002 $self->{before_compile_cbs} = $_[0];
204 382         1058 return $self;
205             }
206             else {
207 360         1480 return $self->{before_compile_cbs};
208             }
209             }
210              
211             sub ld {
212 994     994 1 3290 my $self = shift;
213 994 100       3853 if (@_) {
214 389         19686 $self->{ld} = $_[0];
215 389         1520 return $self;
216             }
217             else {
218 605         5113 return $self->{ld};
219             }
220             }
221              
222             sub ldflags {
223 914     914 1 2192 my $self = shift;
224 914 100       3154 if (@_) {
225 382         1160 $self->{ldflags} = $_[0];
226 382         942 return $self;
227             }
228             else {
229 532         2391 return $self->{ldflags};
230             }
231             }
232              
233             sub dynamic_lib_ldflags {
234 641     641 1 1754 my $self = shift;
235 641 100       2482 if (@_) {
236 382         1021 $self->{dynamic_lib_ldflags} = $_[0];
237 382         967 return $self;
238             }
239             else {
240 259         1914 return $self->{dynamic_lib_ldflags};
241             }
242             }
243              
244             sub thread_ldflags {
245 645     645 1 1965 my $self = shift;
246 645 100       2667 if (@_) {
247 382         2139 $self->{thread_ldflags} = $_[0];
248 382         1121 return $self;
249             }
250             else {
251 263         1627 return $self->{thread_ldflags};
252             }
253             }
254              
255             sub ld_optimize {
256 1239     1239 1 3717 my $self = shift;
257 1239 100       7025 if (@_) {
258 382         1288 $self->{ld_optimize} = $_[0];
259 382         937 return $self;
260             }
261             else {
262 857         8145 return $self->{ld_optimize};
263             }
264             }
265              
266             sub lib_dirs {
267 976     976 1 3032 my $self = shift;
268 976 100       3684 if (@_) {
269 382         1083 $self->{lib_dirs} = $_[0];
270 382         1055 return $self;
271             }
272             else {
273 594         2967 return $self->{lib_dirs};
274             }
275             }
276              
277             sub libs {
278 1307     1307 1 4279 my $self = shift;
279 1307 100       4717 if (@_) {
280 713         2543 $self->{libs} = $_[0];
281 713         3104 return $self;
282             }
283             else {
284 594         3147 return $self->{libs};
285             }
286             }
287              
288             sub before_link_cbs {
289 713     713 1 2403 my $self = shift;
290 713 100       3005 if (@_) {
291 382         1230 $self->{before_link_cbs} = $_[0];
292 382         911 return $self;
293             }
294             else {
295 331         2006 return $self->{before_link_cbs};
296             }
297             }
298              
299             sub output_type {
300 1956     1956 1 5009 my $self = shift;
301 1956 100       5974 if (@_) {
302 379         1407 $self->{output_type} = $_[0];
303 379         925 return $self;
304             }
305             else {
306 1577         8407 return $self->{output_type};
307             }
308             }
309              
310             # Class Methods
311             sub new {
312 382     382 1 9526 my $class = shift;
313            
314 382         1589 my $self = {@_};
315              
316 382   33     3287 bless $self, ref $class || $class;
317            
318 382         3669 my $file_optional = $self->file_optional;
319            
320 382         2202 my $file = $self->file;
321 382 50 66     1730 if (!$file_optional && !defined $file) {
322 0         0 confess "\"file\" option must be specified";
323             }
324            
325             # cc
326 382 50       1495 unless (defined $self->{cc}) {
327 382         3612 $self->cc($Config{cc});
328             }
329              
330             # ccflags
331 382 50       1884 unless (defined $self->{ccflags}) {
332 382         2139 $self->ccflags([]);
333             }
334            
335             # dynamic_lib_ccflags
336 382 50       1440 unless (defined $self->{dynamic_lib_ccflags}) {
337 382 50       3358 if ($^O eq 'MSWin32') {
338 0         0 $self->dynamic_lib_ccflags([]);
339             }
340             else {
341 382         2549 $self->dynamic_lib_ccflags(['-fPIC']);
342             }
343             }
344            
345             # thread_ccflags
346 382 50       1591 unless (defined $self->{thread_ccflags}) {
347 382 50       1395 if ($^O eq 'MSWin32') {
348 0         0 $self->thread_ccflags([]);
349             }
350             else {
351 382         1879 $self->thread_ccflags(['-pthread']);
352             }
353             }
354            
355             # optimize
356 382 50       1410 unless (defined $self->{optimize}) {
357 382         2322 $self->optimize('-O3');
358             }
359            
360             # include_dirs
361 382 50       1505 unless (defined $self->{include_dirs}) {
362 382         2025 $self->include_dirs([]);
363             }
364            
365             # spvm_core_include_dir
366 382 50       1987 unless (defined $self->spvm_core_include_dir) {
367 382         2074 my $builder_dir = SPVM::Builder::Util::get_builder_dir_from_config_class();
368 382         1534 my $spvm_core_include_dir = "$builder_dir/include";
369            
370 382         1320 $self->spvm_core_include_dir($spvm_core_include_dir);
371             }
372            
373             # native_include_dir
374 382 50       1780 unless (defined $self->native_include_dir) {
375 382 100       1446 if (defined $file) {
376 37         248 my $native_dir = $self->_remove_ext_from_config_file($file);
377 37         114 $native_dir .= '.native';
378 37         151 my $native_include_dir = "$native_dir/include";
379            
380 37         137 $self->native_include_dir($native_include_dir);
381             }
382             }
383            
384             # native_src_dir
385 382 50       1760 unless (defined $self->native_src_dir) {
386 382 100       1397 if (defined $file) {
387 37         206 my $native_dir = $self->_remove_ext_from_config_file($file);
388 37         124 $native_dir .= '.native';
389 37         143 my $native_src_dir = "$native_dir/src";
390            
391 37         129 $self->native_src_dir($native_src_dir);
392             }
393             }
394            
395             # source_files
396 382 50       1459 unless (defined $self->{source_files}) {
397 382         2130 $self->source_files([]);
398             }
399            
400             # before_compile_cbs
401 382 50       1545 unless (defined $self->{before_compile_cbs}) {
402 382         1671 $self->before_compile_cbs([]);
403             }
404            
405             # resources
406 382 50       1668 unless (defined $self->{resources}) {
407 382         1256 $self->{resources} = {};
408             }
409            
410             # ld
411 382 50       1235 unless (defined $self->{ld}) {
412 382         2625 $self->ld($Config{ld});
413             }
414            
415             # ldflags
416 382 50       1936 unless (defined $self->{ldflags}) {
417 382         1732 $self->ldflags([]);
418             }
419            
420             # output_type
421 382 100       2019 unless (defined $self->output_type) {
422 379         1192 $self->output_type('dynamic_lib');
423             }
424            
425             # dynamic_lib_ldflags
426 382 50       1488 unless (defined $self->{dynamic_lib_ldflags}) {
427 382 50       1670 if ($^O eq 'MSWin32') {
428 0         0 $self->dynamic_lib_ldflags(['-mdll', '-s']);
429             }
430             else {
431 382         2166 $self->dynamic_lib_ldflags(['-shared', '-pthread']);
432             }
433             }
434            
435             # thread_ldflags
436 382 50       1385 unless (defined $self->{thread_ldflags}) {
437 382 50       1366 if ($^O eq 'MSWin32') {
438 0         0 $self->thread_ldflags([]);
439             }
440             else {
441 382         2125 $self->thread_ldflags(['-pthread']);
442             }
443             }
444            
445             # ld_optimize
446 382 50       1462 unless (defined $self->{ld_optimize}) {
447 382         1791 $self->ld_optimize('-O2');
448             }
449            
450             # lib_dirs
451 382 50       1410 unless (defined $self->{lib_dirs}) {
452 382         2011 $self->lib_dirs([]);
453             }
454            
455             # libs
456 382 50       1440 unless (defined $self->{libs}) {
457 382         2155 $self->libs([]);
458             }
459            
460             # before_link_cbs
461 382 50       1556 unless (defined $self->{before_link_cbs}) {
462 382         1917 $self->before_link_cbs([]);
463             }
464            
465 382 50       1472 unless (defined $self->{_loaded_config_files}) {
466 382         16847 $self->{_loaded_config_files} = [];
467             }
468            
469 382         1502 return $self;
470             }
471              
472             sub new_c {
473 359     359 1 2155 my $class = shift;
474            
475 359         2566 my $self = $class->new(@_);
476            
477 359         2143 $self->ext('c');
478            
479 359         819 return $self;
480             }
481              
482             sub new_c99 {
483 1     1 1 541 my $class = shift;
484            
485 1         4 my $self = $class->new_c(@_);
486            
487             # C99
488 1         6 $self->std('c99');
489            
490 1         2 return $self;
491             }
492              
493             sub new_c11 {
494 1     1 1 556 my $class = shift;
495            
496 1         4 my $self = $class->new_c(@_);
497            
498             # C11
499 1         7 $self->std('c11');
500            
501 1         3 return $self;
502             }
503              
504             sub new_gnu99 {
505 355     355 1 10714 my $class = shift;
506            
507 355         2458 my $self = $class->new_c(@_);
508            
509             # GNU C99
510 355         2123 $self->std('gnu99');
511            
512 355         1151 return $self;
513             }
514              
515             sub new_gnu11 {
516 1     1 1 503 my $class = shift;
517            
518 1         4 my $self = $class->new_c(@_);
519            
520             # GNU C11
521 1         9 $self->std('gnu11');
522            
523 1         3 return $self;
524             }
525              
526              
527             sub new_cpp {
528 6     6 1 520 my $class = shift;
529            
530 6         22 my $self = $class->new(@_);
531            
532             # The compiler
533             # [Memo]Free BSD don't have g++ in the environment clang++ exists.
534             # [Memo]"Clang" or "clang" is assumed.
535 6         154 my $config_gcc_version = $Config{gccversion};
536 6 50       48 if ($config_gcc_version =~ /\bclang\b/i) {
537 0         0 $self->cc('clang++');
538 0         0 $self->ld('clang++');
539             }
540             else {
541 6         24 $self->cc('g++');
542 6         16 $self->ld('g++');
543             }
544            
545 6         34 $self->ext('cpp');
546            
547 6         18 return $self;
548             }
549              
550             sub new_cpp11 {
551 3     3 1 1032 my $class = shift;
552            
553 3         27 my $self = $class->new_cpp(@_);
554            
555             # C++11
556 3         17 $self->std('c++11');
557            
558 3         10 return $self;
559             }
560              
561             sub new_cpp14 {
562 1     1 1 513 my $class = shift;
563            
564 1         5 my $self = $class->new_cpp(@_);
565            
566             # C++14
567 1         7 $self->std('c++14');
568            
569 1         4 return $self;
570             }
571              
572             sub new_cpp17 {
573 1     1 1 527 my $class = shift;
574            
575 1         7 my $self = $class->new_cpp(@_);
576            
577             # C++17
578 1         6 $self->std('c++17');
579            
580 1         10 return $self;
581             }
582              
583             # Instance Methods
584             sub add_ccflag {
585 2     2 1 23 my ($self, @ccflags) = @_;
586            
587 2         4 push @{$self->{ccflags}}, @ccflags;
  2         10  
588             }
589              
590             sub add_include_dir {
591 11     11 1 131 my ($self, @include_dirs) = @_;
592            
593 11         41 push @{$self->{include_dirs}}, @include_dirs;
  11         122  
594             }
595              
596             sub add_ldflag {
597 2     2 1 14 my ($self, @ldflags) = @_;
598            
599 2         6 push @{$self->{ldflags}}, @ldflags;
  2         8  
600             }
601              
602             sub add_lib_dir {
603 1     1 1 12 my ($self, @lib_dirs) = @_;
604            
605 1         2 push @{$self->{lib_dirs}}, @lib_dirs;
  1         5  
606             }
607              
608             sub add_lib {
609 3     3 1 29 my ($self, @libs) = @_;
610            
611 3         5 push @{$self->{libs}}, @libs;
  3         10  
612             }
613              
614             sub add_static_lib {
615 0     0 1 0 my ($self, @libs) = @_;
616            
617 0         0 my @static_libs;
618 0         0 for my $lib (@libs) {
619 0         0 my $static_lib;
620 0 0       0 if (ref $lib eq 'SPVM::Builder::LibInfo') {
621 0         0 $static_lib = $lib->is_static(1);
622             }
623             else {
624 0         0 my $lib_name = $lib;
625 0         0 $static_lib = SPVM::Builder::LibInfo->new;
626 0         0 $static_lib->name($lib_name);
627 0         0 $static_lib->is_static(1);
628             }
629 0         0 push @static_libs, $static_lib;
630             }
631            
632 0         0 $self->add_lib(@static_libs);
633             }
634              
635             sub add_source_file {
636 17     17 1 224 my ($self, @source_files) = @_;
637            
638 17         42 push @{$self->{source_files}}, @source_files;
  17         82  
639             }
640              
641             sub add_before_compile_cb {
642 112     112 1 665 my ($self, @before_compile_cbs) = @_;
643            
644 112         317 push @{$self->{before_compile_cbs}}, @before_compile_cbs;
  112         784  
645             }
646              
647             sub add_before_link_cb {
648 3     3 0 40 my ($self, @before_link_cbs) = @_;
649            
650 3         7 push @{$self->{before_link_cbs}}, @before_link_cbs;
  3         14  
651             }
652              
653             sub load_config {
654 40     40 1 210 my ($self, $config_file, @args) = @_;
655              
656 40 50       666 unless (-f $config_file) {
657 0         0 confess "The config file \"$config_file\" must exist";
658             }
659 40         226 local @ARGV = @args;
660 40         22552 my $config = do File::Spec->rel2abs($config_file);
661 40 50       692 if ($@) {
662 0         0 confess "The config file \"$config_file\" can't be parsed: $@";
663             }
664            
665 40 50 33     489 unless (defined $config && $config->isa('SPVM::Builder::Config')) {
666 0         0 confess "The config file must be a SPVM::Builder::Config object";
667             }
668            
669 40         102 push @{$config->get_loaded_config_files}, $config_file;
  40         190  
670            
671 40         187 return $config;
672             }
673              
674             sub load_mode_config {
675 3     3 1 20 my ($self, $config_file, $mode, @argv) = @_;
676            
677 3         14 my $mode_config_file = $self->_remove_ext_from_config_file($config_file);
678 3 50       18 if (defined $mode) {
679 0         0 $mode_config_file .= ".$mode";
680             }
681 3         16 $mode_config_file .= ".config";
682            
683 3 50       83 unless (-f $mode_config_file) {
684 0         0 confess "Can't find the config file \"$mode_config_file\"";
685             }
686            
687 3         38 my $config = $self->load_config($mode_config_file, @argv);
688            
689 3         18 return $config;
690             }
691              
692             sub load_base_config {
693 3     3 1 605 my ($self, $config_file, @args) = @_;
694            
695 3         34 my $config = $self->load_mode_config($config_file, undef, @args);
696              
697 3         23 return $config;
698             }
699              
700             sub get_loaded_config_files {
701 258     258 1 863 my $self = shift;
702            
703 258         1230 return $self->{_loaded_config_files};
704             }
705              
706             sub use_resource {
707 12     12 1 118 my ($self, @args) = @_;
708            
709 12         26 my $first_arg;
710 12 50       66 unless (@args % 2 == 0) {
711 12         41 $first_arg = shift @args;
712             }
713            
714 12         30 my $resource;
715 12 50       51 if (ref $first_arg) {
716 0         0 $resource = $first_arg;
717             }
718             else {
719 12         41 my $basic_type_name = $first_arg;
720 12         56 my %args = @args;
721 12 50       49 if (exists $args{class_name}) {
722 0         0 $basic_type_name = delete $args{class_name};
723             }
724 12         160 $resource = SPVM::Builder::Resource->new(class_name => $basic_type_name, %args);
725             }
726            
727 12         60 my $resource_basic_type_name = $resource->class_name;
728 12         43 my $resource_mode = $resource->mode;
729 12         33 my $resource_argv = $resource->argv;
730            
731 12 100       74 my $ext = defined $resource_mode ? "$resource_mode.config" : 'config';
732 12         92 my $config_file_base = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($resource_basic_type_name, $ext);
733            
734 12         99 my $config_file = SPVM::Builder::Util::get_config_file_from_basic_type_name($resource_basic_type_name, $resource_mode);
735            
736 12         89 my $config = $self->load_config($config_file, @$resource_argv);
737 12         60 $config->file($config_file);
738            
739 12         61 $resource->config($config);
740            
741 12         18 my $index = keys %{$self->{resources}};
  12         43  
742            
743 12         119 $self->{resources}->{$resource_basic_type_name} = {resource => $resource, index => $index};
744            
745 12         48 return $resource;
746             }
747              
748             sub disable_resource {
749 350     350 1 1380 my $self = shift;
750 350 100       3548 if (@_) {
751 11         138 $self->{disable_resource} = $_[0];
752 11         66 return $self;
753             }
754             else {
755 339         2686 return $self->{disable_resource};
756             }
757             }
758              
759             sub get_resource {
760 32     32 0 154 my ($self, $resource_basic_type_name) = @_;
761            
762 32 50       158 unless (defined $self->{resources}{$resource_basic_type_name}) {
763 0         0 return;
764             }
765            
766 32         124 my $resource = $self->{resources}{$resource_basic_type_name}{resource};
767            
768 32         122 return $resource;
769             }
770              
771             sub get_resource_names {
772 652     652 1 4513 my ($self) = @_;
773            
774 652         4253 my @resource_names = sort { $self->{resources}{$a}{index} <=> $self->{resources}{$b}{index} } keys %{$self->{resources}};
  8         146  
  652         7219  
775            
776 652         6811 return \@resource_names;
777             }
778              
779             sub clone {
780 0     0 1 0 my ($self) = @_;
781            
782 0         0 my $clone = bless {}, ref $self;
783            
784 0         0 for my $name (keys %$self) {
785 0         0 my $value = $self->{$name};
786            
787 0 0       0 if (ref $value eq 'ARRAY') {
    0          
788 0         0 $clone->{$name} = [@$value];
789             }
790             elsif (ref $value eq 'HASH') {
791 0         0 $clone->{$name} = {%$value};
792             }
793             else {
794 0         0 $clone->{$name} = $value;
795             }
796             }
797            
798 0         0 return $clone;
799             }
800              
801             sub _remove_ext_from_config_file {
802 77     77   212 my ($self, $config_file) = @_;
803            
804 77         2012 my ($config_base_name, $config_dir) = fileparse $config_file;
805            
806 77         660 $config_base_name =~ s/(\.[^\.]+)?\.config$//;
807            
808 77         234 my $config_file_without_ext = "$config_dir$config_base_name";
809            
810 77         245 return $config_file_without_ext;
811             }
812              
813             1;
814              
815             =head1 Name
816              
817             The SPVM::Builder::Config - Config of Compiler and Linker
818              
819             =head1 Description
820              
821             The SPVM::Builder::Config class has methods to manipulate a config to compile source files and generate a dynamic link.
822              
823             =head1 Usage
824              
825             use SPVM::Builder::Config;
826            
827             # Create a config
828             my $config = SPVM::Builder::Config->new(file => __FILE__);
829            
830             # C99
831             my $config = SPVM::Builder::Config->new_c99(file => __FILE__);
832            
833             # GNU C99
834             my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
835            
836             # C++
837             my $config = SPVM::Builder::Config->new_cpp(file => __FILE__);
838            
839             # C++11
840             my $config = SPVM::Builder::Config->new_cpp11(file => __FILE__);
841            
842             # Optimize
843             $config->optimize('-O2');
844            
845             # Optimize with debug mode
846             $config->optimize('-O0 -g');
847            
848             # Adds source files
849             $config->add_source_file('foo.c', 'bar.c', 'baz/baz.c');
850            
851             # Uses resource
852             $config->use_resource('TestCase::Resource::Zlib');
853             $config->use_resource('TestCase::Resource::Foo1', mode => 'mode1', argv => ['args1', 'args2']);
854            
855             # Gets resouce information
856             my $resource = $config->get_resource('TestCase::Resource::Zlib');
857              
858             =head1 Fields
859              
860             =head2 ext
861              
862             my $ext = $config->ext;
863             $config->ext($ext);
864              
865             Gets and sets the C field.
866              
867             This field is the extension of a native class.
868              
869             Examples:
870            
871             # Foo/Bar.c
872             $config->ext('c');
873            
874             # Foo/Bar.cpp
875             $config->ext('cpp');
876              
877             =head2 cc
878              
879             my $cc = $config->cc;
880             $config->cc($cc);
881              
882             Gets and sets the C field.
883              
884             This field is a compiler name.
885              
886             Examples:
887            
888             # gcc
889             $config->cc('gcc');
890            
891             # g++ for C++
892             $config->cc('g++');
893            
894             # nvcc for CUDA/GUP
895             $config->cc('nvcc');
896            
897             # cc that compiled this Perl
898             use Config;
899             $config->cc($Config{cc});
900              
901             =head2 include_dirs
902              
903             my $include_dirs = $config->include_dirs;
904             $config->include_dirs($include_dirs);
905              
906             Gets and sets the C field.
907              
908             This field is an array reference of including directories of the compiler.
909              
910             This is same as C<-I> option of C.
911              
912             =head2 spvm_core_include_dir
913              
914             my $spvm_core_include_dir = $config->spvm_core_include_dir;
915             $config->spvm_core_include_dir($spvm_core_include_dir);
916              
917             Gets and sets the C field.
918              
919             This is the header including directory of the SPVM core.
920              
921             =head2 native_include_dir
922              
923             my $native_include_dir = $config->native_include_dir;
924             $config->native_include_dir($native_include_dir);
925              
926             Gets and sets the C field.
927              
928             This field is the path of the header including directory of this native class.
929              
930             =head2 native_src_dir
931              
932             my $native_src_dir = $config->native_src_dir;
933             $config->native_src_dir($native_src_dir);
934              
935             Gets and sets the C field.
936              
937             This field is the path of the source directory of this native class.
938              
939             =head2 ccflags
940              
941             my $ccflags = $config->ccflags;
942             $config->ccflags($ccflags);
943              
944             Gets and sets the C field.
945              
946             This field is an array reference that contains compiler flags.
947              
948             =head2 dynamic_lib_ccflags
949              
950             my $dynamic_lib_ccflags = $config->dynamic_lib_ccflags;
951             $config->dynamic_lib_ccflags($dynamic_lib_ccflags);
952              
953             Gets and sets the C field.
954              
955             This field is an array reference that contains compiler flags for information when the linker generates a dynamic link.
956              
957             =head2 thread_ccflags
958              
959             my $thread_ccflags = $config->thread_ccflags;
960             $config->thread_ccflags($thread_ccflags);
961              
962             Gets and sets the C field.
963              
964             This field is an array reference that contains compiler flags for thread setting.
965              
966             =head2 std
967              
968             my $std = $config->std;
969             $config->std($std);
970              
971             Gets and sets the C field.
972              
973             This field is the value for C<-std> option of the compiler.
974              
975             Examples:
976              
977             $config->std('c99');
978             $config->std('gnu99');
979             $config->std('cpp');
980             $config->std('cpp11');
981             $config->std('cpp17');
982              
983             =head2 optimize
984              
985             my $optimize = $config->optimize;
986             $config->optimize($optimize);
987              
988             Gets and sets the C field.
989              
990             This field is the option for optimization of the compiler.
991              
992             Examples:
993              
994             $config->optimize('-O3');
995             $config->optimize('-O2');
996             $config->optimize('-g3 -O0');
997              
998             =head2 source_files
999              
1000             my $source_files = $config->source_files;
1001             $config->source_files($source_files);
1002              
1003             Gets and sets the C field.
1004              
1005             This field is a array reference that contains source files.
1006              
1007             The file name is the relative pass from L.
1008              
1009             Examples:
1010              
1011             $config->source_files(['foo.c', 'bar.c']);
1012              
1013             =head2 before_compile_cbs
1014              
1015             my $before_compile_cbs = $config->before_compile_cbs;
1016             $config->before_compile_cbs($before_compile_cbs);
1017              
1018             Gets and sets the C field.
1019              
1020             This field is an array reference that contains the callbacks called before a compilation.
1021              
1022             Examples:
1023              
1024             $config->add_before_compile_cb(sub {
1025             my ($config, $compile_info) = @_;
1026            
1027             my $cc = $compile_info->cc;
1028            
1029             # Do something
1030             });
1031              
1032             =head2 before_link_cbs
1033              
1034             my $before_link_cbs = $config->before_link_cbs;
1035             $config->before_link_cbs($before_link_cbs);
1036              
1037             Gets and sets the C field.
1038              
1039             This field is an array reference that contains the callbacks called before a link.
1040              
1041             Examples:
1042              
1043             $config->add_before_link_cb(sub {
1044             my ($config, $link_info) = @_;
1045            
1046             my $object_files = $link_info->object_files;
1047            
1048             # Do something
1049            
1050             });
1051              
1052             =head2 ld
1053              
1054             my $ld = $config->ld;
1055             $config->ld($ld);
1056              
1057             Gets and sets the C field.
1058              
1059             This field is a linker name.
1060              
1061             =head2 lib_dirs
1062              
1063             my $lib_dirs = $config->lib_dirs;
1064             $config->lib_dirs($lib_dirs);
1065              
1066             Gets and sets the C field.
1067              
1068             This field is an array reference that contains the directories that libraries are searched for by the linker. This is same as C<-L> option of C.
1069              
1070             =head2 libs
1071              
1072             my $libs = $config->libs;
1073             $config->libs($libs);
1074              
1075             Gets and sets the C field.
1076              
1077             This field is an array reference that contains library names or L objects. These libraries are linked by L method.
1078              
1079             =head2 ldflags
1080              
1081             my ldflags = $config->ldflags;
1082             $config->ldflags(ldflags);
1083              
1084             Gets and sets the C field.
1085              
1086             This field is an array reference that contains linker flags.
1087              
1088             =head2 dynamic_lib_ldflags
1089              
1090             my dynamic_lib_ldflags = $config->dynamic_lib_ldflags;
1091             $config->dynamic_lib_ldflags(dynamic_lib_ldflags);
1092              
1093             Gets and sets the C field.
1094              
1095             This field is an array reference that contains linker flags for a dynamic link.
1096              
1097             =head2 thread_ldflags
1098              
1099             my thread_ldflags = $config->thread_ldflags;
1100             $config->thread_ldflags(thread_ldflags);
1101              
1102             Gets and sets the C field.
1103              
1104             This field is an array reference that contains linker flags for thread setting.
1105              
1106             =head2 ld_optimize
1107              
1108             my $ld_optimize = $config->ld_optimize;
1109             $config->ld_optimize($ld_optimize);
1110              
1111             Gets and sets the C field.
1112              
1113             This field is the option for optimization of the linker such as C<-O3>, C<-O2>, C<-g3 -O0>.
1114              
1115             Examples:
1116              
1117             $config->ld_optimize("-O3");
1118              
1119             =head2 force
1120              
1121             my $force = $config->force;
1122             $config->force($force);
1123              
1124             Gets and sets the C field.
1125              
1126             If this field is a true value, the compilation and link are forced without caching.
1127              
1128             If this field is a false value, they are not forced.
1129              
1130             If this field is undef, whether they are forced or not is determined by other conditions.
1131              
1132             =head2 quiet
1133              
1134             my $quiet = $config->quiet;
1135             $config->quiet($quiet);
1136              
1137             Gets and sets the C field.
1138              
1139             If this field is a true value, messages of the compiler and linker are output.
1140              
1141             If this field is a false value, the messages are not output.
1142              
1143             If this field is undef, whether the messages are output or not is determined by other conditions.
1144              
1145             =head2 class_name
1146              
1147             my $basic_type_name = $config->class_name;
1148             $config->class_name($basic_type_name);
1149              
1150             Gets and sets the C field.
1151              
1152             This field is the class name of this config.
1153              
1154             =head2 file
1155              
1156             my $file = $config->file;
1157             $config->file($file);
1158              
1159             Gets and sets the C field.
1160              
1161             This field is the path of the config file.
1162              
1163             =head2 file_optional
1164              
1165             my $file_optional = $config->file_optional;
1166             $config->file_optional($file_optional);
1167              
1168             Gets and sets the C field.
1169              
1170             If this field is false and the file that is given by the L field is not found, an exception is thrown.
1171              
1172             =head2 output_type
1173              
1174             my $output_type = $config->output_type;
1175             $config->output_type($output_type);
1176              
1177             Gets and sets the C field.
1178              
1179             This field is the output type of the linker. C<"dynamic_lib">, C<"static_lib"> and C<"exe"> are available.
1180              
1181             =head2 disable_resource
1182              
1183             my $disable_resource = $config->disable_resource;
1184             $config->disable_resource($disable_resource);
1185              
1186             Gets and sets the C field.
1187              
1188             If this value is true, All resources loaded by the L method is disabled.
1189              
1190             =head1 Class Methods
1191              
1192             =head2 new
1193              
1194             my $config = SPVM::Builder::Config->new(%fields);
1195              
1196             Create a C object with L.
1197              
1198             Exceptions:
1199              
1200             If the L field is not set to a true value, the L field must be passed. Otherwise an exception is thrown.
1201              
1202             Default Field Values:
1203              
1204             If a field is not defined, the field is set to the following default value.
1205              
1206             =over 2
1207              
1208             =item * L
1209              
1210             undef
1211              
1212             =item * L
1213              
1214             undef
1215              
1216             =item * L
1217              
1218             0
1219              
1220             =item * L
1221              
1222             undef
1223              
1224             =item * L
1225              
1226             undef
1227              
1228             =item * L
1229              
1230             undef
1231              
1232             =item * L
1233              
1234             The C<$Config{cc}> of the L class.
1235              
1236             =item * L
1237              
1238             []
1239              
1240             =item * L
1241              
1242             Windows:
1243              
1244             []
1245              
1246             Others:
1247              
1248             ['-fPIC']
1249              
1250             =item * L
1251              
1252             Windows:
1253              
1254             []
1255              
1256             Others:
1257              
1258             ['-pthread']
1259              
1260             =item * L
1261              
1262             undef
1263              
1264             =item * L
1265              
1266             "-O3"
1267              
1268             =item * L
1269              
1270             []
1271              
1272             =item * L
1273              
1274             The header including directory of the SPVM core is created from the class file of the loaded L class.
1275              
1276             The value looks like C.
1277              
1278             =item * L
1279              
1280             If the L field is defined, the path of the header including directory is created from the L field.
1281              
1282             The value looks like C.
1283              
1284             =item * L
1285              
1286             If the L field is defined, the path of the source directory is created from the L field.
1287              
1288             The value looks like C.
1289              
1290             =item * L
1291              
1292             []
1293              
1294             =item * L
1295              
1296             []
1297              
1298             =item * L
1299              
1300             The C<$Config{ld}> of the L class.
1301              
1302             =item * L
1303              
1304             =item * L
1305              
1306             Windows:
1307              
1308             ["-mdll", "-s"]
1309              
1310             Other OSs:
1311              
1312             ['-shared']
1313              
1314             =item * L
1315              
1316             Windows:
1317              
1318             []
1319              
1320             Other OSs:
1321              
1322             ['-pthread']
1323              
1324             =item * L
1325              
1326             "-O2"
1327              
1328             =item * L
1329              
1330             []
1331              
1332             =item * L
1333              
1334             []
1335              
1336             =item * L
1337              
1338             []
1339              
1340             =item * L
1341              
1342             "dynamic_lib"
1343              
1344             =back
1345              
1346             Examples:
1347              
1348             my $config = SPVM::Builder::Config->new(file => __FILE__);
1349              
1350             =head2 new_c
1351            
1352             my $config = SPVM::Builder::Config->new_c(file => __FILE__);
1353              
1354             Calls the L method and sets th L field to C.
1355              
1356             =head2 new_c99
1357            
1358             my $config = SPVM::Builder::Config->new_c99(file => __FILE__);
1359              
1360             Calls the L method and sets the L field to C.
1361              
1362             =head2 new_c11
1363            
1364             my $config = SPVM::Builder::Config->new_c11(file => __FILE__);
1365              
1366             Calls the L method and sets the L field to C.
1367              
1368             =head2 new_gnu99
1369            
1370             my $config = SPVM::Builder::Config->new_gnu99(file => __FILE__);
1371              
1372             Calls the L method and sets the L field to C.
1373              
1374             =head2 new_gnu11
1375            
1376             my $config = SPVM::Builder::Config->new_gnu11(file => __FILE__);
1377              
1378             Calls the L method and sets the L field to C.
1379              
1380             =head2 new_cpp
1381            
1382             my $config = SPVM::Builder::Config->new_cpp(file => __FILE__);
1383              
1384             Calls the L method and sets the L field to C and sets the L field to a C compiler and sets the L field to a C linker.
1385              
1386             If C<$Config{gccversion}> of the L class matches the regex C, the L field and the L field are set to C.
1387              
1388             Otherwise the L field and the L field are set to set to C.
1389              
1390             =head2 new_cpp11
1391            
1392             my $config = SPVM::Builder::Config->new_cpp11(file => __FILE__);
1393              
1394             Calls the L method and sets the L field to C.
1395              
1396             =head2 new_cpp14
1397            
1398             my $config = SPVM::Builder::Config->new_cpp14(file => __FILE__);
1399              
1400             Calls the L method and sets the L field to C.
1401              
1402             =head2 new_cpp17
1403            
1404             my $config = SPVM::Builder::Config->new_cpp17(file => __FILE__);
1405              
1406             Calls the L method and sets the L field to C.
1407              
1408             =head1 Instance Methods
1409              
1410             =head2 add_ccflag
1411              
1412             $config->add_ccflag(@ccflags);
1413              
1414             Adds values after the last element of L field.
1415              
1416             =head2 add_ldflag
1417              
1418             $config->add_ldflag(@ldflags);
1419              
1420             Adds values after the last element of L field.
1421              
1422             =head2 add_include_dir
1423              
1424             $config->add_include_dir(@include_dirs);
1425              
1426             Adds values after the last element of L field.
1427              
1428             =head2 add_lib_dir
1429              
1430             $config->add_lib_dir(@lib_dirs);
1431              
1432             Adds values after the last element of C field.
1433              
1434             =head2 add_source_file
1435              
1436             $config->add_source_file(@source_files);
1437              
1438             Adds elements after the last element of L field.
1439              
1440             =head2 add_before_compile_cb
1441              
1442             $config->add_before_compile_cb(@before_compile_cbs);
1443              
1444             Adds elements after the last element of L field.
1445              
1446             =head2 add_before_compile_cb
1447              
1448             $config->add_before_link_cb(@before_link_cbs);
1449              
1450             Adds elements after the last element of L field.
1451              
1452             =head2 add_lib
1453              
1454             $config->add_lib(@libs);
1455              
1456             Adds library names or L objects after the last element of L field.
1457              
1458             Examples:
1459              
1460             $config->add_lib('gsl');
1461             $config->add_lib('gsl', 'z');
1462             $config->add_lib(
1463             SPVM::Builder::LibInfo->new(name => 'gsl'),
1464             SPVM::Builder::LibInfo->new(name => 'z', abs => 1),
1465             );
1466              
1467             =head2 add_static_lib
1468              
1469             $config->add_static_lib(@libs);
1470              
1471             Adds library names or L objects after the last element of L field.
1472              
1473             C field is set to a true value.
1474              
1475             Examples:
1476              
1477             $config->add_static_lib('gsl');
1478             $config->add_static_lib('gsl', 'z');
1479             $config->add_static_lib(
1480             SPVM::Builder::LibInfo->new(name => 'gsl'),
1481             SPVM::Builder::LibInfo->new(name => 'z', abs => 1),
1482             );
1483              
1484             =head2 use_resource
1485              
1486             my $resource = $config->use_resource($resource_name);
1487             my $resource = $config->use_resource($resource_name, %options);
1488              
1489             Loads a resource by the resource name $resource_name using the L method in the L class, and returns a L object.
1490             my $resource = SPVM::Builder::Resource->new(class_name => $resource_name);
1491             $config->use_resource($resource);
1492              
1493             If the options %options are given, they are used as the options of the L method in the L class.
1494              
1495             my $resource = SPVM::Builder::Resource->new(
1496             class_name => 'Resource::Zlib',
1497             mode => 'production',
1498             argv => ['foo', 'bar'],
1499             );
1500             $config->use_resource($resource);
1501              
1502             Examples:
1503              
1504             $config->use_resource('Resource::Zlib');
1505              
1506             =head2 get_resource_names
1507              
1508             my $resource_names = $config->get_resource_names;
1509              
1510             Gets resource names loaded by the L/"use_resource/"> method.
1511              
1512             =head2 load_config
1513              
1514             my $config = $config->load_config($config_file, @argv);
1515              
1516             Loads a config file, and returns a L object. The argument @argv is set to the @ARGV of the config file.
1517              
1518             =head2 load_base_config
1519              
1520             my $config = $config->load_base_config($config_file, @argv);
1521              
1522             Loads a base config file like C. This method is the alias for the following method call using L.
1523              
1524             my $config = $config->load_mode_config($config_file, undef, @argv);
1525              
1526             =head2 load_mode_config
1527              
1528             my $config = $config->load_mode_config($config_file, $mode, @argv);
1529              
1530             Loads a mode config file like C.
1531              
1532             At first, removes the string matching the regex C<(\.[^\.]+)?\.config$> from the base name of the config file $config_file.
1533              
1534             Next, if the mode $mode is defined, C<.$mode.config> is added to $config_file. Otherwise C<.config> is added.
1535              
1536             Last, L is called with the modified name of the config file.
1537              
1538             =head2 get_loaded_config_files
1539              
1540             Gets the config files loaded by the L method.
1541              
1542             =head2 clone
1543              
1544             my $clone = $self->clone;
1545              
1546             Clones the L object, and returns it.
1547              
1548             =head1 Copyright & License
1549              
1550             Copyright (c) 2023 Yuki Kimoto
1551              
1552             MIT License