File Coverage

blib/lib/App/hopen/T/Gnu/C.pm
Criterion Covered Total %
statement 56 57 98.2
branch 2 4 50.0
condition n/a
subroutine 18 19 94.7
pod n/a
total 76 80 95.0


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