File Coverage

blib/lib/App/hopen/T/Gnu/C.pm
Criterion Covered Total %
statement 53 54 98.1
branch 3 6 50.0
condition n/a
subroutine 17 18 94.4
pod n/a
total 73 78 93.5


line stmt bran cond sub pod time code
1             # App::hopen::T::Gnu::C - support GNU toolset, C language
2             package App::hopen::T::Gnu::C;
3 1     1   524 use Data::Hopen;
  1         3  
  1         57  
4 1     1   5 use strict; use warnings;
  1     1   3  
  1         19  
  1         5  
  1         1  
  1         35  
5 1     1   8 use Data::Hopen::Base;
  1         2  
  1         6  
6              
7             our $VERSION = '0.000012'; # TRIAL
8              
9 1     1   1391 use App::hopen::BuildSystemGlobals; # For $DestDir.
  1         2  
  1         138  
10             # TODO make the dirs available to nodes through the context.
11 1     1   7 use App::hopen::Util::BasedPath;
  1         2  
  1         41  
12              
13 1     1   499 use App::hopen::T::Gnu::C::CompileCmd;
  1         4  
  1         46  
14 1     1   465 use App::hopen::T::Gnu::C::LinkCmd;
  1         4  
  1         37  
15              
16 1     1   6 use Config;
  1         2  
  1         36  
17 1     1   5 use Data::Hopen qw(getparameters);
  1         1  
  1         41  
18 1     1   7 use Data::Hopen::G::GraphBuilder;
  1         1  
  1         41  
19 1     1   5 use Data::Hopen::Util::Data qw(forward_opts);
  1         2  
  1         36  
20 1     1   5 use Data::Hopen::Util::Filename;
  1         3  
  1         24  
21 1     1   5 use File::Which ();
  1         2  
  1         14  
22 1     1   4 use Path::Class;
  1         2  
  1         554  
23              
24             my $FN = Data::Hopen::Util::Filename->new; # for brevity
25             our $_CC; # Cached compiler name
26              
27             # Docs {{{1
28              
29             =head1 NAME
30              
31             App::hopen::T::Gnu::C - support for the GNU toolset, C language
32              
33             =head1 SYNOPSIS
34              
35             In a hopen file:
36              
37             use language 'C';
38              
39             # Use via Data::Hopen::G::GraphBuilder:
40             $Build->H::files(...)->C::compile->default_goal;
41              
42             The inputs come from earlier in the build graph.
43             TODO support specifying compiler arguments.
44              
45             =cut
46              
47             # }}}1
48              
49             =head1 STATIC FUNCTIONS
50              
51             Arguments to the static functions are parsed using L<Getargs::Mixed>
52             (via L<Data::Hopen/getparameters>).
53             Therefore, named arguments start with a hyphen (e.g., C<< -name=>'foo' >>,
54             not C<< name=>'foo' >>).
55              
56             =head2 compile
57              
58             Create a new compilation command. Inputs come from the build graph,
59             so parameters other than C<-name> are disregarded (TODO permit specifying
60             compilation options or object-file names). Usage:
61              
62             use language 'C';
63             $builder_or_dag->H::files('file1.c')->C::compile([-name=>'node name']);
64              
65             =cut
66              
67             sub compile {
68             my ($builder, %args) = getparameters('self', [qw(; name)], @_);
69             my $node = App::hopen::T::Gnu::C::CompileCmd->new(
70             compiler => $_CC,
71             forward_opts(\%args, 'name')
72             );
73              
74             hlog { __PACKAGE__, 'Built compile node', Dumper($node) } 2;
75              
76             return $node; # The builder will automatically add it
77             } #compile()
78              
79             make_GraphBuilder 'compile';
80              
81             =head2 link
82              
83             Create a new link command. Pass the name of the
84             executable. Object files are on the incoming asset-graph edges. Usage:
85              
86             use language 'C';
87             $builder_or_dag->C::link([-exe=>]'output_file_name'[, [-name=>]'node name']);
88              
89             TODO? Permit specifying that you want C<ld> or another linker instead of
90             using the compiler?
91              
92             =cut
93              
94             sub link {
95             my ($builder, %args) = getparameters('self', [qw(exe; name)], @_);
96              
97             my $dest = based_path(path => file($FN->exe($args{exe})), base => $DestDir);
98              
99             my $node = App::hopen::T::Gnu::C::LinkCmd->new(
100             linker => $_CC,
101             dest => $dest,
102             forward_opts(\%args, 'name')
103             );
104             hlog { __PACKAGE__, 'Built link node', Dumper($node) } 2;
105              
106             return $node;
107             } #link()
108              
109             make_GraphBuilder 'link';
110              
111             =head1 INTERNALS
112              
113             =head2 _find_compiler
114              
115             Find the C compiler. Called when this package is first loaded.
116              
117             TODO permit the user to specify an alternative compiler to use
118              
119             TODO should this happen when the DAG runs?
120             Maybe toolsets should get the chance to add a node to the beginning of
121             the graph, before anything else runs. TODO figure this out.
122              
123             =cut
124              
125             sub _find_compiler {
126 1     1   26 foreach my $candidate ($Config{cc}, qw[cc gcc clang]) { # TODO also c89 or xlc?
127 1         8 my $path = File::Which::which($candidate);
128 1 50       231 next unless defined $path;
129              
130 1     0   18 hlog { __PACKAGE__, 'using C compiler', $path }; # Got it
  0         0  
131 1         9 $_CC = $path;
132 1         3 last;
133             }
134              
135 1 50       41 croak "Could not find a C compiler" unless $_CC;
136             } #_find_compiler()
137              
138 1 50   1   80 BEGIN { _find_compiler if eval '$App::hopen::RUNNING'; }
139              
140             1;
141             __END__
142             # vi: set fdm=marker: #