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   71147 use strict;
  283         741  
  283         8715  
4 283     283   1614 use warnings;
  283         661  
  283         10709  
5 283     283   1691 use Config;
  283         576  
  283         10990  
6 283     283   1550 use Carp 'confess';
  283         606  
  283         13641  
7 283     283   1773 use File::Basename 'dirname', 'fileparse';
  283         748  
  283         12201  
8 283     283   2205 use SPVM::Builder::Util;
  283         679  
  283         8019  
9 283     283   125806 use SPVM::Builder::LibInfo;
  283         5389  
  283         18415  
10 283     283   247685 use SPVM::Builder::Resource;
  283         848  
  283         1096614  
11              
12             # Fields
13             sub class_name {
14 346     346 1 938 my $self = shift;
15 346 100       1167 if (@_) {
16 343         931 $self->{class_name} = $_[0];
17 343         801 return $self;
18             }
19             else {
20 3         60 return $self->{class_name};
21             }
22             }
23              
24             sub file {
25 1205     1205 1 3423 my $self = shift;
26 1205 100       4241 if (@_) {
27 12         28 $self->{file} = $_[0];
28 12         25 return $self;
29             }
30             else {
31 1193         5634 return $self->{file};
32             }
33             }
34              
35             sub file_optional {
36 394     394 1 1049 my $self = shift;
37 394 50       1430 if (@_) {
38 0         0 $self->{file_optional} = $_[0];
39 0         0 return $self;
40             }
41             else {
42 394         2054 return $self->{file_optional};
43             }
44             }
45              
46             sub ext {
47 731     731 1 1472 my $self = shift;
48 731 100       1919 if (@_) {
49 377         1024 $self->{ext} = $_[0];
50 377         760 return $self;
51             }
52             else {
53 354         1164 return $self->{ext};
54             }
55             }
56              
57             sub quiet {
58 613     613 1 2732 my $self = shift;
59 613 100       1986 if (@_) {
60 5         13 $self->{quiet} = $_[0];
61 5         8 return $self;
62             }
63             else {
64 608         5747 return $self->{quiet};
65             }
66             }
67              
68             sub force {
69 818     818 1 3246 my $self = shift;
70 818 100       2815 if (@_) {
71 4         8 $self->{force} = $_[0];
72 4         7 return $self;
73             }
74             else {
75 814         5199 return $self->{force};
76             }
77             }
78              
79             sub cc {
80 745     745 1 1956 my $self = shift;
81 745 100       2464 if (@_) {
82 401         3543 $self->{cc} = $_[0];
83 401         1098 return $self;
84             }
85             else {
86 344         1370 return $self->{cc};
87             }
88             }
89              
90             sub ccflags {
91 733     733 1 1816 my $self = shift;
92 733 100       2270 if (@_) {
93 394         1146 $self->{ccflags} = $_[0];
94 394         835 return $self;
95             }
96             else {
97 339         1356 return $self->{ccflags};
98             }
99             }
100              
101             sub dynamic_lib_ccflags {
102 733     733 1 1705 my $self = shift;
103 733 100       2426 if (@_) {
104 394         1016 $self->{dynamic_lib_ccflags} = $_[0];
105 394         911 return $self;
106             }
107             else {
108 339         1370 return $self->{dynamic_lib_ccflags};
109             }
110             }
111              
112             sub thread_ccflags {
113 733     733 1 1765 my $self = shift;
114 733 100       2177 if (@_) {
115 394         1070 $self->{thread_ccflags} = $_[0];
116 394         842 return $self;
117             }
118             else {
119 339         1273 return $self->{thread_ccflags};
120             }
121             }
122              
123             sub std {
124 721     721 1 2414 my $self = shift;
125 721 100       2253 if (@_) {
126 375         982 $self->{std} = $_[0];
127 375         751 return $self;
128             }
129             else {
130 346         1638 return $self->{std};
131             }
132             }
133              
134             sub optimize {
135 736     736 1 1867 my $self = shift;
136 736 100       2307 if (@_) {
137 397         1103 $self->{optimize} = $_[0];
138 397         853 return $self;
139             }
140             else {
141 339         1549 return $self->{optimize};
142             }
143             }
144              
145             sub include_dirs {
146 733     733 1 1960 my $self = shift;
147 733 100       2315 if (@_) {
148 394         971 $self->{include_dirs} = $_[0];
149 394         868 return $self;
150             }
151             else {
152 339         1719 return $self->{include_dirs};
153             }
154             }
155              
156             sub spvm_core_include_dir {
157 1127     1127 1 2474 my $self = shift;
158 1127 100       3372 if (@_) {
159 394         1942 $self->{spvm_core_include_dir} = $_[0];
160 394         1122 return $self;
161             }
162             else {
163 733         2859 return $self->{spvm_core_include_dir};
164             }
165             }
166              
167             sub native_include_dir {
168 1166     1166 1 2544 my $self = shift;
169 1166 100       3108 if (@_) {
170 41         155 $self->{native_include_dir} = $_[0];
171 41         112 return $self;
172             }
173             else {
174 1125         4143 return $self->{native_include_dir};
175             }
176             }
177              
178             sub native_src_dir {
179 789     789 1 1460 my $self = shift;
180 789 100       1937 if (@_) {
181 41         153 $self->{native_src_dir} = $_[0];
182 41         113 return $self;
183             }
184             else {
185 748         2303 return $self->{native_src_dir};
186             }
187             }
188              
189             sub source_files {
190 748     748 1 1607 my $self = shift;
191 748 100       2023 if (@_) {
192 394         1023 $self->{source_files} = $_[0];
193 394         830 return $self;
194             }
195             else {
196 354         1364 return $self->{source_files};
197             }
198             }
199              
200             sub before_compile_cbs {
201 766     766 1 1659 my $self = shift;
202 766 100       2145 if (@_) {
203 394         1039 $self->{before_compile_cbs} = $_[0];
204 394         892 return $self;
205             }
206             else {
207 372         1426 return $self->{before_compile_cbs};
208             }
209             }
210              
211             sub ld {
212 1018     1018 1 2783 my $self = shift;
213 1018 100       3347 if (@_) {
214 401         17626 $self->{ld} = $_[0];
215 401         1458 return $self;
216             }
217             else {
218 617         4179 return $self->{ld};
219             }
220             }
221              
222             sub ldflags {
223 926     926 1 1892 my $self = shift;
224 926 100       2977 if (@_) {
225 394         1104 $self->{ldflags} = $_[0];
226 394         889 return $self;
227             }
228             else {
229 532         2123 return $self->{ldflags};
230             }
231             }
232              
233             sub dynamic_lib_ldflags {
234 653     653 1 1888 my $self = shift;
235 653 100       2451 if (@_) {
236 394         1005 $self->{dynamic_lib_ldflags} = $_[0];
237 394         1218 return $self;
238             }
239             else {
240 259         1929 return $self->{dynamic_lib_ldflags};
241             }
242             }
243              
244             sub thread_ldflags {
245 657     657 1 2116 my $self = shift;
246 657 100       2489 if (@_) {
247 394         1957 $self->{thread_ldflags} = $_[0];
248 394         1056 return $self;
249             }
250             else {
251 263         1525 return $self->{thread_ldflags};
252             }
253             }
254              
255             sub ld_optimize {
256 1263     1263 1 2949 my $self = shift;
257 1263 100       6573 if (@_) {
258 394         1168 $self->{ld_optimize} = $_[0];
259 394         869 return $self;
260             }
261             else {
262 869         7036 return $self->{ld_optimize};
263             }
264             }
265              
266             sub lib_dirs {
267 1000     1000 1 2554 my $self = shift;
268 1000 100       3148 if (@_) {
269 394         960 $self->{lib_dirs} = $_[0];
270 394         978 return $self;
271             }
272             else {
273 606         2527 return $self->{lib_dirs};
274             }
275             }
276              
277             sub libs {
278 1343     1343 1 3579 my $self = shift;
279 1343 100       4060 if (@_) {
280 737         2060 $self->{libs} = $_[0];
281 737         3180 return $self;
282             }
283             else {
284 606         2759 return $self->{libs};
285             }
286             }
287              
288             sub before_link_cbs {
289 737     737 1 2019 my $self = shift;
290 737 100       2775 if (@_) {
291 394         1139 $self->{before_link_cbs} = $_[0];
292 394         879 return $self;
293             }
294             else {
295 343         1666 return $self->{before_link_cbs};
296             }
297             }
298              
299             sub output_type {
300 1992     1992 1 4264 my $self = shift;
301 1992 100       5064 if (@_) {
302 391         1105 $self->{output_type} = $_[0];
303 391         843 return $self;
304             }
305             else {
306 1601         7481 return $self->{output_type};
307             }
308             }
309              
310             # Class Methods
311             sub new {
312 394     394 1 9238 my $class = shift;
313            
314 394         1565 my $self = {@_};
315              
316 394   33     3108 bless $self, ref $class || $class;
317            
318 394         3309 my $file_optional = $self->file_optional;
319            
320 394         2055 my $file = $self->file;
321 394 50 66     1677 if (!$file_optional && !defined $file) {
322 0         0 confess "\"file\" option must be specified";
323             }
324            
325             # cc
326 394 50       1506 unless (defined $self->{cc}) {
327 394         3220 $self->cc($Config{cc});
328             }
329              
330             # ccflags
331 394 50       1806 unless (defined $self->{ccflags}) {
332 394         2082 $self->ccflags([]);
333             }
334            
335             # dynamic_lib_ccflags
336 394 50       1461 unless (defined $self->{dynamic_lib_ccflags}) {
337 394 50       3096 if ($^O eq 'MSWin32') {
338 0         0 $self->dynamic_lib_ccflags([]);
339             }
340             else {
341 394         2174 $self->dynamic_lib_ccflags(['-fPIC']);
342             }
343             }
344            
345             # thread_ccflags
346 394 50       1461 unless (defined $self->{thread_ccflags}) {
347 394 50       1326 if ($^O eq 'MSWin32') {
348 0         0 $self->thread_ccflags([]);
349             }
350             else {
351 394         1976 $self->thread_ccflags(['-pthread']);
352             }
353             }
354            
355             # optimize
356 394 50       1358 unless (defined $self->{optimize}) {
357 394         2203 $self->optimize('-O3');
358             }
359            
360             # include_dirs
361 394 50       1382 unless (defined $self->{include_dirs}) {
362 394         1945 $self->include_dirs([]);
363             }
364            
365             # spvm_core_include_dir
366 394 50       1911 unless (defined $self->spvm_core_include_dir) {
367 394         1742 my $builder_dir = SPVM::Builder::Util::get_builder_dir_from_config_class();
368 394         1435 my $spvm_core_include_dir = "$builder_dir/include";
369            
370 394         1193 $self->spvm_core_include_dir($spvm_core_include_dir);
371             }
372            
373             # native_include_dir
374 394 50       1965 unless (defined $self->native_include_dir) {
375 394 100       1364 if (defined $file) {
376 41         209 my $native_dir = $self->_remove_ext_from_config_file($file);
377 41         109 $native_dir .= '.native';
378 41         137 my $native_include_dir = "$native_dir/include";
379            
380 41         139 $self->native_include_dir($native_include_dir);
381             }
382             }
383            
384             # native_src_dir
385 394 50       1950 unless (defined $self->native_src_dir) {
386 394 100       1276 if (defined $file) {
387 41         202 my $native_dir = $self->_remove_ext_from_config_file($file);
388 41         110 $native_dir .= '.native';
389 41         121 my $native_src_dir = "$native_dir/src";
390            
391 41         117 $self->native_src_dir($native_src_dir);
392             }
393             }
394            
395             # source_files
396 394 50       1294 unless (defined $self->{source_files}) {
397 394         1972 $self->source_files([]);
398             }
399            
400             # before_compile_cbs
401 394 50       1511 unless (defined $self->{before_compile_cbs}) {
402 394         1958 $self->before_compile_cbs([]);
403             }
404            
405             # resources
406 394 50       1667 unless (defined $self->{resources}) {
407 394         1242 $self->{resources} = {};
408             }
409            
410             # ld
411 394 50       1341 unless (defined $self->{ld}) {
412 394         2630 $self->ld($Config{ld});
413             }
414            
415             # ldflags
416 394 50       1730 unless (defined $self->{ldflags}) {
417 394         1727 $self->ldflags([]);
418             }
419            
420             # output_type
421 394 100       1702 unless (defined $self->output_type) {
422 391         1118 $self->output_type('dynamic_lib');
423             }
424            
425             # dynamic_lib_ldflags
426 394 50       1329 unless (defined $self->{dynamic_lib_ldflags}) {
427 394 50       1777 if ($^O eq 'MSWin32') {
428 0         0 $self->dynamic_lib_ldflags(['-mdll', '-s']);
429             }
430             else {
431 394         2301 $self->dynamic_lib_ldflags(['-shared', '-pthread']);
432             }
433             }
434            
435             # thread_ldflags
436 394 50       1481 unless (defined $self->{thread_ldflags}) {
437 394 50       1491 if ($^O eq 'MSWin32') {
438 0         0 $self->thread_ldflags([]);
439             }
440             else {
441 394         1995 $self->thread_ldflags(['-pthread']);
442             }
443             }
444            
445             # ld_optimize
446 394 50       1530 unless (defined $self->{ld_optimize}) {
447 394         1791 $self->ld_optimize('-O2');
448             }
449            
450             # lib_dirs
451 394 50       1313 unless (defined $self->{lib_dirs}) {
452 394         1674 $self->lib_dirs([]);
453             }
454            
455             # libs
456 394 50       1348 unless (defined $self->{libs}) {
457 394         2013 $self->libs([]);
458             }
459            
460             # before_link_cbs
461 394 50       1472 unless (defined $self->{before_link_cbs}) {
462 394         1909 $self->before_link_cbs([]);
463             }
464            
465 394 50       1512 unless (defined $self->{_loaded_config_files}) {
466 394         15124 $self->{_loaded_config_files} = [];
467             }
468            
469 394         1355 return $self;
470             }
471              
472             sub new_c {
473 371     371 1 2097 my $class = shift;
474            
475 371         2364 my $self = $class->new(@_);
476            
477 371         1857 $self->ext('c');
478            
479 371         800 return $self;
480             }
481              
482             sub new_c99 {
483 1     1 1 552 my $class = shift;
484            
485 1         4 my $self = $class->new_c(@_);
486            
487             # C99
488 1         35 $self->std('c99');
489            
490 1         3 return $self;
491             }
492              
493             sub new_c11 {
494 1     1 1 525 my $class = shift;
495            
496 1         4 my $self = $class->new_c(@_);
497            
498             # C11
499 1         4 $self->std('c11');
500            
501 1         3 return $self;
502             }
503              
504             sub new_gnu99 {
505 367     367 1 10308 my $class = shift;
506            
507 367         2340 my $self = $class->new_c(@_);
508            
509             # GNU C99
510 367         1941 $self->std('gnu99');
511            
512 367         1032 return $self;
513             }
514              
515             sub new_gnu11 {
516 1     1 1 530 my $class = shift;
517            
518 1         4 my $self = $class->new_c(@_);
519            
520             # GNU C11
521 1         4 $self->std('gnu11');
522            
523 1         3 return $self;
524             }
525              
526              
527             sub new_cpp {
528 6     6 1 859 my $class = shift;
529            
530 6         21 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       43 if ($config_gcc_version =~ /\bclang\b/i) {
537 0         0 $self->cc('clang++');
538 0         0 $self->ld('clang++');
539             }
540             else {
541 6         20 $self->cc('g++');
542 6         12 $self->ld('g++');
543             }
544            
545 6         22 $self->ext('cpp');
546            
547 6         15 return $self;
548             }
549              
550             sub new_cpp11 {
551 3     3 1 1024 my $class = shift;
552            
553 3         15 my $self = $class->new_cpp(@_);
554            
555             # C++11
556 3         13 $self->std('c++11');
557            
558 3         10 return $self;
559             }
560              
561             sub new_cpp14 {
562 1     1 1 494 my $class = shift;
563            
564 1         4 my $self = $class->new_cpp(@_);
565            
566             # C++14
567 1         3 $self->std('c++14');
568            
569 1         3 return $self;
570             }
571              
572             sub new_cpp17 {
573 1     1 1 538 my $class = shift;
574            
575 1         5 my $self = $class->new_cpp(@_);
576            
577             # C++17
578 1         4 $self->std('c++17');
579            
580 1         2 return $self;
581             }
582              
583             # Instance Methods
584             sub add_ccflag {
585 2     2 1 17 my ($self, @ccflags) = @_;
586            
587 2         4 push @{$self->{ccflags}}, @ccflags;
  2         9  
588             }
589              
590             sub add_include_dir {
591 11     11 1 99 my ($self, @include_dirs) = @_;
592            
593 11         29 push @{$self->{include_dirs}}, @include_dirs;
  11         84  
594             }
595              
596             sub add_ldflag {
597 2     2 1 15 my ($self, @ldflags) = @_;
598            
599 2         4 push @{$self->{ldflags}}, @ldflags;
  2         8  
600             }
601              
602             sub add_lib_dir {
603 1     1 1 10 my ($self, @lib_dirs) = @_;
604            
605 1         2 push @{$self->{lib_dirs}}, @lib_dirs;
  1         4  
606             }
607              
608             sub add_lib {
609 3     3 1 27 my ($self, @libs) = @_;
610            
611 3         7 push @{$self->{libs}}, @libs;
  3         12  
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 228 my ($self, @source_files) = @_;
637            
638 17         34 push @{$self->{source_files}}, @source_files;
  17         95  
639             }
640              
641             sub add_before_compile_cb {
642 112     112 1 372 my ($self, @before_compile_cbs) = @_;
643            
644 112         217 push @{$self->{before_compile_cbs}}, @before_compile_cbs;
  112         748  
645             }
646              
647             sub add_before_link_cb {
648 3     3 0 33 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 44     44 1 206 my ($self, $config_file, @args) = @_;
655              
656 44 50       696 unless (-f $config_file) {
657 0         0 confess "The config file \"$config_file\" must exist";
658             }
659 44         215 local @ARGV = @args;
660 44         29564 my $config = do File::Spec->rel2abs($config_file);
661 44 50       673 if ($@) {
662 0         0 confess "The config file \"$config_file\" can't be parsed: $@";
663             }
664            
665 44 50 33     541 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 44         105 push @{$config->get_loaded_config_files}, $config_file;
  44         186  
670            
671 44         202 return $config;
672             }
673              
674             sub load_mode_config {
675 3     3 1 24 my ($self, $config_file, $mode, @argv) = @_;
676            
677 3         20 my $mode_config_file = $self->_remove_ext_from_config_file($config_file);
678 3 50       22 if (defined $mode) {
679 0         0 $mode_config_file .= ".$mode";
680             }
681 3         17 $mode_config_file .= ".config";
682            
683 3 50       89 unless (-f $mode_config_file) {
684 0         0 confess "Can't find the config file \"$mode_config_file\"";
685             }
686            
687 3         37 my $config = $self->load_config($mode_config_file, @argv);
688            
689 3         14 return $config;
690             }
691              
692             sub load_base_config {
693 3     3 1 588 my ($self, $config_file, @args) = @_;
694            
695 3         28 my $config = $self->load_mode_config($config_file, undef, @args);
696              
697 3         12 return $config;
698             }
699              
700             sub get_loaded_config_files {
701 262     262 1 720 my $self = shift;
702            
703 262         1359 return $self->{_loaded_config_files};
704             }
705              
706             sub use_resource {
707 12     12 1 138 my ($self, @args) = @_;
708            
709 12         31 my $first_arg;
710 12 50       61 unless (@args % 2 == 0) {
711 12         63 $first_arg = shift @args;
712             }
713            
714 12         23 my $resource;
715 12 50       41 if (ref $first_arg) {
716 0         0 $resource = $first_arg;
717             }
718             else {
719 12         36 my $basic_type_name = $first_arg;
720 12         45 my %args = @args;
721 12 50       51 if (exists $args{class_name}) {
722 0         0 $basic_type_name = delete $args{class_name};
723             }
724 12         135 $resource = SPVM::Builder::Resource->new(class_name => $basic_type_name, %args);
725             }
726            
727 12         80 my $resource_basic_type_name = $resource->class_name;
728 12         51 my $resource_mode = $resource->mode;
729 12         41 my $resource_argv = $resource->argv;
730            
731 12 100       70 my $ext = defined $resource_mode ? "$resource_mode.config" : 'config';
732 12         68 my $config_file_base = SPVM::Builder::Util::convert_basic_type_name_to_rel_file($resource_basic_type_name, $ext);
733            
734 12         76 my $config_file = SPVM::Builder::Util::get_config_file_from_basic_type_name($resource_basic_type_name, $resource_mode);
735            
736 12         90 my $config = $self->load_config($config_file, @$resource_argv);
737 12         41 $config->file($config_file);
738            
739 12         66 $resource->config($config);
740            
741 12         20 my $index = keys %{$self->{resources}};
  12         41  
742            
743 12         124 $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 1379 my $self = shift;
750 350 100       2724 if (@_) {
751 11         106 $self->{disable_resource} = $_[0];
752 11         49 return $self;
753             }
754             else {
755 339         2460 return $self->{disable_resource};
756             }
757             }
758              
759             sub get_resource {
760 32     32 0 148 my ($self, $resource_basic_type_name) = @_;
761            
762 32 50       155 unless (defined $self->{resources}{$resource_basic_type_name}) {
763 0         0 return;
764             }
765            
766 32         93 my $resource = $self->{resources}{$resource_basic_type_name}{resource};
767            
768 32         107 return $resource;
769             }
770              
771             sub get_resource_names {
772 664     664 1 4184 my ($self) = @_;
773            
774 664         3652 my @resource_names = sort { $self->{resources}{$a}{index} <=> $self->{resources}{$b}{index} } keys %{$self->{resources}};
  8         120  
  664         6113  
775            
776 664         6758 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 85     85   249 my ($self, $config_file) = @_;
803            
804 85         2086 my ($config_base_name, $config_dir) = fileparse $config_file;
805            
806 85         674 $config_base_name =~ s/(\.[^\.]+)?\.config$//;
807            
808 85         258 my $config_file_without_ext = "$config_dir$config_base_name";
809            
810 85         235 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